using NodeCanvas.Framework; using ParadoxNotion.Design; using UnityEngine; namespace NodeCanvas.Tasks.Conditions { [Category("GameObject")] [Description("A combination of line of sight and view angle check")] public class CanSeeTarget : ConditionTask { [RequiredField] public BBParameter target; [Tooltip("Distance within which to look out for.")] public BBParameter maxDistance = 50; [Tooltip("A layer mask to use for line of sight check.")] public BBParameter layerMask = (LayerMask)( -1 ); [Tooltip("Distance within which the target can be seen (or rather sensed) regardless of view angle.")] public BBParameter awarnessDistance = 0f; public BBParameter viewAngle = 70f; public Vector3 offset; public string report; private RaycastHit hit; protected override string info { get { return "Can See " + target; } } protected override bool OnCheck() { var t = target.value.transform; if ( !t.gameObject.activeInHierarchy ) { return false; } if ( Vector3.Distance(agent.position, t.position) <= awarnessDistance.value ) { if ( Physics.Linecast(agent.position + offset, t.position + offset, out hit, layerMask.value) ) { if ( hit.collider != t.GetComponent() ) { report = hit.collider.name; return false; } } report = "Good Vigil Direct Hit"; return true; } if ( Vector3.Distance(agent.position, t.position) > maxDistance.value ) { report = "Out of max distance"; return false; } // if ( Vector3.Angle(t.position - agent.position, agent.forward) > viewAngle.value ) { // report = "Out of view angle"; // return false; // } var direction = t.position - agent.position; var dir = Quaternion.LookRotation(direction); var angle = Quaternion.Angle(agent.rotation, dir); if (Vector3.Dot(agent.forward, direction) > 0 && viewAngle.value > angle) { } else { report = $"Out of view angle:{angle}"; return false; } if ( Physics.Linecast(agent.position + offset, t.position + offset, out hit, layerMask.value) ) { if ( hit.collider != t.GetComponent() ) { report = hit.collider.name; return false; } } report = "No Obstacle"; return true; } public override void OnDrawGizmosSelected() { if ( agent != null ) { Gizmos.DrawLine(agent.position, agent.position + offset); Gizmos.DrawLine(agent.position + offset, agent.position + offset + ( agent.forward * maxDistance.value )); Gizmos.DrawWireSphere(agent.position + offset + ( agent.forward * maxDistance.value ), 0.1f); Gizmos.DrawWireSphere(agent.position, awarnessDistance.value); Gizmos.matrix = Matrix4x4.TRS(agent.position + offset, agent.rotation, Vector3.one); Gizmos.DrawFrustum(Vector3.zero, viewAngle.value, 5, 0, 1f); } } } }