private void RpcMove(float horizontalMovement, float verticalMovement, Quaternion targetRotation) { //apply input to movement direction movement = new Vector3(horizontalMovement, 0.0f, verticalMovement); //apply camera direction to movement movement = Camera.main.transform.TransformDirection(movement); movement.y = 0.0f; movement.Normalize(); //apply speed to movement movement *= Speed; //change moving state to true when moving Moving = horizontalMovement != 0 || verticalMovement != 0; if (Moving == true) { newRotation = Quaternion.Lerp(GetComponent <Rigidbody>().rotation, targetRotation, rotationSpeed * Time.deltaTime); //rotate character GetComponent <Rigidbody>().MoveRotation(newRotation); Vector3 characterMovement = transform.position + movement; //move character GetComponent <Rigidbody>().MovePosition(characterMovement); //fade into running animation CharacterAnimator.CrossFade("Run", 0.0f); //change character state to moving State = CharacterState.moving; } }
protected void RpcAttack(bool attacking) { if (!CharacterAnimator.GetCurrentAnimatorStateInfo(0).IsName("Attack") && State != CharacterState.attack && State != CharacterState.knockback && State != CharacterState.dead) { CanMove = false; Moving = false; State = CharacterState.attack; StartCoroutine(attackDelay(0.2f)); CharacterAnimator.CrossFade("Attack", 0.0f); } }
//Lauches the attack animation and stops movement for a while. protected override void RpcAttack() { StartCoroutine(StopCharacter(3.0f)); if (!CharacterAnimator.GetCurrentAnimatorStateInfo(0).IsName("Attack")) { CharacterAnimator.CrossFade("Attack", 0.0f); State = CharacterState.attack; StartCoroutine(attackDelay(1.0f)); } //Debug.Log("Enemy attacked."); }
//Deals damage, knocks the enemy back and selects the attacker as the new target. public override void TakeDamage(int damage, float knockback, GameObject attacker) { if (State != CharacterState.dead && State != CharacterState.knockback) { Health = Health - damage; int random = RandomNumberGenerator.NextRandom(1, 5); audioSource.Stop(); if (random == 1) { audioSource.PlayOneShot(attack1); } else if (random == 2) { audioSource.PlayOneShot(attack2); } //Call die if the characte's health goes to zero. if (Health < 1) { Die(attacker); } //The enemy is still alive. Change to damage animation and stop him for a few seconds. else { if (!CharacterAnimator.GetCurrentAnimatorStateInfo(0).IsName("Damage")) { CharacterAnimator.CrossFade("Damage", 0.0f); } //Select the attacker as a new target if he is still alive. if (attacker.tag.Equals("Player") && attacker.GetComponent <Player>().State != CharacterState.dead) { target = attacker; } StartCoroutine(StopCharacter(2.0f)); State = CharacterState.knockback; } } }
//Taunt the target. private IEnumerator TauntCommand() { Debug.Log("An enemy decided to use taunt command."); executingCommand = true; if (target != null && target.GetComponent <Player>().State != CharacterState.dead && State != CharacterState.dead) { CanMove = false; Moving = false; RotateSmoothlyTowardsTarget(target.transform); yield return(new WaitForSeconds(1f)); if (!CharacterAnimator.GetCurrentAnimatorStateInfo(0).IsName("Taunt")) { //Play either one of the taunt sound effect randomly. int random = RandomNumberGenerator.NextRandom(1, 6); audioSource.Stop(); if (random == 1) { audioSource.PlayOneShot(taunt1); } if (random == 2) { audioSource.PlayOneShot(taunt2); } CharacterAnimator.CrossFade("Taunt", 0.0f); } yield return(new WaitForSeconds(1.5f)); CanMove = true; } executingCommand = false; commandDecided = false; yield return(null); }
//Changes character's state to idle if the currently playing animation is called "Idle". Also allows the //character to move again by setting CanMove to true. All the animator's animations except "Death" crossfade to "Idle" automatically. public void SetMovementAnimation() { if (Moving == false && CharacterAnimator.GetCurrentAnimatorStateInfo(0).IsName("Idle") && State != CharacterState.dead) { State = CharacterState.idle; CanMove = true; } else if (Moving == true && CanMove == true && State != CharacterState.knockback && State != CharacterState.dead) { if (State != CharacterState.moving) { State = CharacterState.moving; } if (!CharacterAnimator.GetCurrentAnimatorStateInfo(0).IsName("Run") && !CharacterAnimator.GetCurrentAnimatorStateInfo(0).IsName("Walk")) { CharacterAnimator.CrossFade("Run", 0.0f); } } }
public override void TakeDamage(int damage, float knockback, GameObject attacker) { if (State != CharacterState.dead && State != CharacterState.knockback) { //Debug.Log("Damage dealt to player. His current HP is " + Health+"."); Health = Health - damage; //Call die if the characte's health goes to zero. if (Health < 1) { Die(null); } else { //Animation taken from skeleton so it looks wrong on the knight. CharacterAnimator.CrossFade("Knockback", 0.0f); StartCoroutine(StopCharacter(5.0f)); State = CharacterState.knockback; } } }
// Update is called once per frame void Update() { //Stop executing update methods if the enemy is dead. if (State == CharacterState.dead) { return; } //Kill the enemy if he drops below the imageTarget's y position. KillTheCharacterIfOutOfBounds(); //Changes state and animation to idle and tries to select a new target (current Scene's GameObject with a tag "Player") //randomly if there is no current target or if the target is dead. if (target == null || target.GetComponent <Player>().State == CharacterState.dead) { StopAllCoroutines(); State = CharacterState.idle; Moving = false; CanMove = false; if (!CharacterAnimator.GetCurrentAnimatorStateInfo(0).IsName("Idle")) { CharacterAnimator.CrossFade("Idle", 0.0f); } SelectTargetRandomly(); } //Decide a new command if the previous one has been executed. if (commandDecided == false && executingCommand == false && target != null && State != CharacterState.dead) { CanMove = true; StopAllCoroutines(); DecideCommand(); } //Change the animation and state to idle or run according to the situation. SetMovementAnimation(); }
protected override void Die(GameObject killer) { if (State != CharacterState.dead) { audioSource.PlayOneShot(apologies); CharacterAnimator.CrossFade("Death", 0.0f); State = CharacterState.dead; CanMove = false; Moving = false; Debug.Log("Player died."); StartCoroutine(WaitAndDisable(5.0f, gameObject)); //Notify GameLogic Character killerCharacter = killer != null?killer.GetComponent <Player>() : null; if (killerCharacter == null) { killerCharacter = killer != null?killer.GetComponent <Enemy>() : null; } GameManager.GetInstance().OnDeath(this, killerCharacter); } }
//Kills the enemy and gives the points to the killer. protected override void Die(GameObject killer) { if (State != CharacterState.dead) { GetComponent <Rigidbody>().mass = 0.5f; CharacterAnimator.CrossFade("Death", 0.0f); State = CharacterState.dead; CanMove = false; Moving = false; int random = RandomNumberGenerator.NextRandom(1, 4); audioSource.Stop(); if (random == 1) { audioSource.PlayOneShot(death1); } else if (random == 2) { audioSource.PlayOneShot(death2); } Player killerPlayer = killer != null?killer.GetComponent <Player>() : null; if (killerPlayer == null) { killerPlayer = latestToucher != null?latestToucher.GetComponent <Player>() : null; } GameManager.GetInstance().OnDeath(this, killerPlayer); //Wait for five seconds before destroying this GameObject. StartCoroutine(WaitAndDestroy(10.0f, gameObject)); } }
//Moves the enemy away from the target if he is within the avoidingDistance. If the target is outside the avoidinDistance, //the enemy will stay still and use "Defend" animation. private void AvoidTarget(Transform targetPosition, float avoidingDistance) { if (CanMove == true && State != CharacterState.knockback && State != CharacterState.dead && State != CharacterState.knockback && target != null) { float step = -1 * Speed * Time.deltaTime; float distanceToTarget = Vector3.Distance(transform.position, targetPosition.position); if (distanceToTarget < avoidingDistance) { Moving = true; transform.position = Vector3.MoveTowards(transform.position, targetPosition.position, step); transform.LookAt(targetPosition); if (!CharacterAnimator.GetCurrentAnimatorStateInfo(0).IsName("Walk")) { CharacterAnimator.CrossFade("Walk", 0.0f); } } else { Moving = false; State = CharacterState.defend; RotateSmoothlyTowardsTarget(targetPosition); //GetComponent<Rigidbody>().velocity = Vector3.zero; if (!CharacterAnimator.GetCurrentAnimatorStateInfo(0).IsName("Defend")) { CharacterAnimator.CrossFade("Defend", 0.0f); } } } }