//attack with spherecast public void CheckAttack() { //update attack timer timeSinceAttack += Time.deltaTime; // if not yet time to attack, get out if (timeSinceAttack < attackInterval) { return; } // see if we need to reroute to new target if another enemy is nearby CheckForNearbyEnemy(); // reset timer to allow for next attack check timeSinceAttack = 0; // sphere cast around the attacking game object. Collider[] colliders = Physics.OverlapSphere(associatedWith.transform.position, attackRadius); // get pointer to this as an type-casted object of commonAI commonAI thisAttacker = GetComponent <commonAI>(); GameObject hitObj; foreach (Collider hit in colliders) { hitObj = hit.GetComponent <Collider>().gameObject; // did we find an object we are allowed to attack if (canAttack(hitObj.tag)) { commonAI o = hitObj.GetComponent <commonAI>(); if (o == null) { StateMachineDriver stateMachine = hitObj.GetComponent <StateMachineDriver>(); if (stateMachine != null) { // and back to find another target? // if we just killed the target, // we need to take ourselves OUT of combat mode // (unless something else hits IT again) if (stateMachine.isDead) { thisAttacker.EngagedInCombat = false; continue; } // Send a "hit" message stateMachine.AddAction("hit", damage, thisAttacker.transform); // mark this as being engaged in combat attack mode thisAttacker.EngagedInCombat = true; // turn our game object in the direction of what is being attacked transform.LookAt(hitObj.transform); // based on the initial animation, what is their respective // attack animation name string animComponent.wrapMode = WrapMode.Once; animComponent.Play(attackAnimation); // Allow hit handlers to process OnSuccessfulAttack(hitObj); if (thisAttacker.moveAfterCombat) { PlayWalkAnimation(); } // TODO: How will we get this info from the state machine? // if we just finished infecting the enemy, // take ourselves out of combat and go to another target //if( o.IsInfected ) //{ // thisAttacker.moveAfterCombat = true; // thisAttacker.EngagedInCombat = false; // return; //} } } // if the object is already infected, such as // a zombie or werewolf attempting to attack // a human infected, don't attack it again... if (o != null && o.IsInfected) { continue; } if (o != null && !o.isDestroying) { //Attacking a valid live target o.playSound("attack", hitObj.tag.ToString()); //Debug.Log ("valid attack hit: " + hitObj); // mark this as being engaged in combat attack mode thisAttacker.EngagedInCombat = true; // turn our game object in the direction of what is being attacked transform.LookAt(hitObj.transform); // based on the initial animation, what is their respective // attack animation name string animComponent.wrapMode = WrapMode.Once; animComponent.Play(attackAnimation); // Allow hit handlers to process OnSuccessfulAttack(hitObj); // just to track engaged in attack/combat o.EngagedInCombat = true; // Then, put into queue to get back to walking mode // put this to the tail-end of the animation cycle if (o.moveAfterCombat) { PlayWalkAnimation(); } // stop the game object from moving as we have just engaged attack // dont keep walking if it was attacked o.stop(); // Now, apply damage to other o.takeDamage(damage, thisAttacker); // if we just finished infecting the enemy, // take ourselves out of combat and go to another target if (o.IsInfected) { thisAttacker.moveAfterCombat = true; thisAttacker.EngagedInCombat = false; return; } // if we just killed the target, // we need to take ourselves OUT of combat mode // (unless something else hits IT again) if (o.isDestroying) { thisAttacker.EngagedInCombat = false; } // set flag we hit a valid expected object and exit the loop. // we can't attack more than one thing // break; //} } else { //attacking a house object o2 = hitObj.GetComponent <safeZoneAI>(); if (o2 is safeZoneAI) { // a safe-zone or finish never is of a commonAI and // never moves at the end of combat. animComponent.wrapMode = WrapMode.Once; animComponent.Play(attackAnimation); ((safeZoneAI)o2).takeDamage(damage); } } return; } } }
// FixedUpdate is called fixed number of times per sec void FixedUpdate() { //update attack timer timeSinceAttack += Time.deltaTime; // if not yet time to attack, get out if (timeSinceAttack < intervalBetweenStrikes) { return; } // see if we need to reroute to new target if another enemy is nearby CheckForNearbyEnemy(); // reset timer to allow for next attack check timeSinceAttack = 0; // sphere cast around the attacking game object. Collider[] colliders = Physics.OverlapSphere(gameObject.transform.position, strikeRange); // get pointer to this as an type-casted object of commonAI commonAI thisAttacker = GetComponent <commonAI>(); GameObject hitObj; foreach (Collider hit in colliders) { hitObj = hit.GetComponent <Collider>().gameObject; // did we find an object we are allowed to attack if (CanAttack(hitObj.tag)) { commonAI o = hitObj.GetComponent <commonAI>(); if (o != null && !o.isDestroying) { // if the object is already infected, such as // a zombie or werewolf attempting to attack // a human infected, don't attack it again... if (o.IsInfected) { continue; } //Attacking a valid live target o.playSound("attack", hitObj.tag.ToString()); //Debug.Log ("Striking: " + hitObj.name); stateMachineDriver.AddPriorityAction("strike", hitObj.transform); //Debug.Log ("valid attack hit: " + hitObj); // just to track engaged in attack/combat o.EngagedInCombat = true; // stop the game object from moving as we have just engaged attack // dont keep walking if it was attacked o.stop(); // Now, apply damage to other o.takeDamage(damage, thisAttacker); // if we just killed the target, // we need to take ourselves OUT of combat mode // (unless something else hits IT again) if (o.isDestroying) { // thisAttacker.EngagedInCombat = false; } } else { //attacking a house safeZoneAI o2 = hitObj.GetComponent <safeZoneAI>(); if (o2 != null) { // a safe-zone or finish never is of a commonAI and // never moves at the end of combat. stateMachineDriver.AddPriorityAction("strike", o2.transform); //animComponent.wrapMode = WrapMode.Once; //animComponent.Play(attackAnimation); o2.takeDamage(damage); } } return; } } }