Unity 2020 Mobile Game Development
上QQ阅读APP看书,第一时间看更新

Moving using touch controls

Unity's Input engine has a property called Input.touches, which is an array of Touch objects. The Touch struct contains information on the touch that occurred, having information such as the amount of pressure on the touch and how many times you tapped the screen. It also contains the position property, such as Input.mousePosition, that will tell you what position the tap occurred at, in pixels.

For more info on the Touch struct, check out  https://docs.unity3d.com/ScriptReference/Touch.html.

Let's look at the steps to use touch instead of mouse inputs:

  1. Adjust our preceding code to look something like the following:
//Check if Input has registered more than zero touches
if (Input.touchCount > 0)
{
//Store the first touch detected.
Touch touch = Input.touches[0];

// Converts to a 0 to 1 scale
var worldPos = Camera.main.ScreenToViewportPoint
(touch.position);

float xMove = 0;

// If we press the right side of the screen
if (worldPos.x < 0.5f)
{
xMove = -1;
}
else
{
// Otherwise we're on the left
xMove = 1;
}

// replace horizontalSpeed with our own value
horiztonalSpeed = xMove * dodgeSpeed;

}

Now, you may note that this code looks very similar to what we've written in the preceding section. With that in mind, instead of copying and pasting the appropriate code twice and making changes like a number of starting programmers would do, we can instead take the similarities and make a function. For the differences, we can use parameters to change the value instead.

  1. Keeping that in mind, let's add the following function to the PlayerBehaviour class:
/// <summary> 
/// Will figure out where to move the player horizontally
/// </summary>
/// <param name="pixelPos">The position the player has
/// touched/clicked on</param>
/// <returns>The direction to move in the x axis</returns>
private float CalculateMovement(Vector3 pixelPos)
{
// Converts to a 0 to 1 scale
var worldPos = Camera.main.ScreenToViewportPoint(pixelPos);

float xMove = 0;

// If we press the right side of the screen
if (worldPos.x < 0.5f)
{
xMove = -1;
}
else
{
// Otherwise we're on the left
xMove = 1;
}

// replace horizontalSpeed with our own value
return xMove * dodgeSpeed;
}

Now, instead of using Input.mousePosition or the touch position, we use a parameter for the function. Also, unlike previous functions we've written, this one will actually use a return value; in this case, it will give us a floating-point value. We will use this value in the Update to set horiztonalSpeed to a new value when this function is called. Now, we can call it appropriately.

  1. Now, update the Update function, as follows:
/// <summary>
/// FixedUpdate is called at a fixed framerate and is a prime place
/// to put
/// Anything based on time.
/// </summary>
private void FixedUpdate()
{
// Check if we're moving to the side
var horizontalSpeed = Input.GetAxis("Horizontal") * dodgeSpeed;

// Check if we are running either in the Unity editor or in a
// standalone build.
#if UNITY_STANDALONE || UNITY_WEBPLAYER || UNITY_EDITOR
// Check if we're moving to the side
horizontalSpeed = Input.GetAxis("Horizontal") * dodgeSpeed;

// If the mouse is held down (or the screen is tapped
// on Mobile)
if (Input.GetMouseButton(0))
{
horizontalSpeed =
CalculateMovement(Input.mousePosition);
}

// Check if we are running on a mobile device
#elif UNITY_IOS || UNITY_ANDROID
// Check if Input has registered more than zero touches
if (Input.touchCount > 0)
{
// Store the first touch detected.
Touch touch = Input.touches[0];
horizontalSpeed = CalculateMovement(touch.position);
}
#endif

rb.AddForce(horizontalSpeed, 0, rollSpeed);
}

In the preceding example, I am using a #if directive based on the platform selected. Unity will automatically create a #define depending on what has been selected as the platform we are deploying for. What this #if does, along with #elif and #endif, is allow us to include or exclude code from our project based on these symbols.

In Visual Studio, you may note that if you're building for iOS or Android, the code within the UNITY_IOS || UNITY_ANDROID section is grayed out, meaning that it won't be called currently because we are running the game in the Unity Editor. However, when we export the code to our platform, the appropriate code will be used.

To take a look at all of the other platform-dependent #defines, check out  https://docs.unity3d.com/Manual/PlatformDependentCompilation.html.

This will allow us to specify the code for different versions of our project, which is vital when dealing with multi-platform development.

In addition to Unity's built-in #defines, you can create your own by going to Edit | Project Settings | Player, scrolling down to Other Settings in the Inspector window, and changing the Scripting Define Symbols. This can be great for targeting specific devices or for showing certain pieces of debug information, in addition to a number of other things.
  1. Save the script and dive back into Unity.

Upon exporting your game to your Android device, you should note that the controls now work correctly using our newly created touch code. This allows us to have something that works on mobile as well as PC. Now, let's take a look at some of the mobile-specific ways that we can interpret input.