Unity键按此键启动和停止

时间:2017-07-04 22:54:16

标签: c# unity3d unity5

我不确定我的代码中缺少什么,有人可以帮忙吗?我想按空格键开始重复Blink功能(显然还有其他一些东西),然后再次按空格键停止并继续进入另一个状态。使用下面的代码,按空格键将开始重复闪烁功能,但再次按空格键无效。

    private bool isDown = false;

void Update () {
    if(Input.GetKeyDown (KeyCode.Space)) {
    if (isDown) {
        CancelInvoke("Blink");
        SetState (LightStates.GREEN);
        isDown = false; 
        }
    else {
        SetState (LightStates.OFF);
        GameObject.Find ("GreenLight").GetComponent<Renderer>().material.color = Color.grey;
        InvokeRepeating ("Blink", 0f, 0.1f);
        isDown = true; 
        }
    }
}
编辑:也许我对“按钮”一词的使用被误解了。我很欣赏coroutine的建议,但我想知道如何在按键上启动一个功能,并在同一个键的按键上停止操作。将函数更改为协程并没有让它工作,因为我仍然不知道如何实现按键来启动/停止协程。

最终结果是一样的。按空格键开始操作,再次按下它不会做任何事情。

bool isBlinking = false;
IEnumerator blinkCoroutine;

Renderer yellowLight;

void Start()
{
    blinkCoroutine = blinkCOR();

    //CACHE THE Renderer COMPONENT 
    yellowLight = GameObject.Find("YellowLight").GetComponent<Renderer>()
}

void Update() {
    if (Input.GetKeyDown (KeyCode.Space) && !isBlinking) { 
        BlinkStart();
    } else if (Input.GetKeyDown (KeyCode.Space) && isBlinking) {
        BlinkStop();
    }
}

IEnumerator blinkCOR()
{
    SetState (LightStates.OFF);

    //Everything in the while loop will be called every frame until stopped
    while (true)
    {
        yellowLight.material.color = Color.Lerp(Color.grey, Color.yellow, Mathf.PingPong(Time.time, 1));
        //Wait for the next frame
        yield return null;
    }
}

void BlinkStart()
{
    if (!isBlinking)
    {
        isBlinking = true;
        StartCoroutine(blinkCoroutine);
    }
}

void BlinkStop()
{
    if (isBlinking)
    {
        StopCoroutine(blinkCoroutine);
        isBlinking = false;

        //Restore old state
        SetState (LightStates.GREEN);
    }
}

编辑:完整代码。这是一个状态机,用于切换计时器上的交通灯颜色。在LightStates.RED中,用户应该能够按空格键关闭所有“灯光”并让黄灯从灰色变为黄色。再次按空格键时,状态机应在StateGreen功能中以绿色“灯”重新启动。

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

public class TrafficLightScriptMachine : MonoBehaviour {

private TrafficLight trafficLight;
private LightStates curState = LightStates.OFF;
private Dictionary<LightStates, Action> dic = new Dictionary<LightStates, Action>();

private bool isDown = false;
bool isBlinking = false;
IEnumerator blinkCoroutine;

// Use this for initialization
void Start () {

    trafficLight = GetComponent<TrafficLight>();
    dic.Add (LightStates.OFF, new Action (StateOff));
    dic.Add (LightStates.RED, new Action (StateRed));
    dic.Add (LightStates.YELLOW, new Action (StateYellow));
    dic.Add (LightStates.GREEN, new Action (StateGreen));

    SetState (LightStates.RED);
    blinkCoroutine = blinkCOR();

    GameObject.Find ("GreenLight").GetComponent<Renderer>().material.color = Color.grey;
    GameObject.Find ("RedLight").GetComponent<Renderer>().material.color = Color.grey;
    GameObject.Find ("YellowLight").GetComponent<Renderer>().material.color = Color.grey;


}



// Update is called once per frame
void Update () {

    dic[curState].Invoke();


        if (curState == LightStates.RED && Input.GetKeyDown (KeyCode.Space) && !isBlinking) { 
            BlinkStart();
        } else if (Input.GetKeyDown (KeyCode.Space) && isBlinking) {
            BlinkStop();
        }
}

IEnumerator blinkCOR()
{
    SetState (LightStates.OFF);
    while (true)
    {

        GameObject.Find ("GreenLight").GetComponent<Renderer>().material.color = Color.grey;
        GameObject.Find ("YellowLight").GetComponent<Renderer>().material.color = Color.Lerp(Color.grey, Color.yellow, Mathf.PingPong(Time.time, 1));
        //Wait for the next frame
        yield return null;
    }
}

void BlinkStart()
{
    if (!isBlinking)
    {
        isBlinking = true;
        StartCoroutine(blinkCoroutine);
    }
}

void BlinkStop()
{
    if (isBlinking)
    {
        StopCoroutine(blinkCoroutine);
        isBlinking = false;
        SetState (LightStates.GREEN);
    }
}

public enum LightStates
{
    OFF,
    RED,
    YELLOW,
    GREEN,

    NUM_STATES
}

public void StateRed ()
{
    // if the time passed since reset is greater than the red switch time then switch to yellow state
    if ((trafficLight.GetLightTime()) > (trafficLight.GetRedLight()))
    {
        GameObject.Find ("GreenLight").GetComponent<Renderer>().material.color = Color.grey;
        GameObject.Find ("RedLight").GetComponent<Renderer>().material.color = Color.red;
        // switch to yellow state
        SetState (LightStates.YELLOW);
        trafficLight.ResetTimeSinceLastTransition();
    }
}

public void StateYellow ()
{
    // If the time since the last light transition is greater than the time to stay yellow, transition to green
    if ((trafficLight.GetLightTime()) > (trafficLight.GetYellowLight()))
    {
        GameObject.Find ("RedLight").GetComponent<Renderer>().material.color = Color.grey;
        GameObject.Find ("YellowLight").GetComponent<Renderer>().material.color = Color.yellow;
        // switch to green state
        SetState (LightStates.GREEN);
        trafficLight.ResetTimeSinceLastTransition();
    }
}

public void StateGreen ()
{
    // If the time since the last light transition is greater than the time to stay green, transition to red.
    if ((trafficLight.GetLightTime()) > (trafficLight.GetGreenLight()))
    {
        GameObject.Find ("YellowLight").GetComponent<Renderer>().material.color = Color.grey;
        GameObject.Find ("GreenLight").GetComponent<Renderer>().material.color = Color.green;
        SetState (LightStates.RED);
        trafficLight.ResetTimeSinceLastTransition();
    }
}

public void StateOff ()
{
    gameObject.GetComponent<Renderer>().material.color = Color.grey;
}

public void SetState (LightStates newState)
{
    curState = newState; 
}

}

0 个答案:

没有答案