- Home /
GameObject.SetActive not working in Coroutine?
Hello guys,
I am currently working on a turn-based-Combat sytem, but I have a problem. I want my buttons, which are used to select the targets, to be activated and deactivated at will. But somehow GameObject.SetActive() does not seem to work, even if I assign a parent to my buttons and even if I have the script on another object. Why does this happen? Am I making some silliy error?
Thank you in advance
Code(small sample not the whole code):
IEnumerator playerInput(){
foreach (Transform child in buttonParent){
child.gameObject.SetActive(true);
}
}
That code will only activate the buttons, you'll need to pass false
to SetActive() to deactivate them.
GameObject.SetActive() does work. You're probably either calling it on the wrong thing, calling it twice in quick succession (ie off and on again), or not calling it at all. A few Debug.Log lines might help deter$$anonymous$$e if any of those things is (or isn't) happening.
I don't follow what you're saying about assigning parents and having the script on another object. Those things shouldn't make any difference, so long as you're still calling SetActive() and calling it on the right GameObject.
Having in $$anonymous$$d what Bonfire-Boy said. I think you wanted to do something like this, maybe
Transform buttonParent;
[SerializeField]bool activateThem;
private void Start()
{
buttonParent = this.transform;// equal whatever you want
StartCoroutine( playerInput( activateThem ) );
}
void Update()
{
if ( Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.Space) ) {// or some other condition
activateThem = !activateThem;//invert the bool
StartCoroutine( playerInput(activateThem) );
}
}
IEnumerator playerInput(bool value)
{
foreach ( Transform child in buttonParent ) {
child.gameObject.SetActive( value );
}
yield return null;// or whatever
}
Thanks for the answers and sorry for my bad english, I am german. I will check my code again tomorrow for errors and i will try to implement FDZs idea. The buttons are turned off at the start at the game - I deactivated them in the editor by hand. I will also send the whole code tomorrow, maybe this will give you more insight.
Well, maybe it will hopefully somehow work tomorrow.
Answer by AcePilot10 · Dec 11, 2017 at 08:24 PM
An IEnumerator must have a yield return statement. If you want it to pause every loop, you could say
yield return new WaitForSeconds(AMOUNT OF SECONDS);
or you could simply just do:
yield return null
Which in that case, I don't really understand why you need it to be a coroutine
I see that my inital question was kind of unclear, I will post my whole code tomorrow. I was uncertain if I made an error or if Coroutines were the problem. The coroutine basically exists so that the program waits until the player selected a move - this works just fine. But the buttons that are deactivated at the start of the game wont activate.
Sorry for my unclear question, I hope that now or tomorrow it will be clear to you.
To be fair, you did say that it wasn't complete code. If your actual coroutine didn't have a yield in it, it wouldn't have even compiled.
Here is my full code(exept the enemy ai, i guess that is not important):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class turnBasedCombat : $$anonymous$$onoBehaviour {
public enum turn {
player,
enemy
}
[HideInInspector]public turn Turn;
[HideInInspector]public GameObject[] players, enemys;
[HideInInspector]public Transform buttonParent;
[HideInInspector]public PlayerLog log;
void Awake(){
log = GameObject.Find("Game$$anonymous$$anager").GetComponent<PlayerLog>();
players = GameObject.FindGameObjectsWithTag("player");
enemys = GameObject.FindGameObjectsWithTag("enemy");
int i = Random.Range(0,100);
if(i > 50){
Turn = turn.enemy;
} else if(i < 50) {
Turn = turn.player;
}
buttonParent = GameObject.FindGameObjectWithTag("target").transform;
}
void Update(){
switch(Turn){
case turn.player: //TODO
StartCoroutine("playerInput");
break;
case turn.enemy:
log.AddEvent("Enemys Turn");
enemy();
break;
}
}
[HideInInspector]public bool selectionOn; //checks if a attack is selected and if the target buttons can be activated
[HideInInspector]public GameObject target;
[HideInInspector]public baseAttack att; //This is just the attack that was selected
IEnumerator playerInput(){ //TODO zsm. mit uiFunctions
while(!uiFunctions.performedAction){ //waits for an input
yield return null;
}
if(uiFunctions.performedAction){
selectionOn = true;
att = this.gameObject.GetComponent<uiFunctions>().attack;
if(selectionOn){ //TODO draggable,dynamic list of buttons I$$anonymous$$PORTANT DIE $$anonymous$$NÖPFE müssen angehen
foreach (Transform child in buttonParent){
Debug.Log(child);
child.gameObject.SetActive(true);
}
selectionOn = false;
}
foreach (Transform child in buttonParent){
child.gameObject.SetActive(false);
}
}
uiFunctions.performedAction = false;
Turn = turn.enemy;
//I$$anonymous$$PORTANT yield return null; oder nichts hinschreiben?
}
The buttons are deactivated in the Editor
It's not clear to me what this is supposed to do. But it seems unlikely that your playerInput coroutine is doing what's intended.
The if(uiFunctions.performedAction)
block is the one to look at. It is doing the second of the things I listed above (turning them on and then immediately off again).
First (if selectionOn
is true, which it is because you just set it to be true), you loop through the buttons setting them to be active. Then you immediately loop through them all again setting them all to be inactive. So this code will always end with them all inactive. Stripped down, you're doing this...
foreach (Transform child in buttonParent)
{
child.gameObject.SetActive(true);
}
foreach (Transform child in buttonParent)
{
child.gameObject.SetActive(false);
}
So, what is the intention?
Oh, now I see - it was just a dumb error. The buttons are turned on, but are immediatly turned off. Thank you for your patience and your answer.
Your answer

Follow this Question
Related Questions
GameObject[] Issues 1 Answer
Zombie won't die 2 Answers
SetActive() not working on child objects 2 Answers
!IsActive && !GetRunInEditMode 5 Answers
SetActive is broken 0 Answers