- Home /
is raycast efficient in update ?
Hello,
I am using raycast in my update method to check if the ray from the gun hits the enemy or not. if its hitting then I change the color of the crosshair.
I just want to know if this is the right way of doing it and will not be expensive.
Please let me know if there is any better suggestion.
Below is the code:-
void Update () {
Ray ray = new Ray(transform.position, transform.forward);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, gunRange))
{
if(hit.transform.tag== "Enemy")
{
crossHair.color = Color.red;
}
else
{
crossHair.color = Color.white;
}
}
}
Answer by YoungDeveloper · Apr 17, 2015 at 10:08 PM
Cache the reference and you'll save 4 bytes per allocation. In your case you are generating 8 bytes per frame, if 60 fps, that's a ~480 bytes trash per second, which GC must gracefully handle. Plus you are creating new string too, so that's 2 bytes per char = 10 bytes per frame. One or hundred will do no significant harm, you can always do a test in loop and see the frame rate drop. String comparison is quite slow too, you could cache the last hit gameobject and compare reference, if it's the same, it means it's the same gameobject and there is no need to do string test. Switch and case is also technically faster than if else statement.
private Ray ray;
private RaycastHit hit;
private String enemy = "Enemy";
void Update () {
ray = new Ray(transform.position, transform.forward);
if (Physics.Raycast(ray, out hit, gunRange))
{
if(hit.transform.tag== enemy)
{
crossHair.color = Color.red;
}
else
{
crossHair.color = Color.white;
}
}
}
Also, if you're micro-optimising, use CompareTag() rather than .tag == http://answers.unity3d.com/questions/200820/is-comparetag-better-than-gameobjecttag-performanc.html
And transform used in the Ray constructor should be cached too.
Continuing @tanoshimi caching spree. The idea is if you are accessing something more than 1 time (especially more)through dot operator then that could (or i should say should) be cached. Same goes with crossHair.
Just came across this, and I believe you may be wrong with the memory allocation. With structs and primitive vars, don't they get permanently allocated to the stack rather than the heap if the compiler thinks they will be used often?
i would not bother micro-optimizing this routine. it's only called once per frame. computers are FAST.
if you were doing this stuff say 1000s of times per second ins$$anonymous$$d of just 60 times per second, then you might want to think about caching, object pooling, etc.
it's true that it will be faster if you micro-optimize it, but it just doesn't matter. the amount of time you'll save with these types of things in a 60Hz cycle is negligible compared to the risk of introducing bugs and the maintenance burden of having less readable code. plus of course your own time doing the optimization.
what i would think about is how many objects the ray is potentially colliding with. if you've got a bazillion potential hit-targets out there, that might be expensive.
What reference did you optimize there? Ray and RaycastHit are both a value type, allocated on the call stack in this case. All you did is added size to the behaviour class itself, taking more memory and possibly causing cache misses to happen more often.
All of it completely negligible and unimportant. But don't micro-optimize if you don't know what you are doing - or you will end up doing the opposite, like in this case Also, no new string is created - it's reusing a string from the interned pool. Sorry to tell you, but your answer is wrong as much as it gets
Right, this answer is misleading in many ways. Caching the hardcoded "enemy" string in a variable doesn't improve anything. The actual killer in this code is the usage of the .tag
property which will allocate a new string each time it's read because the string needs to be transferred from native memory into managed memory. That's why we have the CompareTag method which does not allocate any memory since the comparison is done on the native side.
It's generally bad design to extend the lifetime of variables beyond their usage except it actually has some advantage (which isn't the case here).
btw: who the heck in the Unity $$anonymous$$m has run a search and replace on the whole UnityAnswers database and replaced "Sam", "R ", "sal" and a few other strings with "$$anonymous$$"? At least it seems like that. Don't let practicants play with databases ... We're probably lucky they didn't do a "drop database" by accident.
Answer by coolraiman · Feb 17, 2016 at 02:09 PM
i would hide the raycast behind a condition by example if you only raycast if the game is in a specific state and a monster is visible on the screen
and by the order of the condition you are sure to use a minimum processing start with the fastest condition to calculate to the heaviest.
void Update () {
if(gameState == mainGame && (condition that detect if there are monsters at all or within a certain range or visible in the screen using research with tags)
{
Ray ray = new Ray(transform.position, transform.forward);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, gunRange))
{
if(hit.transform.tag== "Enemy")
{
crossHair.color = Color.red;
}
else
{
crossHair.color = Color.white;
}
}
}
}
What about using FixedUpdate ins$$anonymous$$d of update?
In this Unity tutorial it's said that you shouldn't cast rays in FixedUpdate, as it can be called more often than Update, and raycasting is an expensive operation.