which of the following is best way of getting simple 2 axis input?

Hi,

I had learned getting input in unity recently.
so I was doing experiments with it.

I had tried 4 different things so please tell me that is there any difference between the methods I had used and if there is any difference really then which method/procedure is a best practice to follow for a long time.

And please tell me if any better practice is available for taking such inputs if all of these methods aren’t good or if anyone is interested in sharing his/her experiences of taking input.

using UnityEngine;
using System.Collections;

public class MovementScript : MonoBehaviour {
    public float divider=1;
    public float multiplier=1;
    // Use this for initialization
    void Start () {

    }

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

        // Method 1
        this.transform.Translate (Input.GetAxis ("Horizontal") / divider,0, Input.GetAxis("Vertical")/divider);

        // Method 2
        if (Input.GetAxis ("Horizontal") > 0) {
            this.transform.Translate (multiplier, 0, 0);
        }
        if (Input.GetAxis ("Horizontal") < 0)
            this.transform.Translate (-multiplier, 0, 0);
        if (Input.GetAxis ("Vertical") > 0)
            this.transform.Translate (0, 0, multiplier);
        if (Input.GetAxis ("Vertical") < 0)
            this.transform.Translate (0, 0, -multiplier);

        // Method 3
        if (Input.GetAxis("Vertical") != null || Input.GetAxis("Horizontal") != null)
            this.transform.Translate(Input.GetAxis("Horizontal"),0,multiplier* Input.GetAxis("Vertical"));

        // Method 4
        float vecx = this.transform.position.x;
        float vecz = this.transform.position.z;

        this.transform.position = new Vector3 (vecx = vecx + Input.GetAxis ("Horizontal") * multiplier, 0, vecz = vecz + Input.GetAxis ("Vertical") * multiplier);
    }
}

All of them which work (I see you don’t have multiplier* in Method 3 in x axis, assuming error) are suitable, but…
Method 2 won’t account for non-maximum axis offset. Joysticks will either always move at full power or don’t move at all. Is that intended behaviour?
Method 3 does wrong comare: null is reference, not value. You compare value(number) to reference(null)… I don’t remember: it’s either always true or compiler error.
Method 4 remembers last vecx and vecz, but they are local so they get deleted anyway after call has ended. Why do you write them?
The only one that’s easy to read(primary criteria) and doesn’t do anything stupid is either Method 1 or 2 depending on expected behaviour.

Experience? In my experience nothing good comes of Translate(Input.GetAxis(…),…) at all: you don’t account for obstacles, something outside affecting your object, you just blindly move it… Applying force to rigidbody is better.

1 Like

I did a frogger game a while back and used something similar. Instead of using transform.Translate, I use a MoveTowards. This allowed me to use time to get smooth movement. Here is some simple test code to do movement over time by steps.

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

public class Test : MonoBehaviour
{
    public float speed = 2;
    private Transform blocker;
    private bool moving;
    
    void Start() {
        // set this object to a whole number.
        Vector3 pos = transform.position;
        transform.position = new Vector3(Mathf.Round(pos.x), Mathf.Round(pos.y), Mathf.Round(pos.z));

        // set moving to false, so we can move.
        moving = false;

        // create a blocker to block other scripts from moving where I am.
        GameObject blockObj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        blockObj.GetComponent<Renderer>().enabled = false;
        blocker = blockObj.transform;
        blocker.position = transform.position;
    }
    void Update() {
        // if we are moving, continue the move until we reach our destination.
        if (moving) {
            Move();
            return;
        }

        // Method 5
        float v = Input.GetAxis("Vertical");
        float h = Input.GetAxis("Horizontal");

        // use ternary operators to set the values is simple and elegant in this case.
        v = v > 0 ? 1 : v < 0 ? -1 : 0;
        h = h > 0 ? 1 : h < 0 ? -1 : 0;

        // if we are not pressing anything, don't do anything.
        if (v == 0 && h == 0) return;

        // find where we want to go.
        Vector3 target = new Vector3(h, v, 0);

        // see if anything is blocking what we want.
        // we use 0.45 so that we dont accidently hit another collider from a different cell.
        Collider[] Obstacles = Physics.OverlapSphere(transform.position + target, 0.45f);
        if (Obstacles.Length == 0) {
            // if not, set the blocker to our next position.
            blocker.position = transform.position + target;
            moving = true;

            // doing the move here means that we dont see a stop for a frame.
            Move();
        }
    }

    void Move() {
        // do the move towards.
        transform.position = Vector3.MoveTowards(transform.position, blocker.position, speed * Time.deltaTime);

        // check to see if we are still moving
        if (transform.position != blocker.position)
        {
            return;
        }

        // set moving to false, so we can continue moving.
        moving = false;
    }
}

More could be added. So if we overlap sphere and any of the objects are tagged powerup, or monster, we could do something else, other than just sit there.

method 3 is flawed; Input.GetAxis(…) returns 0 for no input, and also floats (the return type) can never be null, an uninitialised float is 0 not null.

0 is not null => always true :slight_smile:

could just use GetAxisRaw() :slight_smile:
http://docs.unity3d.com/ScriptReference/Input.GetAxisRaw.html

Difference between GetAxisRaw and GetAxis is that GetAxis = GetAxisRaw*Time.deltaTime with smoothing(Not sure how smoothing is done). It’s not really what you wrote - it won’t always give you 1/0/-1 on joystick, it can give you 0.25 if joystick is 1/4th moved on axis. This code makes values either 1 0 or -1 no matter what input you use.

Thanks everyone.