Part 18 - Keyboard input - Movement.

By Jamie Chatterton / 2018-06-12

The next thing to do is move the Spawner back and forth under the control of the user again.

There were more axes in the Input, in this case it is the Horizontal axis.

Looking back at the InputManager settings, it has two buttons "left" and "right" being the "Negative Button" and "Positive Button" respectively. "left" and "right" being the cursor keys. So "left" has a negative impact on the Horizontal axis and "right" has a positive impact. There are also alternatives of "a" and "d".

Getting the data from this is again via Input, using the function

Input.GetAxis( axis name )

The axis name being that specified in the InputManager ("Horizontal"). The value it returns being -1 to +1.

We just want to move the Spawner along it's X axis depending on the value in this axis. Essentially adding it to the X position of the Spawner, until it's at its limits, where it needs to stop.

So why don't we do that?

In the Update function of the SpawnerController, add the following

transform.position = transform.position + new Vector3(Input.GetAxis("Horizontal"), 0, 0);

So we are adding the Horizontal axis as a transformation to the X position of the spawner object. Try it… you get something like…

Which is obviously wrong…

The problems?

The cube has no boundaries

The existing coins move with it

We have to limit the cube

We also have to detach the object that moves from where the coins are spawned.

We have to give the spawner a different place to spawn the coins. A different target.

To do this add a

public Transform SpawnLocation;

to the top of the SpawnerController class.

Change the SpawnObject function to

void SpawnObject() {
	var coin = Instantiate(ObjectToSpawn, transform);
	coin.transform.position = SpawnLocation.position;
}

So we are spawning the objects (coins) still children of the spawner object, but setting their position to be that of the SpawnLocation.

We should normally be able to use the 'Cube' object, but it's center is not the centre of the Cube.

Add an Empty GameObject to the Cube (Right click on the Cube, "Create Empty"). Call it "Spawn Location". Set it's transform to (0.5, 0, -0.5)

In the GUI drag the "Spawn Location" from the "Hierarchy" to the Spawner Controller => Spawn Location text box

Open this image in a new tabDrag Spawn Location
Drag Spawn Location
Open this image in a new tabTo Spawn Controller
To Spawn Controller

Also, now delete that bit of code we added to move the SpawnerController… finally our class for now should look like

public class SpawnerController : MonoBehaviour {

	public GameObject ObjectToSpawn;
	public Transform SpawnLocation;

	// Use this for initialization
	void Start () {
	}

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

		if (Input.GetButtonDown("Fire1")) {
			SpawnObject();
		}

	}

	void SpawnObject() {
		var coin = Instantiate(ObjectToSpawn, transform);
		coin.transform.position = SpawnLocation.position;
	}

}

So to move the cube… however … this is not functionality of the SpawnerController, this should be functionality of the object that moves… no?

Create a new Script in the Cube object...Click the Cube, Add Component in the Inspector… I typed MoveController and created a new script when it offered. Again this was created in the root, which I moved into the scripts folder.

Opening up this, we want to move the Cube in the Update function. We can delete the Start function altogether.

public class MoveController : MonoBehaviour {

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

		var position = transform.localPosition;

		position.x += Input.GetAxis("Horizontal");

		transform.localPosition = position;

	}
}

If you run it, you'll find it's stupidly fast. But it kinda works.

Also, the way it tries to emulate an axis it is better to use a different function, GetAxisRaw which gives immediate feedback from the axis, without the 'gravity' and 'sensitivity' that slow down the user's input.

Own final thing we need to do is clamp the position of the spawner.

It may be easier for now to just specify it in code.

In my code so far, moving the cube by eye and looking in the inspector…

We have a minimum of -3

Open this image in a new tabDetermine position 1
Determine position 1

And a maximum of +2

Open this image in a new tabDetermine position 2
Determine position 2

These are local positions, relative to the parent, so if we move the spawner, these won't change. We can just hard-code these for now.

The code for the MoveController now looks like this

public class MoveController : MonoBehaviour {
    // Update is called once per frame
    void Update() {
        var position = transform.localPosition;

        position.x += Mathf.Clamp(Input.GetAxisRaw("Horizontal"), -0.1f, 0.1f);

        if (position.x < -3)
            position.x = -3;

        if (position.x > 2)
            position.x = 2;

        transform.localPosition = position;
    }
}

Finally we have the following…

Git repository: https://bitbucket.org/hiveit/unity-tutorial-coin/src/013_AddingKeyboardControl/

More posts in this series.