頭以外の部分を撃たれた時に、立ち止まってゾンビのアニメーションを変更します。
アニメーターコントローラーをみると、歩くアニメーションと他のアニメーションのステートが同じレイヤーで管理されています。
整数型のパラメータがあり、「animBaseInt」が1~9だと左側のステートに遷移して、「animOtherInt」が1だと右側の歩いているステートに移ります。
例えば、左側の2番めの「Idle_angry」というステートへの遷移の矢印を選択してみます。
インスペクタを見ると、「animBaseInt」が2のときに遷移するようになっています。
このステートから元のステートに戻る矢印を確認します。
遷移の条件を見ると、同じパラメータが2でないときには戻ることがわかります。
ゾンビはデフォルトで歩いている状態からスタートさせているので、animOtherIntだけが1になっています。
同じレイヤーで管理されているので、このままanimBaseIntを変えても、左側のステートには遷移しません。その前にanimOtherIntを0にする必要があります。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class ZombieScript : MonoBehaviour
{
public GameObject player;
NavMeshAgent agent;
public bool stopZombie = false;
public bool RestartWalkingOn = false;
Animator animator;
// Start is called before the first frame update
void Start()
{
agent = GetComponent<NavMeshAgent>();
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (!RestartWalkingOn)
{
if (stopZombie)
{
RestartWalkingOn = true;
//agent.speed = 0f; // ゾンビの動きを止める
agent.isStopped = true; // ゾンビの動きを止める
Invoke("RestartWalking", 2); // 2秒後に再び歩きはじめる
animator.SetInteger("animOtherInt", 0); // 歩いている状態を解除
animator.SetInteger("animBaseInt", 2); // 撃たれたときの状態に遷移
}
else
{
agent.destination = player.transform.position;
}
}
}
void RestartWalking()
{
//agent.speed = 3.5f; // ゾンビを再び歩かせる
agent.isStopped = false; // ゾンビを再び歩かせる
RestartWalkingOn = false;
stopZombie = false;
animator.SetInteger("animBaseInt", 0); // 撃たれたときの状態を解除
animator.SetInteger("animOtherInt", 1); // 歩いている状態に遷移
}
}
ゾンビに付けたスクリプトで、ゾンビの頭以外が撃たれてstopZombieがtrueになると、ゾンビが立ち止まって、animOtherIntを0にしてからanimBaseIntを2にしています。
そして、再度ゾンビを歩かせるときは、animBaseIntを0にしてからanimOtherIntを1に戻します。再度ゾンビを歩かせる関数をInvoke()を使って、ゾンビを立ち止まらせた2秒後に実行しています。
Idle_angtyステートでのアニメーションはループするようになっています。
また、遷移の矢印のHas Exit Time(時間による遷移の条件)がオフになっていて、Transition Duration(遷移にかかる時間)が0になっているので、スクリプトから瞬時にアニメーションを制御できます。
stopZombieをtureにするのは、銃弾に付けたスクリプトで行っています。
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Agent") // ゾンビの頭以外に銃弾が当たった時
{
GameObject parent = collision.gameObject.transform.root.gameObject; // 階層の一番上のオブジェクト
ZombieScript sc_zombie = parent.GetComponent<ZombieScript>();
sc_zombie.stopZombie = true;
}
else if (collision.gameObject.tag == "AgentHead") // ゾンビの頭にあたった時
{
GameObject parent = collision.gameObject.transform.root.gameObject; // 階層の一番上のオブジェクト
// 撃たれたゾンビと同じ場所にラグドールを生成
GameObject ragdollIns = Instantiate(GunScript.girlRagdoll, parent.transform.position, parent.transform.rotation);
ragdollIns.GetComponent<ragDollScript>().impact = -collision.impulse; // ラグドールに力を伝える
Destroy(parent); // 撃たれたゾンビを削除
}
Destroy(gameObject); // 銃弾を削除
}
タグによって、頭と頭以外が撃たれたときの処理を分けています。