Search Unity

Converting Input.GetAxis("Horizontal") into unity UI

Discussion in 'Scripting' started by Farooqui, Oct 16, 2017.

  1. Farooqui

    Farooqui

    Joined:
    Mar 9, 2014
    Posts:
    23
    Hello everyone,
    So i been stuck on this for few days, not sure how I cannot seem to figure out. I am trying to replace Input.GetAxis("Horizontal"); with unity UI, something like 2 buttons which would turn left and right.

    Please help!!!
    thank you

    This code is from the unity car tutorial


    Code (CSharp):
    1.  
    2.  
    3. float angle = maxAngle * Input.GetAxis("Horizontal");
    4.  
    5.     foreach (WheelCollider wheel in m_Wheels)
    6.         {
    7.             // A simple car where front wheels steer while rear ones drive.
    8.             if (wheel.transform.localPosition.z > 0) {
    9.                 wheel.steerAngle = angle;
    10.             }
    11.             if (wheel.transform.localPosition.z < 0)
    12.             {
    13.                 wheel.brakeTorque = handBrake;
    14.             }
    15.  
    16.             if (wheel.transform.localPosition.z < 0 && driveType != DriveType.FrontWheelDrive)
    17.             {
    18.             //    if (tempDamage == false)
    19.                     wheel.motorTorque = torque;
    20.  
    21.             }
    22.  
    23.             if (wheel.transform.localPosition.z >= 0 && driveType != DriveType.RearWheelDrive)
    24.             {
    25.             //    if (tempDamage == false)
    26.                 wheel.motorTorque = torque;
    27. //                print (wheel.motorTorque);
    28.             }
    29.  
    30.             // Update visual wheels if any.
    31.             if (wheelShape)
    32.             {
    33.                 Quaternion q;
    34.                 Vector3 p;
    35.                 wheel.GetWorldPose (out p, out q);
    36.  
    37.                 // Assume that the only child of the wheelcollider is the wheel shape.
    38.                 Transform shapeTransform = wheel.transform.GetChild (0);
    39.                 shapeTransform.position = p;
    40.                 shapeTransform.rotation = q;
    41.             }
    42.         }
    43.  
    44.  
     
  2. MiladZarrin1

    MiladZarrin1

    Joined:
    Jul 7, 2013
    Posts:
    78
    I've made a small project for you. I hope it helps.
    But the core concept is this:

    Code (CSharp):
    1. public void RightButton_Down()
    2. {
    3.     rightPressed = true;
    4. }
    5.  
    6. public void RightButton_Up()
    7. {
    8.     rightPressed = false;
    9. }
    10.  
    11. public void LeftButton_Down()
    12. {
    13.     leftPressed = true;
    14. }
    15.  
    16. public void LeftButton_Up()
    17. {
    18.     leftPressed = false;
    19. }
    20.  
    21.  
    22. void Update()
    23. {
    24.     bool noInput = false;
    25.  
    26.     // detecting the direction which value shoud be going
    27.     int dir = 0;
    28.     if (rightPressed && leftPressed) // both directions
    29.         dir = 0;
    30.     else if (rightPressed) // only right
    31.         dir = 1;
    32.     else if (leftPressed) // only left
    33.         dir = -1;
    34.     else // no input at all. force must be lerp into zero
    35.         noInput = true;
    36.  
    37.  
    38.     if (noInput)
    39.     {
    40.         // lerping force into zero if the force is greater than a threshold (0.01)
    41.         if (Mathf.Abs(inputValue) >= 0.01f)
    42.         {
    43.             int opositeDir = (inputValue > 0) ? -1 : 1;
    44.             inputValue += Time.deltaTime * getBackSpeed * opositeDir;
    45.         }
    46.         else
    47.             inputValue = 0;
    48.     }
    49.     else
    50.     {
    51.         // increase force towards desired direction
    52.         inputValue += Time.deltaTime * dir * moveSpeed;
    53.         inputValue = Mathf.Clamp(inputValue, -1, 1);
    54.     }
    55.  
    56.     showText.text = inputValue.ToString("0.00");
    57. }
    Let me know if anything looks confusing.
     

    Attached Files:

  3. Farooqui

    Farooqui

    Joined:
    Mar 9, 2014
    Posts:
    23
    Thank you Milad, works like a charm!
     
  4. MiladZarrin1

    MiladZarrin1

    Joined:
    Jul 7, 2013
    Posts:
    78
    You're quite welcome :)
     
  5. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,697
    The generalized approach is to use what's called a virtual controller or virtual input. It's just a wrapper around your actual input source. Let's say the wrapper class is named VirtualInput. Then instead of this:
    Code (csharp):
    1. float angle = maxAngle * Input.GetAxis("Horizontal");
    you'd use this:
    Code (csharp):
    1. float angle = maxAngle * VirtualInput.GetAxis("Horizontal");
    This way your code isn't reading directly from a hard-coded input source. It could be reading from Unity Input, or Rewired, or a set of UI buttons, or even an AI script.

    You can also define game-specific input if you want. (Or you can stick with the more generic GetAxis() if you prefer.) For example, let's say you name the wrapper class CarInput, and you define an input named Steering(). Let's also say that the wrapper class is a MonoBehaviour in your scene, and that it has a static variable named instance that points to itself. Then you could use this code:
    Code (csharp):
    1. float angle = maxAngle * CarInput.instance.Steering();
    which might make your code more understandable.

    Below is a version of CarInput that uses Unity Input. Functionally, it's no different from your original code. The Steering() function returns the value of Input.GetAxis("Horizontal").
    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class CarInput : MonoBehaviour {
    4.  
    5.     public static CarInput instance;
    6.     void Awake() {
    7.         instance = this;
    8.     }
    9.  
    10.     public virtual float Steering() {
    11.         return Input.GetAxis("Horizontal");
    12.     }
    13. }
    Here's a subclass that uses Unity UI. The Steering() function returns a float that goes up or down based on holding down left/right UI buttons.
    Code (csharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using UnityEngine.EventSystems;
    4.  
    5. public class CarInputUI : CarInput, IPointerDownHandler, IPointerUpHandler {
    6.  
    7.     public Button leftButton; // Assign in inspector.
    8.     public Button rightButton;
    9.  
    10.     private bool isLeftDown = false;
    11.     private bool isRightDown = false;
    12.     private float steeringValue = 0;
    13.     private float steeringVelocity = 0;
    14.  
    15.     public override float Steering() {
    16.         return steeringValue;
    17.     }
    18.  
    19.     void Update() {
    20.         // If left and right buttons cancel each other out, don't do anything:
    21.         if (isLeftDown == isRightDown) return;
    22.  
    23.         // Otherwise smoothly adjust toward target value:
    24.         var target = 0;
    25.         if (isLeftDown) target = -1;
    26.         else if (isRightDown) target = 1;
    27.         steeringValue = Mathf.SmoothDamp(steeringValue, target, steeringVelocity, 1);
    28.     }
    29.  
    30.     // Add an Event Trigger to your left/right buttons and assign these methods:
    31.     public void OnLeftDown(PointerEventData eventData) { isLeftDown = true; }
    32.     public void OnLeftUp(PointerEventData eventData) { isLeftDown = false; }
    33.     public void OnRightDown(PointerEventData eventData) { isRightDown = true; }
    34.     public void OnRightUp(PointerEventData eventData) { isRightDown = false; }
    35. }
     
    mowax74, sami1592, Farooqui and 2 others like this.
  6. sami1592

    sami1592

    Joined:
    Sep 18, 2013
    Posts:
    57
  7. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,697