Game Design Tips #16 – [Unity + C#] Linear Interpolation

It’s been an awfully long time since my last post – blame coursework! I have a few weeks to get a couple of posts in before I have more coursework and then exams, so enjoy me while I’m here.

If you’ve coded at all with Unity, you’ve probably noticed its API has a lot of methods called ‘lerp’. Mathf.Lerp(), Vector3.Lerp(), Color.Lerp(); all of these are very helpful methods. But what exactly do they do, and how should we be using them properly? First of all, I’m gonna go ahead and show you how they’re meant to be used, then I’m gonna break them horribly to show you cheap ways of doing cool stuff.

How to use Lerp without being hacky

‘Linear Interpolation’ is a lot of syllables to get your head around, so first of all, let me explain what it means. Let’s say we have a thing. We want the thing to change into another thing at a constant (linear) rate. This is what linear interpolation does – it takes a vector, colour, float, you name it, and changes it into a new one.

tip-16_img01

This is the lerp method for Vector3. We pass in startPos, endPos (both Vector3s) and a float parameter; this parameter should be between 0.0 and 1.0. When time = 0.0, the object’s position will be 100% at startPos and 0% at endPos, and when time = 1.0, it will be placed at 0% startPos and 100% endPos. It’s easiest to demonstrate what lerp is doing when talking about Color.Lerp(), so we can use a pretty diagram:

tip-16_img02

Here, the square represents the RGB colour scale found in Unity’s colour picker (well, flipped horizontally). When we use Color.Lerp() in this way, when the third parameter is 0, the method returns a red colour (#ff0000 in hexadecimal RGB colour representation) and when the parameter is 1, we get full white (#ffffff). At any point in between, we blend between the two linearly – at 0.5, we’ll get a pink-ish colour exactly halfway between red and white on the RGB scale (#ff7f7f roughly) and at 0.75, we get something mostly white but retaining a tiny bit of red (about #ffbfbf).

Once we understand what lerp is doing when we pass in certain numbers, we can pull everything together cleanly into a coroutine.

tip-16_img03

We pass in the sprite renderer whose colour will change, the colour it will change to and how long it will take to change. The coroutine automatically works out all of the needed variables for the user, so we don’t need to pass in the start colour. Every frame, we set the new colour of the renderer based on what percentage the current time is between the start and end times. Simple! The final step is to ensure the colour gets set to the end colour exactly, since the loop might have exited only 99.9% through the lerp (it’s never going to be noticeable to the human eye, but I’m doing this for the sake of completeness and to avoid triggering anyone’s OCD).

How to use Lerp badly

Now that we know how to use lerp properly, it’s time to be a terrible person! I’ll show you one popular way of using lerp badly. Assume, for the following example, that the ‘speed’ variable is set to 0.1f.

tip-16_img04

tip-16_img05

I’ve tried to illustrate what happens on each frame here. At the start (on the first time interval), the sprite colour is at its original colour. At the second time interval (0.1s after starting), we have moved 10% from the original position towards the final position. This is easy to understand – we move 10% of the way between full red and full white (assuming the original colour was red and targetCol is white). On the next interval, we have travelled another 10%. However, the starting point was not the original red – it was 10% towards white. This means the current colour is 10% between the last colour and full white; it is now 19% towards full white. This process continues; rather than moving linearly between red and white, the end result is a curve.

The reason this works is because the time parameter we pass in is always a fraction between 0 and 1, but the start colour is always changing too. It’s not exact, but roughly every 0.1s, the colour will change 10%. The numbers above won’t be precise since the lerp is running every frame, not every 0.1s, but hopefully this gives you an idea of how this blasphemy is working behind the scenes. This isn’t how lerp is intended to be used, but it is a cheap way of moving between vectors, colours or floats on a curve. It’s disgustingly amazing – dismazing, if you will.

It’s also worth noting that if the parameter passed to lerp is set to below 0 or above 1, it will snap up or down to those boundary values. Now you should be a certified lerp expert! I’ve put both versions of the linear interpolation script online for you to download if you’re too lazy to copy them (which is only a problem because I’m too lazy to make them look nice without resorting to taking screenshots. My bad).

Game Design Tips #13 – [Unity] ScriptableObjects and Custom Project Gizmos

It’s been a while since my last Game Design Tip, but I’m back and ready to show off some cool things I started using very recently. Ever wanted to save data as an asset in Unity? Turns out, there’s a dead easy way to do that. I’d heard of ScriptableObjects before, but not used them; they’re a godsend for any task where you just care about keeping hold of static data for something – weapons, enemies, item drops, you name it.

I’ll take an example I was working on the other day. I have a load of guns that the player may own, each with their own cooldown rates, damage, clip size and whatnot. My strategy at the time would have been to create a MonoBehaviour script that holds a bunch of public variables, stick that script on a bunch of GameObjects and tweak their variables individually, then save them all as prefabs. Upon needing to read the data, I’d instantiate one of those objects (or have them all instantiated at level start), then read off all the variables. In doing so, I’d waste a bunch of memory loading up GameObjects whose sole purpose was to hold data, clogging up the RAM with redundant data and making the garbage collector mad.

tip_13-01

That was dumb.

Instead, I should have used ScriptableObjects, something Unity provides for this exact purpose. Instead of extending MonoBehaviour, we’re first of all going to extend ScriptableObject. That’s going to tell Unity that this script is special, just like every one of my readers. That’s my flattery quota for the day met!

tip_13-02

You’ll also notice we gave the entire class the [Serializable] attribute. This is provided by the System namespace (hence, that’s included on line 2) and tells Unity we’ll want it to do stuff to it to make it visible in the Inspector. In reality, it’s a lot more complex than that, but we don’t care for now, do we? We just want our data saved. Oh, and I’ve stuck this class in the WeaponClasses namespace for the hell of it, but you can ignore that if you so wish. In my example, WeaponType is just an enum to deduce which class the weapon falls under.

Now that we’ve gone about making our data serializable, we need a way to make these new Weapon objects. There’s probably many ways to do this, but I’ve used a bit of Editor scripting to get the job done. It might look a bit alien at first, but it’ll all start to come together soon.

tip_13-03

This is a brand-new script which doesn’t extend Monobehaviour, ScriptableObject etc. It just needs to import UnityEngine and UnityEditor, and the script must be placed under Assets/Editor. We use the [MenuItem] attribute to add a lovely menu entry for making new weapons – now, we’ll be able to click ‘Assets’ on the toolbar, hover over ‘Create’ and find ‘Weapon’ listed underneath all the usual entries. Clicking this places a brand-spanking-new Weapon under the path defined in the script (line 14) and focuses Unity on the new Weapon in the Project Window (lines 16 and 17). Just a word of warning – it’ll replace anything called NewWeapon.asset in that directory, so I’d rename it straight away! Now you’ll have an awesome new Weapon instance you can reference in your scripts without having to attach it to some empty GameObject.

tip_13-04

Not a typo, just a really fun thing for gunning people down.

I did a little more processing with mine using an additional, more complex Editor script to hide certain variables based on the type of weapon, but this is basically what you get when you click on one of your Weapon instances in the Project window. We’re done with ScriptableObjects now, but let’s go one step further and make a cool gizmo for our Weapons.

Weapon icon

This is the icon I’ll be using. It’s dead easy to tell Unity to use this for our Weapons; just save this under the exact name “Weapon icon.png” or “Weapon icon.tif” – only .png and .tif files are allowed. The syntax is [Class Name] [single space] [the word “icon”] [.png/.tif]. Super simple stuff!

tip_13-05

Now we have pretty-looking icons for our Weapons and a clean way to save data for each Weapon. Unfortunately, it doesn’t make them look different in the Inspector, but at least they have an icon in the Project view that makes them easier to find. I hope this has been helpful, and I’ll be back soon with more tips.

Unity Super-Helpful Tips: Scripting

unity-logo

This is the first in a series of (hopefully) helpful mini-tutorials and tidbits of knowledge I’m gonna be passing onto you, my loyal readers! I say series – you know how these things usually turn out, but I’ll do my best! There’s a wealth of hidden tricks that some of you won’t know about – the point of these posts are to reveal them to you all in their globally-illuminated beauty. I swear Unity 5 hasn’t gone to my head. This post will focus on scripting – I’ll be using C# examples mostly, but these tips should also be applicable to Unityscript.

Changes from Unity 4 to 5

First up, only a tiny change, but an important one; you know all those helpful property getters such as xxxxx.rigidbody, xxxxx.renderer, etc? They got killed off in Unity 5. The API changed, and to better modularise the codebase, these properties no longer exist. A moment of silence for our fallen friends, please. With the exception of .transform, which stays because it’s part of Unity’s core module and not the physics or rendering modules, you’ll need to use something like:

myComponent = GetComponent<MyComponentType>();
myTransform = this.transform;     // Still fine.
myGameObject = this.gameObject;   // Fine, part of MonoBehaviour.

Don’t worry though – Unity 5 ships with a tool for automagically finding usage of the deprecated API and switching usages of it for the new one, so switching old projects to shiny new Unity 5 goodness is a breeze. 

Attributes: Serializable and SerializeField

These are two very helpful attributes I use a lot – SerializeField can be used to make any variable appear in the Inspector, even if it is private.

private int myInt = 0;
[SerializeField] private float myFloat = 0.0f;

The first variable, myInt, won’t show up in the Inspector, as it is private. However, myFloat has the SerializeField attribute before it, so it’ll defy its private modifier like a moody teenager and show up in the Inspector anyway – super handy if you have variables you want to change quickly AND keep private.

Serializable is useful for taking entire private classes and making them visible to the Inspector. But when would that be useful? Say you had a particular kind of object that makes it easier to hold a set of values, but then you only need those objects in a different class.

using UnityEngine;
using System.Collections;
using System;

public class MyClass {
    [SerializeField] private DataHolder dataHolder;
    // do other stuff in the class like usual...

    [Serializable]
    private class DataHolder {
        // variables, methods like usual...
        // can only be accessed from MyClass.
    }
}

In the code, no external class can access the DataHolder class, but since we have added the Serializable attribute, we’ll be able to access any public variables stored in DataHolder in the Inspector through MyClass’ dataHolder variable. It’s also worth noting you’ll be able to see any of DataHolder’s private variables if you prefix them with a SerializeField, too, and you can have arrays and lists of DataHolders. Since Serializable is contained in the System namespace, you’ll need to put “using System;” at the top of your code, too.

Preprocessor Directives – different code based on export platform

One of the great things about Unity is its portability – it exports to EVERYTHING. But what if you wanted one script to do different things based on the platform it’s on? A great example would be controls, which are completely different on mobile compared to desktop. There’s a way to do this using preprocessor directives. Don’t let those huge words dissuade you, they’re easy as hell to put in and very useful!

#if UNITY_EDITOR
    Debug.Log("Only runs in the editor");
#elseif (UNITY_IPHONE || UNITY_ANDROID || UNITY_WP8)
    Debug.Log("Only runs on mobile");
#endif

With these, you can make different parts of the same script become invisible to the platforms they’re not needed for. There’s a whole host of Unity-specific directives, and (in C# at least, I’m not sure about Unityscript) there are many more ways to utilise them.

Invocations and Coroutines

Both of these are hugely useful, and you ought to be using them all over the place. Invoking a method is basically like telling Unity “Do this please. But not yet – maybe in five seconds”. You can even go as far to say “Well, do this thing in seven seconds. Then every three seconds after that” using InvokeRepeating.

Invoke("MyMethod", 5f);
InvokeRepeating("MyRepeatingMethod", 7f, 3f);

Coroutines are a bit more of a pain in the ass to get working, unfortunately. It’s a shame, because they’re awesome. Coroutines are a special kind of method that allow you to use yield statements – in non-jargon terms, you can tell a method to hold its horses and wait for a few seconds, or until the end of the current frame, amongst other things. There’s the CancelInvoke() method too, which will remove all invoked instances of the method passed in and stop them being executed after their waiting time.

void Start () {
    StartCoroutine("DoStuff");
}
private IEnumerator DoStuff () {
    Debug.Log("I'm gonna do stuff");
    yield return WaitForSeconds(2f);
    Debug.Log("I did stuff! Woo!");
}

It’s worth noting a few things: in C#, a coroutine must be called with the StartCoroutine() method. You can pass in the method name as a string (plus one parameter after a comma), or like this

StartCoroutine(DoMoreStuff(5f, 7f, 9f));

which is far more useful for any method that requires more than one parameter. The coroutine method itself must have a return type of “IEnumerator”, and will break horribly if it doesn’t return any yield statement. The “WaitForEndOfFrame()” yield type is really useful because it lets you call code after LateUpdate() has finished doing stuff – consult the order of function execution diagram for more information. Seriously, that thing’s basically the equivalent of the 10 Commandments for Unity Developers. There’s also a StopCoroutine() method which is effectively the analogue of CancelInvoke() but for coroutines.

I’ll be back soon with a heap of useful Unity things soon – it probably won’t be scripting next time, but we’ll be digging into the engine itself.

Four By… Two?

You read that right! A brand new game mode is coming your way – Four By Two plays very differently that the existing two modes, as it relies on split-second reaction times and feels a heck of a lot more tense.

4x8-09

It’s real tense when the game’s all sped up. My high score is 32. How rubbish!

The spawning is a little different for Four By Two, as only single tiles spawn at any one time. However, the gap between tiles spawning is random, which adds to the tension. I’m not too sure what other kinds of mode I can add. Perhaps a ‘Futile’ mode, where you’re stuck forever in a 1×1 square, unable to move, with a score of zero? But that would be stupid, and I’m already sadistic enough with this new mode. I’m thinking of doing more fancy stuff with the camera next, such as zooming in and out.

What improvements are there?

On top of this new mode, there’s a couple tweaks too. You may have noticed before how sometimes a couple more tiles spawned after you die? Well, I had a word with the bit of code that made that happen, and he’s going to be doing a lot less breathing nowadays, so now tiles won’t crowd the right-hand side of the screen after death.

Also, occasionally tiles would spawn in a way that meant you had to move three spaces in one timestep, which was utterly impossible (and rage-inducing at times); now, that won’t happen, because tile sets with only one ‘entrance’ on the top or bottom won’t spawn after tile sets with a singular, opposite ‘exit’. For me, it’s a huge improvement, because I no longer feel cheated by the spawning algorithm.

On top of that, you can now pres ‘esc’ in the middle of a game to die instantly, if you so wish. It’s much quicker than waiting for a tile to appear and take you out.

Are there any other new additions?

Yep! There’s a Credits page (which really does need to be fleshed out with more stuff, because so far I’m the only one credited in it), and the framework is up for an options system, complete with an options menu. However, that’s not yet complete, so the button on the main menu won’t work, but the system will work as required in the background.

4x8-10

I’m stereotypically British, so of course tea needs to be a credit.

Well that’s all for this update! You can go download this latest addition at the usual place. Have fun playing!

-Daniel

Oh, and there’s this, too:

Project Spikes Update #4 – Improving Physics

This update doesn’t have a download to accompany it, but I decided to at least tell you guys how things are going. Or I could disappear for a couple months, but would I do that? (Please don’t answer than, I’m a terrible developer. Development team. Developtron.)

I’ve been working a lot on the cubes and laser turrets in particular. Whereas before the cubes would simply disappear when the fell of the end of the level, now they have a death sequence, where the cubes now shrink into nothingness, but by the next downloadable version, there will also be a particle effect when the cube dies.

Additionally, the evil laser turrets can now harm good turrets and cubes (we offered them anger management classes, but all they did was turn their lasers on us). To show the level of harm inflicted upon the poor cubes/turrets, their texture will change as they get more hurt, to look increasingly abused. I’ve finished the beat-up textures for cubes, and by next update I’ll have done so for turrets, too, along with textures for turrets.

8-8-2014-20-20-2

From the bottom-left, going anti-clockwise: Pristine, Used, Chernobyl.

I’ve also made slightly better models for turrets and I’m halfway through texturing them. The good turrets look much the same, just with a couple more details on the legs and parts of the front, but evil turrets look more like the good turrets in construction, with a bit jutting out of the bottom with the second laser coming out of the lower part. But the best thing about the evil turrets: they now have angry faces!

8-8-2014-21-14-47

I’m not sure if the angry turret is funny or creepy. Or both.

This was a very comical suggestion from a friend, but maybe it needs more work. However, the angry eyebrows will stay. When either of the turrets dies, it turns into a pile of debris, which you can see in front of both turrets. Then you can fling the debris around like no tomorrow! You also can’t collide with the debris, so you won’t be subjected to a horrible bumpy ride while walking over it, and when you pick up a not-dead turret, you won’t collide with it, which was a problem before.

Under the hood there have been a lot of optimisations with turrets too, mostly that evil turrets now don’t have two turret scripts attached to them as I’ve re-written some of the laser’s code, so they use less memory. Which is always a bonus, because everyone loves having RAM lying about. There’s also a couple less interesting tweaks and additions to the pause menu, but no-one cares about that because it doesn’t have eyebrows.

Well, that’s about it for this update. I’ll keep you posted on how things are going, and I hope to put out a new download soon. I may also have a new level done by then, but we’ll see how that goes, because I might improve other stuff first.

-Daniel

Random Code: Pause Menu

Have you ever been creating a game when you thought to yourself, “Hey, I want to pause my game”, then you realised that you’re so silly that you don’t know how? Then this is the script for you!

private var paused: boolean = false;
private var mouseX: MouseLook;
private var mouseY: MouseLook;

function Start()
{
    Screen.showCursor = false;
    Screen.lockCursor = true;

    mouseX = GameObject.FindWithTag("Player").GetComponent(MouseLook);
    mouseY = GameObject.FindWithTag("MainCamera").GetComponent(MouseLook);
}

function Update()
{
    if(Input.GetKeyDown(KeyCode.Escape))
    {
        if(!paused)
        {
            paused = true;
            mouseX.enabled = false;
            mouseY.enabled = false;
            Screen.showCursor = true;
            Screen.hideCursor = false;
        }
        else
        {
            paused = false;
            mouseX.enabled = true;
            mouseY.enabled = true;
            Screen.showCursor = false;
            Screen.hideCursor = true;
        }
    }
}

function OnGUI()
{
    Time.timeScale = 1;
    if(paused)
    {
        Time.timeScale = 0;
        if(GUI.Button(Rect(Screen.width / 2 - 75, 200, 150, 25), "Back To Main Menu"))
        {
            Application.LoadLevel("StartMenu");
        }
        if(GUI.Button(Rect(Screen.width / 2 - 75, 250, 150, 25), "Back to Game"))
        {
            paused = false;
            mouseX.enabled = true;
            mouseY.enabled = true;
            Screen.showCursor = false;
            Screen.hideCursor = true;
        }
    }
}

This script isn’t too hard to get to grips with. First, we declare a few variables, and make them private so another script can’t come along and vandalise them. One to store whether we are saved or not, and two for each of the MouseLook scripts attached to the standard Unity first person controller. When these are initialised in the Start function, the script will look for the tags “Player” and “MainCamera” – in my project, these are the the tags assigned to my main camera and the actual player character, each of which have a MouseLook component. It also hides the cursor from view, and locks it to the centre of the screen.

Then, if the player presses the Escape key, it checks whether the game is paused. If it isn’t, then it pauses the game, disables the MouseLook scripts and frees the cursor; if it is paused, the opposite happens. In the function OnGUI(), which is called every time the frame is drawn and is used to draw stuff on-screen using the basic Unity GUI features, the time scale is set to zero when the game is paused, which stops all movement (this basically is the part of the script that actually pauses the game). Then it draws two GUI buttons, centred in the middle of the screen horizontally; one returns the player to the main menu, and the other unpauses the game. Pressing the first button will run Application.LoadLevel(“StartMenu”); which loads a level named “StartMenu”. The latter just unpauses the game.

PauseMenu1

This is the result when you pause the game, a basic menu with two buttons. In any case, I hope this helps, have fun coding!

Random Code: Player Crouching

Unity includes prefabs for 1st- and 3rd-person characters, but they lack some basic movement features such as sprinting and crouching, which I find to be a little bit stupid, so I’ve written code to do this for me. It’s simple really – it starts by finding the character controller component attached to the player, then gets his (or her, equality fans) height, then when the player is holding the ‘c’ key, it scales down the character controller height so your player can squeeze into tiny gaps –  just attach a script with this code in it to your player and it should work. So, just for you, here is my code for crouching!

private var controller: CharacterController;
private var charHeight: float;

function Start()
{
    charController = GetComponent(CharacterController);
    charHeight = controller.height;
}

function Update()
{
    var height = charHeight;

    if(Input.GetKey("c"))
    {
        height = charHeight / 2;
    }

    var lastHeight = controller.height;
    controller.height = Mathf.Lerp(controller.height, height, 5 * Time.deltaTime);
    transform.position.y += (charController.height - lastHeight) / 2;
}

How it works!

Firstly, the variable controller stores the character controller, then charHeight stores a float. In the start function, it finds the controller attached to the player and defines charHeight as the controller’s height as a reference point. Then in the update function, it takes the height at the start of each frame, then if the ‘c’ key is held down, it basically halves the height (smoothing it by using Mathf.Lerp, which takes the first parameter given to it and changes it to the second parameter over time, changing by the third parameter each frame, so basically in this case it takes the normal character height and changes it to half that by 5 units each second, through use of Time.deltaTime to ensure the change is framerate-independent. If that all made sense.) and moves the whole transform down in the y-direction by half the change in height, to match the change in the controller’s height. The net change is that, when the “c” key is held down, the player, along with the colliders and camera attached to him/her, crouches down. Feel free to use this code in your own projects, and if you have any improvements, you can post a comment here. Have fun crouching, and if none of my explanation made sense, just post a comment and I’ll get back to you 🙂