[Unity3D] ダメージの実装

当たり判定をつける
---
1, Playerの当たり判定をつけたい部位にMeshRenderer、MeshColliderかBoxColliderを付ける
メッシュの形、大きさを調整する
![E599FE31-DB9B-4BF3-8245-F5929249080A.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/76ffa764-af8d-01c4-43ca-652de81e76de.jpeg)
![22DFA714-16A0-44E1-8335-7B79B8D46EA1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/985769cd-811b-d232-df2f-ff488f628309.jpeg)


2, 敵にCapsuleColliderを付け、isTriggerをチェック、Colliderの大きさを調整する
![2E995B94-E9B2-48FA-8236-5FA0625D31AA.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/1c0a7218-4036-c7d4-46a3-1192cdb37466.jpeg)
![2719328B-7D0C-45DB-A772-D43370499E05_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/3f2fd43c-b072-e09c-18c3-1b50f9c93383.jpeg)

3, EnemyMnagerに下記スクリプトを追加し、動作確認する

```C#:EnemyManager
private void OnTriggerEnter(Collider other)　// 当たり判定
    {
        Debug.Log("接触(敵)");
    }
```
4, 敵の部位にBoxColliderを付ける
![367F8A1A-56A6-4243-9607-9A4760C157F8_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/352d1e66-37fc-0f2b-f73e-058643d1199e.jpeg)

5, プレーヤーにCapsuleColliderを付ける
![DD2FDEFC-61F3-4170-A235-2FD465DE89DA.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/34c01a22-ecff-4f65-e5e3-c6b14b890221.jpeg)

6, PlayerManagerに下記スクリプトを追加し、動作確認する

```C#:PlayerManager
private void OnTriggerEnter(Collider other) // 当たり判定
    {
        Debug.Log("接触(プレーヤー)");
    }
```
ダメージを実装
---
1, Damager.csを作成し、各部位に設定する
![11214321-7CAD-4E4C-AF37-E9CF3A5BF4E3.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/41a9db90-48b6-1a46-44d5-0eff2c45dff0.jpeg)

2, Damager.cs、Playermanager,Enemymanagerに下記のスクリプトを記述

```C#:Damager
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Damager : MonoBehaviour
{
    public int damage;
}
```

```C#:PlayerManager
private void OnTriggerEnter(Collider other)
    {
        Damager damager = other.GetComponent<Damager>();
        if (damager != null)
        {
            //ダメージを与えるものにぶつかったら
            Debug.Log("プレーヤーはダメージをうける");
        }
    }
```

```C#:EnemyManager
private void OnTriggerEnter(Collider other)
    {
        Damager damager = other.GetComponent<Damager>();
        if (damager != null)
        {
            //ダメージを与えるものにぶつかったら
            Debug.Log("敵はダメージをうける");
        }
    }
```

ダメージアニメーションの実装
---
1, アニメーションを配置し、AnyStateからMakeTransitionをつける
![055FB971-A60B-4A99-BC31-B00C2212A99F_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/b154f7e5-b011-befa-077e-47539e5ee1bc.jpeg)

2, PrametersにHurtを作り、各項目を設定する
![1913159A-321D-437B-8F54-6501D34FB6A5.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/f6fe8406-3ddd-1f4c-cba9-f870a1b83034.jpeg)

3, 下記コメント部分のコードを追加

```C#:PlayerManager
private void OnTriggerEnter(Collider other)
    {
        Damager damager = other.GetComponent<Damager>();
        if (damager != null)
        {
            //ダメージを与えるものにぶつかったら
            animator.SetTrigger("Hurt");
        }
    }
```

4, 敵も同様にアニメーションを実装する
![E5E0940E-4C6D-4D95-B3A8-78B195B3D55D.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/aca118e4-3efd-3ca9-adef-160fc8feb473.jpeg)

```C#:EnemyManager
private void OnTriggerEnter(Collider other)
    {
        Damager damager = other.GetComponent<Damager>();
        if (damager != null)
        {
            //ダメージを与えるものにぶつかったら
            animator.SetTrigger("Hurt");
        }
    }
```
攻撃の判定
---
1, Playerのanimationを開く
![E5D6A0BA-1B60-4F3D-8CCB-944FCD439318.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/df6bd6b8-88e5-538c-c552-ccd4121d353a.jpeg)

2, playerManagerに下記コメント部分のスクリプトを書く

```C#:PlayerManager
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerManager : MonoBehaviour
{
    float x;
    float z;
    public float moveSpeed;
    public Collider punchCollider; //設定する
    public Collider kickCollider;

    Rigidbody rb;
    Animator animator;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
        animator = GetComponent<Animator>();
        HideColliderPunch();   //最初は隠しておく
        HideColliderKick();
    }

    void Update()
    {
        x = Input.GetAxisRaw("Horizontal");
        z = Input.GetAxisRaw("Vertical");

        //攻撃
        if (Input.GetKeyDown(KeyCode.V))
        {
            animator.SetTrigger("Attack");
        }
        else if (Input.GetKeyDown(KeyCode.C))
        {
            animator.SetTrigger("Kick");
        }
        else if (Input.GetKeyDown(KeyCode.Space))
        {
            animator.SetTrigger("Jump");
        }
        else if (Input.GetKeyDown(KeyCode.M))
        {
            animator.SetTrigger("Brooklyn");
        }
    }

    void FixedUpdate()
    {
        Vector3 direction = transform.position + new Vector3(x, 0, z) * moveSpeed;
        transform.LookAt(direction);

        rb.velocity = new Vector3(x, 0, z) * moveSpeed;
        animator.SetFloat("Speed", rb.velocity.magnitude);
    }

    //攻撃の判定
    public void HideColliderPunch()
    {
        punchCollider.enabled = false; //無効にする
    }
    public void ShowColliderPunch()
    {
        punchCollider.enabled = true;  //有効にする
    }
    public void HideColliderKick()
    {
        kickCollider.enabled = false; //無効にする
    }
    public void ShowColliderKick()
    {
        kickCollider.enabled = true;  //有効にする
    }

    private void OnTriggerEnter(Collider other)
    {
        Damager damager = other.GetComponent<Damager>();
        if (damager != null)
        {
            animator.SetTrigger("Hurt");
        }
    }
}
```
3, 各攻撃にAdd eventで始まりと終わりを部分をつけ、Function部分でShowColliderPunch(), HideColliderPunch()を設定する
![F51E7D93-968E-4609-BF67-A65B6AEB788D.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/873fc1b7-12cc-219f-48c1-f052b34b5764.jpeg)

![307FFF67-435C-4FC1-AFD8-42589DBA0005.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/e8739a85-5d56-c247-ff65-2eb423ad20de.jpeg)

4, 各Colliderがついているものを設定する
![C19624AA-680B-4458-9463-E4DEE7086D13.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/e9c56b60-4889-c3dd-81d4-20ff1f3293ae.jpeg)

5, 敵も同様に設定する

プレイヤーが攻撃を受けても移動出来てしまうバグ修正
---
1, PlayerのGetHitを選択し、PlayerHurtBehaviourを作成する
![85CD48CF-CC57-4088-ADBF-D1A5FF43AA8A_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/70246c80-e236-94d6-b3cb-e20ee31e3ad0.jpeg)

2, 下記コードを記述

```C#:PlayerHurtBehaviour
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerAttackBehaviour : 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<PlayerManager>().moveSpeed = 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)
    {
        animator.GetComponent<PlayerManager>().moveSpeed = 3;
    }

    // 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)
    //}
}
```
攻撃を受けた時に何度もアニメーションが実行されてしまうバグ修正
---
1, EnemyHurtBehaviourとplayerHurtBehaviourに下記コメント部分のコードを追加する

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

public class EnemyHurtBehaviour : 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.ResetTrigger("Hurt"); //攻撃を受けたらリセットする
        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)
    {
        animator.ResetTrigger("Hurt"); //抜けるときもリセットする
    }
```