137 lines
7.0 KiB
C#
137 lines
7.0 KiB
C#
using UnityEngine;
|
|
|
|
namespace BehaviorDesigner.Runtime.Tasks.Movement
|
|
{
|
|
[TaskDescription("Check to see if the any objects are within hearing range of the current agent.")]
|
|
[TaskCategory("Movement")]
|
|
[HelpURL("https://www.opsive.com/support/documentation/behavior-designer-movement-pack/")]
|
|
[TaskIcon("a464405df8e82b24db602534724b5e6f", "941bd88188259374d885440560f1a29d")]
|
|
public class CanHearObject : Conditional
|
|
{
|
|
[Tooltip("Should the 2D version be used?")]
|
|
[UnityEngine.Serialization.FormerlySerializedAs("usePhysics2D")]
|
|
public bool m_UsePhysics2D;
|
|
[Tooltip("Specifies the type of detection that should be used.")]
|
|
public SharedDetectionMode m_DetectionMode = DetectionMode.Object | DetectionMode.ObjectList | DetectionMode.Tag | DetectionMode.LayerMask;
|
|
[Tooltip("The object that we are searching for")]
|
|
[UnityEngine.Serialization.FormerlySerializedAs("targetObject")]
|
|
public SharedGameObject m_TargetObject;
|
|
[Tooltip("The objects that we are searching for")]
|
|
[UnityEngine.Serialization.FormerlySerializedAs("targetObjects")]
|
|
public SharedGameObjectList m_TargetObjects;
|
|
[Tooltip("The tag of the object that we are searching for")]
|
|
[UnityEngine.Serialization.FormerlySerializedAs("targetTag")]
|
|
public SharedString m_TargetTag;
|
|
[Tooltip("The LayerMask of the objects that we are searching for")]
|
|
[UnityEngine.Serialization.FormerlySerializedAs("objectLayerMask")]
|
|
public SharedLayerMask m_TargetLayerMask;
|
|
[Tooltip("If using the object layer mask, specifies the maximum number of colliders that the physics cast can collide with")]
|
|
[UnityEngine.Serialization.FormerlySerializedAs("maxCollisionCount")]
|
|
public int m_MaxCollisionCount = 200;
|
|
[Tooltip("How far away the unit can hear")]
|
|
[UnityEngine.Serialization.FormerlySerializedAs("hearingRadius")]
|
|
public SharedFloat m_HearingRadius = 50;
|
|
[Tooltip("The further away a sound source is the less likely the agent will be able to hear it. " +
|
|
"Set a threshold for the the minimum audibility level that the agent can hear")]
|
|
[UnityEngine.Serialization.FormerlySerializedAs("audibilityThreshold")]
|
|
public SharedFloat m_AudibilityThreshold = 0.05f;
|
|
[Tooltip("The hearing offset relative to the pivot position")]
|
|
[UnityEngine.Serialization.FormerlySerializedAs("offset")]
|
|
public SharedVector3 m_Offset;
|
|
[Tooltip("The returned object that is heard")]
|
|
[UnityEngine.Serialization.FormerlySerializedAs("returnedObject")]
|
|
public SharedGameObject m_ReturnedObject;
|
|
|
|
private Collider[] m_OverlapColliders;
|
|
private Collider2D[] m_Overlap2DColliders;
|
|
|
|
// Returns success if an object was found otherwise failure
|
|
public override TaskStatus OnUpdate()
|
|
{
|
|
m_ReturnedObject.Value = null;
|
|
if ((m_DetectionMode.Value & DetectionMode.Object) != 0 && m_TargetObject.Value != null) {
|
|
var target = m_TargetObject.Value;
|
|
if (Vector3.Distance(target.transform.position, transform.position) < m_HearingRadius.Value) {
|
|
m_ReturnedObject.Value = MovementUtility.WithinHearingRange(transform, m_Offset.Value, m_AudibilityThreshold.Value, m_TargetObject.Value);
|
|
}
|
|
}
|
|
|
|
if (m_ReturnedObject.Value == null && (m_DetectionMode.Value & DetectionMode.ObjectList) != 0) {
|
|
GameObject objectFound = null;
|
|
for (int i = 0; i < m_TargetObjects.Value.Count; ++i) {
|
|
var audibility = 0f;
|
|
GameObject obj;
|
|
if (Vector3.Distance(m_TargetObjects.Value[i].transform.position, transform.position) < m_HearingRadius.Value) {
|
|
if ((obj = MovementUtility.WithinHearingRange(transform, m_Offset.Value, m_AudibilityThreshold.Value, m_TargetObjects.Value[i], ref audibility)) != null) {
|
|
objectFound = obj;
|
|
}
|
|
}
|
|
}
|
|
m_ReturnedObject.Value = objectFound;
|
|
}
|
|
|
|
if (m_ReturnedObject.Value == null && (m_DetectionMode.Value & DetectionMode.Tag) != 0 && !string.IsNullOrEmpty(m_TargetTag.Value)) {
|
|
var targets = GameObject.FindGameObjectsWithTag(m_TargetTag.Value);
|
|
if (targets != null) {
|
|
for (int i = 0; i < targets.Length; ++i) {
|
|
var audibility = 0f;
|
|
GameObject obj;
|
|
if (Vector3.Distance(targets[i].transform.position, transform.position) < m_HearingRadius.Value) {
|
|
if ((obj = MovementUtility.WithinHearingRange(transform, m_Offset.Value, m_AudibilityThreshold.Value, targets[i], ref audibility)) != null) {
|
|
m_ReturnedObject.Value = obj;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_ReturnedObject.Value == null && (m_DetectionMode.Value & DetectionMode.LayerMask) != 0) {
|
|
if (m_UsePhysics2D) {
|
|
if (m_Overlap2DColliders == null) {
|
|
m_Overlap2DColliders = new Collider2D[m_MaxCollisionCount];
|
|
}
|
|
m_ReturnedObject.Value = MovementUtility.WithinHearingRange2D(transform, m_Offset.Value, m_AudibilityThreshold.Value, m_HearingRadius.Value, m_Overlap2DColliders, m_TargetLayerMask.Value);
|
|
} else {
|
|
if (m_OverlapColliders == null) {
|
|
m_OverlapColliders = new Collider[m_MaxCollisionCount];
|
|
}
|
|
m_ReturnedObject.Value = MovementUtility.WithinHearingRange(transform, m_Offset.Value, m_AudibilityThreshold.Value, m_HearingRadius.Value, m_OverlapColliders, m_TargetLayerMask.Value);
|
|
}
|
|
}
|
|
|
|
if (m_ReturnedObject.Value != null) {
|
|
// m_ReturnedObject success if an object was heard
|
|
return TaskStatus.Success;
|
|
}
|
|
|
|
// An object is not within heard so return failure
|
|
return TaskStatus.Failure;
|
|
}
|
|
|
|
// Reset the public variables
|
|
public override void OnReset()
|
|
{
|
|
m_HearingRadius = 50;
|
|
m_AudibilityThreshold = 0.05f;
|
|
}
|
|
|
|
// Draw the hearing radius
|
|
public override void OnDrawGizmos()
|
|
{
|
|
#if UNITY_EDITOR
|
|
if (Owner == null || m_HearingRadius == null) {
|
|
return;
|
|
}
|
|
var oldColor = UnityEditor.Handles.color;
|
|
UnityEditor.Handles.color = Color.yellow;
|
|
UnityEditor.Handles.DrawWireDisc(Owner.transform.position, Owner.transform.up, m_HearingRadius.Value);
|
|
UnityEditor.Handles.color = oldColor;
|
|
#endif
|
|
}
|
|
|
|
public override void OnBehaviorComplete()
|
|
{
|
|
MovementUtility.ClearCache();
|
|
}
|
|
}
|
|
} |