// Update is called once per frame
 private void Update()
 {
     if (Input.GetKeyDown(KeyCode.M))
     {
         int result = PhysicsUtility.OverlapSphereNonAlloc(m_point.position, 10f, ref m_cols, 1 << LayerMask.NameToLayer("Default"));
         Debug.Log(result);
     }
 }
예제 #2
0
        private void Update()
        {
            m_seenTargetsThisFrame.Clear();

            if (m_debugData.Active)
            {
                float length = m_sightData.SightDistance;
                var   color  = m_debugData.SightRaysColor;
                Debug.DrawRay(EyesPosition, EyesForward * length * 0.5f, color);
                Debug.DrawRay(EyesPosition, Quaternion.Euler(EyesUp * m_sightData.SightAngle * 0.5f) * EyesForward * length, color);
                Debug.DrawRay(EyesPosition, Quaternion.Euler(EyesUp * -m_sightData.SightAngle * 0.5f) * EyesForward * length, color);
            }

            int count = PhysicsUtility.OverlapSphereNonAlloc(
                m_sightData.Eyes.position,
                m_sightData.SightDistance,
                ref m_inRangeColliders);

            if (count < 0)
            {
                ClearAllCurrentlySeenTargets();
                return;
            }

            // set ray origin just once since eyes position can't change
            m_cachedRay.origin = EyesPosition;

            for (int i = 0; i < count; i++)
            {
                var c      = m_inRangeColliders[i];
                var target = c.GetComponent <ISightTarget>();
                if (target == null || target.IsInvisible)
                {
                    continue;
                }

                var dirToTarget = EyesPosition - target.Transform.position;
                var distance    = dirToTarget.magnitude;

                if (distance > m_sightData.SightDistance * target.StealthMultiplier)
                {
                    // in stealth if too far is not seeable
                    continue;
                }

                // check angle
                var angle = Vector3.Angle(dirToTarget.normalized, EyesForward);
                if (angle > HalfAngle)
                {
                    // out of sight
                    continue;
                }

                // ray to check occlusion
                m_cachedRay.direction = dirToTarget.normalized;
                if (!Physics.Raycast(m_cachedRay, out m_cachedHit, dirToTarget.magnitude))
                {
                    // is occluded
                    continue;
                }

                m_seenTargetsThisFrame.Add(target);
                if (!m_seenTargets.Contains(target))
                {
                    m_seenTargets.Add(target);
                    target.OnStartBeingSeen(this);
                    StartSeeingTarget?.Invoke(target);
                }
            }

            m_seenTargets.RemoveElementIfContained(m_seenTargetsThisFrame, t =>
            {
                t.OnEndBeingSeen(this);
                StopSeeingTarget?.Invoke(t);
            });
        }
예제 #3
0
        private void Update()
        {
            m_hearedByThisFrame.Clear();

            var   velocity      = m_debugData.UseVelocityDebug ? m_debugData.DebugVelocity : Velocity;
            float noiseDistance = m_noiseData.NoiseCurve.Evaluate(velocity.magnitude) * NoiseMultiplier;

            // search for noise listeners in range
            int count = PhysicsUtility.OverlapSphereNonAlloc(
                m_noiseData.NoiseEmissionPoint.position,
                noiseDistance,
                ref m_inRangeColliders,
                m_noiseData.CanBeHeardByLayers);

            if (count < 0)
            {
                // nothing in range
                CurrentlyHeared = false;
                ClearAllCurrentlyHearingListeners(true);
                return;
            }

            bool hearedThisFrame = false;

            for (int i = 0; i < count; i++)
            {
                var c        = m_inRangeColliders[i];
                var listener = c.GetComponent <INoiseListener>();
                if (listener == null || !listener.Enabled)
                {
                    continue;
                }

                // check if the listener is occluded by something
                foreach (var t in m_noiseData.RayRoots)
                {
                    Vector3 dir = (listener.Transform.position - t.position);
                    m_cachedRay.origin    = t.position;
                    m_cachedRay.direction = dir.normalized;

                    if (m_debugData.Active)
                    {
                        Debug.DrawRay(t.position, dir, m_debugData.OcclusionRaysColor);
                    }

                    bool occluded = false;
                    if (Physics.Raycast(
                            m_cachedRay,
                            out m_cachedHit,
                            dir.magnitude,
                            m_noiseData.OccludedByPhysicalLayers,
                            QueryTriggerInteraction.UseGlobal))
                    {
                        if (m_cachedHit.collider != c)   // hit the listener
                        {
                            occluded = true;
                        }
                    }

                    if (occluded)
                    {
                        continue;
                    }

                    hearedThisFrame = true;

                    m_hearedByThisFrame.Add(listener);
                    if (!m_hearedByListeners.Contains(listener))
                    {
                        m_hearedByListeners.Add(listener);
                        listener.OnStartHearNoise(new NoiseHearedData
                        {
                            Source    = this,
                            Direction = -dir.normalized,
                            Distance  = dir.magnitude
                        });
                    }
                }
            }

            m_hearedByListeners.RemoveElementIfContained(m_hearedByThisFrame, l => l.OnStopHearNoise(this));

            CurrentlyHeared = hearedThisFrame;
        }