Unity图文切换动画异常求助:文本重复/图片无法正常切换
Unity文本与图片淡入淡出切换异常修复
问题根源分析
- 图片动画基准色错误:协程启动时一次性定义了固定颜色值,后续循环中淡入淡出始终基于这个初始值计算,而非图片当前的实际显示状态,导致图片透明度逻辑混乱。
- 图文切换不同步:图片显示状态采用独立toggle的方式,未与文本内容绑定,容易出现文本切换但图片未同步的情况。
- 淡入阶段逻辑疏漏:直接将非目标图片设为全透明,未考虑动画过程中的状态衔接,加剧了显示异常。
修复后的完整代码
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); } }
关键修改说明
- 图文状态绑定:通过文本内容判断当前显示组,确保文本和图片的切换完全同步,避免独立toggle导致的不同步问题。
- 动态Alpha计算:每次淡入淡出时,基于文本和图片的原始RGB颜色动态修改Alpha值,不再依赖固定的初始颜色,保证动画逻辑符合当前显示状态。
- 简化图片状态控制:淡出/淡入阶段仅处理当前显示的图片的透明度,非目标图片保持全透明,逻辑更清晰。
- 移除冗余方法:删除未被调用的
FadeImages方法,精简代码结构。
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

