- Home /
SphereCastAll sees for miles
Hey Guys and Girls,
I am using this line of code
hits = Physics.SphereCastAll(transform.position,transform.localScale.x / 3,playerTransform.position - transform.position, Vector3.Distance(playerTransform.position, transform.position));
to help me enemies spot me!
It works fine and all, but it does mean they can see me from literally hundreds of miles away. I tried writing the code like this,
hits = Physics.SphereCastAll(transform.position,transform.localScale.x / 3,playerTransform.position - transform.position, 10000f);
but then they don't seem to see me at all, I have to get right in there face for it to work!
Can anyone suggest what I am doing wrong.
Thanks in advance!
Well, yes, the 1st version says they can "only" see as far as the player. The 2nd says they can see 10,000. How far away are they usually? $$anonymous$$aybe have enemies copy distance to player into a public var, to check?
But, SphereCast probably isn't what you want. A 1-meter spherecast can't tell the difference between hiding behind a wall, and a head stuck up over it.
I see, so what would you suggest? I thought about using ray cast, but then an enemy would spot the tiniest pixel of the player wouldn't it?
Answer by fafase · Jan 20, 2014 at 06:11 PM
You can use another approach with first checking distance between your player and the enemy:
if(Vector3.Distance(player.position, enemy.position) < range)
{}
then you check for a linecast between the two:
if (!Physics.Linecast (enemy.position, player.position, layerMask))
{}
My advice, place a GO at the level of the eyes of the enemy and use it as starting point. The layerMask will ignore the enemy itself if the linecast is starting from inside a collider of the enemy.
You can see more here http://unitygems.com/basic-ai-character/#Sight The article also includes line of sight so that the enemy does not see you when you are behind him.
Thank you! I used your range idea and now it works! Thank you so much!
Now that you got it working, here is a little trick that won't change much but well, using Distance requires a square root computation which is always more than a no sqr root computation.
So at the moment you are each frame doing:
distance = sqr(x*x+y*y+z*z);
if the distance is 10 then you compare with range which is let's say 20 and you are in. (distance < range)
now what if you do:
x*x+y*y+z*z
you get 100 (10 10) and now you don't compare it with range but with the squared range aka 20 20 = 400. (sqrDistance < sqrRange)
The result is the same except you skip the square root process.
so you get :
if((player.position - enemy.position).sqr$$anonymous$$agnitude < sqrRange)
{}
Answer by Ibzy · Jan 20, 2014 at 04:05 PM
Hi Mr Steve,
One approach many people use is a sphere collider set to Is Trigger?. You then have an OnTriggerEnter() function call the "Attack" function.
I personally tend to use a combination of dot and distance, but I cant remember the exact script (@work) - if required I will post it when I get home.
Hmmm, I know what you mean but I need SphereCastAll because my player needs to be able to hide behind walls. So that wouldn't work in this case.
Your answer

Follow this Question
Related Questions
Suggestions for AI Selecting From Multiple Targets? 3 Answers
Spherecast if hit.distance <=, move the otherway 1 Answer
How can I to tell if something blocks the vision of my enemy? 1 Answer
How would I confine an object to the ground? 2 Answers
Send an enemy back to its spawn point using waypoints 2 Answers