// pushes event onto perceived events list // restarts lifetimeTimer public void PerceiveEvent(MemoryEvent newEvent) { #if UNITY_EDITOR if (newEvent == null) { Debug.LogWarning("Trying to register null as MemoryEvent"); return; } #endif // check if in memory there is any event caused by the same unit as newEvent if (newEvent.perceiveUnit) { for (int i = 0; i < memoryEvents.Length; ++i) { if (memoryEvents[i] != null && memoryEvents[i].perceiveUnit == newEvent.perceiveUnit) { memoryEvents[i] = null; break; } } } lastAddedEvent = (lastAddedEvent + 1) % memoryEvents.Length; memoryEvents[lastAddedEvent] = newEvent; newEvent.lifetimeTimer.Restart(); }
new void Awake() { base.Awake(); //// initialize focus painStorage = RegisterSenseInBlackboard(BehaviourPack.painId); var healthController = GetComponentInParent <HealthController>(); healthController.onDamageCallback += (data) => { if (!tPain.IsReadyRestart()) { return; } MemoryEvent ev = new MemoryEvent(); ev.exactPosition = data.position; ev.forward = data.direction; // we have no information about hit velocity; just assume it is stationary ev.velocity = Vector2.zero; ev.lifetimeTimer.Restart(); painStorage.PerceiveEvent(ev); Debug.DrawRay(ev.position, Vector3.up, Color.blue, 0.25f); }; }
void ReactToNoise(NoiseData data) { if (data.fraction && myUnit.fraction.GetAttitude(data.fraction) != Fraction.EAttitude.EEnemy) { return; } Vector2 toNoise = (Vector2)transform.position - data.position; if (toNoise.sqrMagnitude > hearingDistance * hearingDistance || Random.value > reactionChance) { return; } MemoryEvent ev = new MemoryEvent(); ev.velocity = data.velocity * velocityPredictionScale; ev.forward = data.velocity; ev.exactPosition = data.position; ev.lifetimeTimer.Restart(); noiseStorage.PerceiveEvent(ev); #if UNITY_EDITOR Debug.DrawRay(ev.exactPosition, Vector3.up, Color.blue, 0.5f); #endif }
void InsertEvent(MemoryEvent ev, Fraction.EAttitude attitude) { switch (attitude) { case Fraction.EAttitude.EEnemy: if (trackEnemy) { enemyStorage.PerceiveEvent(ev); } break; case Fraction.EAttitude.EFriendly: if (trackAlly) { allyStorage.PerceiveEvent(ev); } break; case Fraction.EAttitude.ENeutral: if (trackNeutrals) { neutralStorage.PerceiveEvent(ev); } break; } }
private void OnCollisionEnter2D(Collision2D collision) { // omit too weak touches if (collision.relativeVelocity.sqrMagnitude < minimalRelativeVelocity * minimalRelativeVelocity) { return; } // only targets with perceive unit will report // mostly to allow to tune what is perceived PerceiveUnit otherUnit = collision.gameObject.GetComponent <PerceiveUnit>(); if (!otherUnit) { return; } // only report every given seconds if (!tTouch.IsReadyRestart()) { return; } var otherRigidbody = collision.rigidbody; var otherTransform = collision.transform; MemoryEvent ev = new MemoryEvent(); ev.exactPosition = otherTransform.position; ev.forward = otherTransform.up; ev.velocity = otherRigidbody ? otherRigidbody.velocity : Vector2.zero; ev.lifetimeTimer.Restart(); touchStorage.PerceiveEvent(ev); #if UNITY_EDITOR Debug.DrawRay(ev.exactPosition, Vector3.up, Color.blue); #endif }
// returns best event from registered ones by measureEventMethod // the one with greatest evaluation value will be returned or null if none is valid // Events are considered as valid if they are not null and they are not older than maxEventLifeTime public MemoryEvent FindBestEvent(MeasureEventMethod measureEventMethod) { MemoryEvent bestEvent = null; float bestUtility = float.MinValue; foreach (var it in memoryEvents) { if (it == null || it.elapsedTime > maxEventLifetime) { continue; } float utility = measureEventMethod(it); if (utility > bestUtility) { bestUtility = utility; bestEvent = it; } } return(bestEvent); }
public StimuliStorage(int nEvents, float maxEventLifetime) { memoryEvents = new MemoryEvent[nEvents]; this.maxEventLifetime = maxEventLifetime; }
public void SetDestination(MemoryEvent memoryEvent) { this._memoryEvent.velocity = memoryEvent.velocity; this._memoryEvent.exactPosition = memoryEvent.exactPosition; this._memoryEvent.lifetimeTimer.actualTime = memoryEvent.lifetimeTimer.actualTime; }
void PerformSearch() { Fraction myFraction = myUnit.fraction; if (!myFraction) { #if UNITY_EDITOR Debug.LogWarning("No fraction in perceive unit but trying to use sight"); #endif // there's no way to determine where to put events return; } // perform cast int n = Physics.OverlapSphereNonAlloc(cachedTransform.position, searchDistance, StaticCacheLists.colliderCache, memorableMask); // preselect targets // they have to be in proper angle and contain PerceiveUnit for (int i = 0; i < n; ++i) { var it = StaticCacheLists.colliderCache[i]; Transform itTransform = it.transform; //// check if the target is in proper angle Vector3 toIt = itTransform.position - cachedTransform.position; toIt = toIt.To2D(); float cosAngle = Vector2.Dot(toIt.normalized, cachedTransform.forward.To2D()); float angle = Mathf.Acos(cosAngle) * 180 / Mathf.PI; //Debug.Log(angle); bool bProperAngle = angle < coneAngle * 0.5f; if (!bProperAngle) { continue; } // ok, now check if it has PerceiveUnit component // we need it's fraction to determine our attitude PerceiveUnit perceiveUnit = it.GetComponent <PerceiveUnit>(); if (perceiveUnit == myUnit) { // oh, come on do not look at yourself... don't be soo narcissistic continue; } if (!perceiveUnit) { // no perceive unit, this target is invisible to us continue; } Fraction itFraction = perceiveUnit.fraction; if (!itFraction) { // the same as above, return; } //// determine attitude Fraction.EAttitude attitude = myFraction.GetAttitude(itFraction); //// Check if obstacles blocks vision if (DoObstaclesBlockVision(itTransform.position)) { continue; } //// create event var rb = it.attachedRigidbody; MemoryEvent ev = new MemoryEvent { exactPosition = itTransform.position, forward = itTransform.up, // if collider has rigidbody then take its velocity // otherwise there is no simple way to determine event velocity velocity = rb ? rb.velocity * velocityPredictionScale : Vector3.zero, // set up agent responsible for this event perceiveUnit = perceiveUnit }; // ensure event will tick from now on ev.lifetimeTimer.Restart(); Debug.DrawRay(itTransform.position, Vector3.up, Color.blue, _searchTime * nEvents); Debug.DrawRay(itTransform.position, ev.velocity * _searchTime, Color.gray, _searchTime); InsertEvent(ev, attitude); } }