简体   繁体   English

如何淡入/淡出textmesh? 不工作

[英]How can I fade the textmesh in/out ? Not working

At top : 在顶部:

private Vector3 lastFwd;
private float curAngleX = 0;

In Start : 在开始时:

private void Start()
{
    lastFwd = transform.forward;
}

In Update : 在更新中:

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));
    }
}

The Fade methods : 淡入淡出方法:

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;
    }
}

What I want to do is to start fading from 1 to 0 while it's 0 to change the t variable text for example : 我想做的是从1到0开始淡入淡出,而改变t变量文本则为0,例如:

t.text = "Hello";

And then to fade back from 0 to 1. 然后从0变回1。

But it's not making the fade. 但这并没有消退。 If I leave only the line from 1 to 0 it will fade the text. 如果我只保留从1到0的行,它将使文本褪色。 But when the two lines are exist it's not fading at all. 但是,当两条线同时存在时,它根本不会消失。 The text is the same. 文字是一样的。

The complete script : 完整的脚本:

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;
    }
}

The main goal is while the object is rotating to fade out/in the text and while fading to change the text. 主要目标是当对象旋转以淡出/淡入文本时以及淡入淡出以更改文本时。

All these calls 所有这些电话

StartCoroutine(FadeTextToZeroAlpha(1, t));
t.text = "Hello";
StartCoroutine(FadeTextToFullAlpha(0, t));

happen at the same time so you have concurrent routines. 同时发生,因此您有并发例程。

Additionally this might be called in multiple consequent frames -> you should also do it only once! 另外,这可能会在多个后续帧中调用->您也应该只执行一次!

You should pack this into one single routine like 您应该将其打包到一个例程中,例如

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;
    }
}

NOTE 注意

you are calling 你在打电话

FadeTextToFullAlpha(0, t);

but in FadeTextToFullAlpha(float t, TextMesh i) using 但是在FadeTextToFullAlpha(float t, TextMesh i)使用

Time.deltaTime / t

you should strongly avoid dividing by 0 ;) 您应该强烈避免除以0 ;)


You could refactor this a bit using only one method and making it more efficient like (also get used to use proper variable names!). 您可以仅使用一种方法对其进行一点重构,使其效率更高(例如,也习惯使用适当的变量名!)。 I would then use Color.Lerp which allows additional easing-in and -out 然后,我将使用Color.Lerp ,它允许额外的缓入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;
}

Now there is also no trouble with 0 division anymore 现在0除也不再有麻烦了

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM