Building the TestingInput

We are going to use a pattern called a Singleton in order to implement a class that we can access from anywhere in our code, much like the input class from Unity that is currently used. Unity has the benefit of making the input completely static, but for our purposes, we will use the well-defined scripting version. Open the editor and follow the next exercise to build the TestingInput script and object:

  1. Select the HoDLG | Scripts folder and open the Create menu.
  2. From the Create menu, select C# Script. Name the new script Singleton. This script is the standard pattern script from http://wiki.unity3d.com/index.php/Singleton; the script is shown as follows:
using UnityEngine;

namespace Packt.HoDLG
{
/// <summary>
/// Inherit from this base class to create a singleton.
/// e.g. public class MyClassName : Singleton<MyClassName> {}
/// </summary>
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
// Check to see if we're about to be destroyed.
private static bool m_ShuttingDown = false;
private static object m_Lock = new object();
private static T m_Instance;
/// <summary>
/// Access singleton instance through this propriety.
/// </summary>
public static T Instance
{
get
{
if (m_ShuttingDown)
{
Debug.LogWarning("[Singleton] Instance '" + typeof(T) +
"' already destroyed. Returning null.");
return null;
}
lock (m_Lock)
{
if (m_Instance == null)
{
// Search for existing instance.
m_Instance = (T)FindObjectOfType(typeof(T));
// Create new instance if one doesn't already exist.
if (m_Instance == null)
{
// Need to create a new GameObject to attach the singleton to.
var singletonObject = new GameObject();
m_Instance = singletonObject.AddComponent<T>();
singletonObject.name = typeof(T).ToString() + " (Singleton)";
// Make instance persistent.
DontDestroyOnLoad(singletonObject);
}
}
return m_Instance;
}
}
}
private void OnApplicationQuit()
{
m_ShuttingDown = true;
}
private void OnDestroy()
{
m_ShuttingDown = true;
}
}
}
  1. Enter the preceding code, or just use the code downloaded from the book's source. A singleton allows us to define one thread-safe instance of a specific class that all of the objects can refer to. A typical static class will not be thread-safe, and may cause corruption or memory issues.
  2. Create a new script called TestingInput in the HoDLG | Scripts folder and open it for editing. 
  3. We will start the class with the following code:
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace Packt.HoDLG
{
public class TestingInput : Singleton<TestingInput>
{
public string[] axes;
public bool isPlayer;
}
}
  1. Notice the highlighted line, and how we declare the class to extend from the type Singleton that wraps the type TestingInput. This form of recursive typing, which uses generics, is perfect for the singleton. Don't worry if this is a little unclear; the only thing that you need to remember is that we can now access the instance of this class from anywhere in our code. Notice that we mentioned an instance and not a class, meaning that we can also persist the state within our TestingInput class. The variables that we declare here, axes and isPlayer, are either set in the editor or defined in the Start method, as follows:
void Start()
{
axisValues = new Dictionary<string, float>();
//reset the axes to zero
foreach(var axis in axes)
{
axisValues.Add(axis, 0);
}
}
  1. Inside the Start method, we define a Dictionary to hold the axis and values that we want this component to override. This allows us to control which input we want to override. Then, we build the collection of name/value pairs.
  2. Next, we will define a couple methods that will allow us to both mimic and set the axis values of our input system. Unity has no direct way to set the value of an axis. Currently, the Input system queries the hardware directly in order to read the input state, and provides no way to override this for testing. While this is a feature that has long been requested by the community, it remains to be seen whether it will ever be implemented.
  3. We then enter a setAxis and getAxis method, as follows:
public void setAxis(float value, string axisName)
{
if (isPlayer == false && axes.Contains(axisName)) //don't if player mode
{
axisValues[axisName] = value;
}
}
public float getAxis(string axisName)
{
if (isPlayer)
{
return Input.GetAxis(axisName);
}
else if(axes.Contains(axisName))
{
return axisValues[axisName];
}
else
{ return 0; }
}
  1. That completes the script; if you have been adding the code as you go, save the file and return to Unity. At this point, you should see no compiler errors, as all of the required types should be present and accounted for.

That sets up the TestingInput script; now, we need to move on to the next section to add it to the scene.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset