Google 纸板的 Unity3D

Unity3D for Google Cardboard

我在相机上有一个带有 C# 脚本的 VR 场景,允许用户单击一次移动并再次单击停止。

    public float speed = 1.0f;
public bool startedMoving = true;
public GameObject myCam;


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

        if (startedMoving) {
            transform.position += myCam.transform.forward * speed * Time.deltaTime;
        }

//      if(Input.GetButtonDown("Fire1")){
        if (Input.GetMouseButton(0)){
            startedMoving = !startedMoving;
        }
    }

我想知道如何点击并按住向后移动..? 谢谢!

~b

因为您只有一个触发动作,所以您将不得不实施一些基于时间的动作来切换 forward/backwards 移动。例如,如果您快速按下并释放扳机,则可以切换向前行走,但如果您在 N 时间长度后按住扳机,则向后行走。

他是帮助您入门的实际示例。

  • 在 300 毫秒内按下并释放扳机将触发向前移动
  • 按住扳机超过300毫秒将开始向后运动,松开扳机将停止向后运动

这是一个理论例子

public float speed = 1.0f;
bool triggerPressed = false;
float triggerHeldTime = 0f;
public bool movingForwards = false;
public bool movingBackwards = false;


void Update ()
{
    // increment hold time if we're still holding trigger
    if (Input.GetMouseButton(0) && triggerPressed)
        triggerHeldTime += Time.deltaTime;

    if (Input.GetMouseButton(0) && !triggerPressed)
    {
        // reset everything when trigger initially pressed
        movingForards = false;
        movingBackwards = false;  
        triggerHeldTime = 0f;
        triggerPressed = true;
    }
    else if (!Input.GetMouseButton(0) && triggerPressed)
    {
        // upon trigger release

        triggerPressed = false;

        // if we are not moving backwards, toggle forwards movement
        if(!movingBackwards)
            movingForwards = !movingForwards;

        // always reset backwards movement when we release the trigger
        movingBackwards = false;
        triggerHeldTime = 0f;
    }

    // if the trigger has been held for 300ms then move backwards
    if(triggerHeldTime > 0.3f)
    {
        moveForwards = false;
        moveBackwards = true;
    }


    // actually perform the movement
    if (moveForwards)
    {
        transform.position += myCam.transform.forward * speed * Time.deltaTime;
    }
    else if(moveBackwards)
    {
        transform.position -= myCam.transform.forward * speed * Time.deltaTime;
    }

}

使用 enum 表示鼠标状态,而不是 startedMoving 或多个 booleans,这将使一切 更容易 实施。代码中的注释 描述了 它是如何工作的。

using UnityEngine;
using System.Collections;

public class ClickAndHeld : MonoBehaviour
{
    public GameObject myCam;
    CLICK_MODE clickMode = CLICK_MODE.NO_CLICK;
    MOVE_DIRECTION moveDir = MOVE_DIRECTION.IDLE;

    public float speed = 1.0f;


    //If down for 0.5 secods the it is considered Click and Hold instead of Click
    float clickHoldDetectTime = 0.5f;
    float clickCounter = 0; //Dont not change

    void Start()
    {
        StartCoroutine(mover());
    }

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

        if (Input.GetMouseButton(0))
        {

            //If in NO_CLICK, set to CLICKED
            if (clickMode == CLICK_MODE.NO_CLICK)
            {
                //Change the mode to CLICKED
                clickMode = CLICK_MODE.CLICKED;
            }

            //If in CLICKED mode, start counting to clickHoldDetectTime
            if (clickMode == CLICK_MODE.CLICKED)
            {
                clickCounter += Time.deltaTime; //Increment counter

                //Check if we have reached the clickHoldDetectTime time
                if (clickCounter > clickHoldDetectTime)
                {
                    //Reset Counter
                    clickCounter = 0;

                    //Change the mode to CLICK_AND_HELD
                    clickMode = CLICK_MODE.CLICK_AND_HELD;
                }
            }

            //If STILL down and the the current mode is CLICK_AND_HELD then do clickedAndHeldDown stuff
            if (clickMode == CLICK_MODE.CLICK_AND_HELD)
            {
                clickedAndHeldDown();
            }
        }
        else
        {
            //If released and the current mode is CLICKED then do clicked stuff
            if (clickMode == CLICK_MODE.CLICKED)
            {
                clicked();
            }

            //If released and the current mode is CLICK_AND_HELD, change to RELEASED then do relased stuff
            if (clickMode == CLICK_MODE.CLICK_AND_HELD)
            {
                //Change the mode to RELEASED
                clickMode = CLICK_MODE.RELEASED;
                mouseReleasedAfterBeingHeld();
            }


            //Reset each time mouse button is released
            reset();
        }

    }

    IEnumerator mover()
    {
        while (true)
        {

            if (moveDir == MOVE_DIRECTION.IDLE)
            {

            }

            //Move Forward
            if (moveDir == MOVE_DIRECTION.FORWARD)
            {

                transform.position += myCam.transform.forward * speed * Time.deltaTime;
            }

            //Move Backward
            if (moveDir == MOVE_DIRECTION.BACKWARD)
            {
                transform.position -= myCam.transform.forward * speed * Time.deltaTime;
            }
            yield return null;
        }
    }

    private void clicked()
    {
        Debug.Log("CLICKED");

        //If Idle, become Forward
        if (moveDir == MOVE_DIRECTION.IDLE)
        {
            moveDir = MOVE_DIRECTION.FORWARD;
        }

        //If forward, moves become idle
        else if (moveDir == MOVE_DIRECTION.FORWARD)
        {
            moveDir = MOVE_DIRECTION.IDLE;
        }

         //--------------------------------------------------
        //If backward, moves become idle
        else if (moveDir == MOVE_DIRECTION.BACKWARD)
        {
            moveDir = MOVE_DIRECTION.IDLE;
        }
    }

    private void clickedAndHeldDown()
    {
        Debug.Log("CLICKED AND HELD");

        //If Idle, becomes backward
        if (moveDir == MOVE_DIRECTION.IDLE)
        {
            moveDir = MOVE_DIRECTION.BACKWARD;
        }
    }


    //Called when released after being RELEASED from CLICKED_HELD
    private void mouseReleasedAfterBeingHeld()
    {
        Debug.Log("RELEASED AFTER CLICKED AND HELD");

        //If backward, move becomes idle
        if (moveDir == MOVE_DIRECTION.BACKWARD)
        {
            moveDir = MOVE_DIRECTION.IDLE;
        }

        //--------------------------------------------------
        //If forward, move becomes idle
        else if (moveDir == MOVE_DIRECTION.FORWARD)
        {
            moveDir = MOVE_DIRECTION.IDLE;
        }
    }

    void reset()
    {
        clickMode = CLICK_MODE.NO_CLICK;
        clickCounter = 0;
    }
}

public enum CLICK_MODE
{
    NO_CLICK, CLICKED, CLICK_AND_HELD, RELEASED
}

public enum MOVE_DIRECTION
{
    IDLE, FORWARD, BACKWARD
}