void HuntTarget() { goalEntity = enemy; currentState = Const.aiState.Run; idealTransformForward = Vector3.Normalize(enemy.transform.position - transform.position); attackFinished = Time.time + 1.0f; }
void Pain() { if (timeTillPainFinished < Time.time) { currentState = Const.aiState.Run; // go into run after we get hurt goIntoPain = false; timeTillPainFinished = Time.time + timeBetweenPain; } }
void Think() { if (healthManager.health <= 0) { // If we haven't gone into dying and we aren't dead, going into dying if (!ai_dying && !ai_dead) { ai_dying = true; //no going back currentState = Const.aiState.Dying; //start to collapse in a heap, melt, explode, etc. } } switch (currentState) { case Const.aiState.Idle: Idle(); break; case Const.aiState.Walk: Walk(); break; case Const.aiState.Run: Run(); break; case Const.aiState.Attack1: Attack1(); break; case Const.aiState.Attack2: Attack2(); break; case Const.aiState.Attack3: Attack3(); break; case Const.aiState.Pain: Pain(); break; case Const.aiState.Dying: Dying(); break; case Const.aiState.Dead: Dead(); break; case Const.aiState.Inspect: Inspect(); break; case Const.aiState.Interacting: Interacting(); break; default: Idle(); break; } if (currentState == Const.aiState.Dead || currentState == Const.aiState.Dying) { return; // Don't do any checks, we're dead } inSight = CheckIfPlayerInSight(); //if (inSight) backTurned = CheckIfBackIsTurned(); if (enemy != null) { infront = enemyInFront(enemy); inProjFOV = enemyInProjFOV(enemy); rangeToEnemy = Vector3.Distance(enemy.transform.position, transform.position); } else { infront = false; rangeToEnemy = sightRange; } }
void Walk() { if (CheckPain()) { return; // Go into pain if we just got hurt, data is sent by the HealthManager } if (inSight || enemy != null) { currentState = Const.aiState.Run; return; } if (moveType == Const.aiMoveType.None) { return; } nav.speed = walkSpeed; if (WithinAngleToTarget()) { nav.isStopped = false; } else { nav.isStopped = true; } if (Vector3.Distance(transform.position, walkWaypoints[currentWaypoint].position) < nav.stoppingDistance) { if (visitWaypointsRandomly) { currentWaypoint = Random.Range(0, walkWaypoints.Length); } else { currentWaypoint++; if ((currentWaypoint >= walkWaypoints.Length) || (walkWaypoints[currentWaypoint] == null)) { if (dontLoopWaypoints) { currentState = Const.aiState.Idle; // Reached end of waypoints, just stop return; } else { currentWaypoint = 0; // Wrap around if (walkWaypoints[currentWaypoint] == null) { currentState = Const.aiState.Idle; return; } } } } nav.isStopped = true; nav.SetDestination(walkWaypoints[currentWaypoint].transform.position); } }
void Attack1() { // Typically used for melee if (attack1SoundTime < Time.time && SFXAttack1) { SFX.PlayOneShot(SFXAttack1); attack1SoundTime = Time.time + timeBetweenMelee; } if (inSight && infront) { for (int i = 0; i < meleeDamageColliders.Length; i++) { meleeDamageColliders[i].SetActive(true); meleeDamageColliders[i].GetComponent <AIMeleeDamageCollider>().MeleeColliderSetup(index, meleeDamageColliders.Length, impactMelee, gameObject); } } /*if (inSight) { * if ((timeTillMeleeDamageFinished < Time.time) && !attackDamageDone) { * if (rangeToEnemy < meleeRange) { * DamageData ddNPC = Const.SetNPCDamageData(index, Const.aiState.Attack1); * ddNPC.other = gameObject; * ddNPC.attacknormal = Vector3.Normalize(enemy.transform.position - transform.position); * ddNPC.impactVelocity = impactMelee; * float take = Const.a.GetDamageTakeAmount(ddNPC); * if (twoMeleeHits) take *= 0.5f; //halve it for double tap melee attacks * ddNPC.damage = take; * enemy.GetComponent<HealthManager>().TakeDamage(ddNPC); * attackDamageDone = true; * } * } * if (twoMeleeHits && (timeTillMeleeDamage2Finished < Time.time) && !attackDamage2Done) { * if (rangeToEnemy < meleeRange) { * DamageData ddNPC = Const.SetNPCDamageData(index, Const.aiState.Attack1); * float take = Const.a.GetDamageTakeAmount(ddNPC); * ddNPC.other = gameObject; * ddNPC.attacknormal = Vector3.Normalize(enemy.transform.position - transform.position); * ddNPC.impactVelocity = impactMelee2; * take *= 0.5f; //take other half of melee damage on the 2nd swipe * ddNPC.damage = take; * enemy.GetComponent<HealthManager>().TakeDamage(ddNPC); * attackDamage2Done = true; * } * } * }*/ if (timeBetweenMeleeFinished < Time.time) { goIntoPain = false; //prevent going into pain after attack currentState = Const.aiState.Run; return; // Done with attack } }
void Run() { //if (anim.GetBool("Dying")) { currentState = aiState.Dying; return;} if (CheckPain()) { return; // Go into pain if we just got hurt, data is sent by the HealthManager } if (inSight) { nav.angularSpeed = yawspeed; if (rangeToEnemy < meleeRange) { if (hasMelee && !backTurned) { nav.speed = meleeSpeed; timeBetweenMeleeFinished = Time.time + timeBetweenMelee; currentState = Const.aiState.Attack1; return; } } else { if (rangeToEnemy < proj1Range) { if (hasProj1 && !backTurned) { nav.speed = proj1Speed; currentState = Const.aiState.Attack2; return; } } else { if (rangeToEnemy < proj2Range) { if (hasProj2 && !backTurned) { nav.speed = proj2Speed; currentState = Const.aiState.Attack3; return; } } } } nav.isStopped = false; nav.speed = runSpeed; nav.SetDestination(enemy.transform.position); } else { currentState = Const.aiState.Idle; return; } }
void Dying() { if (!dyingSetup) { dyingSetup = true; SFX.PlayOneShot(SFXDeathClip); // Turn off normal NPC collider and enable corpse collider for searching switch (normalCollider) { case collisionType.Box: boxCollider = GetComponent <BoxCollider>(); boxCollider.enabled = false; break; case collisionType.Sphere: sphereCollider = GetComponent <SphereCollider>(); sphereCollider.enabled = false; break; case collisionType.Mesh: meshCollider = GetComponent <MeshCollider>(); meshCollider.enabled = false; break; case collisionType.Capsule: capsuleCollider = GetComponent <CapsuleCollider>(); capsuleCollider.enabled = false; break; } switch (corpseCollider) { case collisionType.Box: boxCollider = GetComponent <BoxCollider>(); boxCollider.enabled = true; boxCollider.isTrigger = false; break; case collisionType.Sphere: sphereCollider = GetComponent <SphereCollider>(); sphereCollider.enabled = true; sphereCollider.isTrigger = false; break; case collisionType.Mesh: meshCollider = GetComponent <MeshCollider>(); meshCollider.enabled = true; meshCollider.isTrigger = false; break; case collisionType.Capsule: capsuleCollider = GetComponent <CapsuleCollider>(); capsuleCollider.enabled = true; capsuleCollider.isTrigger = false; break; } collisionAid1.SetActive(false); collisionAid2.SetActive(false); normalBody.SetActive(false); //deathBody.SetActive(true); for (int i = 0; i < gibs.Length; i++) { gibs[i].SetActive(true); gibs[i].GetComponent <Rigidbody>().WakeUp(); } gameObject.tag = "Searchable"; // Enable searching //nav.speed = nav.speed * 0.5f; // half the speed while collapsing or whatever timeTillDeadFinished = Time.time + timeTillDead; // wait for death animation to finish before going into Dead() } if (timeTillDeadFinished < Time.time) { //ai_dead = true; //ai_dying = false; //nav.isStopped = true; // Stop moving //rbody.isKinematic = true; currentState = Const.aiState.Dead; } }
void Start() { // Initialize everything to default states so everything is happy dead = false; firstSighting = true; currentState = Const.aiState.Idle; tickFinished = Time.time + tickTime; attackFinished = Time.time; // Get some components that we should have healthManager = GetComponent <HealthManager>(); rbody = GetComponent <Rigidbody>(); SFX = GetComponent <AudioSource>(); anim = GetComponent <Animation>(); lastHealth = healthManager.health; // Initialize last health so we can check if we got hurt and go into pain state idealTransformForward = transform.forward; // prefer to go forward initially, then rotate from there later towards attacker or waypoint, or node, etc. enemy = null; // start out with no enemy attacker = null; // start out with no attacker goalPoint = Vector3.zero; // If we accidentally removed an AudioSource component from the GameObject or if we never added one, let us know where this is so we can select it if (SFX == null) { Debug.Log("WARNING: No audio source for npc at: " + transform.position.x.ToString() + ", " + transform.position.y.ToString() + ", " + transform.position.z + "."); } if (healthManager.health > 0) { if (walkWaypoints.Length > 0 && walkWaypoints[currentWaypoint] != null) { currentState = Const.aiState.Walk; // If waypoints are set, start walking to them } else { currentState = Const.aiState.Idle; // Default to idle } } else { dead = true; currentState = Const.aiState.Dead; } }
bool CheckPain() { if (goIntoPain) { currentState = Const.aiState.Pain; if (attacker != null) { if (timeTillEnemyChangeFinished < Time.time) { timeTillEnemyChangeFinished = Time.time + changeEnemyTime; enemy = attacker; // Switch to whoever just attacked us } } goIntoPain = false; timeTillPainFinished = Time.time + timeToPain; return(true); } return(false); }
void Dying() { if (!dyingSetup) { dyingSetup = true; SFX.PlayOneShot(SFXDeathClip); // Turn off normal NPC collider and enable corpse collider for searching switch (normalCollider) { case collisionType.Box: boxCollider = GetComponent <BoxCollider>(); boxCollider.enabled = false; break; case collisionType.Sphere: sphereCollider = GetComponent <SphereCollider>(); sphereCollider.enabled = false; break; case collisionType.Mesh: meshCollider = GetComponent <MeshCollider>(); meshCollider.enabled = false; break; case collisionType.Capsule: capsuleCollider = GetComponent <CapsuleCollider>(); capsuleCollider.enabled = false; break; } switch (corpseCollider) { case collisionType.Box: boxCollider = GetComponent <BoxCollider>(); boxCollider.enabled = true; boxCollider.isTrigger = false; break; case collisionType.Sphere: sphereCollider = GetComponent <SphereCollider>(); sphereCollider.enabled = true; sphereCollider.isTrigger = false; break; case collisionType.Mesh: meshCollider = GetComponent <MeshCollider>(); meshCollider.enabled = true; meshCollider.isTrigger = false; break; case collisionType.Capsule: capsuleCollider = GetComponent <CapsuleCollider>(); capsuleCollider.enabled = true; capsuleCollider.isTrigger = false; break; } gameObject.tag = "Searchable"; // Enable searching nav.speed = nav.speed * 0.5f; // half the speed while collapsing or whatever timeTillDeadFinished = Time.time + timeTillDead; // wait for death animation to finish before going into Dead() } if (timeTillDeadFinished < Time.time) { ai_dead = true; ai_dying = false; currentState = Const.aiState.Dead; } }
void Dying() { if (!dyingSetup) { dyingSetup = true; SFX.PlayOneShot(SFXDeathClip); // Turn off normal NPC collider and enable corpse collider for searching if (boxCollider != null) { boxCollider.enabled = false; } if (sphereCollider != null) { sphereCollider.enabled = false; } if (meshCollider != null) { meshCollider.enabled = false; } if (capsuleCollider != null) { capsuleCollider.enabled = false; } if (searchColliderGO != null) { searchColliderGO.SetActive(true); } gameObject.tag = "Searchable"; // Enable searching nav.speed = nav.speed * 0.5f; // half the speed while collapsing or whatever timeTillDeadFinished = Time.time + timeTillDead; // wait for death animation to finish before going into Dead() } if (timeTillDeadFinished < Time.time) { ai_dead = true; ai_dying = false; currentState = Const.aiState.Dead; } }
void Idle() { // Set animation state anim["Idle"].wrapMode = WrapMode.Loop; anim.Play("Idle"); // Play an idle sound if the idle sound timer has timed out if ((idleTime < Time.time) && (SFXIdle != null)) { SFX.PlayOneShot(SFXIdle); // play idle sound idleTime = Time.time + Random.Range(3f, 10f); // reset the timer to keep idle sounds from playing repetitively } // Check to see if we got hurt if (healthManager.health < lastHealth) { if (healthManager.health <= 0) { currentState = Const.aiState.Dying; return; } SightSound(); enemy = healthManager.attacker; currentState = Const.aiState.Run; return; } lastHealth = healthManager.health; // Take a look around for enemies if (CheckIfPlayerInSight()) { inSight = true; currentState = Const.aiState.Run; // quit standing around and start fighting return; } else { inSight = false; } }
void Idle() { if (enemy != null) { currentState = Const.aiState.Run; return; } nav.isStopped = true; nav.speed = 0; if (idleTime < Time.time && SFXIdle) { SFX.PlayOneShot(SFXIdle); idleTime = Time.time + Random.Range(idleSFXTimeMin, idleSFXTimeMax); } if (CheckPain()) { return; // Go into pain if we just got hurt, data is sent by the HealthManager } CheckIfPlayerInSight(); }
void Walk() { nav.isStopped = false; nav.speed = walkSpeed; int nextPointIndex = currentWaypoint++; if ((nextPointIndex == walkWaypoints.Length) || (walkWaypoints[nextPointIndex] == null)) { nextPointIndex = 0; // Wrap around } if (nextPointIndex == currentWaypoint) { currentState = Const.aiState.Idle; return; // Out of waypoints } if (CheckPain()) { return; // Go into pain if we just got hurt, data is sent by the HealthManager } //anim.SetBool("Walk",true); nav.SetDestination(walkWaypoints[nextPointIndex].transform.position); }
void Idle() { if (enemy != null) { currentState = Const.aiState.Run; return; } nav.isStopped = true; //anim.SetBool("Walk",false); //anim.SetBool("Pain",false); if (idleTime < Time.time && SFXIdle) { SFX.PlayOneShot(SFXIdle); idleTime = Time.time + Random.Range(3f, 10f); } if (CheckPain()) { return; // Go into pain if we just got hurt, data is sent by the HealthManager } CheckIfPlayerInSight(); }
void Dead() { nav.isStopped = true; // Stop moving //anim.speed = 0f; // Stop animation ai_dead = true; ai_dying = false; rbody.isKinematic = true; currentState = Const.aiState.Dead; firstSighting = false; if (healthManager.gibOnDeath) { ExplosionForce ef = GetComponent <ExplosionForce>(); DamageData ddNPC = Const.SetNPCDamageData(index, Const.aiState.Attack3, gameObject); float take = Const.a.GetDamageTakeAmount(ddNPC); ddNPC.other = gameObject; ddNPC.damage = take; if (ef != null) { ef.ExplodeInner(transform.position + explosionOffset, attack3Force, attack3Radius, ddNPC); } healthManager.ObjectDeath(SFXDeathClip); } }
} // dead, do nothing void Dying() { if (!dead) { dead = true; if (explodeOnDeath) { ExplodeOnDeath(); } else { if (boxCollider != null) { boxCollider.enabled = false; } if (sphereCollider != null) { sphereCollider.enabled = false; } if (capsuleCollider != null) { capsuleCollider.enabled = false; } if (meshConvexCollider != null) { meshConvexCollider.enabled = false; } if (searchColliderGO != null) { searchColliderGO.SetActive(true); } } currentState = Const.aiState.Dead; } }
void Attack1() { // Used for melee if (attack1SoundTime < Time.time && SFXAttack1) { SFX.PlayOneShot(SFXAttack1); attack1SoundTime = Time.time + timeBetweenMelee; for (int i = 0; i < meleeDamageColliders.Length; i++) { meleeDamageColliders[i].SetActive(true); meleeDamageColliders[i].GetComponent <AIMeleeDamageCollider>().MeleeColliderSetup(index, meleeDamageColliders.Length, impactMelee, gameObject); } } if (WithinAngleToTarget()) { nav.isStopped = false; } else { nav.isStopped = true; } nav.speed = meleeSpeed; nav.SetDestination(enemy.transform.position); if (timeBetweenMeleeFinished < Time.time) { for (int i = 0; i < meleeDamageColliders.Length; i++) { meleeDamageColliders[i].SetActive(false); // turn off melee colliders } goIntoPain = false; //prevent going into pain after attack currentState = Const.aiState.Run; return; // Done with attack } }
// Initialization and find components void Awake() { //resetPosition = new Vector3(0f,-100000f,0f); // Null position below playable area nav = GetComponent <UnityEngine.AI.NavMeshAgent>(); nav.updatePosition = true; nav.angularSpeed = yawspeed; nav.speed = 0; nav.SetDestination(transform.position); nav.updateRotation = false; //anim = GetComponent<Animator>(); rbody = GetComponent <Rigidbody>(); rbody.isKinematic = true; healthManager = GetComponent <HealthManager>(); boxCollider = GetComponent <BoxCollider>(); sphereCollider = GetComponent <SphereCollider>(); meshCollider = GetComponent <MeshCollider>(); capsuleCollider = GetComponent <CapsuleCollider>(); if (searchColliderGO != null) { searchColliderGO.SetActive(false); } for (int i = 0; i < meleeDamageColliders.Length; i++) { meleeDamageColliders[i].SetActive(false); // turn off melee colliders } currentState = Const.aiState.Idle; currentWaypoint = 0; enemy = null; firstSighting = true; inSight = false; hasSFX = false; goIntoPain = false; dyingSetup = false; ai_dead = false; ai_dying = false; attacker = null; shotFired = false; idleTime = Time.time + Random.Range(idleSFXTimeMin, idleSFXTimeMax); attack1SoundTime = Time.time; attack2SoundTime = Time.time; attack3SoundTime = Time.time; timeBetweenMeleeFinished = Time.time; timeTillEnemyChangeFinished = Time.time; huntFinished = Time.time; attackFinished = Time.time; attack2Finished = Time.time; attack3Finished = Time.time; timeTillPainFinished = Time.time; timeTillDeadFinished = Time.time; meleeDamageFinished = Time.time; gracePeriodFinished = Time.time; randomWaitForNextAttack2Finished = Time.time; breadFinished = Time.time; enemyBreadcrumbs = new List <Vector3>(); damageData = new DamageData(); tempHit = new RaycastHit(); tempVec = new Vector3(0f, 0f, 0f); SFX = GetComponent <AudioSource>(); if (SFX == null) { Debug.Log("WARNING: No audio source for npc at: " + transform.position.x.ToString() + ", " + transform.position.y.ToString() + ", " + transform.position.z + "."); } else { hasSFX = true; } if (walkWaypoints.Length > 0 && walkWaypoints[currentWaypoint] != null && walkPathOnStart) { nav.SetDestination(walkWaypoints[currentWaypoint].transform.position); currentState = Const.aiState.Walk; // If waypoints are set, start walking them from the get go } else { currentState = Const.aiState.Idle; // No waypoints, stay put } //RuntimeAnimatorController ac = anim.runtimeAnimatorController; //for (int i=0;i<ac.animationClips.Length;i++) { // if (ac.animationClips[i].name == "Death") { // timeTillDead = ac.animationClips[i].length; // break; // } //} tick = 0.05f; tickFinished = Time.time + tick; //QUAKE based AI attackFinished = Time.time + 1f; idealTransformForward = transform.forward; }
void Attack2() { if (gracePeriodFinished < Time.time) { if (!shotFired) { shotFired = true; // Typically used for normal projectile attack if (attack2SoundTime < Time.time && SFXAttack2) { SFX.PlayOneShot(SFXAttack2); attack2SoundTime = Time.time + timeBetweenProj1; } if (attack2Type == Const.AttackType.Projectile) { muzzleBurst.SetActive(true); if (DidRayHit(targettingPosition, proj1Range)) { CreateStandardImpactEffects(false); damageData.other = tempHit.transform.gameObject; if (tempHit.transform.gameObject.tag == "NPC") { damageData.isOtherNPC = true; } else { damageData.isOtherNPC = false; } damageData.hit = tempHit; tempVec = transform.position; tempVec.y += verticalViewOffset; tempVec = (enemy.transform.position - tempVec); damageData.attacknormal = tempVec; damageData.damage = 15f; damageData.damage = Const.a.GetDamageTakeAmount(damageData); damageData.owner = gameObject; damageData.attackType = Const.AttackType.Projectile; HealthManager hm = tempHit.transform.gameObject.GetComponent <HealthManager>(); if (hm == null) { return; } hm.TakeDamage(damageData); } } } } if (attackFinished < Time.time) { if (Random.Range(0f, 1f) < attack2RandomWaitChance) { randomWaitForNextAttack2Finished = Time.time + Random.Range(attack2MinRandomWait, attack2MaxRandomWait); } else { randomWaitForNextAttack2Finished = Time.time; } muzzleBurst.SetActive(false); goIntoPain = false; //prevent going into pain after attack currentState = Const.aiState.Run; return; } }
// Initialization and find components void Awake() { //resetPosition = new Vector3(0f,-100000f,0f); // Null position below playable area nav = GetComponent <UnityEngine.AI.NavMeshAgent>(); nav.updatePosition = true; nav.angularSpeed = yawspeed; //anim = GetComponent<Animator>(); rbody = GetComponent <Rigidbody>(); rbody.isKinematic = false; healthManager = GetComponent <HealthManager>(); //Setup colliders for NPC and its corpse if (normalCollider == corpseCollider) { Debug.Log("ERROR: normalCollider and corpseCollider cannot be the same on NPC!"); return; } switch (normalCollider) { case collisionType.Box: boxCollider = GetComponent <BoxCollider>(); boxCollider.enabled = true; break; case collisionType.Sphere: sphereCollider = GetComponent <SphereCollider>(); sphereCollider.enabled = true; break; case collisionType.Mesh: meshCollider = GetComponent <MeshCollider>(); meshCollider.enabled = true; break; case collisionType.Capsule: capsuleCollider = GetComponent <CapsuleCollider>(); capsuleCollider.enabled = true; break; } switch (corpseCollider) { case collisionType.Box: boxCollider = GetComponent <BoxCollider>(); boxCollider.enabled = false; break; case collisionType.Sphere: sphereCollider = GetComponent <SphereCollider>(); sphereCollider.enabled = false; break; case collisionType.Mesh: meshCollider = GetComponent <MeshCollider>(); meshCollider.enabled = false; break; case collisionType.Capsule: capsuleCollider = GetComponent <CapsuleCollider>(); capsuleCollider.enabled = false; break; } currentState = Const.aiState.Idle; currentWaypoint = 0; enemy = null; firstSighting = true; inSight = false; hasSFX = false; goIntoPain = false; dyingSetup = false; ai_dead = false; ai_dying = false; attacker = null; idleTime = Time.time + Random.Range(3f, 10f); attack1SoundTime = Time.time; attack2SoundTime = Time.time; attack3SoundTime = Time.time; timeBetweenMeleeFinished = Time.time; timeTillEnemyChangeFinished = Time.time; //timeBetweenProj1Finished = Time.time; //timeBetweenProj2Finished = Time.time; timeTillPainFinished = Time.time; timeTillDeadFinished = Time.time; SFX = GetComponent <AudioSource>(); if (SFX == null) { Debug.Log("WARNING: No audio source for AI character at: " + transform.position.x.ToString() + ", " + transform.position.y.ToString() + ", " + transform.position.z + "."); } else { hasSFX = true; } if (walkWaypoints.Length == 0 || walkWaypoints[0] == null) { currentState = Const.aiState.Idle; // No waypoints, stay put } else { currentState = Const.aiState.Walk; // If waypoints are set, start walking them from the get go } //RuntimeAnimatorController ac = anim.runtimeAnimatorController; //for (int i=0;i<ac.animationClips.Length;i++) { // if (ac.animationClips[i].name == "Death") { // timeTillDead = ac.animationClips[i].length; // break; // } //} tick = 0.05f; tickFinished = Time.time + tick; //QUAKE based AI attackFinished = Time.time + 1f; showHostileTime = Time.time; sightEntityTime = Time.time; idealTransformForward = transform.forward; }
void Start() { healthManager = GetComponent <HealthManager>(); rbody = GetComponent <Rigidbody>(); SFX = GetComponent <AudioSource>(); anim = GetComponent <Animation>(); //Setup colliders for NPC and its corpse if (normalCollider == corpseCollider) { Debug.Log("ERROR: normalCollider and corpseCollider cannot be the same on NPC!"); return; } switch (normalCollider) { case collisionType.Box: boxCollider = GetComponent <BoxCollider>(); boxCollider.enabled = true; break; case collisionType.Sphere: sphereCollider = GetComponent <SphereCollider>(); sphereCollider.enabled = true; break; case collisionType.Mesh: meshCollider = GetComponent <MeshCollider>(); meshCollider.enabled = true; break; case collisionType.Capsule: capsuleCollider = GetComponent <CapsuleCollider>(); capsuleCollider.enabled = true; break; } switch (corpseCollider) { case collisionType.Box: boxCollider = GetComponent <BoxCollider>(); boxCollider.enabled = false; break; case collisionType.Sphere: sphereCollider = GetComponent <SphereCollider>(); sphereCollider.enabled = false; break; case collisionType.Mesh: meshCollider = GetComponent <MeshCollider>(); meshCollider.enabled = false; break; case collisionType.Capsule: capsuleCollider = GetComponent <CapsuleCollider>(); capsuleCollider.enabled = false; break; } currentState = Const.aiState.Idle; //currentWaypoint = 0; tick = 0.05f; // Think every 0.05f seconds to save on CPU idealTransformForward = transform.forward; enemy = null; attacker = null; firstSighting = true; inSight = false; goIntoPain = false; dyingSetup = false; hopDone = false; idleTime = Time.time + Random.Range(3f, 10f); attackFinished = Time.time + 1f; tickFinished = Time.time + tick; timeTillDeadFinished = Time.time; firingFinished = Time.time; painFinished = Time.time; fireDelayFinished = Time.time; currentPainAnim = painSelection.Pain1; if (SFX == null) { Debug.Log("WARNING: No audio source for npc at: " + transform.position.x.ToString() + ", " + transform.position.y.ToString() + ", " + transform.position.z + "."); hasSFX = false; } else { hasSFX = true; } if (healthManager.health > 0) { if (walkWaypoints.Length > 0 && walkWaypoints[0] != null) { currentState = Const.aiState.Walk; // If waypoints are set, start walking to them } else { currentState = Const.aiState.Idle; // Default to idle } } deathBody.SetActive(false); normalBody.SetActive(true); collisionAid1.SetActive(true); collisionAid2.SetActive(true); }
void Attack() { if (fireDelayFinished > Time.time) { anim.Play("Idle"); anim ["Hop"].time = 0f; } if (fireDelayFinished < Time.time) { anim.Play("Shoot"); AI_Face(); if (firingFinished < Time.time) { currentState = Const.aiState.Run; return; } if (attackFinished < Time.time && firingFinished > Time.time && anim ["Shoot"].time > 0.1f) { if (SFXAttack1 != null) { SFX.PlayOneShot(SFXAttack1); } attackFinished = Time.time + timeBetweenProj1; bool useBlood = false; DamageData damageData = new DamageData(); RaycastHit tempHit = new RaycastHit(); Vector3 tempvec = Vector3.Normalize(fireEndPoint - firePoint.transform.position); Ray tempRay = new Ray(firePoint.transform.position, tempvec); if (Physics.Raycast(tempRay, out tempHit, 200f)) { HealthManager tempHM = tempHit.transform.gameObject.GetComponent <HealthManager> (); if (tempHit.transform.gameObject.GetComponent <HealthManager> () != null) { useBlood = true; } GameObject impact = Const.a.GetObjectFromPool(Const.PoolType.HopperImpact); if (impact != null) { impact.transform.position = tempHit.point; impact.transform.rotation = Quaternion.FromToRotation(Vector3.up, tempHit.normal); impact.SetActive(true); } // Determine blood type of hit target and spawn corresponding blood particle effect from the Const.Pool GameObject impact2 = Const.a.GetObjectFromPool(Const.PoolType.SparksSmall); if (useBlood) { impact2 = GetImpactType(tempHM); } if (impact2 != null) { impact2.transform.position = tempHit.point; impact2.transform.rotation = Quaternion.FromToRotation(Vector3.up, tempHit.normal); impact2.SetActive(true); } damageData.hit = tempHit; damageData.attacknormal = Vector3.Normalize(firePoint.transform.position - fireEndPoint); damageData.damage = Const.a.damagePerHitForWeapon [14]; tempHit.transform.gameObject.SendMessage("TakeDamage", damageData, SendMessageOptions.DontRequireReceiver); GameObject lasertracer = Const.a.GetObjectFromPool(Const.PoolType.LaserLinesHopper); targetEndHelper.transform.position = tempHit.point; if (lasertracer != null) { lasertracer.SetActive(true); lasertracer.GetComponent <LaserDrawing> ().startPoint = firePoint.transform.position; lasertracer.GetComponent <LaserDrawing> ().endPoint = targetEndHelper.transform.position; } } } } }
void Run() { if (CheckPain()) { return; // Go into pain if we just got hurt, data is sent by the HealthManager } if (inSight) { huntFinished = Time.time + huntTime; if (rangeToEnemy < meleeRange) { if (hasMelee && infront) { nav.speed = meleeSpeed; timeBetweenMeleeFinished = Time.time + timeBetweenMelee; currentState = Const.aiState.Attack1; return; } } else { if (rangeToEnemy < proj1Range) { if (hasProj1 && infront && inProjFOV && (randomWaitForNextAttack2Finished < Time.time)) { nav.speed = proj1Speed; shotFired = false; attackFinished = Time.time + timeBetweenProj1 + timeTillActualAttack2; gracePeriodFinished = Time.time + timeTillActualAttack2; targettingPosition = enemy.transform.position; currentState = Const.aiState.Attack2; return; } } else { if (rangeToEnemy < proj2Range) { if (hasProj2 && infront) { nav.speed = proj2Speed; currentState = Const.aiState.Attack3; return; } } } } if (WithinAngleToTarget()) { nav.isStopped = false; } else { nav.isStopped = true; } nav.speed = runSpeed; nav.SetDestination(enemy.transform.position); if (moveType == Const.aiMoveType.None) { nav.isStopped = true; } lastKnownEnemyPos = enemy.transform.position; randSpin = false; if (breadFinished < Time.time) { breadFinished = Time.time + breadCrumbTick; enemyBreadcrumbs.Add(enemy.transform.position); } } else { if (huntFinished > Time.time) { Hunt(); } else { enemy = null; currentState = Const.aiState.Idle; return; } } }
void Run() { AI_Face(); anim.Play("Hop"); if (anim ["Hop"].time > (0.09f * 1.55f)) { if (!hopDone) { hopDone = true; rbody.AddForce(transform.forward * hopForce); } } else { hopDone = false; } // Check to see if we got hurt if (healthManager.health < lastHealth) { if (healthManager.health <= 0) { currentState = Const.aiState.Dying; return; } enemy = healthManager.attacker; currentState = Const.aiState.Run; return; } lastHealth = healthManager.health; // Take a look around for enemies //returnedEnemy = null; // reset temporary GameObject to hold any returned enemy we find //Debug.Log("animHop.time = " + anim["Hop"].time.ToString()); if (anim["Hop"].time > (0.69f * 1.55f) || anim["Hop"].time < (0.09f)) { if (CheckIfEnemyInSight()) { //enemy = returnedEnemy; inSight = true; //nav.SetDestination (enemy.transform.position); // Run to the enemy position float dist = Vector3.Distance(transform.position, enemy.transform.position); // See if we are close enough to attack if (dist < proj1Range) { if (attackFinished < Time.time) { if (CheckIfEnemyInFront(enemy)) { inFront = true; firingFinished = Time.time + timeBetweenProj1; fireDelayFinished = Time.time + delayBeforeFire; fireEndPoint = enemy.transform.position; currentState = Const.aiState.Attack1; return; } else { inFront = false; } } } } } else { inSight = false; inFront = false; } //nav.SetDestination(enemy.transform.position); // Run to the enemy position //navigationTargetPosition = nav.destination; }
// All state changes go in here. Check for stuff. See what we need to be doing. Need to change? void CheckAndUpdateState() { if (currentState == Const.aiState.Dead) { return; } // Check to see if we got hurt if (healthManager.health < lastHealth) { if (healthManager.health <= 0) { currentState = Const.aiState.Dying; return; } lastHealth = healthManager.health; // Make initial sight sound if we aren't running, attacking, or already in pain if (currentState != Const.aiState.Run || currentState != Const.aiState.Attack1 || currentState != Const.aiState.Attack2 || currentState != Const.aiState.Attack3 || currentState != Const.aiState.Pain) { SightSound(); } enemy = healthManager.attacker; currentState = Const.aiState.Run; return; } else { lastHealth = healthManager.health; } // Take a look around for enemies if (enemy == null) { // we don't have an enemy yet so let's look to see if we can see one if (CheckIfPlayerInSight()) { currentState = Const.aiState.Run; // quit standing around and start fighting return; } } else { // We have an enemy now what... // Oh can we still see it? // Can I shoot it? // please?? // Can I melee it? // cherry on top? if (anim.IsPlaying("Hop")) { if (anim ["Hop"].time > (0.69f * 1.55f) || anim ["Hop"].time < (0.09f)) { if (CheckIfEnemyInSight()) { float dist = Vector3.Distance(transform.position, enemy.transform.position); // See if we are close enough to attack if (dist < proj1Range) { if (attackFinished < Time.time) { if (CheckIfEnemyInFront(enemy)) { inFront = true; firingFinished = Time.time + timeBetweenProj1; fireDelayFinished = Time.time + delayBeforeFire; fireEndPoint = enemy.transform.position; currentState = Const.aiState.Attack1; return; } else { inFront = false; } } } } } else { inFront = false; } } } }