- Home /
My object desactive and active multiple time in a frame
Hello i have a very simple problem in my script, the problem is when i press my key, the fonction desactive and active multiple time, i dont understand because i use getkeydown who normally use one frame.
if someone can explain the problem it be very very nice and thankful, sorry for bad english
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LightController : MonoBehaviour
{
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown("f"))
{
if (gameObject.activeSelf == true)
{
gameObject.SetActive(false);
Debug.Log("Desactive light");
}
if (gameObject.activeSelf == false)
{
gameObject.SetActive(true);
Debug.Log("Active light");
}
}
}
}
Answer by Bunny83 · Jan 07, 2019 at 12:38 AM
Look careful at the line where i added the comment:
void Update()
{
if (Input.GetKeyDown("f"))
{
if (gameObject.activeSelf == true)
{
gameObject.SetActive(false);
Debug.Log("Desactive light");
}
// You have no else here.
if (gameObject.activeSelf == false)
{
gameObject.SetActive(true);
Debug.Log("Active light");
}
}
}
Since you have no else between your two if statements, they are both executed one after another when you press your button. So if the object is active when you press the button your first if statement is true and you deactivate the object. Now the execution continues to the second if statement. Since you just deactivated the object the second if statement is also true and you activate the object again within the same frame. Your code only run once.
You should do something like this:
void Update()
{
if (Input.GetKeyDown("f"))
{
if (gameObject.activeSelf)
{
gameObject.SetActive(false);
Debug.Log("Desactive light");
}
else
{
gameObject.SetActive(true);
Debug.Log("Active light");
}
}
}
Or even simpler:
void Update()
{
if (Input.GetKeyDown("f"))
{
gameObject.SetActive(!gameObject.activeSelf);
}
}
This will simple toggle the state since we pass the opposite of the current state as the new state (note the !
).
edit
As it turns out the approach of deactivating the gameobject doesn't work since the gameobject can not activate itself again once it's deactivated. To toggle (enable / disable) just the Light component you can do:
private Light m_Light;
void Awake()
{
m_Light = GetComponent<Light>();
}
void Update()
{
if (Input.GetKeyDown("f"))
{
m_Light.enabled = !m_Light.enabled;
}
}
Answer by Magso · Jan 07, 2019 at 12:35 AM
It's checking both ifs at once, so it's turning off and on in a single frame. Use "else if" on the last if statement, that way it will only do the first statement that returns true and skip the rest.
Thanks now i understand the problem but I use this script but now i cant active light anymore
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LightController : $$anonymous$$onoBehaviour
{
// Update is called once per frame
void Update()
{
if (Input.Get$$anonymous$$eyDown("f"))
{
if (gameObject.activeSelf == true)
{
gameObject.SetActive(false);
Debug.Log("Desactive light");
}
else if (gameObject.activeSelf == false)
{
gameObject.SetActive(true);
Debug.Log("Active light");
}
}
}
}
Well, of course you can't ^^ When you deactivate the whole gameobject the update callback won't be called anymore. The gameobject basically shot itself in the foot.
You have two possible solutions:
First, don't deactivate the gameobject but maybe only disable a certain component. You probably want to disable / enable the Light component of the gameobject.
The other option is to put the light controller on a seperate gameobject that doesn't get deactivated and add a reference to the actual light gameobject and activate / deactivate this referenced object and not the object the script is attached to.
I completely missed that the object was being set inactive. Your first solution is easier.
gameObject.GetComponent<Light>().enabled = true/false;
However just seen GetComponent light is now obsolete!?