public override void EndTouch(SceneControl.TouchEvent args) { // Now, what have we targeted from this click (if anything) Ray r = Camera.main.ScreenPointToRay(args.currentPosition); RaycastHit r_hit; // DID we point to anything from the touch? if (Physics.Raycast(r, out r_hit, Mathf.Infinity)) { GameObject go = Instantiate(lightningPrefab, r_hit.point, Quaternion.Euler(-90.0f, 0.0f, 0.0f)) as GameObject; Collider[] objs = Physics.OverlapSphere(r_hit.point, lightningRange); foreach (Collider obj in objs) { commonAI gameObj = obj.GetComponent <commonAI>(); if (gameObj != null) { ICanBeStruckDown strike = gameObj as ICanBeStruckDown; if (strike != null) { //Debug.Log ("Found object: " + obj.name); strike.StrikeDown(); } } Rigidbody rb = obj.GetComponent <Rigidbody>(); if (rb != null) { rb.AddForce(5.0f * (rb.transform.position - r_hit.point).normalized, ForceMode.Impulse); } } Destroy(go, go.GetComponent <ParticleSystem>().duration); } }
public override void EndTouch(SceneControl.TouchEvent args) { if (cancelled || !firstMovementComplete) { return; } // End of the touch. Perform the influence now. Collider[] objs = Physics.OverlapSphere(firstTouchPosition, 12.0f); foreach (Collider obj in objs) { commonAI gameObj = obj.GetComponent <commonAI>(); if (gameObj != null && gameObj.enabled) { ICanBeInfluenced inf = gameObj as ICanBeInfluenced; if (inf != null) { //Debug.Log ("Found object: " + obj.name); inf.BeInfluenced(firstDirection); continue; } } StateMachineDriver statemachine = obj.GetComponent <StateMachineDriver>(); if (statemachine != null && statemachine.enabled) { statemachine.AddAction("influence", firstDirection); continue; } } }
public void takeDamage(float damageTaken, commonAI attackedBy) { if (isDestroying) { return; } // if already infected, just get out. if (IsInfected) { return; } if (attackedBy is werewolfAi) { attackedByWerewolf = true; // Allow only a 20% chance of being infected vs outright kill. if (Random.Range(0, 100) > 80) { IsInfected = true; return; } } health -= damageTaken; if (health < 0.0f) { die(); } else if (hasHurtAnimation) { animComponent.Play("hurt"); } }
// scare with spherecast public void CheckScare() { //update attack timer timeSinceScare += Time.deltaTime; // if not yet time to scare, get out if (timeSinceScare < fearInterval) { return; } // reset timer to allow for next scare check timeSinceScare = 0; //sphere cast in front of attacking game object. Collider[] colliders = Physics.OverlapSphere(gameObject.transform.position, fearRadius); GameObject scareObj; foreach (Collider hit in colliders) { scareObj = hit.GetComponent <Collider>().gameObject; commonAI o = scareObj.GetComponent <commonAI>(); if (o != null && o is ICanBeScared) { ((ICanBeScared)o).Afraid(); } // unlike attacking. A group of humans in a given // area can ALL be scared away, don't stop at first one. } }
// look for an enemy with three attack distance radius // of where we are moving... private void CheckForNearbyEnemy() { // sphere cast around the attacking game object. Vector3 position = gameObject.transform.position; Collider[] colliders = Physics.OverlapSphere(position, strikeRange * 3.0f); 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 ai = hitObj.GetComponent <commonAI>(); if (ai != null && ai.isDestroying) { continue; } StateMachineDriver sm = hitObj.GetComponent <StateMachineDriver>(); if (sm != null && sm.isDead) { continue; } // Try to reroute to that location //Debug.Log ("Attacking: " + hitObj.name); stateMachineDriver.AddAction("new_target_object", hitObj.transform); return; } } }
// look for a SPECIFIC SINGLE nav target. public static GameObject getRandomNavTarget(eNavTargets tagName) { GameObject[] targets = GameObject.FindGameObjectsWithTag(tagName.ToString()); // if there was not anything, can't return an indexed object of something doesn't exist if (targets.Length == 0) { return((GameObject)null); } // if we DO have targets, see if any are commonAI and are "infected". // if so, don't consider them from either side attraction/attack. for (int i = targets.Length - 1; i >= 0; i--) { commonAI o = targets[i].GetComponent <commonAI>(); if (o != null && o.IsInfected) { targets[i] = (GameObject)null; } } // Yup, we have something, get a random instance from one available return(targets [Random.Range(0, targets.Length)]); }
// look for an enemy with three attack distance radius // of where we are moving... public void CheckForNearbyEnemy() { // use sae attack interval on check, but don't decrease/reset it if (timeSinceAttack < attackInterval) { return; } // sphere cast around the attacking game object. Collider[] colliders = Physics.OverlapSphere(associatedWith.transform.position, attackRadius * 3.0f); // 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; commonAI o = hitObj.GetComponent <commonAI>(); // if already infected, don't falsely keep an attacker // such as werewolf to keep tracking it... if (o != null && o.IsInfected) { continue; } // did we find an object we are allowed to attack if (canAttack(hitObj.tag)) { thisAttacker.moveToSpecificTransform(hitObj.transform); return; } } }
public void takeDamage(float damageTaken, commonAI attackedBy) { if( isDestroying ) return; // if already infected, just get out. if( IsInfected ) return; if( attackedBy is werewolfAi ) { attackedByWerewolf = true; // Allow only a 20% chance of being infected vs outright kill. if( Random.Range(0,100) > 80 ) { IsInfected = true; return; } } health -= damageTaken; if (health < 0.0f) die(); else if( hasHurtAnimation ) animComponent.Play("hurt"); }
// Called from the update method... private bool GatheringSpotHandled() { // if current target is not a human gathering spot, // get out. Nothing handled assocated with gathering spot. if (currentTarget.tag != eNavTargets.HumanGathering.ToString()) { return(false); } // if previously established and target reached, // have we met our time-delay before going to next target? if (gatheringSpotDelay > 0f) { // reduce delay time, if delay completed, get out and return // FALSE... we are not doing anything specific to gathering spot gatheringSpotDelay -= Time.deltaTime; if (gatheringSpotDelay < 0f) { return(false); } // we are still in the delay timeout of gathering. // take a look at other human/guard game objects in the vicinity // as we are so we can "LOOK" at them as if to be engaging in // converstation. Similar approach to that of COMBAT where the // enemies are forced to look at each other when being attacked. Collider[] colliders = Physics.OverlapSphere(gameObject.transform.position, 1); GameObject hitObj; foreach (Collider hit in colliders) { hitObj = hit.GetComponent <Collider>().gameObject; // did we find an object we are allowed to attack if (hitObj.tag.Equals("Human") || hitObj.tag.Equals("Guard")) { commonAI o = hitObj.GetComponent <commonAI>(); // turn our game object in the direction of what is being attacked transform.LookAt(hitObj.transform); // stop our game object from walking / moving around animComponent.Play("idle"); // break out of loop of possible humans to look at. break; } } // yes, we handled something (even if ATTEMPTING to look at other humans) return(true); } // Not already within a timing-out delay at gathering point. // We may still be walking towards our gathering spot... did we get there yet? if (reachedTarget()) { // Yup, we DID hit our gathering spot... set delay and get out // random timeout is 5 seconds minimum PLUS another 1 to 5 seconds gatheringSpotDelay = 5f + Random.Range(1f, 5f); return(true); } // nope, nothing handled... user still walking... return(false); }
//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; } } }