Bentoon
Bentoon

Reputation: 79

Unity3D for Google Cardboard

I have a VR Scene with a C# Script on the camera that allows the user to Click Once to move and again to stop.

    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;
        }
    }

What I want to know is how I can CLICK & HOLD to move Backwards..? Thank you!

~ b

Upvotes: 1

Views: 165

Answers (2)

Programmer
Programmer

Reputation: 125445

Use enum the represent the status of the mouse instead of startedMoving or multiple booleans that will make everything easier to implement. The comment in the code describes how it works.

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
}

Upvotes: 2

Rob
Rob

Reputation: 7099

Because you only have one trigger action you're going to have to implement something time based for toggling forward/backwards movement. For example, if you press and release the trigger quickly then forward walk could be toggled, but if you're holding the trigger after N length of time then walk backwards.

He's a practical example to get you starting.

  • Pressing and releasing the trigger within 300ms will toggle forward movement
  • Pressing and holding the trigger for longer than 300ms will begin backwards movement, releasing the trigger then will stop backwards movement

This is a theoretical example

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;
    }

}

Upvotes: 1

Related Questions