Hello there.
I am not sure if there’s something wrong with my code or if that’s how it should work. So I am making some game where you get auto-generated maze and I wanted to put some “enemies” in there. They’re comming to you as they see you. The problem is that when using triggers they can “see” you through walls. Maybe they don’t go through walls, but they try to. Later when you get into this point you can see few monsters waiting for you. So I decided to go with raycasts to check if enemy can actually see player. Here is my code:
void OnTriggerStay(Collider other) {
if (other.CompareTag("Player")) {
hitColliders = Physics.OverlapSphere(transform.position, sphereRadius);
for (int i = 0; i < hitColliders.Length;i++ ) {
if (hitColliders[i].CompareTag("Player"))
{
if (Vector3.Distance(target.position, transform.position) > 1.5f)
{
transform.LookAt(target);
transform.position += transform.forward * movspeed * Time.deltaTime;
}
}
}
}
}
When I get out of their sphere, they stop following me, fine. But I’ve put giant cube on scene and whenever I am behind it, the enemy is still trying to get me… so that didn’t work any better than with only triggers. I am doing something wrong?
Please let me know if you know any way to make it work nicely. Monsters trying to go into walls don’t look very good to be honest.
Best regards.
I don’t see any raycasts in that code. Raycasts are indeed the correct way to do visibility testing (in most cases).
Read through the docs for Physics.Raycast… there are many overloads of that method, but the docs include a simple example for each one.
OverlapSphere returns every collider in the radius on the given layermask. So basically, yeah, you can ‘see’ everything because thats exactly what you would expect.
For each of those hits you’ll want to do a line-of-sight check to confirm that there is visibility to the target. Use Physics.Raycast for that. On confirmed targets you’ll put them in a list of enemies that are ‘known’ and can be pursued or a last known position of the target being pursued. Otherwise as soon as LoS is broken they’ll stop.
1 Like
You just enlightened me. Thanks for spending your time for replaying
Have a nice day.
1 Like
Thanks for the idea [quote=“LaneFox, post:3, topic: 659947, username:LaneFox”]
[/quote]
I initially had just raycast which felt it needed too much accuracy (as in, you must look directly into target) and then spherecast was too broad, it detected things behind walls etc. So here’s my combined spherecast + raycast detector for objects with imaginary component “MyTarget”
RaycastHit[] raycastHits = new RaycastHit[4];
int hits = Physics.SphereCastNonAlloc(rayStart, 0.2f, rayDirection, raycastHits, rayDistance, layerMask);
if (hits > 0)
{
for (int i = 0; i < hits; i++)
{
myTarget = raycastHits[i].transform.GetComponent<MyTargetComponent>();
if (myTarget != null)
{
// check visible
if (Physics.Raycast(rayStart, rayDirection, out raycastHit, rayDistance, layerMask))
{
// it's visible, break out of the loop
if (myTarget.IsInteractable)
{
// do stuff
}
break;
}
}
}
}
}
EDIT: not working, my raycast detects the last collider, so if there’s 2 objects in line it hits the one behind, not in front. Gotta check why.