【问题标题】:Unity 3d Invokerepeating for blinking Images用于闪烁图像的 Unity 3d Invokerepeating
【发布时间】:2020-05-29 23:22:22
【问题描述】:

我正在开发一个汽车游戏项目。我制作了一个 UI 面板,其中有两个 UI 图像(Left_Image 和 Right_Image)。当我按下“左”按钮时,Left_Image 开始闪烁,当我按下“右”按钮时,Right_Image 开始闪烁。但我想要的是,如果 Right_Image 已经闪烁并且我按下“左”按钮,那么 Left_Image 开始闪烁但 Right_Images 应该停止。我已经尝试了所有技巧,但没有运气。请帮忙。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Indicators_UI : MonoBehaviour {

    public GameObject flash_right;
    public GameObject flash_left;

    public float interval;

    void Start()
    {
        InvokeRepeating("RightFlash", 0, interval);
        InvokeRepeating("LeftFlash", 0, interval);
    }

    void Update ()
    {
        if (ControlFreak2.CF2Input.GetAxis ("right") != 0) {

            if (!IsInvoking("RightFlash"))
                InvokeRepeating("RightFlash", 0.35f, 0.35f);
        } 
        else
        {
            CancelInvoke("RightFlash");
        }
        if (ControlFreak2.CF2Input.GetAxis ("left") != 0) {
            if (!IsInvoking("LeftFlash"))
                InvokeRepeating("LeftFlash", 0.35f, 0.35f);
        } 
        else
        {
            CancelInvoke("LeftFlash");
        }
    }

    void RightFlash()
    {
        if(flash_right.activeSelf)
            flash_right.SetActive(false);
        else
            flash_right.SetActive(true);
    }

    void LeftFlash()
    {
        if(flash_left.activeSelf)
            flash_left.SetActive(false);
        else
            flash_left.SetActive(true);
    }
}

【问题讨论】:

  • 为什么不只是添加一个布尔值并拥有 flashleft、flashright 并相应地设置和使用它们

标签: c# unity3d user-interface 3d repeat


【解决方案1】:

感谢derHugo...我认为问题在于切换状态,如果:

if (ControlFreak2.CF2Input.GetAxis ("left") != 0) {

ControlFreak2.CF2Input.GetAxis(“右”)!= 1

} 但我得到错误:只有赋值、调用、递增、递减、等待和新对象表达式可以用作语句

【讨论】:

  • 请看我更新的答案。此外,这似乎是一条评论,可能不应该作为答案发布
  • 得到意外的符号 `CancelInvoke'
  • 修复了 CancelInvoke 但现在无法使用 nameof 运算符,因为它不是 C# 4.0 语言规范的一部分
  • 您使用什么 Unity 版本?我们目前正在支持 c#7.0 ...
【解决方案2】:

一般不要InvokeRepeating 等与string 一起使用!通过名称调用方法不是很容易维护。如果您想使用它们,请至少使用nameof 以确保名称没有拼写错误。

那你就不能这样做

void Update ()
{
    if (ControlFreak2.CF2Input.GetAxis ("right") != 0) 
    {
        if (!IsInvoking(nameof(RightFlash)))
        {
            if(IsInvoking(nameof(LeftFlash)) CancelInvoke(nameof(LeftFlash));

            InvokeRepeating(nameof(RightFlash), 0.35f, 0.35f);
        }
    } 
    else
    {
        CancelInvoke(nameof(RightFlash));
    }

    if (ControlFreak2.CF2Input.GetAxis ("left") != 0) 
    {
        if (!IsInvoking(nameof(LeftFlash)))
        {
            if(IsInvoking(nameof(RightFlash)) CancelInvoke(nameof(RightFlash));

            InvokeRepeating(nameof(LeftFlash), 0.35f, 0.35f);
        }
    } 
    else
    {
        CancelInvoke(nameof(LeftFlash));
    }
}

// Btw: These you can implement way shorter this way ;)
void RightFlash()
{
    flash_right.SetActive(!flash_right.activeSelf);
}

void LeftFlash()
{
    flash_left.SetActive(!flash_left.activeSelf);
}

在您的情况下,我实际上宁愿使用简单的计时器,因为无论如何您都需要 Update 方法来获取用户输入,所以为什么要过于复杂:

private float timerLeft;
private float timerRight;

void Update ()
{
    if (ControlFreak2.CF2Input.GetAxis ("right") != 0) 
    {
        timerRight -= Time.deltaTime;
        if (timerRight <= 0)
        {
            timerRight = interval;

            RightFlash();
        }
    }
    // simply make them exclusive so only one button is handled at a time
    // if you press both at the same time right overrules
    else if (ControlFreak2.CF2Input.GetAxis ("left") != 0) 
    {
        timerLeft -= Time.deltaTime;
        if (timerLeft <= 0)
        {
            timerLeft = interval;

            LeftFlash();
        }
    } 
}

void RightFlash()
{
    flash_right.SetActive(!flash_right.activeSelf);
}

void LeftFlash()
{
    flash_left.SetActive(!flash_left.activeSelf);
}

【讨论】:

    猜你喜欢
    • 2010-10-29
    • 2012-08-22
    • 2015-04-25
    • 2012-05-13
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2021-03-03
    • 1970-01-01
    相关资源
    最近更新 更多