private void OnTriggerStay2D(Collider2D collision) { if (!collision.attachedRigidbody) { return; } AiPerceiveUnit unit = collision.GetComponent <AiPerceiveUnit>(); if (!unit) { return; } _noiseAccumulator += collision.attachedRigidbody.velocity.magnitude * walkVelocityScale; if (_noiseAccumulator > noiseThreshold && AiSenseNoise.CanSpreadNoise()) { _noiseAccumulator = 0; NoiseData noiseData = new NoiseData(); noiseData.position = collision.transform.position; noiseData.velocity = collision.attachedRigidbody.velocity; noiseData.fraction = unit.fraction; AiSenseNoise.SpreadNoise(noiseData); } }
public new void Start() { base.Start(); _instigator = GetComponentInParent <AiPerceiveUnit>(); if (propagateFraction) { _fraction = GetComponentInParent <AiFraction>(); } }
new void Start() { base.Start(); _transform = transform; //rotationApplyTime.actualTime += 10000000000000000000; _instigator = GetComponentInParent <AiPerceiveUnit>(); if (propagateFraction) { _fraction = GetComponentInParent <AiFraction>(); } }
bool DoObstaclesBlockVision(Vector2 target) { // we will change searchDistance based on visibility of obstacles; float searchDistance = this.searchDistance; Vector2 toTarget = target - (Vector2)transform.position; float toTargetSq = toTarget.sqrMagnitude; int n = Physics2D.RaycastNonAlloc(transform.position, toTarget, StaticCacheLists.raycastHitCache, toTarget.magnitude, obstacleMask); bool bObstaclesBlocksVision = false; for (int i = 0; i < n; ++i) { var it = StaticCacheLists.raycastHitCache[i]; AiPerceiveUnit unit = it.collider.GetComponent <AiPerceiveUnit>(); if (!unit) { // we assume objects that do not have perceive unit will behave as non transparent // so we can't see our target bObstaclesBlocksVision = true; break; } if (unit == myUnit) { // well, i'm not that fat ... i guess continue; } searchDistance *= unit.transparencyLevel; if (searchDistance * searchDistance < toTargetSq * myUnit.distanceModificator) // transparency is reduced too much to see the target { bObstaclesBlocksVision = true; break; } } Debug.DrawRay(transform.position, toTarget, bObstaclesBlocksVision ? Color.yellow : Color.green, 0.25f); return(bObstaclesBlocksVision); }
void OnReceiveDamage(HealthController.DamageData data) { if (!data.causer) { return; } if (data.causer == currentObject) { damageAccumulator -= data.damage.toFloat(); } else if (-data.damage.toFloat() > damageAccumulator) { damageAccumulator = -data.damage.toFloat(); currentObject = data.causer; currentUnit = data.causer.GetComponentInParent <AiPerceiveUnit>(); lastPosition = currentObject.transform.position; } }
void Propagate(HealthController.DamageData data, AiPerceiveUnit unit) { var colliders = Physics2D.OverlapCircleAll(transform.position, propagateRadius); foreach (var it in colliders) { if (Random.value <= propagateChance) { var holder = it.GetComponentInChildren <AiPerceptionHolder>(); if (holder) { holder.InsertToMemory(unit, EMemoryEvent.ENoise, data.position, Vector2.zero, memoryTime, matureTime + matureTimeMaxOffset * Random.value, shadeTime); } } } if (propatationPrefab) { Instantiate(propatationPrefab, transform.position, Quaternion.identity); } }
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 AiPerceiveUnit otherUnit = collision.gameObject.GetComponent <AiPerceiveUnit>(); 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 }
private void OnCollisionEnter2D(Collision2D collision) { AiPerceiveUnit unit = collision.gameObject.GetComponent <AiPerceiveUnit>(); if (fraction && unit && unit.fraction && fraction.GetAttitude(unit.fraction.fractionName) == AiFraction.Attitude.friendly) { return; } HealthController health = collision.gameObject.GetComponent <HealthController>(); if (health) { Destroy(gameObject); health.DealDamage(damage * body.velocity.magnitude); Rigidbody2D _body = collision.gameObject.GetComponent <Rigidbody2D>(); if (_body) { _body.AddForce(-transform.up * pushForce * Time.fixedDeltaTime); } } }
public void insertToMemory(AiPerceiveUnit unit, float distance) { bool bFound = false; foreach (var itMemory in memory) { if (itMemory.unit == unit) { itMemory.remainedTime.restart(); itMemory.lastDistance = distance; bFound = true; break; } } if (!bFound) { var memoryItem = new MemoryItem(); memoryItem.unit = unit; memoryItem.remainedTime = new Timer(memoryTime); memoryItem.lastDistance = distance; memory.Add(memoryItem); } }
public override AiPerceiveUnit GetTarget() { if (timerRecalculate.isReadyRestart()) { timerRecalculate.cd = Random.Range(reevaluateTimeMin, reevaluateTimeMin); target = null; /// TODO how to efficiently iterate backwards in c#? Check it foreach (var it in mind.myPerception.memory) { if (it.unit.fraction && it.unit.fraction.gameObject != mind.myFraction.gameObject) { if (CheckRequirements(it)) { target = it.unit; break; } } } } return(target); }
void PerformSearch() { AiFraction 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 = Physics2D.OverlapCircleNonAlloc(transform.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 Vector2 toIt = itTransform.position - transform.position; float cosAngle = Vector2.Dot(toIt.normalized, transform.up); 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 AiPerceiveUnit // we need it's fraction to determine our attitude AiPerceiveUnit perceiveUnit = it.GetComponent <AiPerceiveUnit>(); 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; } AiFraction itFraction = perceiveUnit.fraction; if (!itFraction) { // the same as above, return; } //// determine attitude AiFraction.EAttitude attitude = myFraction.GetAttitude(itFraction); //// Check if obstacles blocks vision if (DoObstaclesBlockVision(itTransform.position)) { continue; } //// create event MemoryEvent ev = new MemoryEvent(); ev.exactPosition = itTransform.position; ev.forward = itTransform.up; // if collider has rigidbody then take its velocity // otherwise there is no simple way to determine event velocity ev.velocity = it.attachedRigidbody ? it.attachedRigidbody.velocity * velocityPredictionScale : Vector2.zero; // set up agent reponsible for this event ev.perceiveUnit = perceiveUnit; // ensure event will tick from now on ev.lifetimeTimer.Restart(); Debug.DrawRay(ev.exactPosition, Vector3.up, Color.blue, searchTime * nEvents); Debug.DrawRay(ev.exactPosition, ev.velocity * searchTime, Color.gray, searchTime); InsertEvent(ev, attitude); } }
private void Start() { holder = GetComponent <AiPerceptionHolder>(); myUnit = GetComponentInParent <AiPerceiveUnit>(); }
/// auto compute direction of unit public bool InsertToMemory(AiPerceiveUnit unit, EMemoryEvent eventType, Vector2 position, float predictionScale, float remainTime = 1f, float matureTime = 0f, float shadeTime = 0f, float importance = 1f) { if (!unit.memoriable) { return(false); } int id = (int)eventType; var mem = eventMemory[id]; /// search if the unit is recorded in our memory /// if so then update it if (unit) { foreach (var itMemory in mem) { if (itMemory.unit == unit) { /// spatial data if (itMemory.remainedTime.ElapsedTime() > 3 * float.Epsilon) { itMemory.direction = (position - itMemory.exactPosition) * (predictionScale / itMemory.remainedTime.ElapsedTime()); /// auto compute direction } /// else keep last value... dunno what to do in case of such a small time step itMemory.exactPosition = position; /// time data itMemory.remainedTime.Restart(); itMemory.matureTime = 0f; /// list is not sorted anyEventAdded[id] = true; return(false); } } } /// otherwise insert new item MemoryEvent item = new MemoryEvent(); item.unit = unit; item.hadUnit = unit != null; /// spatial data item.exactPosition = position; item.direction = Vector2.zero; /// time data item.remainedTime = new Timer(); item.remainedTime.Restart(); item.matureTime = matureTime; item.knowledgeTime = remainTime; item.shadeTime = shadeTime; item.importance = importance; mem.Add(item); /// list is not sorted anyEventAdded[id] = true; return(true); }
public bool InsertToMemory(AiPerceiveUnit unit, EMemoryEvent eventType, Vector2 position, Vector2 direction, float remainTime = 1f, float matureTime = 0f, float shadeTime = 0f, float importance = 1f) { if (!unit.memoriable) { return(false); } int id = (int)eventType; var mem = eventMemory[id]; /// search if the unit is recorded in our memory /// if so then update it if (unit) { foreach (var itMemory in mem) { if (itMemory.unit == unit) { /// time data /// /// If information is mature - result should be mature too /// if (itMemory.remainedTime.IsReady(itMemory.matureTime)) { itMemory.matureTime = 0; itMemory.remainedTime.Restart(); } else { itMemory.matureTime = matureTime; } itMemory.knowledgeTime = remainTime; itMemory.shadeTime = shadeTime; /// spatial data itMemory.exactPosition = position; itMemory.direction = direction; itMemory.importance = importance; /// list is not sorted anyEventAdded[id] = true; return(false); } } } /// otherwise insert new item MemoryEvent item = new MemoryEvent(); item.unit = unit; item.hadUnit = unit != null; /// spatial data item.exactPosition = position; item.direction = direction; /// time data item.remainedTime = new Timer(); item.remainedTime.Restart(); item.matureTime = matureTime; item.knowledgeTime = remainTime; item.shadeTime = shadeTime; item.importance = importance; mem.Add(item); /// list is not sorted anyEventAdded[id] = true; return(true); }
protected void Awake() { myUnit = GetComponentInParent <AiPerceiveUnit>(); behaviourController = GetComponentInChildren <AiBehaviourController>(); }
public void Start() { renderers = GetComponentsInChildren <SpriteRenderer>(); unit = GetComponentInParent <AiPerceiveUnit>(); }