- Home /
why do these both codes work similarly when they are put inside update function...
Method1::
{
Collider[] hits = Physics.OverlapSphere(transform.position, radius, enemyLayer);
foreach (Collider c in hits)
{
c.gameObject.GetComponent().TakeDamage(damageAmount);
}
enabled = false;
}
Method2::
{ Collider[] hits = Physics.OverlapSphere(transform.position, radius, enemyLayer);
foreach (Collider c in hits)
{
c.gameObject.GetComponent().TakeDamage(damageAmount);
enabled = false;
}
}
Answer by Bunny83 · Jul 09, 2018 at 02:30 AM
Well changing the enabled state of your script does not terminate the execution of your method. Actually the only thing that could terminate the execution would be an exception. If no exception is thrown a method will always execute until it's finished. This is even true when you deactivate or destroy your gameobject. Note when i said "destroy" i even mean DestroyImmediate and not Destroy as Destroy is always delayed until the end of the current frame (which includes the end of your method ^^).
Have a look at this example:
void Update ()
{
if (Input.GetKeyDown(KeyCode.Space))
{
DestroyImmediate(gameObject);
Debug.Log("After destroyed gameObject");
Debug.Log("Destroyed: " + name);
Debug.Log("This will not print");
}
Debug.Log("Finished Update");
}
When you press the Space bar the if condition will be true and the Update method will enter the if body. The first debug.Log statement is still executed because as i said the current method will continue until it reaches the end or if an exception is thrown. In this case here we will get an exception when the "name" property is evaluated. This is because the name of the gameobject was stored on the native C++ side. However when destroying an object the native object doesn't exist anymore. Though the managed object (your actual script instance) still exists since managed objects can never be destroyed manually. As long as your script does not touch anything related to the native object (like calling GetComponent, accessing "transform", etc on your destroyed object) the method will always complete.
In your case you only set the enabled state of your script to false. That means the object is still there and only the next frame Unity will not call Update on your object. However the current execution is of course finished.
Answer by hectorux · Jul 04, 2018 at 11:40 PM
Because that enable is generic, it may be a global and will always set to false
No, my problem is that in $$anonymous$$ethod1, the script will first take damage for all the hits in the array and than the gameobject(in which this script is attached) will be disabled and thats what happening while running this code(No Problem Here). But in $$anonymous$$ethod 2 shouldn't it take damage for the first element in array and than disable the gameobject(in which this script is attached)..But it is also giving same behaviour as that by method1
Note that the enabled property just controls your script component, not the whole gameobject. Setting enabled to false will just tell Unity to not call Update and other callbacks from now on. To deactivate the whole gameObject you have to use gameObject.SetActive(false);
The most important differences are:
enabled just prevents "some" callbacks on your script, but not all. Certain callbacks are still fired like OnBecameVisible for example.
setting enabled of your script to false will not affect other components on the same gameobject
deactivating the gameobject (with SetActive) will deactivate the whole gameobject. This does have an affect for all components. Also a deactivated gameobject won't receive any of the "normal" callbacks from Unity. It's like the object doesn't exist from the engine's point of view. However you can still call method on components on that gameobject from another gameobject.
Answer by YBtheS · Jul 09, 2018 at 12:46 AM
Note: I am partly working off of your comment on @hectorux's answer
No because to disable a game object you need to do GameObject.SetActive(false);
. enabled
doesn't have control of this. If you want the change in enabled
to immediately change the state of the game object than you have to do this:
{ Collider[] hits = Physics.OverlapSphere(transform.position, radius, enemyLayer);
foreach (Collider c in hits)
{
c.gameObject.GetComponent().TakeDamage(damageAmount);
enabled = false;
c.gameObject.SetActive(enabled); //This is assuming that you are trying to disable c.gameObject
}
}
So essentially, the reason why they work the same way it seems (I can't tell definitively without more code) is because you are using c.gameObject.SetActive(enabled)
somewhere later in the code. enabled
will be set to false however it will only change the state of the game object once you have called the SetActive method.
Uhm enabled is a property of every $$anonymous$$onoBehaviour component (actually defined in the baseclass Behaviour). So he actually disables this component where this code is located in.
However changing the state of the component does not "magically" ter$$anonymous$$ate the execution ^^.
Oh really? I never knew that. I'll edit my answer.
Edit: Wait a $$anonymous$$ute... the Behaviour.enabled referred to when I look it up in the API is one that I actually knew of. The problem here is that there is no component referenced. He would need to do someComponent.enabled = false;
would he not? Also he said that he wants to disable the enter game object, not just the component so this wouldn't achieve his goal anyways.
Your answer
Follow this Question
Related Questions
why do these both codes work similarly when they are put inside update function... 2 Answers
Finding object in update function not working. 0 Answers
Update breaks function 2 Answers
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers