Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class SphereContainsDataState : BaseAI.DataAIState
- {
- protected float sphereRadius = 0.0f;
- protected LayerMask layerMask;
- protected Vector3 offsetPos = Vector3.zero;
- protected Quaternion offsetRot = Quaternion.identity;
- protected Matrix4x4 parentTransform = Matrix4x4.identity;
- protected Collider[] overlappedColliders = null;
- protected int maxOverlappedColliders = 20;
- public SphereContainsDataState(BaseAI newThinker) : base(newThinker) { }
- protected override void UpdateData(float deltaTime)
- {
- Vector3 spherePos = Vector3.zero;
- Quaternion sphereRot = Quaternion.identity; // (we don't use this, but the calc needs it anyways)
- MathManager.CalcRelativeTransforms(parentTransform, offsetPos, offsetRot, out spherePos, out sphereRot);
- if ((overlappedColliders == null) || (overlappedColliders.Length != maxOverlappedColliders)) { overlappedColliders = new Collider[maxOverlappedColliders]; }
- Physics.OverlapSphereNonAlloc(spherePos, sphereRadius, overlappedColliders, layerMask);
- //TemporaryShape.DebugBox(new Vector3(sphereRadius * 2, sphereRadius * 2, sphereRadius * 2), 0.1f, spherePos, sphereRot);
- base.UpdateData(deltaTime);
- }
- }
- public class CanSeeDataState : SphereContainsDataState
- {
- // The radius of the vision sphere
- protected float viewRadius = 10.0f;
- // The local offset from the parent to the center of the vision sphere
- protected Vector3 visionOffset = Vector3.zero;
- // (if NULL, we just assume the vision cone is attached to the EnemyAI we're processing on)
- protected GameObject visionAttachedTo = null;
- // Should we update the parameters we use for our vision sweep?
- protected bool visionCheckParamsDirty = true;
- public CanSeeDataState(BaseAI newThinker) : base(newThinker) { }
- public CanSeeDataState(BaseAI newThinker, LayerMask visibleLayers, float newRadius, Vector3 newOffset) : base(newThinker)
- {
- layerMask = visibleLayers;
- viewRadius = newRadius;
- visionOffset = newOffset;
- }
- protected override void UpdateData(float deltaTime)
- {
- if (visionCheckParamsDirty)
- {
- UpdateVisionCheckParameters();
- visionCheckParamsDirty = false;
- }
- base.UpdateData(deltaTime);
- // @TODO: Run over the overlappedColliders, and throw out any that can't actually be seen for whatever reason. Like maybe they have an invisibility state, or similar
- // AI-driven reasons we can't actually see them right now.
- }
- protected virtual void UpdateVisionCheckParameters()
- {
- sphereRadius = viewRadius;
- offsetPos = visionOffset;
- if (visionAttachedTo != null) { parentTransform = visionAttachedTo.gameObject.transform.localToWorldMatrix; }
- else { parentTransform = ourAI.gameObject.transform.localToWorldMatrix; }
- }
- }
- public class EnemyCanSeeDataState : CanSeeDataState
- {
- // Block/ignore the vision parameter constructors in base. You don't need to specify vision settings through the state, it draws on EnemyAI for that.
- public EnemyCanSeeDataState(BaseAI newThinker) : base(newThinker) { }
- protected override void UpdateVisionCheckParameters()
- {
- EnemyAI ourEnemyAI = (EnemyAI)ourAI;
- sphereRadius = ourEnemyAI.visionRadius;
- offsetPos = ourEnemyAI.visionOffset;
- parentTransform = ourEnemyAI.gameObject.transform.localToWorldMatrix;
- }
- }
- public class ForgiveUnseenDataState : EnemyCanSeeDataState
- {
- protected Dictionary<GameObject, float> forgivenessAccumulator = new Dictionary<GameObject, float>();
- protected Dictionary<GameObject, LifeAndDeath> forgivenObjToLife = new Dictionary<GameObject, LifeAndDeath>();
- protected const float ForgivenessTimeout = 5.0f;
- public ForgiveUnseenDataState(BaseAI newThinker) : base(newThinker) { }
- protected override void UpdateData(float deltaTime)
- {
- EnemyAI ourEnemyAI = (EnemyAI)ourAI;
- if (ourEnemyAI == null) { return; }
- base.UpdateData(deltaTime);
- // First, make sure everything presently in our HateList is represented in our forgiveness list. If it wasn't already there, we assume it's fresh hate (delicious, fresh hate)
- foreach (KeyValuePair<LifeAndDeath, float> hate in ourEnemyAI.HateList)
- {
- if (!forgivenessAccumulator.ContainsKey(hate.Key.gameObject))
- {
- forgivenessAccumulator.Add(hate.Key.gameObject,-deltaTime);
- forgivenObjToLife.Add(hate.Key.gameObject, hate.Key);
- }
- }
- // Then, go through and additionally reset forgiveness on anything we can see
- for (int index = 0; index < overlappedColliders.Length; index++)
- {
- if (forgivenessAccumulator.ContainsKey(overlappedColliders[index].gameObject))
- {
- forgivenessAccumulator[overlappedColliders[index].gameObject] = -deltaTime;
- }
- }
- // Finally, accrue forgiveness time on everything (which is why we initialized to -deltaTime). Anything that reaches forgiveness threshold - forgive!
- List<KeyValuePair<GameObject, float>> forgivenessAccumulatorList = new List<KeyValuePair<GameObject, float>>(forgivenessAccumulator);
- foreach (KeyValuePair<GameObject, float> forgivenessPair in forgivenessAccumulatorList)
- {
- float newForgiveness = forgivenessPair.Value + deltaTime;
- if (newForgiveness >= ForgivenessTimeout) { Forgive(ourEnemyAI, forgivenessPair.Key); }
- else
- {
- forgivenessAccumulator[forgivenessPair.Key] = newForgiveness;
- }
- }
- }
- protected void Forgive(EnemyAI forgivingAI, GameObject receivingForgiveness)
- {
- forgivenessAccumulator.Remove(receivingForgiveness);
- forgivingAI.ClearHate(forgivenObjToLife[receivingForgiveness]);
- forgivenObjToLife.Remove(receivingForgiveness);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment