Mapping inputs to an on-screen joystick

If your game is played on a mobile device, AC allows for moving the player around by dragging a finger over the whole screen. However, you may wish to limit such input to an on-screen UI.

In this tutorial, we'll create a UI that can be used to move the player around the scene. We'll demonstrate a couple of techniques: one made with AC's own Menu system, and then one using a third-party asset.

Assuming you already have a Player defined, go to the Settings Maanger, and set the Movement method to Direct. This allows us to control the Player by pressing the Horizontal and Vertical axes (by default, these are mapped to your cursor keys).

Set the Input method is set to Touch Screen, and then the Direct movement field (under "Movement settings" to Custom Input:


Method 1: Built-in

We'll now create a new Menu that simulates input keys for us. This can be done in Unity UI or AC's built-in Menu controls, but here we'll use Unity UI.

Create a new UI Button by choosing GameObject → UI → Button from the top toolbar.

Name the new Canvas DPadUI, and the new Button Up. Duplicate this button three times, and name them Down, Left and Right.

Position and style these buttons to suit using Unity's controls:

Finally, prefab this UI by dragging it into an Asset folder.

We're now ready to link this to AC's Menu system so that we can control it within AC. In AC's Menu Manager, click Create new menu and name it DPad.

Set the Source to Unity Ui Prefab, and the Appear type to During Gameplay. Then assign our new prefab as the Linked Canvas.

In the list of this Menu's elements, create four Buttons and name them as before. Assign each of the prefab's buttons to its corresponding Linked button field in the Menu Manager.

NOTE: If you have structured your Canvas' hierarchy differently and cannot access your UI Buttons within the prefab, you can assign their local (scene) instances instead - just be sure to click Apply to the Canvas afterwards to update the prefab.

We can now dictate what happens when each UI button is clicked from within our Menu Manager. In the list of properties of each element, set the Responds to field to Pointer Down, and the Click type to Simulate Input:

Set the fields for each element as follows:

Up

  • Simulate: Axis
  • Input axis: Vertical
  • Input value: 1

Down

  • Simulate: Axis
  • Input axis: Vertical
  • Input value: -1

Left

  • Simulate: Axis
  • Input axis: Horizontal
  • Input value: -1

Right

  • Simulate: Axis
  • Input axis: Horizontal
  • Input value: 1

You should now be able to hold these buttons down in-game to control the player.

Method 2: Third-party joystick

In this alternative method, we'll link the free Simple Touch Controller asset - which provides an on-screen joystick - to AC so that we can control our Player with it.

This method will make use of input overrides, which is covered in this tutorial. Though the process is quite simple, you should still read that tutorial to understand the principles involved.

Once the Simple Touch Controller asset has been imported, find the SimpleTouch Joystick prefab in its Prefabs folder.

Create a new Canvas (GameObject -> UI -> Canvas from the top toolbar), and drag the SimpleTouch Joystick prefab onto it in the scene's Hierarchy:

We'll now write a short script that reads in the input of this joystick, and sends it to AC. Create a new C# script named ACJoystick and attach it to the Canvas.

Open the script, and create a public SimpleTouchController variable named moveController:

public SimpleTouchController moveController;

This will be used to override AC's Horizontal and Vertical inputs. This is done by writing a new listener for AC's InputGetAxisDelegate, which - when assigned - can override AC's regular calls to Input.GetAxis(). This delegate takes the axis' name as a single parameter, and returns that axis value as a float - so let's write a function that matches that:

private float CustomGetAxis (string axisName)
{
	if (axisName == "Horizontal")
	{
		return moveController.GetTouchPosition.x;
	}
	if (axisName == "Vertical")
	{
		return moveController.GetTouchPosition.y;
	}
	try
	{
		return Input.GetAxis (axisName);
	}
	catch 
	{
		return 0f;
	}
}

The "try/catch" statement is necessary to avoid errors if other inputs that AC relies on are undefined.

We now just need to tell AC to listen to this function whenever it wants to read an axis value. We can do that within the Start() function:

void Start ()
{
	AC.KickStarter.playerInput.InputGetAxisDelegate = CustomGetAxis;
}

Save the script, assign the SimpleTouch Joystick object to the Move Controller field that appears in its Inspector. You should now be able to control the Player using the on-screen joystick.

using UnityEngine;

public class ACJoystick : MonoBehaviour
{
	
	public SimpleTouchController moveController;

	private void Start ()
	{
		AC.KickStarter.playerInput.InputGetAxisDelegate = CustomGetAxis;
	}

	private float CustomGetAxis (string axisName)
	{
		if (axisName == "Horizontal")
		{
			return moveController.GetTouchPosition.x;
		}
		if (axisName == "Vertical")
		{
			return moveController.GetTouchPosition.y;
		}

		try
		{
			return Input.GetAxis (axisName);
		}
		catch
		{
			return 0f;
		}
	}

}