Alexander

Alexander

hit me up
Home

Duracell VR Mini Games

Alexander - 21/02/2017

Duracell asked for a series of mini games for the Samsung Gear VR which would be taken around the world as part of an installation for members of the public to play.

In the app you play as a child in their bedroom who wants to play with some of their toys. There are three mini games: RC Racer where you drive an RC Car along a track around the bedroom, Find The Toy where you are using a torch to find toys in your toy cupboard and Channel Hopper where you flick through TV channels to find the show you want to watch. In each mini game the Duracell Bunny will ask you for what they want and you will start slowly progressing with some difficulty until the Duracell Bunny replaces your low power batteries with brand new Duracell batteries. The games then become much easier to complete and you are rewarded with a battery at the end of each one. Once you have collected all three batteries you have completed the experience and a party scene plays out in the room. The experience lasts approximately five minutes across all mini games.

I led the development of the project where I assigned roles to the developers and artists, developed the core game loop to support the mini games, developed the RC Racer and Find The Toy games, implemented my Input Manager to allow for controller input which changes across the different mini games and created an additional localisation app which was used to define the settings for the main VR app.

RC Racer uses a predefined spline for the car to follow and the player controls the throttle of the car. The car follows the xz position of the spline but the y position is determined by physics, much like the popular Trials games. There are a couple of scripted sequences where the car will follow seamlessly enter and exit a scripted animation, for example when driving up the large ramp the car will get huge air and backflip before landing on the ramp the other side where the player regains control.

 

Duracell_02

Duracell_01

Unity Attributes

Alexander - 13/12/2016

Unity’s attributes are a simple and powerful way to essentially stop you from making so many mistakes, or at least give others looking at your code or using a tool you created some idea of what it’s meant to do. This isn’t an exhaustive list but aims to cover the majority of the more commonly used ones.

 

 

AddComponentMenuAllows you to place a script anywhere in the “Component” menu, instead of just the “Component->Scripts” menu

This is purely for organising your components in the “Component” menu

Note: the function has to be non-static.

[AddComponentMenu("Example/Example Class")]
public class ExampleClass : MonoBehaviour
{
}

 

 

ColorUsage – Configure the usage of the ColorField and Color Picker for a color


[ColorUsage(bool showAlpha, bool hdr, float minBrightness, float maxBrightness, float minExposureValue, float maxExposureValue)]

 


public class ExampleClass : MonoBehaviour
{
    [SerializeField]
    [ColorUsage(false, true, 0.6f, 0.8f, 0.5f, 0.7f)]
    Color color;
}

 

 

ContextMenu – Allows you to add commands to the context menu

This is the easiest way to create a method which can be run while in edit or play mode at the command of the user, great for capturing screenshots like in the example below.

Note: the function has to be non-static.

public class CaptureScreenShot : MonoBehaviour
{
    [SerializeField]
    int SuperSample = 3;

    [ContextMenu("Capture Shot")]
    void CaptureShot()
    {
        Application.CaptureScreenshot("Screenshot_" + gameObject.name + "_" + Time.realtimeSinceStartup.ToString() + ".png", SuperSample);
    }
}

 

 

ContextMenuItem – Add a context menu to a field that calls a named method

ContextMenuItem is essentially ContextMenu but worse. Instead of adding to the drop down context menu of a component it adds a context menu when right clicking on an individual field, so far so good, but the method you assign to that field ironically has no context of which field you clicked on, so if you wanted to write a method which randomises a value – like the one below – you would need to do it once for each field you want to randomise.

So in conclusion it can only do the exact same as what ContextMenu does just in a different place in the inspector, and on top of this it calls the method by string, so if you rename the method you’ll need to update the attribute too. If you know of a way of doing more with ContextMenuItem then please let me know!

public class ExampleClass : MonoBehaviour
{
    [ContextMenuItem("Randomize Value", "Randomize")]
    [SerializeField]
    int m_Number;

    private void Randomize()
    {
        m_Number = Random.Range(0, 10);
    }
}

 

 

CreateAssetMenuMark a ScriptableObject-derived type to be automatically listed in the Assets/Create submenu

This is the easiest way to create ScriptableObjects. You just need to specify the default file name and the menu location / name and you’ll be able to create new ScriptableObjects of this type in just a couple of clicks.

Note: Unlike classes ScriptableObjects need to have a separate script for each one where the script name matches the class name. This can be particularly annoying because it’ll work fine at first but once you reload Unity it won’t find the classes and you will lose all the data saved in your .asset files.

[CreateAssetMenu(fileName = "ExampleFile", menuName = "Example/Example Class")]
public class ExampleClass : ScriptableObject
{
    [SerializeField]
    int m_Number;
}

 

 

Delayed Make a float, int, or string variable in a script be delayed

When assigning a value to the associated variable the new value will not be assigned until the user presses enter or changes focus to a different variable (as opposed to simply being able to click away).

public class ExampleClass : MonoBehaviour
{
    [SerializeField]
    [Delayed]
    int m_Number;
}

 

 

DisallowMultipleComponent – Prevents MonoBehaviour of same type (or subtype) to be added more than once to a GameObject

You will have seen the effect of this with some of Unity’s components, for example you can’t have more than one Rigidbody on a single GameObject and the use of this attribute prevents you from doing so.


[DisallowMultipleComponent]
public class ExampleClass : MonoBehaviour
{
}

 

 

ExecuteInEditMode – Any instance of the MonoBehaviour will have its callback functions executed while the Editor is not in playmode

The example below will rotate the Transform of the GameObject it is attached to to look at a Transform defined by the user in the inspector while the editor is in edit mode.

Note: the functions are not called constantly like they are in play mode.

  • Update is only called when something in the scene changed.
  • OnGUI is called when the Game View recieves an Event.
  • OnRenderObject and the other rendering callback functions are called on every repaint of the Scene View or Game View.
[ExecuteInEditMode]
public class ExampleClass : MonoBehaviour
{
    [SerializeField]
    Transform target;
    void Update()
    {
        if (target)
            transform.LookAt(target);
    }
}

 

 

HeaderAdd a header above some fields in the Inspector

This is purely for organising the inspector to make it clearer, but it can also help when looking through your code.

public class ExampleClass : MonoBehaviour
{
    [Header("Health Settings")]
    [SerializeField]
    int m_Health = 0;
    [SerializeField]
    int m_MaxHealth = 100;

    [Header("Shield Settings")]
    [SerializeField]
    int m_Shield = 0;
    [SerializeField]
    int m_MaxShield = 100;
}

 

 

HelpURLProvide a custom documentation URL for a class

This link is opened when you click on the reference icon (the book with a question mark on) of the associated component in the inspector.

You’ll only ever need this if you’re creating a tool that you’re sharing with others and have online documentation to accompany it.


[HelpURL("http://onf.re/unity-attributes/")]

 

 

HideInInspectorMakes a variable not show up in the inspector but be serialized

This is essentially used in the opposite way to the SerializeField attribute. You may want to expose a variable to other classes but not the inspector, and that’s what this is for.

public class ExampleClass : MonoBehaviour
{
    [HideInInspector]
    public int Number;
}

 

 

MultilineMake a string be edited with a multi-line textfield

Nice and simple, show a specified number of lines for a string exposed to the inspector.

Note: by default it will show 3 lines, and make sure you don’t use a number below 1 as the inspector will still try and draw it.

public class ExampleClass : MonoBehaviour
{
    [Multiline]
    [SerializeField]
    string m_Name;
}

 

 

PropertyAttributeBase class to derive custom property attributes from

If you want to create custom attributes for script variables, this is what you need to inherit from.

A custom attribute can be hooked up with a custom PropertyDrawer class to control how a script variable with that attribute is shown in the Inspector.

 

 

Preserve – Prevents byte code stripping from removing a class, method, field, or property

When you create a build, Unity will try to strip unused code from your project. You may sometimes want some code to not be stripped, even if it looks like it is not used. This can happen for instance if you use reflection to call a method, or instantiate an object of a certain class. Preserve will prevent this from happening.

public class ReflectionExample
{
    static public void InvokeFooByReflection()
    {
        typeof(ReflectionExample).GetMethod("Foo", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null);
    }

    // No other code directly references the Boink method, so when when stripping is enabled,
    // it will be removed unless the [Preserve] attribute is applied.
    [Preserve]
    static void Foo()
    {
        Debug.Log("Bar");
    }
}

 

 

RangeMake a float or int variable be restricted to a specific range

This is useful when you have a known range for your variable. The inspector will draw a slider making it easier to use, especially with integers as the slider handle will lock to the nearest value.

public class ExampleClass : MonoBehaviour
{
    [Range(1, 10)]
    [SerializeField]
    int m_Number;
}

 

 

RequireComponentAutomatically adds required components as dependencies

If your component depends on another component on the same GameObject, you should always use the RequireComponent attribute. Below is a very common example where you want to cache a component to prevent unnecessary GetComponent calls as this is notoriously slow. By using the RequireComponent attribute we can guarantee that this GameObject will have the component we depend on, so as long as we cache the component once we never need to null check the variable because the component cannot be removed or destroyed.

Note: This can behave unexpectedly with interfaces. Say you have a public interface IMyInterface in a script called IMyInterface.cs then using RequireComponent will throw an error. If you rename your script to something else (e.g. you put your interfaces into a script names Interfaces.cs) then Unity won’t add a component when you add your dependant component (makes sense, interfaces are pretty abstract), but if you manually add something which implements IMyInterface then Unity will not let you remove it.

[RequireComponent(typeof(Rigidbody))]
public class ExampleClass : MonoBehaviour
{
    Rigidbody m_Rigidbody;

    void Awake()
    {
        m_Rigidbody = GetComponent<Rigidbody>();
    }
}

 

 

SelectionBaseMark this GameObject as a selection base object for Scene View picking

When selecting a child of GameObject marked as the selection base in the Scene View then the selection base GameObject will be selected instead.

Note: If you click on an object that is part of a prefab, the root of the prefab is selected, because a prefab root is treated as a selection base.

[SelectionBase]
public class ExampleClass : MonoBehaviour
{
}

 

 

SerializeFieldForce Unity to serialize a private field

By forcing Unity to serialize a private field we can expose it to the inspector without having to declare the variable as public. This way it isn’t unnecessarily exposed to other classes but we can still assign a value in a nice and easy way.

 

 

SpaceAdd some spacing in the Inspector

This is purely for organising the inspector to make it clearer. Spacing is in pixels.

Note: Attributes aren’t necessarily drawn in the inspector in the order they are coded! Therefore all attributes have an optional attribute to specify the order they should be drawn in the inspector. In the example below the spacing will be drawn (or I suppose to be more specific, not drawn 😉 ) before the Header because of the specified order.

public class ExampleClass : MonoBehaviour
{
    [Header("Health Settings")]
    [SerializeField]
    int m_Health = 0;
    [SerializeField]
    int m_MaxHealth = 100;

    [Space(20, order = 1)]

    [Header("Shield Settings", order = 2)]
    [SerializeField]
    int m_Shield = 0;
    [SerializeField]
    int m_MaxShield = 100;
}

 

 

TextArea – Make a string be edited with a height-flexible and scrollable text area

This is essentially the same as the Multiline attribute but you can specify the minimum and maximum number of lines for the inspector to draw. The field will expand according to the size of the text and a scrollbar will appear if the text is bigger than the area available.

public class ExampleClass : MonoBehaviour
{
    [TextArea(2, 4)]
    [SerializeField]
    string m_Description;
}

 

 

TooltipSpecify a tooltip for a field in the Inspector window

The tooltip is shown when hovering over the field it is associated to.

public class ExampleClass : MonoBehaviour
{
    [Tooltip("The maximum health the player can have.")]
    [SerializeField]
    int m_MaxHealth = 100;
}

 

Input Registrar – Example

Alexander - 09/06/2016

This is my input system. There are many like it, but thi- okay yeah, I made that joke last time.

So when working on Charge the HTC Vive wasn’t out yet and very little had been made for it in Unity beyond tech demos and the example code people were sharing for VR controller input was mostly just button checks in the update loop – classic ‘my first game’ stuff. On top of this most of the good input solutions for Unity are premium, and as good as assets such as Rewired are, sometimes you want to make your own thing which is good enough for you because ‘it’s free’ to do so.

Since Charge I reworked Input Registrar to be more than just a Vive solution that can easily be expanded for different controllers, easy input rebinding, multiple players etc. I’m gonna start with showing a simple example of how to use Input Registrar with the HTC Vive to add some basic shooting functionality. The following script would be added to both of the Controller GameObjects which are part of the SteamVR CameraRig prefab.

using InputRegistrar;

[RequireComponent(typeof(SteamVR_TrackedObject))]
public class ViveController : MonoBehaviour
{
    SteamVR_TrackedObject trackedObject;

    [SerializeField]
    InputManager inputManager;

    void Start()
    {
        trackedObject = GetComponent<SteamVR_TrackedObject>();

        Initialise();
    }

    public void Initialise()
    {
        inputManager.Initialise((int)trackedObject.index);
        inputManager.RegisterButtonInput(new ButtonGesture(InputValue.Beta, ButtonAction.OnPressDown), Shoot);
        inputManager.RegisterAxisInput(new AxisGesture(InputValue.Beta, AxisAction.GetAxis), TriggerHeld);
    }

    void Update()
    {
        inputManager.Update();
    }

    void Shoot()
    {
        inputManager.VibrateController(0.8f);

        Ray raycast = new Ray(transform.position, transform.forward);
        RaycastHit hit;
        bool bHit = Physics.Raycast(raycast, out hit, 50f);
        if (bHit)
        {
            Rigidbody rb = hit.collider.GetComponent<Rigidbody>();
            if(rb)
                rb.AddForceAtPosition(transform.forward * 50f, hit.point, ForceMode.Impulse);
        }
    }

    void TriggerHeld(float _value)
    {
        print("Trigger squeeze amount: " + _value);
    }
}

Firstly, and most importantly, we need an InputManager (in the InputRegistrar namespace, not the Unity one) which is a serializable non mono class. This can either be serialized allowing us to set the InputMethod in the inspector (in this case Vive, but could also be Xbox controller, keyboard etc), or an instance can be created in code.

As this is a Vive input script we need a variable for the SteamVR_TrackedObject because we need a way to differentiate which controller we want to get the input from, which is done by passing the controller index to the input manager on line 20 (highlighted).

Now we want to register all the inputs which in this case is just two, one ButtonInput and one AxisInput. The process is essentially the same but differentiating between a button and an axis allows us to clearly define if we want to return a value or not; see how TriggerHeld expects a float while Shoot does not even though both apply to the same input (InputValue.Beta, explained below). There is also a third case for DoubleAxisInput which expects a Vector2 which for the Vive controller is only applicable for the touchpad.

To specify what InputGesture we want to map a method to we pass a gesture to RegisterInput – where a gesture is a combination of an InputValue and an InputAction. The InputValue is the shortcode for the button or axis on the controller, e.g. for the Vive alpha is the touchpad, beta is the trigger, gamma is the grip buttons and delta is the application menu button. I use the greek alphabet as a layer between the input and output (see Command Pattern) which allows for easy remapping, controller swapping etc. Say I want to swap from a PS4 controller to an Xbox One controller in a PC game then all I need to do is unregister the current PS4 registrar and register an Xbox registrar without having to worry about how each input maps on the new controller. Finally the InputAction is the action we want to check the specified input for, in this case OnPressDown is the first instance a button is pressed down and GetAxis will call the associated method whenever an axis is not zero.

This has been a quick look into Input Registrar and hopefully I’ll get round to sharing more of the how it works code soon.

Non MonoBehaviour State Machine

Alexander - 08/06/2016

This is my state machine. There are many like it, but this one is mine.

I originally wrote this when working in XNA a couple of years ago and more recently I wanted a state machine in Unity. There are a number of solutions out there but I remembered I had my own so I adapted it for use in Unity which is what I’m sharing today.

In short this state machine requires one initial set-up where you create an instance of the state machine and a number states. From there you define the transitions between states so the state machine knows when to change state and which state to change to. I’m essentially describing state machines in general so let’s get on with the code.

public abstract class State<T>
{
    public abstract void Enter(T owner);    //Do something the instance we enter this state
    public abstract void Execute(T owner);  //Do something each update tick while in this state
    public abstract void Exit(T owner);     //Do one last thing before we exit this state

    public string Name { get; set; }

    private List<Transition<T>> transitions = new List<Transition<T>>();
    public List<Transition<T>> Transitions
    {
        get { return transitions; }
    }

    public void AddTransition(Transition<T> _transition)
    {
        transitions.Add(_transition);
    }
}

The three methods Enter, Execute and Exit need to be overridden in derived State classes which is where the functionality of the state is defined. Each state also has a list of transitions which are defined by: A) the condition which needs to be met in order to trigger the transition and B) the state which needs to be transitioned to when the condition is met (see Transition class below). Lastly the state can be given a name so it doesn’t feel unloved.

public delegate bool Condition();

public class Transition<T>
{
    public readonly State<T> NextState;
    public readonly Condition Condition;

    public Transition(State<T> _nextState, Condition _condition)
    {
        NextState = _nextState;
        Condition += _condition;
    }
}

Now we just need the actual state machine which puts it all together.

public class FSM<T>
{
    T owner;

    State<T> currentState;
    public State<T> CurrentState
    {
        get { return currentState; }
    }

    public FSM(T _owner)
    {
        owner = _owner;
        currentState = null;
    }

    public void Initialise(State<T> _state)
    {
        currentState = _state;
        currentState.Enter(owner);
    }

    public void Update()
    {
        if (currentState == null)
            return;

        foreach (Transition<T> transition in currentState.Transitions)
        {
            if (transition.Condition())
            {
                currentState.Exit(owner);
                currentState = transition.NextState;
                currentState.Enter(owner);
            }
        }
        currentState.Execute(owner);
    }
}

You will probably have noticed that each class is generic. This is done so that the states can access the instance of the class passed to the constructor (see public FSM(T _owner) on line 11). This will most likely be the class in which the state machine is created (unless you find some other funky use for it). You’ll then create an instance of a number of states, one of which can be used to initialise the state machine.

Each update tick the state machine loops through all the transitions in the current state and checks them to see if the conditions for those transitions are met, and if they are it transitions to the new state.

Below is a quick example of how to implement the state machine in a mono based class.

public class Example : MonoBehaviour
{
    FSM<Example> stateMachine;

    bool toggleme;

    void Start()
    {
        toggleme = false;

        //Create an instance of the state machine
        stateMachine = new FSM<Example>(this); 

        //Create instances of each state class
        StateOne stateOne = new StateOne();
        StateTwo stateTwo = new StateTwo();

        //Add a transition to State One which changes to State Two when toggleme is true
        stateOne.AddTransition(new Transition<Example>(stateTwo, () => (toggleme == true)));
        //and vice versa
        stateTwo.AddTransition(new Transition<Example>(stateOne, () => (toggleme == false)));

        //Set the initial state of the state machine
        stateMachine.Initialise(stateOne);
    }
    
    void Update()
    {
        stateMachine.Update();

        //Press the Space key to toggle the bool toggleme which will
        //trigger the transitions between State One and State Two
        if (Input.GetKeyDown(KeyCode.Space))
            toggleme = !toggleme;
    }
}

In this example whenever then space key is pressed the state machine will transition between StateOne and StateTwo which will log a message to the console saying which state we have just transitioned to (these states are identical except for their name, see the code below).

Once you have created an instance of a state you can start adding transitions to it. On line 19 (highlighted) you can see a transition is added to the state StateOne by creating a new transition (passing the same type as when the state machine is initialised) and passing the state we want to transition to and the condition that needs to be met to trigger the transition. The condition is most easily created using a lambda expression and passing your condition such as toggleme == true in the example above.

class StateOne : State<Example>
{
    public StateOne()
    {
        Name = "State One";
    }

    public override void Enter(Example _owner)
    {
        //Do something the instance we enter this state
        Debug.Log("Entered " + Name);
    }

    public override void Execute(Example _owner)
    {
        //Do something each update tick while in this state
    }

    public override void Exit(Example _owner)
    {
        //Do one last thing before we exit this state
    }
}

As mentioned earlier, the methods of each state provide access to the mono based class which was passed when creating the state machine. This allows us to call methods on that class and with it you can do mono based stuff 😉

This is one of the simplest versions of this state machine and it can easily be expanded with additional functionality that is commonly seen in some other state machines such as the ability to see the previous state.

Drop a comment below if you have any questions or perhaps you just want to say something.

Alexander Dudok de Wit

http://onf.re/