You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中如何在父物体脚本中仅用子物体hitBox碰撞器检测伤害

问题描述

我是Unity新手,正在制作一个骷髅敌人,该GameObject下至少有4个碰撞器子物体,但我只想通过名为“hitBox”的子物体碰撞器检测对玩家造成的伤害。我知道可以给hitBox添加脚本并使用OnTriggerEnter2D函数实现,但希望仅通过挂载在骷髅GameObject上的Skeleton.cs脚本来完成。请问是否有类似OnChildTriggerEnter2D的函数可以解决这个问题?

附上我的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Skeleton : MonoBehaviour
{
    #region Public Variables
    public float attackDistance;
    public float moveSpeed;
    public float timer;
    public GameObject hotZone;
    public GameObject triggerArea;
    public float hp_skel;

    [HideInInspector] public Transform target;
    [HideInInspector] public bool inRange; 
    #endregion

    #region Private Variables
    private Animator anim;
    private float distance;
    public bool attackMode;
    private float intTimer;
    #endregion

    void Awake() {
        intTimer = timer;
        anim = GetComponent<Animator>();
    }
    
    void Update()
    {
        if (inRange)
        {
            EnemyLogic();
        }
    }

    void EnemyLogic()
    {
        distance = Vector2.Distance(transform.position, target.position);

        if(distance > attackDistance)
        {
            Move();
            StopAttack();   
        }
        else if(attackDistance >= distance)
        {
            Attack();
        }
    }

    void Move()
    {
        anim.SetInteger("Idle", 1);
        anim.SetBool("canWalk", true);
        if (!anim.GetCurrentAnimatorStateInfo(0).IsName("attack"))
        {
            Vector2 targetPosition = new Vector2(target.position.x, transform.position.y);
            transform.position = Vector2.MoveTowards(transform.position, targetPosition, moveSpeed * Time.deltaTime);
        }
    }

    void Attack()
    {
        timer = intTimer;
        attackMode = true;

        anim.SetInteger("Idle", 1);
        anim.SetBool("canWalk", false);
        anim.SetBool("Attack", true);
    }

    void StopAttack()
    {
        attackMode = false;
        anim.SetBool("Attack", false);
    }

    
    public void Flip()
    {
        Vector3 rotation = transform.eulerAngles;
        if(target.position.x < transform.position.x)
        {
            rotation.y = 180f;
        }
        else
        {
            rotation.y = 0f;
        }
        transform.eulerAngles = rotation;
    }
}
解决方案

Unity没有内置的OnChildTriggerEnter2D函数,但可以通过以下两种方式实现需求:

方法1:给hitBox添加极简转发脚本(推荐)

虽然你不想给hitBox单独加脚本,但这个脚本仅负责把触发事件传递给父物体的Skeleton组件,代码非常轻量:

创建一个名为HitBoxForwarder.cs的脚本,挂载到hitBox物体上:

using UnityEngine;

public class HitBoxForwarder : MonoBehaviour
{
    private Skeleton parentSkeleton;

    void Awake()
    {
        // 获取父物体的Skeleton组件
        parentSkeleton = GetComponentInParent<Skeleton>();
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        // 只在攻击模式下触发伤害检测
        if (parentSkeleton.attackMode)
        {
            parentSkeleton.OnHitBoxTrigger(other);
        }
    }
}

然后在你的Skeleton.cs中添加处理伤害的函数:

// 新增:处理hitBox的触发事件
public void OnHitBoxTrigger(Collider2D other)
{
    // 检测碰撞对象是否是玩家(根据你的玩家标签调整)
    if (other.CompareTag("Player"))
    {
        // 这里写对玩家造成伤害的逻辑,比如调用玩家的受伤函数
        // other.GetComponent<PlayerHealth>().TakeDamage(1);
        Debug.Log("玩家受到伤害");
    }
}

方法2:在Skeleton脚本中主动检测hitBox的碰撞(无需额外脚本)

如果不想给hitBox加任何脚本,可以在攻击动画的关键帧(比如挥砍动作命中的瞬间)调用一个检测函数,主动判断hitBox范围内是否有玩家:

首先在Skeleton.cs中添加以下代码:

// 新增:获取hitBox的碰撞器组件
private Collider2D hitBoxCollider;

void Awake() {
    intTimer = timer;
    anim = GetComponent<Animator>();
    // 找到hitBox子物体的碰撞器
    hitBoxCollider = transform.Find("hitBox").GetComponent<Collider2D>();
}

// 新增:在攻击动画的关键帧调用这个函数(需要在Animator窗口给动画添加事件)
public void CheckHitBox()
{
    if (!attackMode) return;

    // 检测hitBox范围内的玩家碰撞器
    Collider2D[] hitColliders = Physics2D.OverlapBoxAll(hitBoxCollider.bounds.center, hitBoxCollider.bounds.size, 0f);
    foreach (var collider in hitColliders)
    {
        if (collider.CompareTag("Player"))
        {
            // 这里写伤害逻辑
            Debug.Log("玩家受到伤害");
            // 防止一次攻击多次触发伤害
            break;
        }
    }
}

然后在Unity的Animator窗口中,选中骷髅的攻击动画,在动画的命中关键帧位置添加一个动画事件,调用Skeleton组件的CheckHitBox函数即可。

注意:方法2需要精准控制动画事件的时间,不如方法1的触发事件准确,但完全不需要额外脚本。

内容的提问来源于stack exchange,提问作者mumber162

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 00:55:20