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

如何实现玩家靠近火焰对象时仅单次触发后退动画?

玩家靠近火焰仅触发一次后退动画修复

现有8个标记为"Spreaded Fire"的对象,需求是当玩家靠近任意一个该类对象时,仅播放一次"Walk Backward"动画。
当前代码存在逻辑缺陷:动画会被多次触发;即使多个火焰对象在检测范围内,也无法保证仅触发一次动画。

原问题代码

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;
using UnityStandardAssets.Characters.ThirdPerson;

public class SpreadedFireDistanceCheck : MonoBehaviour
{
    public Transform player;
    public List<GameObject> spreadedFires = new List<GameObject> ();

    private Animator anim;
    private bool doOnce = true;

    void Start()
    {
        spreadedFires = GameObject.FindGameObjectsWithTag("Spreaded Fire").ToList();
        anim = player.GetComponent<Animator>();
    }

    private void Update()
    {
        foreach(GameObject spreadedFire in spreadedFires)
        {
            if(Vector3.Distance(player.transform.position, spreadedFire.transform.position) < 5f && doOnce)
            {
                anim.Play("Walk Backward");
                doOnce = false;
            }
            else
            {
                doOnce = true;
            }
        }
    }
}

问题根源

原代码的遍历逻辑存在致命缺陷:

  • 每遍历一个火焰对象就修改doOnce的值,当第一个火焰触发动画并将doOnce设为false后,下一个不在范围内的火焰会立即把doOnce改回true
  • 导致后续每一帧Update中,只要有火焰在范围内,动画就会被反复触发

修复后的代码

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityStandardAssets.Characters.ThirdPerson;

public class SpreadedFireDistanceCheck : MonoBehaviour
{
    public Transform player;
    public List<GameObject> spreadedFires = new List<GameObject>();

    private Animator anim;
    private bool hasPlayedBackwardAnim = false;

    void Start()
    {
        spreadedFires = GameObject.FindGameObjectsWithTag("Spreaded Fire").ToList();
        anim = player.GetComponent<Animator>();
    }

    private void Update()
    {
        // 一次性判断是否有任意火焰在玩家5米范围内
        bool isNearAnyFire = spreadedFires.Any(fire => 
            Vector3.Distance(player.position, fire.transform.position) < 5f);

        // 仅当进入火焰范围且未播放过动画时触发一次
        if (isNearAnyFire && !hasPlayedBackwardAnim)
        {
            anim.Play("Walk Backward");
            hasPlayedBackwardAnim = true;
        }
        // 离开火焰范围后重置状态,下次靠近可再次触发
        else if (!isNearAnyFire && hasPlayedBackwardAnim)
        {
            hasPlayedBackwardAnim = false;
        }
    }
}

关键修改点

  1. 语义化变量命名:将doOnce改为hasPlayedBackwardAnim,状态含义更清晰
  2. 批量判断逻辑:使用Any()方法一次性检测所有火焰,避免逐个遍历修改状态
  3. 状态控制逻辑优化:仅在「进入范围且未触发过动画」时播放一次;离开范围后重置状态,保证下次靠近仍能触发
  4. 清理冗余引用:移除了未使用的TMPro命名空间

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:55:21