Ejemplo n.º 1
0
        public Vector3 CheckPosition(Vector3 _position, float _range, LayerMask _mask)
        {
            Collider[] _colliders = Physics.OverlapSphere(_position, _range, _mask);

            int i = 0;

            while (i < _colliders.Length)
            {
                Collider _collider = _colliders[i];

                if (_collider != null)
                {
                    // try to get the closest point but this could fail for some reasons ...
                    Vector3 _point = _collider.ClosestPointOnBounds(_position);

                    // ... so compare the points and try to get the closest point on another way ...
                    if (_point == _position)
                    {
                        _point = SystemTools.ClosestPointOnSurface(_collider, _position);
                    }

                    if (_point == _position)
                    {
                        _point = _collider.transform.position;
                    }

                    _position += (_position - _point).normalized * (PositionTools.Distance(_position, _point) + _range);
                }
                i++;
            }

            return(_position);
        }
Ejemplo n.º 2
0
        public WaypointObject GetWaypointByPosition(Vector3 _position)
        {
            WaypointObject new_waypoint       = null;
            int            new_waypoint_index = m_WaypointIndex;
            float          distance           = Mathf.Infinity;

            List <WaypointObject> _waypoints = GetEnabledWaypoints();

            for (int i = 0; i < _waypoints.Count; i++)
            {
                float tmp_distance = PositionTools.Distance(_position, _waypoints[i].TargetOffsetPosition);
                if (tmp_distance < distance)
                {
                    new_waypoint_index = i;
                    new_waypoint       = _waypoints[new_waypoint_index];
                    distance           = tmp_distance;
                }
            }

            if (new_waypoint != null)
            {
                m_LastWaypoint  = m_Waypoint;
                m_Waypoint      = new_waypoint;
                m_WaypointIndex = new_waypoint_index;
            }

            return(m_Waypoint);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets the nearest focused entity by the specified type.
        /// </summary>
        /// <returns>The nearest focused entity by type.</returns>
        /// <param name="_type">Type.</param>
        /// <param name="_allow_child">If set to <c>true</c> allow child.</param>
        public ICECreatureEntity GetBestCounterpartByType(EntityClassType _type, int _max_counterparts, bool _allow_child = false)
        {
            ICECreatureEntity _best_entity   = null;
            float             _best_distance = Mathf.Infinity;
            int _best_counterparts           = _max_counterparts;

            // transform buffer
            Transform _transform = this.transform;

            for (int i = 0; i < ActiveCounterparts.Count; i++)
            {
                ICECreatureEntity _entity = ActiveCounterparts[i];

                if (_entity != null && _entity.EntityType == _type)
                {
                    Transform _entity_transform    = _entity.transform;
                    int       _entity_counterparts = _entity.ActiveCounterparts.Count;
                    float     _entity_distance     = PositionTools.Distance(_transform.position, _entity_transform.position);

                    if ((_entity_distance <= _best_distance) &&
                        (_allow_child || _entity_transform.IsChildOf(_transform) == false) &&
                        (_best_counterparts == -1 || _entity_counterparts <= _best_counterparts))
                    {
                        _best_counterparts = _entity_counterparts;
                        _best_distance     = _entity_distance;
                        _best_entity       = _entity;
                    }
                }
            }

            return(_best_entity);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets the nearest focused entity.
        /// </summary>
        /// <returns>The nearest focused entity.</returns>
        /// <param name="_allow_child">If set to <c>true</c> allow child.</param>
        public ICECreatureEntity GetNearestActiveCounterparts(bool _allow_child = false)
        {
            ICECreatureEntity _best_entity   = null;
            float             _best_distance = Mathf.Infinity;

            // transform buffer
            Transform _transform = this.transform;

            for (int i = 0; i < ActiveCounterparts.Count; i++)
            {
                ICECreatureEntity _entity = ActiveCounterparts[i];

                if (_entity != null)
                {
                    // transform buffer
                    Transform _entity_transform = _entity.transform;

                    float _distance = PositionTools.Distance(_transform.position, _entity_transform.position);
                    if (_distance < _best_distance)
                    {
                        if (_allow_child || _entity_transform.IsChildOf(_transform) == false)
                        {
                            _best_distance = _distance;
                            _best_entity   = _entity;
                        }
                    }
                }
            }

            return(_best_entity);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Update the turret incl. movements and scan for targets
        /// </summary>
        public bool Update()
        {
            if (Owner == null)
            {
                return(false);
            }

            Scan();

            m_IsFocused = false;
            m_IsMoving  = false;

            // runs the default behaviour if there is no target
            if (m_ActiveTarget == null)
            {
                if (UseParkPosition)
                {
                    if (PivotType == MountingPivotType.PivotalPoint)
                    {
                        PivotPoint.rotation = Quaternion.Slerp(PivotPoint.rotation, DefaultPivotRotation, RotationSpeed * Time.deltaTime);

                        if (Quaternion.Angle(PivotPoint.rotation, DefaultPivotRotation) > MaxAngularDeviation)
                        {
                            m_IsMoving = true;
                        }
                    }
                    else if (PivotType == MountingPivotType.SeperateAxes)
                    {
                        if (PivotYawAxis != null)
                        {
                            if (PositionTools.Distance(PivotYawAxis.localEulerAngles, new Vector3(0, DefaultPivotYawRotation, 0)) > MaxAngularDeviation)
                            {
                                PivotYawAxis.localEulerAngles = new Vector3(0, Mathf.LerpAngle(PivotYawAxis.localEulerAngles.y, DefaultPivotYawRotation, RotationSpeed * Time.deltaTime), 0);
                                m_IsMoving = true;
                            }
                            else
                            {
                                PivotYawAxis.localEulerAngles = new Vector3(0, DefaultPivotYawRotation, 0);
                            }
                        }

                        if (PivotPitchAxis != null)
                        {
                            if (PositionTools.Distance(PivotPitchAxis.localEulerAngles, new Vector3(DefaultPivotPitchRotation, 0, 0)) > MaxAngularDeviation)
                            {
                                PivotPitchAxis.localEulerAngles = new Vector3(Mathf.LerpAngle(PivotPitchAxis.localEulerAngles.x, DefaultPivotPitchRotation, RotationSpeed * Time.deltaTime), 0, 0);
                                m_IsMoving = true;
                            }
                            else
                            {
                                PivotPitchAxis.localEulerAngles = new Vector3(DefaultPivotPitchRotation, 0, 0);
                            }
                        }
                    }
                }
            }

            // focus an existing target
            else
            {
                float    _height   = 1;
                Collider _collider = m_ActiveTarget.GetComponent <Collider>();
                if (_collider != null)
                {
                    _height = _collider.bounds.size.magnitude / 3;
                }

                _height += VerticalTargetAdjustment;

                Vector3 _target_pos = m_ActiveTarget.position + (Vector3.up * _height);

                if (PivotType == MountingPivotType.PivotalPoint)
                {
                    Quaternion _rotation = Quaternion.LookRotation(_target_pos - PivotPoint.position, Vector3.up);
                    PivotPoint.rotation = Quaternion.Slerp(PivotPoint.rotation, _rotation, RotationSpeed * Time.deltaTime);

                    if (Quaternion.Angle(PivotPoint.rotation, _rotation) < MaxAngularDeviation)
                    {
                        m_IsFocused = true;
                        m_IsMoving  = false;
                    }
                    else
                    {
                        m_IsFocused = false;
                        m_IsMoving  = true;
                    }
                }
                else if (PivotType == MountingPivotType.SeperateAxes)
                {
                    if (PivotYawAxis != null)
                    {
                        Vector3    _yaw_pos = new Vector3(_target_pos.x, PivotYawAxis.position.y, _target_pos.z);
                        Quaternion _yaw_rot = Quaternion.LookRotation(_yaw_pos - PivotYawAxis.position, Vector3.up);
                        PivotYawAxis.rotation = Quaternion.Slerp(PivotYawAxis.rotation, _yaw_rot, RotationSpeed * Time.deltaTime);

                        if (Quaternion.Angle(PivotYawAxis.rotation, _yaw_rot) <= MaxAngularDeviation)
                        {
                            m_IsFocused = true;
                            m_IsMoving  = false;
                        }
                        else
                        {
                            m_IsFocused = false;
                            m_IsMoving  = true;
                        }
                    }

                    if (PivotPitchAxis != null)
                    {
                        Vector3 _pitch_dir = PivotPitchAxis.position - _target_pos;
                        Vector3 _pitch_hor = new Vector3(_pitch_dir.x, 0, _pitch_dir.z);
                        float   _angle     = MathTools.NormalizeAngle(360 + Vector3.Angle(_pitch_dir, _pitch_hor) * Mathf.Sign(Vector3.Dot(_pitch_dir, Vector3.up)));

                        PivotPitchAxis.localEulerAngles = new Vector3(Mathf.LerpAngle(PivotPitchAxis.localEulerAngles.x, _angle, RotationSpeed * Time.deltaTime), 0, 0);

                        if (m_IsFocused && PositionTools.Distance(PivotPitchAxis.localEulerAngles, new Vector3(_angle, 0, 0)) <= MaxAngularDeviation)
                        {
                            m_IsFocused = true;
                            m_IsMoving  = false;
                        }
                        else
                        {
                            m_IsFocused = false;
                            m_IsMoving  = true;
                        }
                    }
                }
            }

            if (m_IsMoving)
            {
                MovingSound.Play();
            }
            else
            {
                MovingSound.Stop();
            }

            return(m_IsFocused);
        }
    //private Quaternion m_MoveRotation;
    //private float m_MoveAngle = 0;

    /// <summary>
    /// DoUpdateMovePosition can be used to override the default move position of a creature. This delegated method will be called on each frame update
    /// </summary>
    /// <param name="_sender">Sender.</param>
    /// <param name="_origin_position">Origin position.</param>
    /// <param name="_new_position">New position.</param>
    private void DoUpdateMovePosition(GameObject _sender, Vector3 _transform_position, ref Vector3 _new_move_position)
    {
        // just to make sure that all required objects are available
        if (Controller == null || Controller.Creature.ActiveTarget == null || Controller.Creature.Move.TargetMovePositionReached)
        {
            return;
        }

        // the active target move position is the final destination the creature have to reach
        Vector3 _target_move_position = Controller.Creature.ActiveTargetMovePosition;

        // this will adapt the target move position to the grid
        Vector3 _grid_target_move_position = GetGridPosition(_target_move_position);

        // here we apapt the level of the new move position
        m_GridMovePosition.y = transform.position.y;

        // if the creature is near to the given node point we have to generate the next one
        if (PositionTools.Distance(m_GridMovePosition, transform.position) < Controller.Creature.Move.DesiredStoppingDistance)
        {
            // direction to the original target move position of the active target
            Vector3 _dir = (_target_move_position - transform.position).normalized;

            // here we get the next grid position according to the direction and the specified grid size
            Vector3 _next_grid_pos = GetGridPosition(transform.position + (_dir * GridSize));

            // We do not want to allow diagonal movements, so we have to adjust all the paths that are longer than the grid size.
            if (PositionTools.Distance(m_GridMovePosition, _next_grid_pos) > GridSize + Controller.Creature.Move.DesiredStoppingDistance)
            {
                // ... in this case the selection of the direction will be done by chance
                if (UnityEngine.Random.Range(0, 1) == 0)
                {
                    _next_grid_pos.x = m_GridMovePosition.x;
                }
                else
                {
                    _next_grid_pos.z = m_GridMovePosition.z;
                }
            }

            // we take the new position only if this is closer to the target than the current one
            //if( ( _next_grid_pos - _grid_target_move_position ).magnitude < ( m_GridMovePosition - _grid_target_move_position ).magnitude )

            m_GridMovePosition = _next_grid_pos;
            m_GridMoveRotation = Quaternion.LookRotation((m_GridMovePosition - transform.position).normalized);
        }
        else
        {
            // this code block makes sure that a creature is always on the grid
            float   _speed          = (Controller.Creature.Move.DesiredVelocity.z > 0 ? Controller.Creature.Move.DesiredVelocity.z : 1) * Time.deltaTime;
            Vector3 _move_direction = (m_GridMovePosition - transform.position);
            if (Mathf.Abs(_move_direction.x) < Mathf.Abs(_move_direction.z))
            {
                transform.position = Vector3.Lerp(transform.position, new Vector3(transform.position.x + _move_direction.x, transform.position.y, transform.position.z), _speed);
            }
            else if (Mathf.Abs(_move_direction.z) < Mathf.Abs(_move_direction.x))
            {
                transform.position = Vector3.Lerp(transform.position, new Vector3(transform.position.x, transform.position.y, transform.position.z + _move_direction.z), _speed);
            }
        }

        // here we finally override the default move position of the creature
        _new_move_position = m_GridMovePosition;
    }
Ejemplo n.º 7
0
        public Vector3 Scan(Transform _transform, Vector3 _position, LayerMask _ground_mask, LayerMask _water_mask, float _offset)
        {
            if (ScanningRange == 0 || ScanningAngle == 0 || (!UseSlopeLimits && !AvoidWater))
            {
                return(_position);
            }

            if (Owner == null)
            {
                SetOwner(_transform.gameObject);
            }

            RaycastHit _hit;

            Vector3 _pos = PositionTools.GetDirectionPosition(_transform, 0, ScanningRange);

            _offset += m_VerticalRaycastOffset + ScanningRange;
            _pos.y  += _offset;

            if (UseSlipping && MaxSurfaceSlopeAngle > 0)
            {
                if (Physics.Raycast(_transform.position + Vector3.up, Vector3.down, out _hit, Mathf.Infinity, _ground_mask, WorldManager.TriggerInteraction))
                {
                    if (Mathf.Abs(Vector3.Angle(_hit.normal, Vector3.up)) > MaxSurfaceSlopeAngle)
                    {
                        m_SlopePathPosition  = Vector3.zero;
                        _transform.position += new Vector3(_hit.normal.x * 9.8f * Time.deltaTime, 0, _hit.normal.z * 9.8f * Time.deltaTime);
                        return(_position);
                    }
                }
            }

            if (m_SlopePathPosition == Vector3.zero || PositionTools.Distance(_transform.position, m_SlopePathPosition) < ScanningRange * 0.25f)
            {
                LayerMask _combined_mask = _ground_mask;

                if (_water_mask.value != 0)
                {
                    _combined_mask |= _water_mask;
                }

                if (Physics.Raycast(_pos, Vector3.down, out _hit, Mathf.Infinity, _combined_mask, WorldManager.TriggerInteraction))
                {
                    Vector3 _dir           = (_hit.point - _transform.position).normalized;
                    float   _path_angle    = Vector3.Angle(_dir, Vector3.down) - 90;
                    float   _surface_angle = Vector3.Angle(_hit.normal, Vector3.up);

                    if ((MaxSurfaceSlopeAngle > 0 && Mathf.Abs(_surface_angle) > MaxSurfaceSlopeAngle) ||
                        (MaxPathSlopeAngle > 0 && Mathf.Abs(_path_angle) > MaxPathSlopeAngle) ||
                        (AvoidWater && SystemTools.IsInLayerMask(_hit.transform.gameObject, _water_mask)))
                    {
                        DebugLine(_hit.point, _hit.point + (Vector3.up * 2), Color.yellow);

                        for (int i = ScanningAngle; i <= 180; i += ScanningAngle)
                        {
                            Vector3 _pos_right = Vector3.zero;
                            Vector3 _pos_left  = Vector3.zero;

                            int _right_angle = i;
                            _pos    = PositionTools.GetDirectionPosition(_transform, _right_angle, ScanningRange);
                            _pos.y += _offset;
                            if (Physics.Raycast(_pos, Vector3.down, out _hit, Mathf.Infinity, _combined_mask, WorldManager.TriggerInteraction))
                            {
                                _dir           = (_hit.point - _transform.position).normalized;
                                _path_angle    = Vector3.Angle(_dir, Vector3.down) - 90;
                                _surface_angle = Vector3.Angle(_hit.normal, Vector3.up);

                                bool _walkable_right = true;
                                bool _water          = false;

                                if (MaxSurfaceSlopeAngle > 0 && Mathf.Abs(_surface_angle) > MaxSurfaceSlopeAngle)
                                {
                                    _walkable_right = false;
                                }

                                if (MaxPathSlopeAngle > 0 && _walkable_right && Mathf.Abs(_path_angle) > MaxPathSlopeAngle)
                                {
                                    _walkable_right = false;
                                }

                                if (AvoidWater && SystemTools.IsInLayerMask(_hit.transform.gameObject, _water_mask))
                                {
                                    _walkable_right = false;
                                    _water          = true;
                                }

                                if (DebugRayIsEnabled)
                                {
                                    float _h = (MaxPathSlopeAngle > 0 ? MathTools.Normalize(MaxPathSlopeAngle - Mathf.Abs(_path_angle), 0, MaxPathSlopeAngle) :  MathTools.Normalize(MaxSurfaceSlopeAngle - _surface_angle, 0, MaxSurfaceSlopeAngle));
                                    //DebugLine( _pos, _hit.point, ( _water ? Color.blue : ( _walkable_right ? Color.green : new HSBColor( _h * 0.3333333f, 1f, 1f ).ToColor() ) ) );
                                    DebugLine(_hit.point, _hit.point + (Vector3.up * 2), (_water ? Color.blue : (_walkable_right ? Color.green : new HSBColor(_h * 0.3333333f, 1f, 1f).ToColor())));
                                }

                                if (_walkable_right)
                                {
                                    _pos_right = _hit.point;
                                }
                            }
                            else
                            {
                                m_VerticalRaycastOffset += 0.25f;
                            }

                            int _left_angle = 360 - i;
                            _pos    = PositionTools.GetDirectionPosition(_transform, _left_angle, ScanningRange);
                            _pos.y += _offset;
                            if (Physics.Raycast(_pos, Vector3.down, out _hit, Mathf.Infinity, _combined_mask, WorldManager.TriggerInteraction))
                            {
                                _dir           = (_hit.point - _transform.position).normalized;
                                _path_angle    = Vector3.Angle(_dir, Vector3.down) - 90;
                                _surface_angle = Vector3.Angle(_hit.normal, Vector3.up);

                                bool _walkable_left = true;
                                bool _water         = false;

                                if (MaxSurfaceSlopeAngle > 0 && Mathf.Abs(_surface_angle) > MaxSurfaceSlopeAngle)
                                {
                                    _walkable_left = false;
                                }

                                if (MaxPathSlopeAngle > 0 && _walkable_left && Mathf.Abs(_path_angle) > MaxPathSlopeAngle)
                                {
                                    _walkable_left = false;
                                }

                                if (AvoidWater && SystemTools.IsInLayerMask(_hit.transform.gameObject, _water_mask))
                                {
                                    _walkable_left = false;
                                    _water         = true;
                                }

                                if (DebugRayIsEnabled)
                                {
                                    float _h = (MaxPathSlopeAngle > 0 ? MathTools.Normalize(MaxPathSlopeAngle - Mathf.Abs(_path_angle), 0, MaxPathSlopeAngle) :  MathTools.Normalize(MaxSurfaceSlopeAngle - _surface_angle, 0, MaxSurfaceSlopeAngle));
                                    //DebugLine( _pos, _hit.point, ( _water ? Color.blue : ( _walkable_left ? Color.green : new HSBColor( _h * 0.3333333f, 1f, 0.25f ).ToColor() ) ) );
                                    DebugLine(_hit.point, _hit.point + (Vector3.up * 2), (_water ? Color.blue : (_walkable_left ? Color.green : new HSBColor(_h * 0.3333333f, 1f, 1f).ToColor())));
                                }

                                if (_walkable_left)
                                {
                                    _pos_left = _hit.point;
                                }
                            }
                            else
                            {
                                m_VerticalRaycastOffset += 0.25f;
                            }

                            if (_pos_right != Vector3.zero && _pos_left != Vector3.zero)
                            {
                                //if( Vector3.Distance( _position, _pos_right ) <= Vector3.Distance( _position, _pos_left ) )
                                if (UnityEngine.Random.Range(0, 2) == 0)
                                {
                                    m_SlopePathPosition = _pos_right;
                                }
                                else
                                {
                                    m_SlopePathPosition = _pos_left;
                                }

                                break;
                            }
                            else if (_pos_right != Vector3.zero)
                            {
                                m_SlopePathPosition = _pos_right;
                                break;
                            }
                            else if (_pos_left != Vector3.zero)
                            {
                                m_SlopePathPosition = _pos_left;
                                break;
                            }
                        }
                    }
                    else
                    {
                        m_SlopePathPosition = Vector3.zero;

                        if (DebugRayIsEnabled)
                        {
                            float _h = (MaxPathSlopeAngle > 0 ? MathTools.Normalize(MaxPathSlopeAngle - Mathf.Abs(_path_angle), 0, MaxPathSlopeAngle) :  MathTools.Normalize(MaxSurfaceSlopeAngle - _surface_angle, 0, MaxSurfaceSlopeAngle));
                            DebugLine(_pos, _hit.point + (Vector3.up * 2), new HSBColor(_h * 0.3333333f, 1f, 0.25f).ToColor());
                            DebugLine(_hit.point, _hit.point + (Vector3.up * 2), new HSBColor(_h * 0.3333333f, 1f, 1f).ToColor());
                        }
                    }
                }
                else
                {
                    m_VerticalRaycastOffset += 0.25f;
                }
            }

            if (m_SlopePathPosition != Vector3.zero)
            {
                DebugLine(m_SlopePathPosition, m_SlopePathPosition + (Vector3.up * 2), Color.green);
                _position = m_SlopePathPosition;
            }

            return(_position);
        }
Ejemplo n.º 8
0
        public Vector3 Scan(Transform _transform, Vector3 _position, LayerMask _mask, float _stopping_distance, float _speed)
        {
            if ((!UseDynamicScanningRange && ScanningRange == 0) || (UseDynamicScanningRange && _speed == 0))
            {
                return(_position);
            }

            if (Time.time - m_StartTime <= m_ExpectedActionTime)
            {
                return(_position);
            }


            m_ActionType = ObstacleAvoidanceActionType.None;

            m_StoppingDistance = _stopping_distance;

            if (Owner != _transform.gameObject)
            {
                SetOwner(_transform.gameObject);
            }

            float _vertical_offset = 0;

            Vector3 _avoid_position = _position;
            Vector3 _transform_pos  = _transform.position;
            Vector3 _move_pos       = _position;
            float   _distance       = (UseDynamicScanningRange ? _speed * DynamicScanningRangeSpeedMultiplier : ScanningRange);

            _transform_pos.y = _transform_pos.y + _vertical_offset;
            _move_pos.y      = _transform_pos.y;


            RaycastHit _hit;
            RaycastHit _hit_up   = new RaycastHit();
            RaycastHit _hit_down = new RaycastHit();

            Vector3 _desired_dir = _position - _transform.position;
            Vector3 _origin      = _transform.position + (_transform.up * VerticalRaycastOffset);
            Vector3 _origin_up   = _transform.position + (_transform.up * (VerticalRaycastOffset + VerticalRaycastOffsetDifference));              // TODO : slide height
            Vector3 _origin_down = _transform.position + (_transform.up * (VerticalRaycastOffset - VerticalRaycastOffsetDifference));              // TODO : slide height
            Vector3 _forward     = _transform.forward;

            float _cross_down_distance = (UseCrossBelowSpeed ? _speed * CrossBelowStartDistanceSpeedMultiplier : CrossBelowStartDistance);
            float _cross_up_distance   = (UseCrossOverSpeed ? _speed * CrossOverStartDistanceSpeedMultiplier : CrossOverStartDistance);

            float _hit_down_distance = Mathf.Infinity;
            float _hit_up_distance   = Mathf.Infinity;

            m_CrossBelowPossible = false;
            m_CrossOverPossible  = false;

            if (UseOvercomeObstacles && Physics.Raycast(_origin_down, _forward, out _hit_down, _distance, _mask, WorldManager.TriggerInteraction) && !_hit_down.transform.IsChildOf(_transform))
            {
                DebugLine(_origin_down, _hit_down.point, Color.red);
                DebugRay(_origin_down, _forward * _cross_down_distance, Color.blue);
                _hit_down_distance   = _hit_down.distance;
                m_CrossBelowPossible = true;
            }
            else if (UseOvercomeObstacles)
            {
                DebugRay(_origin_down, _forward * _distance, Color.green);
            }

            if (UseOvercomeObstacles && Physics.Raycast(_origin_up, _forward, out _hit_up, _distance, _mask, WorldManager.TriggerInteraction) && !_hit_up.transform.IsChildOf(_transform))
            {
                DebugLine(_origin_up, _hit_up.point, Color.red);
                DebugRay(_origin_up, _forward * _cross_up_distance, Color.blue);
                _hit_up_distance    = _hit_up.distance;
                m_CrossOverPossible = true;
            }
            else if (UseOvercomeObstacles)
            {
                DebugRay(_origin_up, _forward * _distance, Color.green);
            }

            // CHECK POSIBLE CROSS OVER
            if (UseOvercomeObstacles && _hit_down_distance < _hit_up_distance)
            {
                if (_hit_down.distance < _cross_up_distance)
                {
                    m_DesiredCrossOverPosition   = _hit_down.point;
                    m_DesiredCrossOverPosition.y = _hit_down.collider.bounds.center.y + 0.5f * Owner.GetComponent <Collider>().bounds.extents.y + 0.075f;
                    m_StartTime          = Time.time;
                    m_ExpectedActionTime = _cross_up_distance * 2 / (_speed > 0 ? _speed : 1);
                    m_ActionType         = ObstacleAvoidanceActionType.CrossOver;
                }
            }
            // CHECK POSIBLE CROSS BELOW
            else if (UseOvercomeObstacles && _hit_up_distance < _hit_down_distance)
            {
                if (_hit_up.distance < _cross_down_distance)
                {
                    m_DesiredCrossBelowPosition = _position + (1.25f * _hit_up.distance * _forward);
                    m_StartTime          = Time.time;
                    m_ExpectedActionTime = _cross_down_distance * 2 / (_speed > 0 ? _speed : 1);
                    m_ActionType         = ObstacleAvoidanceActionType.CrossBelow;
                }
            }
            // CHECK AVOIDANCE
            else if (Physics.Raycast(_origin, _forward, out _hit, _distance, _mask, WorldManager.TriggerInteraction))
            {
                if (!_hit.transform.IsChildOf(_transform))
                {
                    DebugLine(_origin, _hit.point, Color.red);

                    if (_desired_dir.magnitude < PositionTools.Distance(_hit.point, _transform.position))
                    {
                        DebugLine(_origin, _desired_dir, Color.green);
                        m_ObstacleAvoidancePosition = Vector3.zero;
                        m_FixDirection = PreferedDirectionType.UNDEFINED;
                    }
                    else
                    {
                        if (_distance > _hit.collider.bounds.size.magnitude * 0.5f)
                        {
                            _distance = _hit.collider.bounds.size.magnitude * 0.5f;
                        }
                        else if (_distance > new Vector2(_hit.collider.bounds.size.z, _hit.collider.bounds.size.x).magnitude)
                        {
                            _distance = new Vector2(_hit.collider.bounds.size.z, _hit.collider.bounds.size.x).magnitude;
                        }

                        DebugLine(_origin, _hit.point, Color.red);

                        int     _cost_right  = 0;
                        Vector3 _avoid_right = Vector3.zero;
                        for (int i = ScanningAngle; i <= 360; i += ScanningAngle)
                        {
                            _cost_right++;
                            Vector3 _pos = PositionTools.GetDirectionPosition(_transform, i, _distance);

                            if (!Physics.Linecast(_origin, _pos, _mask))
                            {
                                _avoid_right = _pos;
                                DebugLine(_origin, _pos, SystemTools.ColorA(Color.blue, 0.5f));
                                break;
                            }
                            else
                            {
                                //TODO: if there is no free position we could determinate the best posibility
                                DebugLine(_origin, _pos, SystemTools.ColorA(Color.red, 0.25f));
                            }
                        }

                        int     _cost_left  = 0;
                        Vector3 _avoid_left = Vector3.zero;
                        for (int i = 360 - ScanningAngle; i > 0; i -= ScanningAngle)
                        {
                            _cost_left++;
                            Vector3 _pos = PositionTools.GetDirectionPosition(_transform, i, _distance);

                            if (!Physics.Linecast(_origin, _pos, _mask))
                            {
                                _avoid_left = _pos;
                                DebugLine(_origin, _pos, SystemTools.ColorA(Color.blue, 0.5f));
                                break;
                            }
                            else
                            {
                                //TODO: if there is no free position we could determinate the best posibility
                                DebugLine(_origin, _pos, SystemTools.ColorA(Color.red, 0.25f));
                            }
                        }


                        // selects the best solution according to the given costs
                        if (_avoid_right != Vector3.zero && _avoid_left != Vector3.zero)
                        {
                            if (_cost_left < _cost_right)
                            {
                                m_ObstacleAvoidancePosition = _avoid_left;
                            }
                            else if (_cost_right < _cost_left)
                            {
                                m_ObstacleAvoidancePosition = _avoid_right;
                            }
                            else
                            {
                                m_ObstacleAvoidancePosition = (Random.Range(0, 1) == 1 ? _avoid_left : _avoid_right);
                            }
                        }
                        else if (_avoid_right != Vector3.zero)
                        {
                            m_ObstacleAvoidancePosition = _avoid_right;
                        }
                        else if (_avoid_left != Vector3.zero)
                        {
                            m_ObstacleAvoidancePosition = _avoid_left;
                        }

                        // makes sure that the creature will not change the direction if not needed
                        if (UseFixDirection)
                        {
                            if (m_FixDirection == PreferedDirectionType.UNDEFINED)
                            {
                                if (m_ObstacleAvoidancePosition == _avoid_right)
                                {
                                    m_FixDirection = PreferedDirectionType.RIGHT;
                                }
                                else if (m_ObstacleAvoidancePosition == _avoid_left)
                                {
                                    m_FixDirection = PreferedDirectionType.LEFT;
                                }
                            }
                            else if (m_FixDirection == PreferedDirectionType.RIGHT && _avoid_right != Vector3.zero)
                            {
                                m_ObstacleAvoidancePosition = _avoid_right;
                            }
                            else if (m_FixDirection == PreferedDirectionType.LEFT && _avoid_left != Vector3.zero)
                            {
                                m_ObstacleAvoidancePosition = _avoid_left;
                            }
                        }
                    }
                }
            }
            else
            {
                DebugRay(_origin, _forward * _distance, Color.green);

                m_FixDirection = PreferedDirectionType.UNDEFINED;

                if (Physics.Raycast(_origin, _desired_dir, out _hit, _distance, _mask, WorldManager.TriggerInteraction))
                {
                    DebugLine(_origin, _hit.point, SystemTools.ColorA(Color.red, MathTools.Normalize(_distance - PositionTools.Distance(_hit.point, _origin), 0, _distance)));

                    if (AvoidanceMovePositionReached)
                    {
                        m_ObstacleAvoidancePosition = _transform.position + (_transform.forward * _distance);
                    }
                }
                else
                {
                    DebugRay(_origin, _desired_dir.normalized * _distance, Color.gray);
                    m_ObstacleAvoidancePosition = Vector3.zero;
                }
            }

            if (m_ObstacleAvoidancePosition != Vector3.zero)
            {
                _avoid_position = m_ObstacleAvoidancePosition;
            }

            return(_avoid_position);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// SendDamage handles damage and impact forces for the specified target object. You can use this static method to
        /// affect each entity object within your scene. Please note that _target can be adjusted to null, in
        /// such a case the _force_type will be automatically changed to DamageForceType.Explosion and the origin
        /// of the detonation will be the _sender.transform.position.
        /// </summary>
        /// <param name="_sender">Sender.</param>
        /// <param name="_target">Target.</param>
        /// <param name="_impact_type">Impact type.</param>
        /// <param name="_damage">Damage.</param>
        /// <param name="_damage_method">Damage method.</param>
        /// <param name="_damage_point">Damage point.</param>
        /// <param name="_force_type">Force type.</param>
        /// <param name="_force">Force.</param>
        /// <param name="_radius">Radius.</param>
        public static void SendDamage(GameObject _sender, GameObject _target, DamageTransferType _impact_type, float _damage, string _damage_method, Vector3 _damage_point, DamageForceType _force_type, float _force, float _radius)
        {
            if (_sender == null)
            {
                return;
            }

            if (_target == null)
            {
                _force_type = DamageForceType.Explosion;
            }

            // If the force type is an explosion will will handle first the explosion impact to all objects around the specified target
            // in cases the target will be NULL (e.g. remote or timed detonation of an explosive etc.) the sender will be the origin of
            // the explosion.
            if (_force_type == DamageForceType.Explosion)
            {
                _damage_point = (_damage_point == Vector3.zero ? (_target != null ? _target.transform.position : _sender.transform.position) : _damage_point);

                Collider[] _colliders = Physics.OverlapSphere(_damage_point, _radius);
                if (_colliders != null)
                {
                    foreach (Collider _collider in _colliders)
                    {
                        if (_collider == null || _collider.gameObject == _target || _collider.gameObject == _sender)
                        {
                            continue;
                        }

                        float _distance   = PositionTools.Distance(_damage_point, _collider.gameObject.transform.position);
                        float _multiplier = Mathf.Clamp01(1 - MathTools.Normalize(_distance, 0, _radius));

                        // If a explosion radius is given we will try to apply a suitable force to the colliders gamesobject
                        if (_radius > 0)
                        {
                            if (_collider.attachedRigidbody != null && !_collider.attachedRigidbody.isKinematic)
                            {
                                _collider.attachedRigidbody.AddExplosionForce(_force * _multiplier, _damage_point, _radius);
                            }
                            else
                            {
                                ICEWorldEntity _entity = ICEWorldEntity.GetWorldEntity(_collider.gameObject);
                                if (_entity != null)
                                {
                                    Vector3 _direction = _collider.transform.position - _damage_point;
                                    _entity.ApplyImpact(_direction, _force * _multiplier);
                                }
                            }
                        }

                        // SendTargetDamage will try now to damage the colliders gameobject according to the given distance and multiplier
                        ICEWorldEntity.SendTargetDamage(_sender, _collider.gameObject, _impact_type, _damage * _multiplier, _damage_method, _damage_point, _force_type, _force * _multiplier);
                    }
                }
            }


            if (_target != null)
            {
                // whenever a target is specified and the defined force type isn't NONE we try to apply also a force to the target
                if (_force_type != DamageForceType.None)
                {
                    Vector3 _direction = _target.transform.position - _sender.transform.position;
                    _direction.Normalize();
                    // Handle Target Rigidbody and forces
                    Rigidbody _target_rigidbody = _target.GetComponent <Rigidbody>();
                    if (_target_rigidbody != null && !_target_rigidbody.isKinematic)
                    {
                        _target_rigidbody.AddForce(_direction.normalized * _force, ForceMode.Force);
                    }
                    else
                    {
                        ICEWorldEntity _entity = ICEWorldEntity.GetWorldEntity(_target);
                        if (_entity != null)
                        {
                            _entity.ApplyImpact(_direction, _force);
                        }
                    }
                }

                // Finally we try to damage the specified target
                ICEWorldEntity.SendTargetDamage(_sender, _target, _impact_type, _damage, _damage_method, _damage_point, _force_type, _force);
            }
        }
Ejemplo n.º 10
0
        public bool Check(Transform _transform, Vector3 _velocity)
        {
            if (!Enabled || _transform == null)
            {
                return(false);
            }

            if (_velocity.z == 0)
            {
                m_DeadlockMoveTimer = 0;
                m_DeadlockLoopTimer = 0;
                return(false);
            }

            m_DeadlockMoveTimer += Time.deltaTime;
            m_DeadlockLoopTimer += Time.deltaTime;

            if (m_DeadlockPosition == Vector3.zero)
            {
                m_DeadlockPosition = _transform.position;
            }

            if (m_DeadlockMoveTimer >= MoveInterval)
            {
                m_DeadlocksDistance = PositionTools.Distance(_transform.position, m_DeadlockPosition);

                // CHECK DEADLOCK
                if (m_DeadlocksDistance <= MinMoveDistance)
                {
                    if (m_Deadlocked == false)
                    {
                        m_DeadlocksCount++;
                    }

                    m_DeadlocksCriticalPositions.Add(_transform.position);

                    if (m_DeadlocksCriticalPositions.Count > MoveMaxCriticalPositions)
                    {
                        m_Deadlocked = true;
                    }
                }
                else if (m_DeadlocksCriticalPositions.Count > 0)
                {
                    m_DeadlocksCriticalPositions.RemoveAt(0);
                }
                else
                {
                    m_DeadlockPosition  = _transform.position;
                    m_DeadlockMoveTimer = 0;
                }
            }

            // CHECK INFINITY LOOP
            if (m_DeadlockLoopTimer >= LoopInterval)
            {
                if (m_DeadlocksDistance <= LoopRange)
                {
                    if (m_Deadlocked == false)
                    {
                        m_DeadlockLoopsCount++;
                    }

                    m_DeadlocksCriticalLoops.Add(_transform.position);

                    if (m_DeadlocksCriticalLoops.Count > LoopMaxCriticalPositions)
                    {
                        m_Deadlocked = true;
                    }
                }
                else if (m_DeadlocksCriticalLoops.Count > 0)
                {
                    m_DeadlocksCriticalLoops.RemoveAt(0);
                }
                else
                {
                    m_DeadlockLoopTimer = 0;
                }
            }

            if (m_DeadlockMoveTimer == 0 && m_DeadlocksCriticalPositions.Count == 0 && m_DeadlockLoopTimer == 0 && m_DeadlocksCriticalLoops.Count == 0)
            {
                m_Deadlocked = false;
            }

            return(m_Deadlocked);
        }
Ejemplo n.º 11
0
        private bool IsTargetUpdatePermitted(TargetObject _target)
        {
            if (_target == null)
            {
                return(false);
            }

            if (m_ActiveTarget == null || Behaviour.ActiveBehaviourMode == null || Behaviour.ActiveBehaviourMode.Favoured.Enabled == false)
            {
                return(true);
            }

            bool _permitted = true;

            if ((Behaviour.ActiveBehaviourMode.Favoured.Enabled == true) && (
                    (Behaviour.ActiveBehaviourMode.Favoured.Runtime > 0 && Behaviour.BehaviourTimer < Behaviour.ActiveBehaviourMode.Favoured.Runtime) ||
                    (Behaviour.ActiveBehaviourMode.Favoured.FavouredUntilNextMovePositionReached && !Move.MovePositionReached) ||
                    (Behaviour.ActiveBehaviourMode.Favoured.FavouredUntilTargetMovePositionReached && !Move.TargetMovePositionReached) ||
                    (Behaviour.ActiveBehaviourMode.Favoured.FavouredUntilNewTargetInRange(_target, PositionTools.Distance(_target.TargetGameObject.transform.position, Owner.transform.position))) ||
                    (Behaviour.ActiveBehaviourMode.HasActiveDetourRule && Behaviour.ActiveBehaviourMode.Favoured.FavouredUntilDetourPositionReached && !Move.DetourComplete)))
            {
                _permitted = false;
            }
            else
            {
                _permitted = true;
            }

            //mode check - the new mode could be also forced, so we have to check this here
            if (_permitted == false)
            {
                BehaviourModeObject _mode = Behaviour.GetBehaviourModeByKey(_target.Behaviour.CurrentBehaviourModeKey);

                if (_mode != null && _mode.Favoured.Enabled == true)
                {
                    if (Behaviour.ActiveBehaviourMode.Favoured.FavouredPriority > _mode.Favoured.FavouredPriority)
                    {
                        _permitted = false;
                    }
                    else if (Behaviour.ActiveBehaviourMode.Favoured.FavouredPriority < _mode.Favoured.FavouredPriority)
                    {
                        _permitted = true;
                    }
                    else
                    {
                        _permitted = (Random.Range(0, 1) == 0?false:true);
                    }
                }
            }


            return(_permitted);
        }