public void ClearFromCache(ISightTarget target)
 {
     if (vertexCache.ContainsKey(target.gameObject.GetInstanceID()))
     {
         vertexCache[target.gameObject.GetInstanceID()].Clear();
     }
 }
        public virtual bool GenerateCache(ISightTarget target)
        {
            var skinnedRenderer = target.gameObject.GetComponentInChildren <SkinnedMeshRenderer>();

            if (skinnedRenderer != null)
            {
                AddToCache(target, skinnedRenderer.transform, skinnedRenderer.sharedMesh, skinnedRenderer);
                return(true);
            }

            var meshFilter = target.gameObject.GetComponentInChildren <MeshFilter>();

            if (meshFilter != null)
            {
                AddToCache(target, meshFilter.transform, meshFilter.sharedMesh, null);
                return(true);
            }

            var spriteRender = target.gameObject.GetComponentInChildren <SpriteRenderer>();

            if (spriteRender != null)
            {
                var mesh = GenerateMeshFromSprite(spriteRender.sprite);
                AddToCache(target, spriteRender.transform, mesh, null);
                return(true);
            }

            if (config.debug)
            {
                Debug.LogError("Spot object without a (Skinned) Mesh Renderer! - If the object you're trying to detect doesn't have a renderer use manual mode instead.", target.gameObject);
            }

            return(false);
        }
        protected virtual void AddToCache(ISightTarget target, Transform meshParent, Mesh mesh, SkinnedMeshRenderer skinnedMeshRenderer)
        {
            int instanceID = target.gameObject.GetInstanceID();

            //int sampleCount = config.sampleCount;
            int sampleCount   = Mathf.Clamp(20, 0, mesh.vertexCount); // TODO: FIX -- When a sight viewer with 1 sample indexes first, one with a higher sample count won't re-index...
            var randomIndices = new int[sampleCount];

            for (int i = 0; i < sampleCount; i++)
            {
                int index = UnityEngine.Random.Range(0, mesh.vertexCount);
                randomIndices[i] = index;
            }

            if (vertexCache.ContainsKey(instanceID) == false)
            {
                if (config.debug)
                {
//                    Debug.Log("Added new object (" + target.name + ") to cache", target.gameObject);
                }

                vertexCache.Add(instanceID, new SightCacheLookup(target, meshParent, mesh, randomIndices, skinnedMeshRenderer));
                return;
            }

            if (config.debug)
            {
                Debug.Log("Re-building cache for " + target.name, target.gameObject);
            }

            vertexCache[instanceID] = new SightCacheLookup(target, meshParent, mesh, randomIndices, skinnedMeshRenderer);
        }
        public void ExtrapolatePath(ISightTarget target, float secondsForward, out SightTargetSampleData[] extrapolationData)
        {
            var samples = _samplesQueue[target];

            if (_extrapolatedData.ContainsKey(target) == false)
            {
                _extrapolatedData.Add(target, new SightTargetSampleData[samples.maxCount]);
            }

            var extrapolationSamples = _extrapolatedData[target];

            int counter     = 0;
            var firstSample = samples.FirstOrDefault();

            foreach (var currentSample in samples)
            {
                extrapolationSamples[counter] = new SightTargetSampleData()
                {
                    position = target.transform.position + (currentSample.position - firstSample.position),
                    rotation = target.transform.rotation * (Quaternion.Inverse(currentSample.rotation) * firstSample.rotation), // * by inverse gives dif.
                    time     = LosUtility.time + (currentSample.time - firstSample.time)
                };

                counter++;
            }

            extrapolationData = extrapolationSamples;
        }
示例#5
0
        public void ExtrapolatePath(ISightTarget target, float secondsForward, out SightTargetSampleData[] extrapolationData)
        {
            var samples = _samplesQueue[target];

            if (_extrapolatedData.ContainsKey(target) == false)
            {
                _extrapolatedData.Add(target, new SightTargetSampleData[_config.extrapolateSampleCount]);
            }

            var extrapolationSamples = _extrapolatedData[target];

            var firstSample  = samples.First();
            var secondSample = samples.ElementAt(1);
            var dir          = secondSample.position - firstSample.position;

            for (int i = 0; i < samples.count; i++)
            {
                extrapolationSamples[i] = new SightTargetSampleData()
                {
                    position = target.transform.position + dir * i,
                    time     = LosUtility.time + (i * _config.updateInterval)
                };
            }

            extrapolationData = extrapolationSamples;
//            Debug.Log("Extrapolated path", target.gameObject);
        }
示例#6
0
 public void ClearSamplesForTarget(ISightTarget target)
 {
     if (_samplesQueue.ContainsKey(target))
     {
         _samplesQueue[target].Clear();
     }
 }
示例#7
0
        public float CalculateAggroForTarget(ISightTarget target)
        {
            // TODO: May create some GC...
            _hearingHistory.RemoveAll(o => o.Value < LosUtility.time);

            float extra = 0f;

            foreach (var keyValuePair in _hearingHistory)
            {
                var source = keyValuePair.Key.audioSource;
                if (source.emitter.transform == target.transform || source.emitter.transform.IsChildOf(target.transform))
                {
                    extra += keyValuePair.Key.volume * intensity;
                }
            }

            return(extra);
//            var listener = _observerAggro.observer.gameObject.GetComponent<IListener>();
//            if (listener != null && listener.lastHeardAudioSource != null)
//            {
//                var source = listener.lastHeardAudioSource.Value.audioSource;
//                if (source.emitter == target.gameObject || source.emitter.transform.IsChildOf(listener.transform))
//                {
//                    return listener.lastHeardAudioSource.Value.volume * intensity;
//                }
//            }
//            return 0f;
        }
        private void DrawModuleOutputForTarget(ISightTarget sightTarget)
        {
            EditorGUI.indentLevel++;

            var t = (ObserverAggroBehaviour)target;

            var obj = t.aggroDict.FirstOrDefault(o => o.Key == sightTarget).Value;

            if (obj != null)
            {
                foreach (var module in t.aggroModules)
                {
                    if (module.enabled == false)
                    {
                        continue;
                    }

                    var    max   = t.aggroModules.Max(o => o.name.Length);
                    var    tabs  = Mathf.FloorToInt(max / (float)module.name.Length) + 1;
                    string final = module.name;

                    for (int i = 0; i < tabs; i++)
                    {
                        final += "\t";
                    }

                    EditorGUILayout.LabelField(string.Format("{0} -\t{1}", final, module.CalculateAggroForTarget(sightTarget)));
                }
            }

            EditorGUI.indentLevel--;
        }
 protected void NotifyTargetWithHighestAggroChanged(ISightTarget target, float aggro)
 {
     gameObject.GetComponents(_callbacks);
     foreach (var callback in _callbacks)
     {
         callback.OnTargetWithHighestAggroChanged(target, aggro);
     }
 }
        public SightTargetAggroInfo GetAggroForTarget(ISightTarget target)
        {
            if (aggroDict.ContainsKey(target) == false || target.IsDestroyed())
            {
                return(null);
            }

            return(aggroDict[target]);
        }
示例#11
0
        public void ForgetTarget(ISightTarget target)
        {
            var info = GetInRangeTargetInfo(target);

            if (info != null)
            {
                targetsInRange.Remove(info);
            }
        }
示例#12
0
        /// <summary>
        /// Detect the given target instantly. The object will have to be in range, otherwise the call is ignored.
        /// </summary>
        public void DetectTarget(ISightTarget target)
        {
            var info = GetInRangeTargetInfo(target);

            if (info != null)
            {
                TargetDetected(info);
            }
        }
        public void GetFromCache(ISightTarget target, out SightCacheLookup cacheLookup)
        {
            if (vertexCache.ContainsKey(target.gameObject.GetInstanceID()))
            {
                cacheLookup = vertexCache[target.gameObject.GetInstanceID()];
                return;
            }

            throw new InvalidOperationException("Given object is not in cache, check if an object is in cache first by calling Contains");
        }
示例#14
0
        public float CalculateAggroForTarget(ISightTarget target)
        {
            var info = target.GetInfoFromObserver(_observerAggro.observer);

            if (info != null)
            {
                return(info.visibleFactor * intensity);
            }

            return(0f);
        }
        public float CalculateAggroForTarget(ISightTarget target)
        {
            var info = target.GetInfoFromObserver(_observerAggro.observer); // Safe to assume info is available here, considering we're getting the update call.

            if (info == null || info.lastSeenAt.HasValue == false)
            {
                return(0f);
            }

            return(Vector3.Dot(_observerAggro.observer.transform.forward, Vector3.Normalize(target.transform.position - _observerAggro.observer.transform.position)) * intensity);
        }
        public float CalculateAggroForTarget(ISightTarget target)
        {
            var info = target.GetInfoFromObserver(_observerAggro.observer);

            if (info != null)
            {
                return((_observerAggro.observer.config.viewingDistance - info.distance) / _observerAggro.observer.config.viewingDistance * intensity);
            }

            return(0f);
        }
        public float CalculateAggroForTarget(ISightTarget target)
        {
            var info = target.GetInfoFromObserver(_observerAggro.observer);

            if (info != null)
            {
                return(Mathf.Clamp(info.visibleForSeconds, 0f, maxTime) * intensity);
            }

            return(0f);
        }
 public override void Init(FsmState state)
 {
     base.Init(state);
     if (target != null && target.Value != null)
     {
         iSightTarget = target.Value.GetComponent <ISightTarget>();
         if (iSightTarget == null)
         {
             LogError("No sight target found");
         }
     }
 }
        /// <summary>
        /// </summary>
        /// <returns>Returns the info the observer has about this target.
        /// Returns null if the observer has no info on this target.</returns>
        public static SightTargetInfo GetInfoFromObserver(this ISightTarget target, IObserver observer)
        {
            foreach (var info in observer.targetsInRange)
            {
                if (info.target == target)
                {
                    return(info);
                }
            }

            return(null);
        }
        protected virtual void UpdateAggro()
        {
            ForgetTargetsNow(); // In case some were queued up.
            var before = _targetWithHighestAggro;

            _targetWithHighestAggro = null;
            float targetsHighestAggro = 0f;

            foreach (var keyValuePair in aggroDict)
            {
//                if (keyValuePair.Key.enabled == false)
//                {
//                    if (_targetWithHighestAggro == keyValuePair.Key)
//                    {
//                        _targetWithHighestAggro = null;
//                    }
//
//                    continue;
//                }

                if (keyValuePair.Key.IsDestroyed())
                {
                    ForgetTarget(keyValuePair.Key);
                    continue;
                }

                keyValuePair.Value.modulesValue = 0f;

                foreach (var module in _aggroModules)
                {
                    if (ReferenceEquals(module, null) || module.Equals(null) || module.enabled == false)
                    {
                        continue;
                    }

                    keyValuePair.Value.modulesValue += module.CalculateAggroForTarget(keyValuePair.Key);

                    if (_targetWithHighestAggro == null || _targetWithHighestAggro.IsDestroyed() || keyValuePair.Value.finalValue > targetsHighestAggro)
                    {
                        _targetWithHighestAggro = keyValuePair.Key;
                        targetsHighestAggro     = keyValuePair.Value.finalValue;
                    }
                }
            }

            if (before != _targetWithHighestAggro)
            {
                NotifyTargetWithHighestAggroChanged(_targetWithHighestAggro, targetsHighestAggro);
            }

            ForgetTargetsNow(); // After updating some modules may want to forget a target.
        }
示例#21
0
        public SightTargetInfo GetInRangeTargetInfo(ISightTarget target)
        {
            // NOTE: FirstOrDefault generates GC - So manual loop
            foreach (var t in targetsInRange)
            {
                if (t.target == target)
                {
                    return(t);
                }
            }

            return(null);
        }
示例#22
0
        public override void Init(FsmState state)
        {
            base.Init(state);

            if (sightTarget != null && sightTarget.Value != null)
            {
                _sightTarget = sightTarget.Value.GetComponent <ISightTarget>();
                if (_sightTarget == null)
                {
                    LogError("No target found, can't detect targets!");
                }
            }
        }
        public void ChangeAggroForTarget(ISightTarget target, float changeAmount)
        {
            var t = GetAggroForTarget(target);

            if (t != null)
            {
                SetAggroForTarget(target, t.addValue + changeAmount);
            }
            else
            {
                SetAggroForTarget(target, changeAmount);
            }
        }
 public void SetAggroForTarget(ISightTarget target, float amount)
 {
     if (aggroDict.ContainsKey(target) == false)
     {
         aggroDict.Add(target, new SightTargetAggroInfo(target, defaultAggroValue)
         {
             addValue = amount
         });
     }
     else
     {
         aggroDict[target].addValue = amount;
     }
 }
示例#25
0
        public float CalculateAggroForTarget(ISightTarget target)
        {
            var listener = _observerAggro.observer.gameObject.GetComponent <IListener>();

            if (listener != null && listener.lastHeardAudioSource != null)
            {
                var source = listener.lastHeardAudioSource.Value.audioSource;
                if (source.emitter == target.gameObject || source.emitter.transform.IsChildOf(listener.transform))
                {
                    return(Vector3.Dot(_observerAggro.observer.transform.forward, Vector3.Normalize(listener.lastHeardAudioSource.Value.audioSource.transform.position - _observerAggro.observer.transform.position)));
                }
            }

            return(0f);
        }
示例#26
0
        private void TargetCameIntoRange(ISightTarget target)
        {
            var sightInfo = new SightTargetInfo(target, this);

            targetsInRange.Add(sightInfo);


            observer.gameObject.GetComponents(_observerCallbacksList);
            foreach (var callback in _observerCallbacksList)
            {
                callback.OnTargetCameIntoRange(sightInfo);
            }

            sightInfo.target.gameObject.GetComponents(_sightTargetCallbacksList);
            foreach (var callback in _sightTargetCallbacksList)
            {
                callback.OnCameIntoObserverRange(sightInfo);
            }
        }
 protected void AddTargetToAggroList(ISightTarget target)
 {
     // Could've been forced before with AddAggroToTarget
     if (aggroDict.ContainsKey(target) == false)
     {
         var aggroBehaviour = target.gameObject.GetComponent <SightTargetAggroBehaviour>();
         if (aggroBehaviour != null)
         {
             aggroDict.Add(target, new SightTargetAggroInfo(target, aggroBehaviour.aggroConfig.defaultAggro)
             {
                 multiplier = aggroBehaviour.aggroConfig.aggroMultiplier
             });
         }
         else
         {
             aggroDict.Add(target, new SightTargetAggroInfo(target, defaultAggroValue));
         }
     }
 }
        public float CalculateAggroForTarget(ISightTarget target)
        {
            var info = target.GetInfoFromObserver(_observerAggro.observer);

            if (info != null && info.lastSeenAt.HasValue)
            {
                var diff    = (info.lastSeenAt.Value.time - LosUtility.time);
                var diffAbs = Mathf.Abs(diff);
                if (diffAbs > startAfterInvisibleTime)
                {
                    if (diffAbs > forgetTargetAfterSecondsInvisible)
                    {
                        _observerAggro.ForgetTarget(target);
                    }

                    return(diff * intensity);
                }
            }

            return(0f);
        }
示例#29
0
        public void TakeSample(ISightTarget target)
        {
            if (_samplesQueue.ContainsKey(target) == false)
            {
                _samplesQueue.Add(target, new FixedSizeQueue <SightTargetSampleData>(2));
            }

            _samplesQueue[target].Enqueue(new SightTargetSampleData()
            {
                time     = LosUtility.time,
                position = target.transform.position,
                rotation = target.transform.rotation
            });

            //            _samplesQueue[target].Enqueue(new SightTargetSampleData()
            //            {
            //                time = LosUtility.time,
            //                position = target.transform.position + new Vector3(UnityEngine.Random.value * _config.extrapolateRandomNoiseFactor, 0f, UnityEngine.Random.value * _config.extrapolateRandomNoiseFactor),
            //                rotation = target.transform.rotation * Quaternion.Euler(0f, UnityEngine.Random.value * 10 * _config.extrapolateRandomNoiseFactor, 0f)
            //            });
        }
        public override void Init(FsmState state)
        {
            base.Init(state);
            if (target != null && target.Value != null)
            {
                _target = target.Value.GetComponent <ISightTarget>();
                if (_target == null)
                {
                    LogError("No sight target component found on gameObject");
                }
            }

            if (observer != null && observer.Value != null)
            {
                _observer = observer.Value.GetComponent <IObserver>();
                if (_observer == null)
                {
                    LogError("No observer component found on gameObject.");
                }
            }
        }