Virtual joystick for Input.GetKey - C#

Hi guys. I have a project going on where I control a flying object. It does not move on the y-axis, but it is able to move both on the x-axis and the z-axis.

What I want to achieve is to add a virtual joystick for mobile use. How would I go about doing this? I have only seen tutorials for this using GetAxis (“Horizontal/Vertical”).

Here is my script for it:

PlaneController2 : MonoBehaviour {

    public Animator theAnimator;

    float acceleration = 0.0f;

    public Text speedText;

    public GameObject breakLights;
    public GameObject speedLights;

    // Use this for initialization
    void Start ()
    {
        theAnimator = GetComponentInChildren <Animator> ();
        acceleration = 15.0f;
        speedText.text = "Speed: " + Mathf.Round (acceleration);
    }
   
    // Update is called once per frame
    void Update ()
    {
        MovePlane ();
        RotatePlane ();
        speedText.text = "Speed: " + Mathf.Round (acceleration);
    }

    void MovePlane ()
    {
        if (Input.GetKey (KeyCode.UpArrow))
        {
            if (acceleration < 25.0f)
            {
                acceleration += 0.1f;
            }
       
            speedLights.SetActive (true);

        }

        else
        {
            speedLights.SetActive (false);
        }

        if (Input.GetKey (KeyCode.UpArrow) && !Input.GetKey (KeyCode.LeftArrow) && !Input.GetKey (KeyCode.RightArrow))
        {
            if (acceleration < 25.0f)
            {
                acceleration += 0.1f;
            }

            PlaneIdle ();
        }

        if (Input.GetKey (KeyCode.DownArrow))
        {
            if (acceleration > 15.0f) {
                acceleration -= 0.1f;
        }
            breakLights.SetActive (true);
        }

        else
        {
            breakLights.SetActive (false);
        }

        if (Input.GetKey (KeyCode.DownArrow) && !Input.GetKey (KeyCode.LeftArrow) && !Input.GetKey (KeyCode.RightArrow))
        {
            if (acceleration < 15.0f)
            {
                acceleration -= 0.1f;
            }

            PlaneIdle ();
        }



        if (!Input.GetKey (KeyCode.UpArrow) && !Input.GetKey (KeyCode.DownArrow))
            {
            if (acceleration > 20.0f)
            {
                acceleration -= 0.1f;
            }

            if (acceleration < 20.0f)
            {
                acceleration += 0.1f;
            }
               
                PlaneIdle ();

            }

        transform.Translate (transform.forward * acceleration * Time.deltaTime, Space.World);
    }

    void RotatePlane ()
    {
        if (Input.GetKey (KeyCode.LeftArrow))
        {
            transform.Rotate (transform.up, -100.0f * Time.deltaTime, Space.World);
            //planeLeft = true;
            //planeIdle = false;
            //theAnimator.SetBool ("PlaneIdle", false);
            //theAnimator.SetBool ("PlaneLeft", true);
            PlaneLeft ();
        }

        if (Input.GetKey (KeyCode.LeftArrow) && Input.GetKey (KeyCode.LeftShift))
        {
            transform.Rotate (transform.up, -150.0f * Time.deltaTime, Space.World);
            //planeLeft = true;
            //planeIdle = false;
            //theAnimator.SetBool ("PlaneIdle", false);
            //theAnimator.SetBool ("PlaneLeft", true);
            PlaneExtraLeft ();
        }

        if (Input.GetKey (KeyCode.RightArrow))
        {
            transform.Rotate (transform.up, +100.0f * Time.deltaTime, Space.World);
            //planeRight = true;
            //planeIdle = false;
            //theAnimator.SetBool ("PlaneIdle", false);
            //theAnimator.SetBool ("PlaneRight", true);
            PlaneRight ();
        }

        if (Input.GetKey (KeyCode.RightArrow) && Input.GetKey (KeyCode.LeftShift))
        {
            transform.Rotate (transform.up, +150.0f * Time.deltaTime, Space.World);
            //planeLeft = true;
            //planeIdle = false;
            //theAnimator.SetBool ("PlaneIdle", false);
            //theAnimator.SetBool ("PlaneLeft", true);
            PlaneExtraRight ();
        }

    }

    void PlaneLeft ()
    {
        theAnimator.SetBool ("PlaneIdle", false);
        theAnimator.SetBool ("PlaneExtraLeft", false);
        theAnimator.SetBool ("PlaneExtraRight", false);
        theAnimator.SetBool ("PlaneRight", false);
        theAnimator.SetBool ("PlaneLeft", true);
    }

    void PlaneExtraLeft ()
    {
        theAnimator.SetBool ("PlaneIdle", false);
        theAnimator.SetBool ("PlaneLeft", false);
        theAnimator.SetBool ("PlaneRight", false);
        theAnimator.SetBool ("PlaneExtraRight", false);
        theAnimator.SetBool ("PlaneExtraLeft", true);
    }

    void PlaneRight ()
    {
        theAnimator.SetBool ("PlaneIdle", false);
        theAnimator.SetBool ("PlaneLeft", false);
        theAnimator.SetBool ("PlaneExtraLeft", false);
        theAnimator.SetBool ("PlaneExtraRight", false);
        theAnimator.SetBool ("PlaneRight", true);
    }

    void PlaneExtraRight ()
    {
        theAnimator.SetBool ("PlaneIdle", false);
        theAnimator.SetBool ("PlaneLeft", false);
        theAnimator.SetBool ("PlaneExtraLeft", false);
        theAnimator.SetBool ("PlaneRight", false);
        theAnimator.SetBool ("PlaneExtraRight", true);
    }

    void PlaneIdle ()
    {
        theAnimator.SetBool ("PlaneLeft", false);
        theAnimator.SetBool ("PlaneExtraLeft", false);
        theAnimator.SetBool ("PlaneRight", false);
        theAnimator.SetBool ("PlaneExtraRight", false);
        theAnimator.SetBool ("PlaneIdle", true);
    }

    void OnTriggerEnter (Collider other)
    {
        if (other.tag == "DoubleAcceleration")
        {
            acceleration = acceleration * 2;
        }
    }
}

There are some virtual joysticks in the Standard Assets package for Unity5.

I also have one in here that I call VAButton, and sample code to use it:

https://bitbucket.org/kurtdekker/proximity_buttons

Thank you for your reply @Kurt-Dekker !
However, I didn’t really get it to work. It seems like all the examples I can find is for GetAxis. What I need to do is to specify if it’s moving left or right and up or down. Not to just simply state if it’s moving along one of the axes.

Now, I have this script which successfully tells me where I move the joystick. I feel incredibly stupid, cause I believe what I have to do now, must be the easiest part. But I’m stuck.

In the Update where I have the Debug.Log saying “flying forward” I have tried making that movement into a void in the PlaneController script like this:

public void FlyingForward ()
    {
        if (acceleration < 25.0f)
        {
            acceleration += 0.1f;
        }

        speedLights.SetActive (true);
    }

And then simply stating thePlayer.FlyingForward (); where the Debug.Log is.

I have also tried this inside the Update of the new script:

if (joystickImg.rectTransform.anchoredPosition.y > 0)
        {
            if (thePlayer.acceleration < 25.0f)
            {
                thePlayer.acceleration += 0.1f;
            }

            thePlayer.speedLights.SetActive (true);
        }

Any help is greatly appreciated.
Here is the VirtualJoystick script:

VirtualJoystick : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler
{
    public PlaneController2 thePlayer;

    private Image bgImg;
    private Image joystickImg;
    private Vector3 inputVector;

    private void Start ()
    {
        thePlayer = FindObjectOfType <PlaneController2> ();
        bgImg = GetComponent <Image> ();
        joystickImg = transform.GetChild (0).GetComponent <Image> ();
    }

    void Update ()
    {
        if (joystickImg.rectTransform.anchoredPosition.x == 0 && joystickImg.rectTransform.anchoredPosition.y == 0)
        {
            Debug.Log ("Player idle");
        }

        if (joystickImg.rectTransform.anchoredPosition.y > 0)
        {
            Debug.Log ("Flying forward");
        }
    }

    public virtual void OnDrag (PointerEventData ped)
    {
        Vector2 pos;
        if (RectTransformUtility.ScreenPointToLocalPointInRectangle (bgImg.rectTransform, ped.position, ped.pressEventCamera, out pos))
        {
            pos.x = (pos.x / bgImg.rectTransform.sizeDelta.x);
            pos.y = (pos.y / bgImg.rectTransform.sizeDelta.y);

            inputVector = new Vector3 (pos.x * 2 + 1, 0, pos.y * 2 - 1);
            inputVector = (inputVector.magnitude > 1.0f) ? inputVector.normalized : inputVector;

            // Move JoystickIMG

            joystickImg.rectTransform.anchoredPosition = new Vector3 (inputVector.x * (bgImg.rectTransform.sizeDelta.x / 3), inputVector.z * (bgImg.rectTransform.sizeDelta.y / 3));
        }
    }
       
    public virtual void OnPointerDown (PointerEventData ped)
    {
        OnDrag (ped);
    }

    public virtual void OnPointerUp (PointerEventData ped)
    {
        inputVector = Vector3.zero;
        joystickImg.rectTransform.anchoredPosition = Vector3.zero;
    }


}

I’ve tested a few different things now, and it seems like I have done everything correctly. But I am not able to use the acceleration float as intended when I’m using the joystick. I am only allowed to set the float to a number. I can’t change the float at run time. Meaning, I can’t use:

    if (joystickImg.rectTransform.anchoredPosition.y > 0)
        {
            if (thePlayer.acceleration < 25.0f)
            {
                thePlayer.acceleration += 0.1f;
            }

        }

I’m only allowed to do this:

if (joystickImg.rectTransform.anchoredPosition.y > 0)
        {
            thePlayer.acceleration = 25.0f;
        }

This doesn’t really make much sense to me…