[Unity3D] 敵の実装

敵を実装する
---
1, 敵を配置し、Rigidbodyを付ける
![53E40FC7-E593-4A27-B961-CB6F0A5442A8.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/762f699e-9fbe-6f34-9bb4-1a32d628e111.jpeg)

2, NavMeshAgentも付ける
![DDFF2C8E-3B8B-4FC5-9A8E-3CCE9BC59AE7_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/d9eec6e3-d68e-fa12-f289-bfd8237ea8bb.jpeg)

3, Window→AI→Navigationを選択する
![E57DF3F9-E7F2-48A3-8A75-51EAE1D35CAD.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/a4964cd0-6881-b0be-9854-4c3894464778.jpeg)

4, NavigationのObjectでTrrainを選択すると加えられるので、NavigationStaticにチェックを入れる
![5BDD30D6-F4D4-4EEF-BDC9-2B28ADB8D18E_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/38edeca5-e944-badf-a1c9-b8b7c35504ec.jpeg)

5, Bakeに行き、Bakeを押す
(その他に追加したいcubeなどObjectがあれば４〜５を繰り返して選択するとObjectを避けるようにできる)
![E813423B-57CA-45C5-A7B7-E121E6F46355.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/a60776d4-200b-771f-616a-9b7770d97298.jpeg)

スクリプトの作成
---
1, EnemyManagerを作成し、Enemyにアタッチする
![62118959-FC59-40F6-B3C6-6D8410B7BAF0_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/e88142aa-eee7-1089-3717-f2e2bc4f97c1.jpeg)

2, 下記コードを書く

```C#:EnemyManager
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class EnemyManager : MonoBehaviour
{
    public Transform target;
    NavMeshAgent agent;

    void Start()
    {
        agent = GetComponent<NavMeshAgent>(); //agentを設定
        agent.destination = target.position; //agentの場所はどこですか？ ＝ ターゲットの場所です
    }

    void Update()
    {
        agent.destination = target.position;
    }
}
```
3, EnemyのTagetにPlayerを設定する

![2FE8CBD0-FC65-4EA0-90B2-978FB3C80CB9.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/d52c2580-49c3-5234-bcb3-6146af6722bc.jpeg)

4, 動作確認をしながらSpeedや止まる距離など調整する
![66E3FE98-E83D-4130-AAEE-D141DFBD7EA9.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/f3ebb7e0-feb9-c2b1-2ee4-07b44b63d989.jpeg)

アニメーションの実装
---
1, AniMationControllerの(EnemyController)を作成し、AnimationのControllerにセットする
![48CE42FB-9A83-4A26-92C5-A0F6F7CB1E9C.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/6be58825-fea9-248d-9523-fbed8fe55e03.jpeg)

2, 各アニメーションを配置する
![130B0FC9-17EF-445E-9654-08EFD40BD7AE_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/297ae9ac-4bc9-7e18-e061-6b3f4003d453.jpeg)

3, Parametersでfloat型のDistanceを作成する
![44DB1D00-DD6D-40B0-9CA5-ACBB46D72A0B_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/1d5ca37d-570e-0dff-c5e0-d2aa8d927ec9.jpeg)

４, 各TransitionにDistanceを設定する
（距離に応じて動作させるため）
![2F276307-E726-4DDC-8203-603D94EE17CA.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/285d042f-da69-1238-feba-0e9de838fda4.jpeg)

![02A88AA6-E661-413F-9240-67AD76D0ABFE.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/7eabb524-6c11-0613-a089-37ac90a2f865.jpeg)

![56EBFCD2-634C-43AE-BFB0-5F2E86CFBD7A.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/dde75eb5-2028-c0fe-d72a-41061b817146.jpeg)

![1615D2A5-F3A8-4AB2-AC03-ECE062A1FDFB.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/dd94a835-23db-e968-2676-cd96035db5e1.jpeg)

5, 各TransitionのHasExitのチェックを外す、TransitionDuratiorは０にする
![5F3C3C66-E1C6-4A0A-AC8F-12F43CDF61F0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/a29239ce-a9cf-612c-ce00-315a2815ddb7.jpeg)

スクリプトから動作させる
---
1, EnemyManagerに下記コメント部分のスクリプトを追加

```C#:EnemyManager
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class EnemyManager : MonoBehaviour
{
    public Transform target;
    NavMeshAgent agent;
    Animator animator;  //アニメーターを作成

    void Start()
    {
        animator = GetComponent<Animator>();    // アニメーターを取得
        agent = GetComponent<NavMeshAgent>(); 
        agent.destination = target.position; 
    }

    void Update()
    {
        agent.destination = target.position;
        animator.SetFloat("Distance", agent.remainingDistance); //Distanceを取得して距離に応じて動作する
    }
}
```
2, IdleやWalkなど各アニメーションクリップを選択し、EnemyIdleBehaviourやEnemyWalkBehaviourを作成する
（他のアニメーションにも必要であれば作成）
![F588F3DD-6CB1-40E0-B27E-81B24C835C06.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/da51223e-462a-20df-c76d-507f338f4368.jpeg)

3, 下記スクリプトを記述する

```C#:EnemyIdleBehaviour
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;   //AIを使用するため

public class EnemyIdleBehaviour : StateMachineBehaviour
{
    // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        animator.GetComponent<NavMeshAgent>().speed = 0;    // idleの時はスピードを0にする
    }

    // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
    //override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateExit is called when a transition ends and the state machine finishes evaluating this state
    //override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateMove is called right after Animator.OnAnimatorMove()
    //override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that processes and affects root motion
    //}

    // OnStateIK is called right after Animator.OnAnimatorIK()
    //override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that sets up animation IK (inverse kinematics)
    //}
}
```

```C#:EnemyWalkBehaviour
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class EnemyWalkBehaviour : StateMachineBehaviour
{
    // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        animator.GetComponent<NavMeshAgent>().speed = 2;
    }

    // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
    //override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateExit is called when a transition ends and the state machine finishes evaluating this state
    //override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateMove is called right after Animator.OnAnimatorMove()
    //override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that processes and affects root motion
    //}

    // OnStateIK is called right after Animator.OnAnimatorIK()
    //override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that sets up animation IK (inverse kinematics)
    //}
}
```

```C#:EnemyPunchBehaviour
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class EnemyPunchBehaviour : StateMachineBehaviour
{
    // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        animator.GetComponent<NavMeshAgent>().speed = 0;
    }

    // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
    //override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateExit is called when a transition ends and the state machine finishes evaluating this state
    //override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateMove is called right after Animator.OnAnimatorMove()
    //override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that processes and affects root motion
    //}

    // OnStateIK is called right after Animator.OnAnimatorIK()
    //override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that sets up animation IK (inverse kinematics)
    //}
}
```