- Home /
Accessing other objects efficiently
When an object touches the trigger, the trigger wants to know how to deal with this object. Calling GetComponent() several times per frame is not very efficient, I've read. Tags cannot be used because they're not strictly associated with components.
Is there an efficient way to access component code of an object at runtime (such as from OnTriggerStay). For example, some game engines would have something like a collider.gameObject.userData object which can be cast at runtime yielding decent performance (although that's somewhat nasty as well). The userData would be a class that caches all the components at load time, for example.
Thanks!
Attaching a script to the game object with a type of collider that your player or some body is colliding with, marking it as a trigger, and acting upon that event in OnTriggerEnter, Stay or Exit doesn't work out?
How would OnTriggerStay know what type of object touched the trigger? Without calling GetComponent (potentially) many times per frame?
Answer by skovacs1 · Oct 22, 2010 at 08:28 PM
You're asking how to avoid GetComponent(), right?
GetComponent returns the component instance of something somewhere. To avoid calling GetComponent you must to get the component and store it somewhere more accessible.
Storing the component in general
Since you don't really know what you're colliding with, simply storing the collided object may not work for you. If you only have certain things that can collide with this, then you can store and check against those. If your use case promotes recurrent collisions, you could still cache the last object & component that were collided with and when a new collision occurs, check and use them if they're the same, otherwise chuck them and GetComponent.
Static = everybody knows about it
Using statically scoped functions and variables would make things even easier, but such scripts may need to be a little smarter than the average script because static functions cannot access the public Monobehaviour-local variables that would refer to the instance to which the script is attached. If there's only a few objects, this is viable and potentially more efficient solution as a static script with a static, quicker-to-search container (HashSet for example) that contains references to the things you care about colliding with, can be quickly searched, which is likely less overhead than getComponent;
Every Frame?
You say you're concerned about calling GetComponent every frame. Why would you do that then? You could avoid OnTriggerStay by storing the component of the object OnTriggerEnter and removing the it OnTriggerExit, performing whatever it is you were doing OnTriggerStay within Update to each component stored and this would call GetComponent only OnCollisionEnter and maybe OnCollisionExit, but not every frame.
Another thing that worked in my case (I'm ashamed to admit this just came to me) is changing the trigger's receiver. 90% of the collisions that matter to me occur between the character and the game object -- so implementing the trigger callback in the objects, and comparing the character's static instance with the collider GameObject is a way to get rid of 90% of GetComponent calls in my case.
Thanks for the answer!
I was also able to reduce GetComponent calls further by adding a component that caches all components present at load time. Then, all subsequent component lookups are made through that component to guarantee only 1 lookup per object. Again, probably pretty obvious and doesn't always help, but worked in my case and just wanted to share! Thanks again
Your answer
Follow this Question
Related Questions
SendMessage or GetComponent 1 Answer
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
How do I select a joint component from a GameObject that has multiple joint components? 1 Answer
accessing script components from external objects 2 Answers
Implementing Setter/Getter 0 Answers