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

Unity中变换音效无法切换Audio Source Clip,行走音效正常

问题分析与解决

核心问题

你的代码里Update函数每帧都会执行行走音效的设置,当触发变换音效后,只要isMoving为false,下一秒Update就会把AudioSource的clip强行改回walk,直接覆盖了变换音效的设置。另外Transform里用Input.GetKey会持续触发播放逻辑,进一步加剧冲突。

具体修复步骤

  1. 优化行走音效触发逻辑
    不要每帧都设置clip和播放,只在状态切换或当前音效不符合时执行:
void Update()
{
    Animate();
    Transform();

    // 行走音效:仅当未移动、不在变换状态且当前音效不是walk时才播放
    if (!isMoving && source.clip != walk)
    {
        source.clip = walk;
        source.Play();
    }
    // 移动时停止行走音效
    else if (isMoving && source.clip == walk && source.isPlaying)
    {
        source.Stop();
    }
}
  1. 变换音效改为单次触发
    把Input.GetKey换成Input.GetKeyDown,避免按住按键时反复执行播放逻辑,同时播放前先停止当前音效:
void Transform()
{
    // 用GetKeyDown代替GetKey,只在按键按下的第一帧触发
    if(Input.GetKeyDown(KeyCode.Space) && hasTransformed)
    {
        anim.SetTrigger("retransform");
        decrease1 = true;
        timerToChange = 1.7f;
        hasTransformed = false;
        
        source.Stop();
        source.clip = transformation;
        source.Play();
    }
    if (Input.GetKeyDown(KeyCode.T) && !hasTransformed)
    {
        anim.SetTrigger("transform");
        decrease = true;
        timerToChange = 1.7f;
        hasTransformed = true;
        
        source.Stop();
        source.clip = transformation;
        source.Play();
    }

    // 原有计时与状态切换逻辑保留
    if (decrease)
    {
        timerToChange -= Time.deltaTime;
    }
    if (decrease1)
    {
        timerToChange -= Time.deltaTime;
    }
    if(timerToChange <= 0 && hasTransformed)
    {
        bodyParts.SetActive(false);
        bodyParts1.SetActive(false);
        bodyParts2.SetActive(false);
        robotCollider.isTrigger = true;
        car.SetActive(true);
        carCollider.isTrigger = false;
    }
    if (timerToChange <= 0 && !hasTransformed)
    {
        bodyParts.SetActive(true);
        bodyParts1.SetActive(true);
        bodyParts2.SetActive(true);
        robotCollider.isTrigger = false;
        car.SetActive(false);
        carCollider.isTrigger = true;
    }
}
  1. 额外优化:添加变换状态锁(可选)
    新增isTransforming变量,标记变换过程,彻底避免行走音效干扰:
private bool isTransforming;

void Update()
{
    Animate();
    Transform();

    // 排除变换状态,避免音效冲突
    if (!isMoving && !isTransforming && source.clip != walk)
    {
        source.clip = walk;
        source.Play();
    }
    else if (isMoving && source.clip == walk && source.isPlaying)
    {
        source.Stop();
    }
}

void Transform()
{
    if(Input.GetKeyDown(KeyCode.Space) && hasTransformed)
    {
        isTransforming = true;
        anim.SetTrigger("retransform");
        decrease1 = true;
        timerToChange = 1.7f;
        hasTransformed = false;
        
        source.Stop();
        source.clip = transformation;
        source.Play();
    }
    if (Input.GetKeyDown(KeyCode.T) && !hasTransformed)
    {
        isTransforming = true;
        anim.SetTrigger("transform");
        decrease = true;
        timerToChange = 1.7f;
        hasTransformed = true;
        
        source.Stop();
        source.clip = transformation;
        source.Play();
    }

    if (decrease)
    {
        timerToChange -= Time.deltaTime;
        // 变换完成后解除标记
        if(timerToChange <= 0)
        {
            decrease = false;
            isTransforming = false;
        }
    }
    if (decrease1)
    {
        timerToChange -= Time.deltaTime;
        if(timerToChange <= 0)
        {
            decrease1 = false;
            isTransforming = false;
        }
    }

    // 原有状态切换逻辑保留
    if(timerToChange <= 0 && hasTransformed)
    {
        bodyParts.SetActive(false);
        bodyParts1.SetActive(false);
        bodyParts2.SetActive(false);
        robotCollider.isTrigger = true;
        car.SetActive(true);
        carCollider.isTrigger = false;
    }
    if (timerToChange <= 0 && !hasTransformed)
    {
        bodyParts.SetActive(true);
        bodyParts1.SetActive(true);
        bodyParts2.SetActive(true);
        robotCollider.isTrigger = false;
        car.SetActive(false);
        carCollider.isTrigger = true;
    }
}

关键说明

  • Update里的行走音效逻辑是冲突根源,每帧强制设置clip会覆盖所有其他音效,必须改成状态驱动的触发方式。
  • GetKeyDown确保变换音效只播放一次,不会因按住按键反复触发。
  • 变换状态锁可以彻底隔离两种音效的触发时机,避免交叉干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 16:45:38