- Home /
Is enabling and disabling a script component with an Update() function in it a good practice?
Hiya!
I have a player movement script that checks whether or not the player is where the mouse has clicked. The update function in the player movement script looks a bit like this:
function Update()
{
if (player != playerDestinationPosition)
{
// then player should move to the destination position
}
}
In this game the player won't always be moving around, so I don't want the update to be checking the player's position all the time. My current player script has no update function in it but it enables the player movement script containing the above update function. When the player stops, the player movement script is disabled, meaning the update ceases to run until the player clicks again.
I'm thinking of ditching this method in favour of some coroutines, but can anyone think of any reason why not to use this method?
Thanks very much!
Romano
Answer by haim96 · May 12, 2014 at 06:05 AM
coroutine are nice but you need to be careful with them. for example not to run corutine more then once when not needed etc... it can impact performance. after all, if all you have inside the update is the movement there is no reason why not to leave it there with simple if statement (you will need it any why with coroutine as well, no? )
but if the update is always checking the if statement, isnt that some overhead that could be reduced by disabling the script?
and you should cache the player transform component so moving it and checking the position will impact less the performance.
Transform cachedTransform;
void Start(){
cachedTransform = GetComponent<Transform>();
}
then use it like this: cachedTransform.position
maybe, but you need to remember that you need to activate it back some how by second script. maybe by clicking the mouse button...
any way, here nice optimization doc from unity:
http://docs.unity3d.com/410/Documentation/ScriptReference/index.Performance_Optimization.html
I know about caching the transform, thanks for that :)
I've also read the performance optimisation doc. At the end it says: "3. Use Coroutines. The problem with Update calls is that they happen every frame. Quite possibly checking the distance to the player could be performed only every 5 seconds. This would save a lot of processing power."
Which is the reason I've got a script enabling/ disabling the script with the update function in it.
One script (called player) enables the script-with-the-update ( called player$$anonymous$$oveScript) and player$$anonymous$$oveScript disables itself when the conditions for existing are no longer met.
All seems fine to me, but I haven't seen many people recommend this method which makes me think theres probably a reason for it.
some good link about this:
and mobile optimization: https://docs.unity3d.com/Documentation/$$anonymous$$anual/iphone-PracticalScriptingOptimizations.html
i prefer to add links to since they explain better thing then i can with my english... :)
and another think about GC.. i read somewhere that it is a good idea to run GC when ever you can - not in game run time, for example when showing pause screen, before level start etc...
Answer by Owen-Reynolds · May 12, 2014 at 02:45 PM
There's only one player, so not really any reason to complicate things by trying to save a single "am I moving" check each frame.
And Update may eventually want code for managing an idle, or a head look, or a "recoil" after being hit... , where it needs to always run.
Coroutines are also good for things that won't abort, and are the only thing happening that way. If you have a regular move target with Update movement, you can easily change the target, or cancel movement by changing it to your current position. If coroutines move you, tougher. If you aren't careful, they just fight each other.
Hiya, thanks for answering :)
It's true that there's only one player but there will be many other scripts with update functions checking just one thing. After a while wouldn't it become helpful to disable some of these, including the player movement?
Currently I'm controlling animation separately so that update function will never have anything other than the movement code.
If you want to go that way, then maybe change every Update into do$$anonymous$$ove? Then the master script in charge of disable/enable can ins$$anonymous$$d keep it's own list of "things that move" and can call or not call do$$anonymous$$ove on each. $$anonymous$$ore of a traditional program$$anonymous$$g style.
I don't know there's anything wrong with disabling a script. But I feel I've gotten funny results, like it still runs OnEnter(?)
I think that's kinda what I'm doing? Unless I haven't understood what you just said, which is possible. I'm not sure what OnEnter is either, interesting that there's funny results with enable/ disable though...
What I mean is, change the name of Update() to do$$anonymous$$ove(). Now it will never auto-run. Your master scene script would have: foreach(mobScript ms in active$$anonymous$$obList) ms.do$$anonymous$$ove();
. To "disable" a script, move it to your personal Inactive$$anonymous$$obList.
This is old-style game code, such as XNA would use, or Unity secretly uses. It isn't really better, but it maybe feels like more what you're trying to do.
I'm sure script disable has some precise rules (does OnCollision still get called?,) I've just never tested and feel like I've been surprised.
the enabled property only affects the functions that are called at set intervals. The $$anonymous$$B documentation lists them all.
Your answer
Follow this Question
Related Questions
Checkibg Rigidbody2d and component problems 0 Answers
How to trigger udpate in editor mode only when I modify component parameters 1 Answer
Turn off a script? 2 Answers
How to Get TextMesh component from the Gameobject the script is attached to? 3 Answers
How to attach a prefab to a script that is added dynamically 0 Answers