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

Unity图文切换动画异常求助:文本重复/图片无法正常切换

Unity文本与图片淡入淡出切换异常修复

问题根源分析

  1. 图片动画基准色错误:协程启动时一次性定义了固定颜色值,后续循环中淡入淡出始终基于这个初始值计算,而非图片当前的实际显示状态,导致图片透明度逻辑混乱。
  2. 图文切换不同步:图片显示状态采用独立toggle的方式,未与文本内容绑定,容易出现文本切换但图片未同步的情况。
  3. 淡入阶段逻辑疏漏:直接将非目标图片设为全透明,未考虑动画过程中的状态衔接,加剧了显示异常。

修复后的完整代码

using System;
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class DatesAnimation : MonoBehaviour
{
    public TMP_Text firstTextMesh;
    public TMP_Text secondTextMesh;
    public Image firstImage;
    public Image secondImage;
    public float animSpeedInSec = 1f;
    bool keepAnimating = false;

    private string firstNumber = "4.11.1995";
    private string secondNumber = "7.10.2023";
    private string firstString = "אתה";
    private string secondString = "אשם";

    private void Start()
    {
        // 初始化文本与图片状态
        firstTextMesh.text = firstNumber;
        secondTextMesh.text = ReverseString(firstString);
        SetImageVisibility(true);

        startTextMeshAnimation();
    }

    private IEnumerator anim()
    {
        // 保留文本的RGB颜色,仅动态修改Alpha
        Color textFirstBase = firstTextMesh.color;
        Color textSecondBase = secondTextMesh.color;
        // 保留图片的RGB颜色,仅动态修改Alpha
        Color imageFirstBase = firstImage.color;
        Color imageSecondBase = secondImage.color;

        while (keepAnimating)
        {
            // 获取当前显示状态(通过文本判断,确保图文同步)
            bool isShowingFirstSet = firstTextMesh.text == firstNumber;

            // --- 淡出阶段:当前显示的文本和图片全部透明 ---
            for (float counter = 0; counter < animSpeedInSec; counter += Time.deltaTime)
            {
                if (!keepAnimating) yield break;
                float alpha = Mathf.Lerp(1f, 0f, counter / animSpeedInSec);
                
                firstTextMesh.color = new Color(textFirstBase.r, textFirstBase.g, textFirstBase.b, alpha);
                secondTextMesh.color = new Color(textSecondBase.r, textSecondBase.g, textSecondBase.b, alpha);
                
                firstImage.color = new Color(imageFirstBase.r, imageFirstBase.g, imageFirstBase.b, isShowingFirstSet ? alpha : 0f);
                secondImage.color = new Color(imageSecondBase.r, imageSecondBase.g, imageSecondBase.b, !isShowingFirstSet ? alpha : 0f);
                
                yield return null;
            }

            // --- 切换文本内容 ---
            firstTextMesh.text = isShowingFirstSet ? secondNumber : firstNumber;
            secondTextMesh.text = isShowingFirstSet ? ReverseString(secondString) : ReverseString(firstString);
            // 更新显示状态
            isShowingFirstSet = !isShowingFirstSet;

            // --- 淡入阶段:新的文本和图片渐显 ---
            for (float counter = 0; counter < animSpeedInSec; counter += Time.deltaTime)
            {
                if (!keepAnimating) yield break;
                float alpha = Mathf.Lerp(0f, 1f, counter / animSpeedInSec);
                
                firstTextMesh.color = new Color(textFirstBase.r, textFirstBase.g, textFirstBase.b, alpha);
                secondTextMesh.color = new Color(textSecondBase.r, textSecondBase.g, textSecondBase.b, alpha);
                
                firstImage.color = new Color(imageFirstBase.r, imageFirstBase.g, imageFirstBase.b, isShowingFirstSet ? alpha : 0f);
                secondImage.color = new Color(imageSecondBase.r, imageSecondBase.g, imageSecondBase.b, !isShowingFirstSet ? alpha : 0f);
                
                yield return null;
            }
        }
    }

    // 设置图片初始可见性
    private void SetImageVisibility(bool showFirst)
    {
        Color imageFirstBase = firstImage.color;
        Color imageSecondBase = secondImage.color;
        
        firstImage.color = new Color(imageFirstBase.r, imageFirstBase.g, imageFirstBase.b, showFirst ? 1f : 0f);
        secondImage.color = new Color(imageSecondBase.r, imageSecondBase.g, imageSecondBase.b, showFirst ? 0f : 1f);
    }

    void startTextMeshAnimation()
    {
        if (keepAnimating) return;
        keepAnimating = true;
        StartCoroutine(anim());
    }

    void changeTextMeshAnimationSpeed(float animSpeed)
    {
        animSpeedInSec = animSpeed;
    }

    void stopTextMeshAnimation()
    {
        keepAnimating = false;
    }

    private string ReverseString(string s)
    {
        char[] charArray = s.ToCharArray();
        Array.Reverse(charArray);
        return new string(charArray);
    }
}

关键修改说明

  1. 图文状态绑定:通过文本内容判断当前显示组,确保文本和图片的切换完全同步,避免独立toggle导致的不同步问题。
  2. 动态Alpha计算:每次淡入淡出时,基于文本和图片的原始RGB颜色动态修改Alpha值,不再依赖固定的初始颜色,保证动画逻辑符合当前显示状态。
  3. 简化图片状态控制:淡出/淡入阶段仅处理当前显示的图片的透明度,非目标图片保持全透明,逻辑更清晰。
  4. 移除冗余方法:删除未被调用的FadeImages方法,精简代码结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 18:27:10