Esempio n. 1
0
        // 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);
        }
Esempio n. 2
0
        // 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);
        }