Need help with enemy cone sight

I currently have an enemy script that is used for 2d or topdown, but I cant seem to figure out how to make it a 3d cone instead. (My Script is down below)

I got help from making it by a enemy field of view tutorial on youtube.
only used part 1 though

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class FieldOfView : MonoBehaviour
{

private Patrol patrol;

public Transform Player;
public float viewRadius;
[Range(0, 360)]
public float viewAngle;

public LayerMask targetMask;
public LayerMask obstacleMask;

public List visibleTargets = new List();

void Awake() {

patrol = GetComponent();

}

IEnumerator FindTargetsWithDelay(float delay)
{
while (true)
{
yield return new WaitForSeconds(delay);
FindVisibleTargets();
}
}

void FindVisibleTargets()
{
visibleTargets.Clear();
Collider[ ] targetsInViewRadius = Physics.OverlapSphere(transform.position, viewRadius, targetMask);

for (int i = 0; i < targetsInViewRadius.Length; i++)
{
Transform target = targetsInViewRadius*.transform;*
Vector3 dirToTarget = (target.position - transform.position).normalized;
if (Vector3.Angle(transform.forward, dirToTarget) < viewAngle / 2)
{
float dstToTarget = Vector3.Distance(transform.position, target.position);
if (!Physics.Raycast(transform.position, dirToTarget, dstToTarget, obstacleMask))
{
visibleTargets.Add(target);

}
}
}
}
public Vector3 DirFromAngle(float angleInDegrees, bool angleIsGlobal)
{
if (!angleIsGlobal)
{
angleInDegrees += transform.eulerAngles.y;
}
return new Vector3(Mathf.Sin(angleInDegrees * Mathf.Deg2Rad), 0, Mathf.Cos(angleInDegrees * Mathf.Deg2Rad));
}
void Update()
{

if (visibleTargets.Contains(Player))
{
patrol.isChasing = true;

}
// else {
//patrol.isChasing = false;

//}
}
void Start()
{

StartCoroutine(“FindTargetsWithDelay”, .2f);
}
}

it is for a 3d first person stealth game btw
so the cone needs to be 3d and able to rotate

Oh and it needs to be C# :open_mouth:

Please use Code Tags when pasting snippets into the forum.

First, code tags are essential or it’s unreadable. Using code tags properly - Unity Engine - Unity Discussions Second, you should use the edit button instead of posting two or three times in a row.

The cone actually probably wouldn’t rotate though- the perspective would be fixed to the character’s torso or more likely head and move around when the head does. This can be accomplished far more easily using a basic trigger collider- it handles things in much the same way as Physics.OverlapSphere, but in the background and in the shape that you want (the shape of the trigger). You could then just run everything in OnTriggerEnter/OnTriggerStay/OnTriggerExit.

ok ill repost the code

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class FieldOfView : MonoBehaviour
{


private Patrol patrol;

public Transform Player;
public float viewRadius;
[Range(0, 360)]
public float viewAngle;

public LayerMask targetMask;
public LayerMask obstacleMask;


public List<Transform> visibleTargets = new List<Transform>();

void Awake() {



patrol = GetComponent<Patrol>();

}



IEnumerator FindTargetsWithDelay(float delay)
{
while (true)
{
yield return new WaitForSeconds(delay);
FindVisibleTargets();
}
}

void FindVisibleTargets()
{
visibleTargets.Clear();
Collider[] targetsInViewRadius = Physics.OverlapSphere(transform.position, viewRadius, targetMask);

for (int i = 0; i < targetsInViewRadius.Length; i++)
{
Transform target = targetsInViewRadius.transform;
Vector3 dirToTarget = (target.position - transform.position).normalized;
if (Vector3.Angle(transform.forward, dirToTarget) < viewAngle / 2)
{
float dstToTarget = Vector3.Distance(transform.position, target.position);

if (!Physics.Raycast(transform.position, dirToTarget, dstToTarget, obstacleMask))
{
visibleTargets.Add(target);

}


}




}



}


public Vector3 DirFromAngle(float angleInDegrees, bool angleIsGlobal)
{
if (!angleIsGlobal)
{
angleInDegrees += transform.eulerAngles.y;
}
return new Vector3(Mathf.Sin(angleInDegrees * Mathf.Deg2Rad), 0, Mathf.Cos(angleInDegrees * Mathf.Deg2Rad));
}







void Update()
{



if (visibleTargets.Contains(Player))
{
patrol.isChasing = true;

}
// else {


//patrol.isChasing = false;

//} 
}
void Start()
{


StartCoroutine("FindTargetsWithDelay", .2f);

}
}

Ill try that out person with anime profile picture

1 Like

that doesnt work because then the enemy can see through walls

Please use the edit button to add information to your posts rather than double or triple posting, especially for quick edits like these, and please copy your code directly from the script and paste into the Insert Code window, because the code is still unreadable. You also really should’ve edited the first post and fixed it there rather than posting it again. This thread is getting pretty messy now and it might keep people who want to help you from bothering to sift through it.

The Physics.OverlapSpheres method won’t stop seeing enemies through walls either- you’ll need a quick raycast from the viewer to the seen-object whenever an object is colliding with the view area to verify whether they’ve been seen or not, just as the current code raycasts against the objects found within the OverlapSpheres function. The biggest difference is that doing it on collision means you only need to check the line-of-sight if something is actually capable of being in line-of-sight, instead of every single frame and iterating over every object in the scene with a collider attached. The performance difference is pretty huge.

You can increase the quality of this by raycasting against body parts that are commonly “sticking out” like hands and feet and the head, so that you can more accurately say “that person’s been spotted”- a single raycast against the chest means a heavy character could hide behind a lamppost, which is comical but shouldn’t really work. Linecasts would also work better. You can also easily define the view area using whatever simple mesh collider you add to the object, making it bigger or smaller or a different shape as needed, instead of doing it mathematically like this.

Check out this thread here: Raycasting a cone instead of single ray? - Unity Engine - Unity Discussions

2 Likes

i understand now

so if it collides with the cone trigger then send out a ray to see if it is not behind a wall

also your game looks very cool :open_mouth:
love
Ja’hana

im sorry for my forums noobness
first forum post ever