Unity6 攻擊碰撞與怪物受擊動畫設定流程

·

  1. 設定攻擊 Collider
  2. 新增控制 Collider 的腳本
  3. 設定動畫事件(Animation Event)
  4. 怪物受擊腳本

設定攻擊Colider

對撞機collider是一種看不見但有形狀的區域,可以讓 Unity 偵測物體是否「接觸」或「穿過」它,並觸發物理或事件反應。

  • 在角色下新增一個空的子物件(命名為AttackRange)。
  • 在子物件上加 BoxCollider 或 SphereCollider,並勾選 Is Trigger。
  • 調整 Collider 的 Center 和 Size,讓它覆蓋攻擊範圍。
  • 給這個子物件加上 Tag 如:NinjaAttack。
  • 預設將 Collider 的 enabled 設為 false。

當你在角色下新增一個名為 AttackRange 的子物件並加上 Collider 時,建議將它放置在角色攻擊方向的正前方,並依照武器或動作的實際範圍來調整大小與位置。這樣做可以更準確地控制攻擊判定區域,避免出現角色尚未出拳卻已命中敵人的情況。同時,預設將 Collider 設為 disabled,可以透過動畫事件或程式邏輯在出招瞬間啟用,讓攻擊判定更具真實感與精準度。

設定動畫事件(Animation Event)

  • 選擇 punch 動畫,打開 Animation 視窗。
  • 在攻擊開始的格數加 Animation Event,Function 填 EnableAttackCollider
  • 在攻擊結束的格數加 Animation Event,Function 填 DisableAttackCollider
  • 設定好後按 Apply。

新增控制 Collider 的程式

實作EnableAttackCollider與DisableCollider兩個簡單的函式給動畫事件使用。主要是控制attackCollider的開關

using UnityEngine;



public class NinjaAttackCollider : MonoBehaviour

{

    public Collider attackCollider;



    void Start()

    {

        if (attackCollider != null)

            attackCollider.enabled = false;

    }



    // 給動畫事件呼叫

    public void EnableAttackCollider()

    {

        if (attackCollider != null)

            attackCollider.enabled = true;

    }



    public void DisableAttackCollider()

    {

        if (attackCollider != null)

            attackCollider.enabled = false;

    }

}

怪物受擊腳本(MonsterHit)

  • 確認怪物有 Animator,且 Animator 有 hit 這個 trigger。
  • 怪物必須有 Collider(Is Trigger)和 Rigidbody(isKinematic = true)。
  • 掛在所有需要受擊反應的怪物上
using UnityEngine;

public class MonsterHit : MonoBehaviour
{
    private Animator animator;
    public float knockbackDistance = 0.5f; // 後退距離,可在 Inspector 調整

    void Start()
    {
        animator = GetComponent<Animator>();
    }

    void OnTriggerEnter(Collider other)
    {
        // 假設攻擊的 Collider 有設 tag 為 "NinjaAttack"
        if (other.CompareTag("NinjaAttack"))
        {
            animator.SetTrigger("hit");
            // 往攻擊來源的反方向後退
            Vector3 backDir = -(other.transform.forward).normalized;
            transform.position += backDir * knockbackDistance;
        }
    }
}