// Returns success if an object was found otherwise failure public override LocomotionStatus OnUpdate() { if (targetObjects != null && targetObjects.Count > 0) { // If there are objects in the group list then search for the object within that list GameObject objectFound = null; for (int i = 0; i < targetObjects.Count; ++i) { float audibility = 0; GameObject obj; if (Vector3.Distance(targetObjects[i].transform.position, agent.position) < hearingRadius) { if ((obj = LocomotionUtility.WithinHearingRange(agent, offset, audibilityThreshold, targetObjects[i], ref audibility)) != null) { objectFound = obj; } } } returnedObject = objectFound; } else if (targetObject == null) { // If the target object is null then determine if there are any objects within hearing range based on the layer mask if (usePhysics2D) { if (overlap2DColliders == null) { overlap2DColliders = new Collider2D[maxCollisionCount]; } returnedObject = LocomotionUtility.WithinHearingRange2D(agent, offset, audibilityThreshold, hearingRadius, overlap2DColliders, objectLayerMask); } else { if (overlapColliders == null) { overlapColliders = new Collider[maxCollisionCount]; } returnedObject = LocomotionUtility.WithinHearingRange(agent, offset, audibilityThreshold, hearingRadius, overlapColliders, objectLayerMask); } } else { GameObject target; if (!string.IsNullOrEmpty(targetTag)) { target = GameObject.FindGameObjectWithTag(targetTag); } else { target = targetObject; } if (Vector3.Distance(target.transform.position, agent.position) < hearingRadius) { returnedObject = LocomotionUtility.WithinHearingRange(agent, offset, audibilityThreshold, targetObject); } } if (returnedObject != null) { // returnedObject success if an object was heard return(LocomotionStatus.SUCCESS); } // An object is not within heard so return failure return(LocomotionStatus.FAILURE); }
// returns success if any object is within distance of the current object. Otherwise it will return failure public override LocomotionStatus OnUpdate() { if (agent == null || _objects == null) { return(LocomotionStatus.FAILURE); } if (_overlapCast) { _objects.Clear(); if (usePhysics2D) { var colliders = Physics.OverlapSphere(agent.position, magnitude, objectLayerMask.value); for (int i = 0; i < colliders.Length; ++i) { _objects.Add(colliders[i].gameObject); } } else { var colliders = Physics2D.OverlapCircleAll(agent.position, magnitude, objectLayerMask.value); for (int i = 0; i < colliders.Length; ++i) { _objects.Add(colliders[i].gameObject); } } } Vector3 direction; // check each object. All it takes is one object to be able to return success for (int i = 0; i < _objects.Count; ++i) { if (_objects[i] == null) { continue; } direction = _objects[i].transform.position - (agent.position + offset); // check to see if the square magnitude is less than what is specified if (Vector3.SqrMagnitude(direction) < _sqrMagnitude) { // the magnitude is less. If lineOfSight is true do one more check if (lineOfSight) { if (LocomotionUtility.LineOfSight(agent, offset, _objects[i], targetOffset, usePhysics2D, ignoreLayerMask.value)) { // the object has a magnitude less than the specified magnitude and is within sight. Set the object and return success returnedObject = _objects[i]; return(LocomotionStatus.SUCCESS); } } else { // the object has a magnitude less than the specified magnitude. Set the object and return success returnedObject = _objects[i]; return(LocomotionStatus.SUCCESS); } } } // no objects are within distance. Return failure return(LocomotionStatus.FAILURE); }
// Keep searching until an object is seen or heard (if senseAudio is enabled) public override LocomotionStatus OnUpdate() { if (HasArrived()) { // The agent should pause at the destination only if the max pause duration is greater than 0 if (maxPauseDuration > 0) { if (_destinationReachTime == -1) { _destinationReachTime = Time.time; _pauseTime = Random.Range(minPauseDuration, maxPauseDuration); if (onRest != null) { onRest.Invoke(); } } if (_destinationReachTime + _pauseTime <= Time.time) { SetTarget(); } } else { SetTarget(); } } // Detect if any objects are within sight if (_overlapColliders == null) { _overlapColliders = new Collider[maxCollisionCount]; } if (senseSight) { returnedObject = LocomotionUtility.WithinSight(agent, positionOffset, fieldOfViewAngle, viewDistance, _overlapColliders, objectLayerMask, targetOffset, ignoreLayerMask, useTargetBone, targetBone); // If an object was seen then return success if (returnedObject != null) { return(LocomotionStatus.SUCCESS); } } // Detect if any object are within audio range (if enabled) if (senseAudio) { returnedObject = LocomotionUtility.WithinHearingRange(agent, positionOffset, audibilityThreshold, hearingRadius, _overlapColliders, objectLayerMask); // If an object was heard then return success if (returnedObject != null) { return(LocomotionStatus.SUCCESS); } } UpdateNavMeshObstacle(); // No object has been seen or heard so keep searching return(LocomotionStatus.RUNNING); }
public override void OnDrawGizmosSelected() { LocomotionUtility.DrawViewOfSight(agent, positionOffset, fieldOfViewAngle, 0, viewDistance, false); }
// Returns success if an object was found otherwise failure public override LocomotionStatus OnUpdate() { // The collider layers on the agent can be set to ignore raycast to prevent them from interferring with the raycast checks. if (disableAgentColliderLayer) { if (_agentColliderGameObjects == null) { if (usePhysics2D) { var colliders = agent.GetComponentsInChildren <Collider2D>(); _agentColliderGameObjects = new GameObject[colliders.Length]; for (int i = 0; i < _agentColliderGameObjects.Length; ++i) { _agentColliderGameObjects[i] = colliders[i].gameObject; } } else { var colliders = agent.GetComponentsInChildren <Collider>(); _agentColliderGameObjects = new GameObject[colliders.Length]; for (int i = 0; i < _agentColliderGameObjects.Length; ++i) { _agentColliderGameObjects[i] = colliders[i].gameObject; } } _originalColliderLayer = new int[_agentColliderGameObjects.Length]; } // Change the layer. Remember the previous layer so it can be reset after the check has completed. for (int i = 0; i < _agentColliderGameObjects.Length; ++i) { _originalColliderLayer[i] = _agentColliderGameObjects[i].layer; _agentColliderGameObjects[i].layer = _ignoreRaycastLayer; } } if (usePhysics2D) { if (targetObjects != null && targetObjects.Count > 0) { // If there are objects in the group list then search for the object within that list GameObject objectFound = null; float minAngle = Mathf.Infinity; for (int i = 0; i < targetObjects.Count; ++i) { float angle; GameObject obj; if ((obj = LocomotionUtility.WithinSight(agent, positionOffset, fieldOfViewAngle, viewDistance, targetObjects[i].gameObject, targetOffset, true, angleOffset2D, out angle, ignoreLayerMask, useTargetBone, targetBone)) != null) { // This object is within sight. Set it to the objectFound GameObject if the angle is less than any of the other objects if (angle < minAngle) { minAngle = angle; objectFound = obj; } } } returnedObject = objectFound; } else if (targetObject != null) { // If the target is not null then determine if that object is within sight returnedObject = LocomotionUtility.WithinSight2D(agent, positionOffset, fieldOfViewAngle, viewDistance, targetObject.gameObject, targetOffset, angleOffset2D, ignoreLayerMask, useTargetBone, targetBone); } else if (!string.IsNullOrEmpty(targetTag)) { // If the target tag is not null then determine if there are any objects within sight based on the tag returnedObject = LocomotionUtility.WithinSight2D(agent, positionOffset, fieldOfViewAngle, viewDistance, GameObject.FindGameObjectWithTag(targetTag), targetOffset, angleOffset2D, ignoreLayerMask, useTargetBone, targetBone); } else { // If the target object is null and there is no tag then determine if there are any objects within sight based on the layer mask if (_overlap2DColliders == null) { _overlap2DColliders = new Collider2D[maxCollisionCount]; } returnedObject = LocomotionUtility.WithinSight2D(agent, positionOffset, fieldOfViewAngle, viewDistance, _overlap2DColliders, objectLayerMask, targetOffset, angleOffset2D, ignoreLayerMask); } } else { if (targetObjects != null && targetObjects.Count > 0) { // 指定对象列表是否在视野 // If there are objects in the group list then search for the object within that list GameObject objectFound = null; float minAngle = Mathf.Infinity; for (int i = 0; i < targetObjects.Count; ++i) { float angle; GameObject obj; if ((obj = LocomotionUtility.WithinSight(agent, positionOffset, fieldOfViewAngle, viewDistance, targetObjects[i].gameObject, targetOffset, false, angleOffset2D, out angle, ignoreLayerMask, useTargetBone, targetBone)) != null) { // This object is within sight. Set it to the objectFound GameObject if the angle is less than any of the other objects if (angle < minAngle) { minAngle = angle; objectFound = obj; } } } returnedObject = objectFound; } else if (targetObject != null) { // 指定对象是否在视野 // If the target is not null then determine if that object is within sight returnedObject = LocomotionUtility.WithinSight(agent, positionOffset, fieldOfViewAngle, viewDistance, targetObject.gameObject, targetOffset, ignoreLayerMask, useTargetBone, targetBone); } else if (!string.IsNullOrEmpty(targetTag)) { // 指定tag的对象是否在视野 // If the target tag is not null then determine if there are any objects within sight based on the tag returnedObject = LocomotionUtility.WithinSight(agent, positionOffset, fieldOfViewAngle, viewDistance, GameObject.FindGameObjectWithTag(targetTag), targetOffset, ignoreLayerMask, useTargetBone, targetBone); } else { // 通过碰撞检测是否有target在视野 // If the target object is null and there is no tag then determine if there are any objects within sight based on the layer mask if (_overlapColliders == null) { _overlapColliders = new Collider[maxCollisionCount]; } returnedObject = LocomotionUtility.WithinSight(agent, positionOffset, fieldOfViewAngle, viewDistance, _overlapColliders, objectLayerMask, targetOffset, ignoreLayerMask, useTargetBone, targetBone); } } if (disableAgentColliderLayer) { for (int i = 0; i < _agentColliderGameObjects.Length; ++i) { _agentColliderGameObjects[i].layer = _originalColliderLayer[i]; } } if (returnedObject != null) { // Return success if an object was found return(LocomotionStatus.SUCCESS); } // An object is not within sight so return failure return(LocomotionStatus.FAILURE); }
public override void OnDrawGizmosSelected() { LocomotionUtility.DrawViewOfSight(agent, positionOffset, fieldOfViewAngle, angleOffset2D, viewDistance, usePhysics2D); }