在顶部:
private Vector3 lastFwd;
private float curAngleX = 0;
在"开始"屏幕中:
private void Start()
{
lastFwd = transform.forward;
}
更新中 :
void Update()
{
var curFwd = transform.forward;
// measure the angle rotated since last frame:
var ang = Vector3.Angle(curFwd, lastFwd);
if (myApproximation(ang, 179f, 1f) == true)
{
var t = transform.GetChild(0).GetComponent<TextMesh>();
StartCoroutine(FadeTextToZeroAlpha(1, t));
t.text = "Hello";
StartCoroutine(FadeTextToFullAlpha(0, t));
}
}
淡入淡出方法:
public IEnumerator FadeTextToFullAlpha(float t, TextMesh i)
{
i.color = new Color(i.color.r, i.color.g, i.color.b, 0);
while (i.color.a < 1.0f)
{
i.color = new Color(i.color.r, i.color.g, i.color.b, i.color.a + (Time.deltaTime / t));
yield return null;
}
}
public IEnumerator FadeTextToZeroAlpha(float t, TextMesh i)
{
i.color = new Color(i.color.r, i.color.g, i.color.b, 1);
while (i.color.a > 0.0f)
{
i.color = new Color(i.color.r, i.color.g, i.color.b, i.color.a - (Time.deltaTime / t));
yield return null;
}
}
我想做的是开始从 1 淡入 0 而它是 0 以更改 t 变量文本,例如:
t.text = "Hello";
然后从 0 淡回 1。
但它并没有褪色。 如果我只保留从 1 到 0 的行,它将淡化文本。 但是当两条线存在时,它一点也不褪色。文本是相同的。
完整脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class OnMouseOverEvent : MonoBehaviour
{
public float speed = 5f;
public float distanceToMove = 1f;
public bool goForward;
public Vector3 startPos;
public Vector3 endPos;
private bool isRotating = false;
private Vector3 lastFwd;
private float curAngleX = 0;
private void Start()
{
lastFwd = transform.forward;
startPos = transform.position;
endPos = transform.position - Vector3.forward * distanceToMove;
}
void Update()
{
if (goForward && isRotating == false)
{
transform.position = Vector3.MoveTowards(transform.position, endPos, speed * Time.deltaTime);
}
else if (isRotating == false)
{
transform.position = Vector3.MoveTowards(transform.position, startPos, speed * Time.deltaTime);
}
var curFwd = transform.forward;
// measure the angle rotated since last frame:
var ang = Vector3.Angle(curFwd, lastFwd);
if (myApproximation(ang, 179f, 1f) == true)
{
var t = transform.GetChild(0).GetComponent<TextMesh>();
StartCoroutine(FadeTextToZeroAlpha(1, t));
t.text = "Hello";
StartCoroutine(FadeTextToFullAlpha(0, t));
}
}
public IEnumerator FadeTextToFullAlpha(float t, TextMesh i)
{
i.color = new Color(i.color.r, i.color.g, i.color.b, 0);
while (i.color.a < 1.0f)
{
i.color = new Color(i.color.r, i.color.g, i.color.b, i.color.a + (Time.deltaTime / t));
yield return null;
}
}
public IEnumerator FadeTextToZeroAlpha(float t, TextMesh i)
{
i.color = new Color(i.color.r, i.color.g, i.color.b, 1);
while (i.color.a > 0.0f)
{
i.color = new Color(i.color.r, i.color.g, i.color.b, i.color.a - (Time.deltaTime / t));
yield return null;
}
}
private bool myApproximation(float a, float b, float tolerance)
{
return (Mathf.Abs(a - b) < tolerance);
}
private void OnMouseOver()
{
goForward = true;
}
private void OnMouseExit()
{
goForward = false;
}
private void OnMouseDown()
{
if (isRotating == false && transform.name == "Options")
StartCoroutine(Rotate(5));
}
IEnumerator Rotate(float duration)
{
Quaternion startRot = transform.rotation;
float t = 0.0f;
while (t < duration)
{
isRotating = true;
t += Time.deltaTime;
transform.rotation = startRot * Quaternion.AngleAxis(t / duration * 360f, Vector3.up);
yield return null;
}
transform.rotation = startRot;
isRotating = false;
}
}
主要目标是在对象旋转以淡出/淡入文本时,以及在淡入淡出以更改文本时。
所有这些调用
StartCoroutine(FadeTextToZeroAlpha(1, t));
t.text = "Hello";
StartCoroutine(FadeTextToFullAlpha(0, t));
同时发生,因此您有并发例程。
此外,这可能会在多个后续帧中调用 ->您也应该只执行一次!
你应该把它打包成一个单一的例程,比如
private bool isUpdatingDisplay;
// Get this reference only ONCE
// better would even be if you can already reference it via the Inspector
[SerializeField] privtae TextMesh textMesh;
private void Awake()
{
if(!textMesh) textMesh = transform.GetChild(0).GetComponent<TextMesh>();
}
void Update()
{
....
// only start fading if it isn't doing it already
if(!isUpdatingDisplay)
{
StartCoroutine(UpdateDisplayPhrase("Hello"), t);
}
....
}
private IEnumerator UpdateDisplayPhrase(string text, TextMesh t)
{
// this should actually be impossible to happen
// but just in case ignore this call if a routine is already running
if(isUpdatingDisplay) yield brake;
// block multiple calls
isUpdatingDisplay = true;
// you can simply yield IEnumerators so they are executed and at the same time
// wait until finished
yield return FadeTextToZeroAlpha(1, t);
t.text = "Hello";
// NOTE: you pass in 0
// -> DIVIDING BY 0 ?!
yield return FadeTextToFullAlpha(0, t);
// when done reset the blocking flag
isUpdatingDisplay = false;
}
public IEnumerator FadeTextToFullAlpha(float t, TextMesh i)
{
i.color = new Color(i.color.r, i.color.g, i.color.b, 0);
while (i.color.a < 1.0f)
{
// DIVIDING BY 0 ?!
i.color = new Color(i.color.r, i.color.g, i.color.b, i.color.a + (Time.deltaTime / t));
yield return null;
}
}
public IEnumerator FadeTextToZeroAlpha(float t, TextMesh i)
{
i.color = new Color(i.color.r, i.color.g, i.color.b, 1);
while (i.color.a > 0.0f)
{
i.color = new Color(i.color.r, i.color.g, i.color.b, i.color.a - (Time.deltaTime / t));
yield return null;
}
}
注意
您正在呼叫
FadeTextToFullAlpha(0, t);
但在FadeTextToFullAlpha(float t, TextMesh i)
使用
Time.deltaTime / t
您应该强烈避免除以0
;)
您可以仅使用一种方法对其进行重构,并使其更有效率,例如(也习惯于使用正确的变量名!然后我会使用允许额外缓入和缓出的Color.Lerp
public IEnumerator FadeTextTo(float targetAlpha, float maxDuration, TextMesh textMesh)
{
// more efficient to get both colors beforehand
var fromColor = textMesh.color;
var toColor = new Color(fromColor.r, fromColor.g, fromColor.b, targetAlpha);
// this is optional ofcourse but I like to do this in order to
// always have the same fading speed even if it is already slightly faded into one direction
var actualDuration = maxDuration * Mathf.Abs(fromColor.a - toColor.a);
var passedTime = 0f;
while (passedTime < actualDuration)
{
var lerpFactor = passedTime / actualDuration;
// now the huge advantage is that you can add ease-in and -out if you like e.g.
//lerpFactor = Mathf.SmoothStep(0, 1, lerpFactor);
i.color = Color.Lerp(fromColor, toColor, lerpFactor);
// avoid overshooting
passedTime += Mathf.Min(Time.deltaTime, actualDuration - passedTime);
yield return null;
}
// just to be sure in the end always set it once
i.color = toColor;
}
现在0
师也没有麻烦了