【问题标题】:How to fade out / disapear a GameObject slowly?如何慢慢淡出/消失游戏对象?
【发布时间】:2019-05-31 06:13:38
【问题描述】:

我有一个必须让一些游戏对象消失的功能,此时我使用 SetActive(false) 但它不应该立即消失,它应该在 2 或 3 秒内慢慢消失。我想不透明度应该慢慢变成透明或类似的东西......

public void SlotCheck(string gemColor,GameObject slotColor,GameObject 
puzzleStuk,ref int scoreGem,ref bool Visibility)
{
if (DragHandler2.itemBegingDragged.name.Contains(gemColor)
DragHandler2.itemBegingDragged.transform.parent.name == "green_small_b")
     {
         Visibility=false;
         puzzleStuk.SetActive(Visibility);
         slotColor.SetActive(false);
         DragHandler2.itemBegingDragged.SetActive(false);
         scoreGem--;
     }

 }

【问题讨论】:

  • 随时间改变不透明度(在Update 或使用协程) - 你必须自己编写代码

标签: c# unity3d visibility opacity gameobject


【解决方案1】:

你可以得到一个GameObject的Renderer组件,然后在Update()中逐渐改变颜色的alpha。

例如:

Renderer renderer;

void Start() {
    renderer  = GetComponent<Renderer>();
}

void Update() {
    Color oldCol = renderer.material.color;
    Color newCol = new Color(oldCol.r, oldCol.g, oldCol.b, oldCol.a - 0.01f);
    renderer.material.color = newCol;
}

当然,您不应该使用像0.01f 这样的硬编码值,而应该使用来自检查器的值。这也应该乘以Time.deltaTime,以免淡出速度基于FPS。

在此示例中,某些名称或类似名称可能不是 100% 正确,但它应该让您知道要查看 Unity API documentation 的哪个部分。

【讨论】:

  • 我正在尝试在上面的函数中使用游戏对象的渲染器测试基本代码。 puzzleStuk.GetComponent().material.color = Color.red;它不工作我没有看到游戏对象改变它的颜色。
  • 以下代码也不起作用 rend = puzzleStuk.GetComponent(); rend.enabled = false;
【解决方案2】:

您可以将CoroutineColor.Lerp 结合使用,以随着时间的推移降低所有材质的 alpha 值。

(我假设您的意思是这里的渲染器网格不是 UI 的东西,但这也可以以类似的方式工作)

// How long should fading take (in seconds)
public float fadingDuration = 1;

// For storing Renderer components
private Renderer[] renderers;

// For storing original color data
private List<Color> originalColors = new List<Color>();

// For storing FadeOut color data
// (= Original data with alpha=0)
private List<Color> fadeOutColors = new List<Color>();

private void Awake() {
    // Get all renderers, own and children
    renderers  = GetComponentInChildren<Renderer>(true);

    // Run through renderers
    foreach(var rend in renderers)
    {
        // Run through all materials
        foreach (vat mat in rend.materials)
        {
            // Get original color
            var color = mat.color;
            // Add to original list
            originalColors.Add(color);

            // Get fadeout color (alpha 0)
            var fadeoutColor = new Color(color.r, color.g, color.b, 0);

            // Add to fadeout list
            fadeoutColors.Add(fadeOutColor);
    } 
}

// Call this to start fading
public void StartFadeout()
{
    StartCoroutine(FadeOut());
}

private IEnumerator FadeOut()
{
    var timePassed = 0;

    while(timePassed < fadingDuration)
    {
        // Get factor between 0 and 1 depending on passed time
        var lerpFactor = timePassed / fadingDuration;

        // Run through all renderers
        int colorIndex = 0;
        foreach(var rend in renderers)
        {
            // Run through all materials
            foreach (vat mat in rend.materials)
            {
                // Set color interpolated between original and FadeOut color depending on lerpFactor
                mat.color = Color.Lerp(originalColors[colorIndex], fadeOutColors[colorIndex], lerpFactor);

                // Count up index
                colorIndex++;
            }
        }

        // Add time passed since last frame
        timePassed += Time.deltaTime;

        // return to render the frame and continue from here in the next frame
        yield return null;
    }

    // In the end just to be sure apply the final target values (FadeOut colors)
    // Alternatively you could also deactivate/destroy the object here

    // Run through all materials
    int colorIndex = 0;
    foreach(var rend in renderers)
    {
        // Run through all materials
        foreach (vat mat in rend.materials)
        {
            // Set color to final FadeOut value
            mat.color = fadeOutColors[colorIndex];

            // Count up index
            colorIndex++;
        }
    } 
}

请注意,要在所有材质上使用透明度,必须使用支持透明度的着色器。


但这可能不是关于性能的最佳解决方案。特别是由于多个渲染器可能引用相同的材​​质,因此在当前示例中可能存在一些冗余。

但是,如果您无论如何只有一个渲染器和一种材质,您可以稍微调整代码并跳过所有循环;)

【讨论】:

    【解决方案3】:

    正如之前的答案所述,您可以轻松操作

    meshrenderer.material.color=new Color (,,,x);

    要添加的一个重要细节是需要在透明队列中设置材质(并支持透明度)。这是通过材质检查器中的下拉菜单实现的,用于标准表面着色器,但必须在自定义着色器中通过使用一个负 alpha 混合模式和自定义着色器中的透明队列来处理

    Tags {"Queue"="Transparent" "RenderType"="Transparent" }

    Blend SrcAlpha OneMinusSrcAlpha

    【讨论】:

    • 我在函数中使用以下代码来测试游戏对象的渲染器。 puzzle_1.GetComponentInChildren().material.color = Color.red; Puzzle_1 是一个游戏对象,通常应在调用该函数后将其颜色更改为红色。但它没有响应它什么都没有改变......
    【解决方案4】:

    这是我使用协程的方法。

    void Awake()
    {
        StartCoroutine(FadeOutMaterial(1f));
    }
    
    IEnumerator FadeOutMaterial(float fadeSpeed)
    {
        Renderer rend = objectToFade.transform.GetComponent<Renderer>();
        Color matColor = rend.material.color;
        float alphaValue = rend.material.color.a;
    
        while (rend.material.color.a > 0f)
        {
            alphaValue -= Time.deltaTime / fadeSpeed;
            rend.material.color = new Color(matColor.r, matColor.g, matColor.b, alphaValue);
            yield return null;
        }
        rend.material.color = new Color(matColor.r, matColor.g, matColor.b, 0f);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多