简体   繁体   English

按下按钮即可执行功能(unity3d / C#)

[英]Execute function on button press (unity3d/C#)

Basically, what I'm trying to do is when pressing Z - it executes function to spin, and X - it executes function to stop spinning. 基本上,我想做的是按下Z键-它执行旋转功能,而X键-执行停止旋转功能。 Before, I had UI buttons which worked perfectly fine, now I try doing it by button but nothing happens. 以前,我的UI按钮工作得很好,现在我尝试通过按钮进行操作,但没有任何反应。

Also, if you can suggest on how to make it start spinning and stop spinning by only pressing "Space" button, that'd be great. 另外,如果您可以仅按“空格”按钮就如何开始旋转和停止旋转提出建议,那就太好了。

Heres my code so far: 到目前为止,这是我的代码:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class spin : MonoBehaviour
{
    public float speed = 500f;
    public Button starter;
    public Button stopper;
    bool isSpinning = false;

    IEnumerator spinnerCoroutine;

    void Start()
    {
        //The spin function
        spinnerCoroutine = spinCOR();

        //Button btn = starter.GetComponent<Button>();
        //Button butn = stopper.GetComponent<Button>();

        //butn.onClick.AddListener(FidgetSpinnerStop);
        //btn.onClick.AddListener(FidgetSpinnerStart);


        if (Input.GetKey(KeyCode.Z)) {

            FidgetSpinnerStart();
        }

        if (Input.GetKey(KeyCode.X)) {
            FidgetSpinnerStop();
        }
    }

    IEnumerator spinCOR()
    {
        //Spin forever untill FidgetSpinnerStop is called 
        while (true)
        {
            transform.Rotate(Vector3.up, speed * Time.deltaTime);
            //Wait for the next frame
            yield return null;
        }
    }

    void FidgetSpinnerStart()
    {
        //Spin only if it is not spinning
        if (!isSpinning)
        {
            isSpinning = true;
            StartCoroutine(spinnerCoroutine);
        }
    }

    void FidgetSpinnerStop()
    {
        //Stop Spinning only if it is already spinning
        if (isSpinning)
        {
            StopCoroutine(spinnerCoroutine);
            isSpinning = false;
        }
    }
}

Thanks. 谢谢。

Your input logic is only executed once, when Start() is executed. 当执行Start()时,您的输入逻辑仅执行一次。

Put it in the Update() method to check for it every frame. 将其放在Update()方法中以检查每一帧。

In this case remove the coroutine and put its logic (without the while -loop) into the Update() method aswell. 在这种情况下,请删除协程并将其逻辑(不带while -loop)也放入Update()方法中。

public class spin : MonoBehaviour
{
    [SerializeField]
    private float speed = 500f;

    [SerializeField]
    private Button starter;

    [SerializeField]
    private Button stopper;

    [SerializeField]
    bool isSpinning = false;

    void Update()
    {    
        if (Input.GetKeyDown(KeyCode.Z))
        {
            isSpinning = true ;
        }

        if (Input.GetKeyDown(KeyCode.X))
        {
            isSpinning = false ;
        }

        if( isSpinning )
        {
             transform.Rotate(Vector3.up, speed * Time.deltaTime)
        }
    }
}

Further reading 进一步阅读

There are just two problems in your code: 您的代码中只有两个问题:

1 .Checking the keypress in the Start() function. 1。检查Start()函数中的按键。

The Start() will be called once while the Update() function will be called every frame. Start()将被调用一次,而Update()函数将在每一帧被调用。

You need to use the Update() function to constantly poll the input every frame. 您需要使用Update()函数在每个帧中不断轮询输入。

2 .Using Input.GetKey() function to check for keypress. 2。使用Input.GetKey()函数检查按键。

The Input.GetKey() function can return true multiple times over several frames. Input.GetKey()函数可以在几帧中多次返回true。 While you may not see any problems now, that's because the isSpinning variable is preventing possible problems but you will run into problems if you want to add more code directly inside the if (Input.GetKey(KeyCode.Z)) code because those code will execute multiple times in a frame. 虽然您现在可能看不到任何问题,但这是因为isSpinning变量可以防止可能的问题,但是如果您想直接在if (Input.GetKey(KeyCode.Z))代码内添加更多代码,则会遇到问题。在一个框架中执行多次。

You need to use the Input.GetKeyDown() function. 您需要使用Input.GetKeyDown()函数。

public class spin : MonoBehaviour
{
    public float speed = 500f;
    public Button starter;
    public Button stopper;
    bool isSpinning = false;

    IEnumerator spinnerCoroutine;

    void Start()
    {
        spinnerCoroutine = spinCOR();
    }

    void Update()
    {    
        if (Input.GetKeyDown(KeyCode.Z)) {

            FidgetSpinnerStart();
        }

        if (Input.GetKeyDown(KeyCode.X)) {
            FidgetSpinnerStop();
        }
    }

    IEnumerator spinCOR()
    {
        //Spin forever until FidgetSpinnerStop is called 
        while (true)
        {
            transform.Rotate(Vector3.up, speed * Time.deltaTime);
            //Wait for the next frame
            yield return null;
        }
    }

    void FidgetSpinnerStart()
    {
        //Spin only if it is not spinning
        if (!isSpinning)
        {
            isSpinning = true;
            StartCoroutine(spinnerCoroutine);
        }
    }

    void FidgetSpinnerStop()
    {
        //Stop Spinning only if it is already spinning
        if (isSpinning)
        {
            StopCoroutine(spinnerCoroutine);
            isSpinning = false;
        }
    }
}

Also, if you can suggest on how to make it start spinning and stop spinning by only pressing "Space" button, that'd be great 另外,如果您可以仅按“空格”按钮就如何开始旋转和停止旋转提出建议,那将是很好的选择

You can do that with KeyCode.Space . 您可以使用KeyCode.Space做到这KeyCode.Space Check if Space key is pressed then check the isSpinning variable before starting/stopping the coroutine. 检查是否按下空格键,然后在启动/停止协程之前检查isSpinning变量。

Just replace the Update function above with the one below: 只需将下面的Update功能替换为下面的一个:

void Update()
{
    //Start if Space-key is pressed AND is not Spinning
    if (Input.GetKeyDown(KeyCode.Space) && !isSpinning)
    {
        FidgetSpinnerStart();
    }

    //Stop if Space-key is pressed AND is already Spinning   
    else if (Input.GetKeyDown(KeyCode.Space) && isSpinning)
    {
        FidgetSpinnerStop();
    }
}

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

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