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

多僵尸同时碰撞玩家时如何仅触发单个GRAB STATE?

解决多丧尸同时抓取玩家的问题

核心问题是玩家没有标记“已被抓取”的状态,导致所有碰撞到玩家的丧尸都会触发抓取逻辑。以下是具体解决方案:

1. 给玩家添加被抓取状态标记

在玩家脚本中新增状态变量,用于标识是否已被丧尸抓取:

// 玩家脚本示例(Unity C#)
public class Player : MonoBehaviour
{
    private bool _isBeingGrabbed = false;
    // 提供外部访问的只读属性
    public bool IsBeingGrabbed => _isBeingGrabbed;

    // 设置被抓取状态的方法
    public void SetGrabbedState(bool state)
    {
        _isBeingGrabbed = state;
        if (state)
        {
            // 隐藏Sprite、禁用移动与控制
            GetComponent<SpriteRenderer>().enabled = false;
            GetComponent<PlayerMovement>().enabled = false;
            GetComponent<PlayerInput>().enabled = false;
        }
        else
        {
            // 恢复Sprite、移动与控制
            GetComponent<SpriteRenderer>().enabled = true;
            GetComponent<PlayerMovement>().enabled = true;
            GetComponent<PlayerInput>().enabled = true;
        }
    }
}

2. 修改丧尸的碰撞触发逻辑

在丧尸的碰撞检测代码中,先判断玩家是否未被抓取,只有满足条件时才进入GRAB STATE:

// 丧尸脚本示例(Unity C#)
public class Zombie : MonoBehaviour
{
    private void OnCollisionEnter2D(Collision2D other)
    {
        Player player = other.gameObject.GetComponent<Player>();
        if (player != null && !player.IsBeingGrabbed)
        {
            // 进入GRAB STATE并播放抓取动画
            EnterGrabState();
            // 通知玩家设置被抓取状态
            player.SetGrabbedState(true);
        }
    }

    private void EnterGrabState()
    {
        // 切换到抓取状态的逻辑(如播放动画、停止移动)
        GetComponent<Animator>().SetTrigger("Grab");
        GetComponent<ZombieMovement>().enabled = false;
    }

    // 退出抓取状态的方法(供玩家挣脱时调用)
    public void ExitGrabState()
    {
        // 恢复到正常状态的逻辑
        GetComponent<Animator>().SetTrigger("ExitGrab");
        GetComponent<ZombieMovement>().enabled = true;
    }
}

3. 完善玩家挣脱逻辑

当玩家成功挣脱时,需要通知当前抓取的丧尸退出GRAB STATE,并重置自身的被抓取状态:

// 玩家脚本中添加挣脱逻辑
public void TryEscape()
{
    if (_isBeingGrabbed)
    {
        // 找到当前抓取的丧尸(可通过玩家与丧尸的碰撞引用或状态记录)
        Zombie grabbingZombie = FindObjectOfType<Zombie>(x => x.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).IsName("Grab"));
        if (grabbingZombie != null)
        {
            grabbingZombie.ExitGrabState();
        }
        SetGrabbedState(false);
    }
}

4. 可选:优化抓取优先级(避免冲突)

如果需要确保同一时间只有一只丧尸能抓取玩家,可以在玩家脚本中记录当前抓取的丧尸引用:

// 玩家脚本修改
public Zombie CurrentGrabbingZombie { get; private set; }
public bool IsBeingGrabbed => CurrentGrabbingZombie != null;

public void SetGrabbedState(Zombie zombie)
{
    CurrentGrabbingZombie = zombie;
    // 隐藏Sprite、禁用移动等逻辑...
}

public void ReleaseGrab()
{
    if (CurrentGrabbingZombie != null)
    {
        CurrentGrabbingZombie.ExitGrabState();
        CurrentGrabbingZombie = null;
    }
    // 恢复Sprite、移动等逻辑...
}

此时丧尸的碰撞判断需改为:

if (player != null && player.CurrentGrabbingZombie == null)
{
    EnterGrabState();
    player.SetGrabbedState(this);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:10:36