AI Perception in Unreal Engine 4 – How to Setup

For those of you who are wondering what AI Perception is – this is a really nice system in UE4 that provides an easy way for the enemy AI in your game to track hostile/friendly/neutral characters. For example if the enemy AI sees the main character, he will attack it an so on. The AI can become aware of characters through vision, or if they hear them. There are many predefined senses.

The reason for this post is that setting up the AI Perception is very easy, but there is not much documentation yet and it was very hard for me to find a proper way to set it right.

The Setup

There are two components that we need: AIPerceptionComponent and AIPerceptionStimuliSourceComponent. The AIPerceptionComponent is the component that listens for perception stimulants (sight, hearing, etc.). The AIPerceptionStimuliSourceComponent is a stimuli source for the AIPerceptionComponent. The stimuli source stimulates the perception of the enemy AI, so that it can detect the source (our character for example).

I’ve seen many people add the AIPerceptionComponent to the enemy Character, but that is incorrect. It must be added to it’s AI Controller.

AIPerceptionComponent Setup

We create a default AIController, and the only component we add to it is an AIPerception Component. We are going to configure it only for sight sense like so.

AEnemyAIController

UAIPerceptionComponentSetup

I left everything to the default values. As you can see it’s setup only to detect enemies.

AIPerceptionStimuliSourceComponent Setup

The AIPerceptionStimuliSourceComponent must be added to any actors that we want to be stimuli sources for the AIPerceptionComponent. In our case we add it to our character.

AKnightCharacter

UAIPerceptionStimuliSourceComponent

Is it working?

Lets add an event to the EnemyAIController Blueprint to see if it’s working.

BP_EnemyAIController

PerceptionNotWorking

Well, the “Found” message is not printed so it’s not working. Well I can actually say that it works properly. The message is not being printed on screen because the enemy is not considering us as an enemy. By default all characters are neutral to each other. So how do we tell the enemy AI that the main character is actually an enemy?

Different Teams Setup

We need to place the enemy AI and our character in different teams. By default they are in a team NoTeam which is an enum value that equals to 255. Unfortunately it can’t be done entirely in blueprints. We need to write some code.

In the constructor of the AEnemyAIController we set the team of the AI like so.

AEnemyAIController::AEnemyAIController(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	// Assign to Team 1
	SetGenericTeamId(FGenericTeamId(1));
}

We can’t do the same with the player controller however. Here is the tricky part. A player is controlling a character that is of a certain team, the controller itself doesn’t have a team.

In order to assign our character to a team he needs to implement the IGenericTeamAgentInterface interface. The AIController already implements it. Then we need to override the GetGenericTeamId function. Lets do it.

// KnightCharacter.h
UCLASS()
class THEKNIGHT_API AKnightCharacter : public ACharacter, public IGenericTeamAgentInterface
{
	GENERATED_BODY()

	// ...

private:
	FGenericTeamId TeamId;

	virtual FGenericTeamId GetGenericTeamId() const override;

	// ...
};

// KnightCharacter.cpp
AKnightCharacter::AKnightCharacter(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	// ...
	TeamId = FGenericTeamId(0);
	// ...
}

FGenericTeamId AKnightCharacter::GetGenericTeamId() const
{
	return TeamId;
}

Now if we test it again, the enemy is considering us as an enemy and is seeing us.

PerceptionWorking

The reason our character is “Found” if we exit the field of view of the enemy is that the perceptions is updated when we exit the sight of the enemy too.

How To Create A Fancy Portal Effect In Unity

Expectations

Recently I created a portal particle system in Unity for a game that I am developing. I am really pleased with the result and I want to share with you how to create one yourselves. Here is the final effect that we will be making today.

What do we need

We need four textures

T_Portalbackground
T_PortalCircle
T_PortalDust
T_PortalNoise

With the first 3 we are going to create the particle system itself, which consists of 5 sub-particle systems. With the noise texture (the one with RGB colors) we are going to distort each sub-system to achieve the final result.

We are also going to need 2 custom shaders – Additive and Multiplicative Particle Distortion Shaders. They are very cheap and optimized especially for mobile devices. The game I am working on is a mobile game after all.

Here is the Additive Shader

Shader "Custom/Mobile/Particles/Additive Distortion" {
	Properties{
		_MainTex("Main Texture", 2D) = "white" {}
		_NoiseTex("Noise Texture", 2D) = "white" {}
		_IntensityAndScrolling("Intensity (XY), Scrolling (ZW)", Vector) = (0.1,0.1,0.1,0.1)
	}
	SubShader{
		Tags {
			"IgnoreProjector" = "True"
			"Queue" = "Transparent"
			"RenderType" = "Transparent"
		}
		Pass {
			Blend One One
			ZWrite Off

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"

			uniform sampler2D _MainTex;
			uniform sampler2D _NoiseTex;
			uniform float4 _MainTex_ST;
			uniform float4 _NoiseTex_ST;
			uniform float4 _IntensityAndScrolling;

			struct VertexInput {
				float4 vertex : POSITION;
				float2 texcoord0 : TEXCOORD0;
				float2 texcoord1 : TEXCOORD1;
				float4 vertexColor : COLOR;
			};

			struct VertexOutput {
				float4 pos : SV_POSITION;
				float2 uv0 : TEXCOORD0;
				float2 uv1 : TEXCOORD1;
				float4 vertexColor : COLOR;
			};

			VertexOutput vert(VertexInput v) {
				VertexOutput o;
				o.uv0 = TRANSFORM_TEX(v.texcoord0, _MainTex);
				o.uv1 = TRANSFORM_TEX(v.texcoord1, _NoiseTex);
				o.uv1 += _Time.yy * _IntensityAndScrolling.zw;
				o.vertexColor = v.vertexColor;
				o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

				return o;
			}

			float4 frag(VertexOutput i) : COLOR {
				float4 noiseTex = tex2D(_NoiseTex, i.uv1);
				float2 offset = (noiseTex.rg * 2 - 1) * _IntensityAndScrolling.rg;
				float2 uvNoise = i.uv0 + offset;
				float4 mainTex = tex2D(_MainTex, uvNoise);
				float3 emissive = (mainTex.rgb * i.vertexColor.rgb) * (mainTex.a * i.vertexColor.a);

				return fixed4(emissive, 1);
			}
			ENDCG
		}
	}
	FallBack "Mobile/Particles/Additive"
}

And the Multiplicative Shader

Shader "Custom/Mobile/Particles/Multiply Distortion" {
	Properties{
		_MainTex("Main Texture", 2D) = "white" {}
		_NoiseTex("Noise Texture", 2D) = "white" {}
		_IntensityAndScrolling("Intensity (XY), Scrolling (ZW)", Vector) = (0.1,0.1,0.1,0.1)
	}
	SubShader{
		Tags {
			"IgnoreProjector" = "True"
			"Queue" = "Transparent"
			"RenderType" = "Transparent"
		}
		Pass {
			Blend DstColor Zero
			ZWrite Off

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"

			uniform sampler2D _MainTex;
			uniform sampler2D _NoiseTex;
			uniform float4 _MainTex_ST;
			uniform float4 _NoiseTex_ST;
			uniform float4 _IntensityAndScrolling;

			struct VertexInput {
				float4 vertex : POSITION;
				float2 texcoord0 : TEXCOORD0;
				float2 texcoord1 : TEXCOORD1;
				float4 vertexColor : COLOR;
			};

			struct VertexOutput {
				float4 pos : SV_POSITION;
				float2 uv0 : TEXCOORD0;
				float2 uv1 : TEXCOORD1;
				float4 vertexColor : COLOR;
			};

			VertexOutput vert(VertexInput v) {
				VertexOutput o;
				o.uv0 = TRANSFORM_TEX(v.texcoord0, _MainTex);
				o.uv1 = TRANSFORM_TEX(v.texcoord1, _NoiseTex);
				o.uv1 += _Time.yy * _IntensityAndScrolling.zw;
				o.vertexColor = v.vertexColor;
				o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

				return o;
			}

			float4 frag(VertexOutput i) : COLOR {
				float4 noiseTex = tex2D(_NoiseTex, i.uv1);
				float2 offset = (noiseTex.rg * 2 - 1) * _IntensityAndScrolling.rg;
				float2 uvNoise = i.uv0 + offset;
				float4 mainTex = tex2D(_MainTex, uvNoise);
				float3 emissive = lerp(float3(1,1,1), mainTex.rgb * i.vertexColor.rgb, mainTex.a * i.vertexColor.a);

				return fixed4(emissive, 1);
			}
			ENDCG
		}
	}
	FallBack "Mobile/Particles/Multiply"
}

As you can see, they are almost exactly the same. The difference is only in the blending and the calculation of the emissive color in the fragment function.

Step By Step

First we are going to make the particle system with the built-in mobile additive and multiplicative shaders, and then we are going to add distortion with our custom shaders. I want to do this, so you can see how big the difference is.

Background

Using an additive shader we start by emitting a single particle with the first texture. The exact color is “FFFFFF4B“. It should look like this.

Nice start huh?

Black Hole

Yeah, you hear right. We are going to create a black hole.
By using a multiplicative shader we are going to emit a single smaller black circle over the white one. The exact color is “000000AF“. Something like this.

Rotating Frame

Next using an additive shader and the second texture we emit 3 circles – each with different start rotation and angular velocity. The exact color is “FFFFFF80“”. It looks like this.

Pulsing Circles

Again using an additive shader and the second texture we start emitting pulsing circles from the center towards the frame. Each circle has different start rotation and no angular velocity. The rate is 3 particles per 2 seconds. Again the color of each circle is “FFFFFF80“.

Small Sucked Particles

Using an additive shader and the third texture we add small particles that are sucked into the portal. Again the color is “FFFFFF80“.

Adding Distortion

The only thing that’s left is adding distortion to each sub-particle system with our custom additive and multiplicative shaders and the noise texture. The only thing we don’t distort are the sucked particles.

Bezier Curves

Bezier Curves are very useful and have many applications, but what do we need to know to implement one ourselves? Well, you can keep reading, or you can just download the unity package that I made.

Lerp (Linear Interpolation)

Before we start we need to know what Lerp is. If you want to understand it more mathematically you can check the description in wikipedia. It’s very simple. Lerp is a function which takes three parameters – a, b and t, where a is start value, b is end value, and t is time (between 0 and 1). The function is defined like this

Lerp

In code it looks like this

float Lerp(float a, float b, float t)
{
    return (1f - t) * a + t * b;
}

Note that we can use the same logic if we want to lerp vectors

Vector3 Lerp(Vector3 a, Vector3 b, float t)
{
    return (1f - t) * a + t * b;
}

Bezier Curves

Now that we know what lerp is we can start.
A bezier curve is also defined by a function, but a function of higher degree (cubic to be precise). For a cubic curve we need 4 points (control points). These 4 points control the shape of the curve. Lets call the points p0, p1, p2 and p3. p0 is called start point, p1start tangent, p2end tangent, and p3end point. Lets imagine that the points are positioned like this:

Control Points

The slider at the bottom represents the t value.
In order to construct the function we are going to go through some steps. In each step we are going to make some lerps, and at the end we will combine these lerps.

Step One

We are going to make 3 lerps – between p0 and p1, between p1 and p2, and between p2 and p3.

Vector3 a = Lerp(p0, p1, t);
Vector3 b = Lerp(p1, p2, t);
Vector3 c = Lerp(p2, p3, t);

It looks like this

Lerp One

Now lets draw lines between a and b, and between b and c

Lerp One Plus Lines

Step Two

Again we are going to make some lerps – this time between a and b, and between b and c

Vector3 d = Lerp(a, b, t);
Vector3 e = Lerp(b, c, t);

Lerp Two

Now lets draw a line between d and e

Lerp Two Plus Lines

Step Three

Now all we need to do is to make one last lerp between d and e, so we can find the point on the curve at any given time t.

Vector3 pointOnCurve = Lerp(d, e, t);

Lets draw the point

Lerp Three

And now let’s draw the bezier curve

Draw Curve

The Function

Now if we combine all these lerps, we get the final function that defines any bezier curve by 4 points and a t value

Vector3 GetPointOnBezierCurve(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
{
    Vector3 a = Lerp(p0, p1, t);
    Vector3 b = Lerp(p1, p2, t);
    Vector3 c = Lerp(p2, p3, t);
    Vector3 d = Lerp(a, b, t);
    Vector3 e = Lerp(b, c, t);
    Vector3 pointOnCurve = Lerp(d, e, t);

    return pointOnCurve;
}

However this function is not very cheap. With a little math we can simplify the function and thus improve the performance.

Optimizations

Mathematically the function looks like this

Point On Curve

With a little calculations on paper we can simplify it to this

Optimized

So the final function in code can be written like this

Vector3 GetPointOnBezierCurve(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
{
    float u = 1f - t;
    float t2 = t * t;
    float u2 = u * u;
    float u3 = u2 * u;
    float t3 = t2 * t;

    Vector3 result =
        (u3) * p0 +
        (3f * u2 * t) * p1 +
        (3f * u * t2) * p2 +
        (t3) * p3;

    return result;
}

Bezier Splines (Bezier Paths)

What if we want to create a more complex curve?
There are two options:

  • Use a higher degree function
  • Combine (chain) cubic bezier curves

The first option is not very good, because every time we increase the degree of the function, we create more job for the CPU (we increase the number of calculations).
The second one is more widely used, and it can be explained like this:

Bezier Spline

p3 is the end of the first bezier curve and the start of the second one, and so on.

Observer Pattern

What is the observer pattern used for, and why do we need it? If you’ve heard of the Model-View-Controller architectural pattern, let me tell you that underlying that is the Observer pattern. Observer is so widely used that java put it in its core library (java.util.Observer) and C# baked it right into the language (the event keyword).

In game development we have so many classes that do very different things. It’s good to keep them as decoupled as possible, but sometimes that is very hard. The observer pattern is a great tool to keep your code decoupled very easily.

Achievement System

Let’s say that we want to implement an achievement system. We can have so many different achievements like “Make 20 consecutive headshots”, “Beat the game under 3 hours”, “Fall from high height without dying”. Unlocking these achievements means that we have to make calls to some methods in many different places in our code. Let’s take for example the “Fall from high height without dying”. As you can guess this achievement is somehow tied to the Physics Engine, but do we really want to see a call to AchievementsManager.Unclock(Achievement.FallFromHighHeightWithoutDying) right in the middle of our collision detection or something? How do we avoid that?

That’s what the observer pattern is for. It lets one piece of code announce that something interesting happened without actually caring who receives the notification.

Imagine that our game world consists of entities. The interface for our entities is something like this:

public interface IEntity
{
    void PhysicsUpdate();

    // Other methods
}

The Physics Engine is responsible to update the physics of all entities in the game world. Our character is also an entity, and his PhysicsUpdate() method may look something like this:

public class Character : IEntity
{
    public virtual void PhysicsUpdate()
    {
        // Apply gravity and stuff...

        if (this.FellFromHighHeightWithoutDying())
        {
            AchievementsManager.Unlock(Achievement.FallFromHighHeightWithoutDying);
        }
    }

    // Other code...
}

We want to get rid of the call that unlocks the achievement through our AchievementsManager, because this way we couple the achievements system with our character. We are going to replace it with a call to another method:

NotifyObservers(this, Event.FallFromHighHeightWithoutDying);

This single line of code just says: “Look, I don’t know if anybody cares, but this entity just fell from high height without dying”. If someone cares however, he knows what to do. That someone is actually the observer. There can also be more than one observer, but let’s not get ahead of ourselves. Now we are decoupled from the AchievementsManager, but where did we actually get the NotifyObservers method from? All I can say is that it’s part of the big picture. Now lets draw that picture.

The Observer

Let’s start with the observer class. All observers observe for something interesting to happen. The interface for all observers is as follows.

public interface IObserver
{
    void OnNotify(IEntity entity, Event ev);
}

In our case the observer is the AchievementsManager.

public class AchievementsManager : IObserver
{
    public void OnNotify(IEntity entity, Event ev)
    {
        switch (ev)
        {
            case Event.FallFromHighHeightWithoutDying:
                bool isEntityCharacter = (entity as Character) != null;
                if (isEntityCharacter)
                {
                    this.UnlockAchievement(Achievement.FallFromHighHeightWithoutDying);
                }

                break;

            // Other cases...
        }
    }

    private void UnlockAchievement(Achievement achievement)
    {
        // Unlock if not already unlocked...
    }
}

The Observable Objects

The observable objects are the objects that are being observed by observers. These objects must also notify the observers if anything interesting happened. Let’s implement the interface for all observable objects. We need to be able to add, remove and notify any observers.

public interface IObservable
{
    void AddObserver(IObserver observer);

    void RemoveObserver(IObserver observer);

    void NotifyObservers(IEntity entity, Event ev);
}

In our case the observable object is our Character.

public class Character : IEntity, IObservable
{
    private List<IObserver> observers;

    // IEntity interface implementation
    public virtual void PhysicsUpdate()
    {
        // Apply gravity and stuff...

        if (this.FellFromHighHeightWithoutDying())
        {
            this.NotifyObservers(this, Event.FallFromHighHeightWithoutDying);
        }
    }
    // END IEntity interface implementation

    // IObservable interface implementation
    public virtual void AddObserver(IObserver observer)
    {
        this.observers.Add(observer);
    }

    public virtual void RemoveObserver(IObserver observer)
    {
        this.observers.Remove(observer);
    }

    public virtual void NotifyObservers(IEntity entity, Event ev)
    {
        foreach (var observer in this.observers)
        {
            observer.OnNotify(entity, ev);
        }
    }
    // END IObservable interface implementation
}

Now you see how it works. Our character is being observed by the achievement system. However, he actually doesn’t know that. He only knows that maybe he is being or is not being observed (sounds spooky :D). Either way, he must notify his observers (if any) when something interesting happens. The good thing is that he actually doesn’t know the true faces of his observers. He only has a list of references to instances of some interface. In this list our AchivementsManager is present, because the manager needs to know when the character falls from high height without dying. There is no problem for the AchievementsManager to know about the existence of our character, the problem is when our character knows about the manager. However, that problem is no more thanks to the observer pattern.

Deleting Observers

If you are using C# for a scripting language, or any language with garbage collection you must be wary of memory leaks. What do I mean? Let’s say for example that we have an observer (UI Screen) that observers some stats of our main character. When the player displays this UI screen, it’s added to the list of observers of the character, so when the stats change the UI screen is notified and updated. Let’s say the player closes this screen. The screen is not visible anymore. However the garbage collector will not delete it. You know why? Because we didn’t remove the observer from the list of observers. Our main character has a reference to the UI screen and the GC will not delete it.

If some observer has done it’s job and is not needed anymore, make sure that not a single observable object has a reference to it. Otherwise the observer won’t be garbage collected.

State Pattern

Why do we need this pattern and when to use it? In order to show you we are first going to see some bad code, and then we are going to rewrite the code with the state pattern.

Bad Code

Imagine that we are working on a third person stealth game, and we need to implement the character and make him respond to user input. He can jump and duck.

public class Character
{
    private bool isGrounded;
    private bool isDucking;
    private bool isJumping;

    public void Update()
    {
        // Update the player depending on the private fields
    }

    public void HandleInput(Input input)
    {
        if (input == Input.PRESS_SPACE)
        {
            if (this.isGrounded && !this.isDucking)
            {
                this.isJumping = true;
                this.isGrounded = false;
            }
        }
        else if (input == Input.PRESS_CTRL)
        {
            if (this.isGrounded)
            {
                this.isDucking = true;
            }
        }
        else if (input == Input.RELEASE_CTRL)
        {
            if (this.isDucking)
            {
                this.isDucking = false;
            }
        }
    }
}

At first glance this code is not written badly. When we press “Space” the character can jump only if he is grounded and not ducking. If we press “Ctrl” the character can duck only if he is grounded, not when he is jumping, and so on, and so on. Now imagine that the character can also swim, or even skydive like in Just Cause. Maybe he can also enter different vehicles (cars, jet planes). For all these states of the character we need different booleans – isSwimming, isSkydiving, isInCar, isInJetPlane. In all of these states the character has different input handling. If he is grounded for example and we press “Space” he will jump, but what if he is swimming, or he is in a car and we press “Space” again. Maybe while swimming  the character will ascent, and while he is in a car he will activate the brakes of the car. Now imagine that the character can do many other things. Soon our HandleInput(Input input) and Update() methods will be a nightmare to extent and maintain. In such cases the use of state machines can save our lives.

Finite State Machines

Finite State Machines are very simple. They only sound fancy. We can visualize our current character logic like that

State Machine

  1. The machine has a fixed set of states – Grounded, Ducking and Jumping in our case
  2. Only one state can be active at a time
  3. We can send input to the machine – in our case this is raw input from the user
  4. Each state has a set of transitions – each associated with an input and pointing to another state

Good Code – The State Pattern

Basically, all we need to do is to implement a finite state machine in code. How do we do that? If you are doing it for the first time – it’s hard. It’s actually very easy. Once you see how to do it, you won’t forget it.


Let us first start by implementing an interface for all states. Lets name it ICharacterState

public interface ICharacterState
{
    void OnEnter(Character character);

    void OnExit(Character character);

    void ToState(Character character, ICharacterState targetState);

    void Update(Character character);

    void HandleInput(Character character, Input input);
}

OnEnter and OnExit are very useful, because we can execute some code when the character enters/exits a specific state – play a sound, change the animation of the character, etc. These methods will be called automatically when we make a call to the ToState method. In order to make it automated we need a base abstract class for all of the states. Lets name it CharacterStateBase. But first lets change out Character class like this.

public class Character
{
    private ICharacterState state;

    public ICharacterState State
    {
        get
        {
            return this.state;
        }
        set
        {
            this.state = value;
        }
    }

    public void Update()
    {
        this.State.Update(this);
    }

    public void HandleInput(Input input)
    {
        this.State.HandleInput(this, input);
    }

    // Other code
}

The character has a state. In his Update() method we update his current state. Every state also has a different input handling. In the HandleInput(Input input) method we just make a call to the HandleInput(Character character, Input input) method of the current state.


And now the CharacterStateBase class.

public abstract class CharacterStateBase : ICharacterState
{
    public virtual void OnEnter(Character character) { }

    public virtual void OnExit(Character character) { }

    public virtual void ToState(Character character, ICharacterState targetState)
    {
        character.State.OnExit(character);
        character.State = targetState;
        character.State.OnEnter(character);
    }

    public abstract void Update(Character character);

    public abstract void HandleInput(Character character, Input input);
}

All that is left is to implement the “Grounded”, “Jumping” and “Ducking” states.


public class GroundedCharacterState : CharacterStateBase
{
    // Some code

    public override void HandleInput(Character character, Input input)
    {
        if (input == Input.PRESS_SPACE)
        {
            this.ToState(character, STATE_JUMPING);
        }
        else if (input == Input.PRESS_CTRL)
        {
            this.ToState(character, STATE_DUCKING);
        }

        // More code
    }

    public override void Update(Character character)
    {
        // Some code
    }
}

public class JumpingCharacterState : CharacterStateBase
{
    // Some code

    public override void HandleInput(Character character, Input input)
    {
        // Some code
    }

    public override void Update(Character character)
    {
        if (character.IsGrounded())
        {
            this.ToState(character, STATE_GROUNDED);
        }

        // More code
    }
}

public class DuckingCharacterState : CharacterStateBase
{
    // Some code

    public override void HandleInput(Character character, Input input)
    {
        if (input == Input.RELEASE_CTRL)
        {
            this.ToState(character, STATE_GROUNDED);
        }

        // More code
    }

    public override void Update(Character character)
    {
        // Some code
    }
}

The STATE_GROUNDED, STATE_JUMPING and STATE_DUCKING are just references to instances of GroundedCharacterState, JumpingCharacterState and DuckingCharacterState. You can create them anywhere you want. I personally like to create static readonly instances in the CharacterStateBase class.


I personally love this pattern. It’s very easy to extent the behavior of the character, we just need to create a bunch of different states. Once created we don’t touch them anymore. But as good as it is, there are also problems.

Concurrent State Machines

Lets imagine that the character is running. He is in a running state. But can he run and shoot at the same time? The problem is that only one state can be active at a time. The character can’t run and shoot at the same time, but we want him to be able to do so. One solution is to create a state that combines both the running and the shooting states. That however is not a very good solution. Imagine that the character can shoot while jumping, ducking, walking. Even worse – the character can shoot with different types of weapons (pistols, rifles, grenade launchers). The input handling for these weapons is a little different from one another. If we are to create that many combined states, we will end up overkilling the architecture of our code. A better solution is to create a secondary state, that can be updated separately from the main state. The character class will look like this.

public class Character
{
    private ICharacterState state;
    private ICharacterState equipmentState;

    public void Update()
    {
        this.State.Update(this);
        this.EquipmentState.Update(this);
    }

    public void HandleInput(Input input)
    {
        this.State.HandleInput(this, input);
        this.EquipmentState.HandleInput(this, input);
    }

    // Other code
}

When to Use

There is not a strict rule when to use it. This applies to all patterns in general. You need to ask yourself three questions:

  • Do you have an entity whose behavior changes based on some internal state?
  • Can that state be rigidly divided into one of a relatively small number of distinct options?
  • Does the entity respond to a series of inputs or events over time?

If the answer to all questions is a “YES” then you might consider using this pattern.

I’ve used it for simple AI behaviors. You can actually check this Video Tutorial from Unity Technologies. A guy shows how to implement a basic state machine for AI. However if you want to create a more complex AI, I advise you to use Behavior Trees. I’ve actually never used them myself, but I know that they are the right way to do more advanced AI.

I’ve also used the state pattern when I was implementing the UI in the main menu of a certain game. I had a bunch of screens and you can go from one screen to another, based on some user input. Each state is a different UI Screen. Based on the user input I just make transitions between the screens.

A Description of the C++ “typename” keyword

Hi guys, I found a really cool post about the description of the typename keyword in C++, so I decided to repost. Here is the original post

A Secondary Use

There is a use of typename that is entirely distinct from the main focus of this discussion. I will present it first because it is easy. It seems to me that someone said “hey, since we’re adding typename anyway, why not make it do this” and people said “that’s a good idea.”

Most older C++ books, when discussing templates, use syntax such as the following:

template <class T> ...

I know when I was starting to learn templates, at first I was a little thrown by the fact that T was prefaced by class, and yet it was possible to instantiate that template with primitive types such as int. The confusion was very short-lived, but the use of class in that context never seemed to fit entirely right. Fortunately for my sensibilities, it is also possible to use typename:

template <typename T> ...

This means exactly the same thing as the previous instance. The typename and class keywords can be used interchangeably to state that a template parameter is a type variable (as opposed to a non-type template parameter).

I personally like to use typename in this context because I think it’s ever-so-slightly clearer. And maybe not so much “clearer” as just conceptually nicer. (I think that good names for things are very important.) Some C++ programmers share my view, and use typename for templates. (However, later we will see how it’s possible that this decision can hurt readability.) Some programmers make a distinction between templates that are fully generic (such as the STL containers) and more special purpose ones that can only take certain classes, and use typename for the former category and class for the latter. Others use class exclusively. This is just a style choice.

However, while I use typename in real code, I will stick to class in this document to reduce confusion with the other use of typename.

The real reason for typename

This discussion I think follows fairly closely appendix B from the book C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond by David Abrahams and Aleksey Gurtovoy, though I don’t have it in front of me now. If there are any deficiencies in my discussion of the issues, that book contains the clearest description of them that I’ve seen.

Some definitions

There are two key concepts needed to understand the description of typename, and they are qualified and dependent names.

Qualified and unqualified names

A qualified name is one that specifies a scope. For instance, in the following C++ program, the references to cout and endl are qualified names:

#include <iostream>

int main()  {
   std::cout << "Hello world!" << std::endl;
}

In both cases, the use of cout and endl began with std::.

Had I decided to bring cout and endl into scope with a using declaration or directive*, and used just cout by itself, they would have been unqualified names, because they would lack the std::.

(* Remember, a using declaration is like using std::cout;, and actually introduces the name cout into the scope that the using appears in. A using directive is of the form using namespace std; and makes names visible but doesn’t introduce anything. [I’m not sure this is true. Just a warning.])

Note, however, that if I had brought them into scope with using but still used std::cout, it remains a qualified name. The qualified-ness of a name has nothing to do with what scope it’s used in, what names are visible at that point of the program etc.; it is solely a statement about the name that was used to reference the entity in question. (Also note that there’s nothing special about std, or indeed about namespaces at all. vector::iterator is a nested name as well.)

Dependent and non-dependent names

A dependent name is a name that depends on a template parameter. Suppose we have the following declaration (not legal C++):

template <class T>
class MyClass {
   int i;
   vector<int> vi;
   vector<int>::iterator vitr;

   T t;
   vector<T> vt;
   vector<T>::iterator viter;
};

The types of the first three declarations are known at the time of the template declaration. However, the types of the second set of three declarations are not known until the point of instantiation, because they depend on the template parameter T.

The names T, vector, and vector::iterator are called dependent names, and the types they name are dependent types. The names used in the first three declarations are called non-dependent names, at the types are non-dependent types.

The final complication in what’s considered dependent is that typedefs transfer the quality of being dependent. For instance:

typedef T another_name_for_T;

another_name_for_T is still considered a dependent name despite the type variable T from the template declaration not appearing.

Some other issues of wording

Note that while there is a notion of a dependent type, there is not a notion of a qualified type. A type can be unqualified in one instance, and qualified the next; the qualification is a property of a particular naming of a type, not of the type itself. (Indeed, when a type is first defined, it is always unqualified.)

However, it will be useful to refer to a qualified type; what I mean by this is a qualified name that refers to a type. I will switch back to the more precise wording when I talk about the rules of typename.

The problem

So now we can consider the following example:

template <class T>
void foo() {
   T::iterator * iter;
   ...
}

What did the programmer intend this bit of code to do? Probably, what the programmer intended was for there to be a class that defined a nested type called iterator:

class ContainsAType {
   class iterator { ... }:
   ...
};

and for foo to be called with an instantiation of T being that type:

foo<ContainsAType>();

In that case, then line 3 would be a declaration of a variable called iter that would be a pointer to an object of type T::iterator (in the case of ContainsAType, int*, making iter a double-indirection pointer to an int). So far so good.

However, what the programmer didn’t expect is for someone else to come up and declare the following class:

class ContainsAValue {
   static int iterator;
};

and call foo instantiated with it:

foo<ContainsAValue>();

In this case, line 3 becomes a statement that evaluates an expression which is the product of two things: a variable called iter (which may be undeclared or may be a name of a global) and the static variable T::iterator.

Uh oh! The same series of tokens can be parsed in two entirely different ways, and there’s no way to disambiguate them until instantiation. C++ frowns on this situation. Rather than delaying interpretation of the tokens until instantiation, they change the language:

Before a qualified dependent type, you need typename

To be legal, assuming the programmer intended line 3 as a declaration, they would have to write

template <class T>
void foo() {
   typename T::iterator * iter;
   ...
}

Without typename, there is a C++ parsing rule that says that qualified dependent names should be parsed as non-types even if it leads to a syntax error. Thus if there was a variable called iter in scope, the example would be legal; it would just be interpreted as multiplication. Then when the programmer instantiated foo with ContainsAType, there would be an error because you can’t multiply something by a type.

typename states that the name that follows should be treated as a type. Otherwise, names are interpreted to refer to non-types.

This rule even holds if it doesn’t make sense even if it doesn’t make sense to refer to a non-type. For instance, suppose we were to do something more typical and declare an iterator instead of a pointer to an iterator:

template <class T>
void foo() {
   typename T::iterator iter;
   ...
}

Even in this case, typename is required, and omitting it will cause compile error. As another example, typedefs also require use:

template <class T>
void foo() {
   typedef typename T::iterator iterator_type;
   ...
}

The rules

Here, in excruciating detail, are the rules for the use of typename. Unfortunately, due to something which is hopefully not-contagious apparently affecting the standards committee, they are pretty complicated.

  1. typename is prohibited in each of the following scenarios:
    • Outside of a template definition. (Be aware: an explicit template specialization (more commonly called a total specialization, to contrast with partial specializations) is not itself a template, because there are no missing template parameters! Thus typename is always prohibited in a total specialization.)
    • Before an unqualified type, like int or my_thingy_t.
    • When naming a base class. For example, template class my_class : C::some_base_type { ... }; may not have a typename before C::some_base_type.
    • In a constructor initialization list.
  2. typename is mandatory before a qualified, dependent name which refers to a type (unless that name is naming a base class, or in an initialization list).
  3. typename is optional in other scenarios. (In other words, it is optional before a qualified but non-dependent name used within a template, except again when naming a base class or in an initialization list.)
    Again, these rules are for standard C++98/03. C++11 loosens the restrictions. I will update this page after I figure out what they are.

Abstract Input System in Unity

Right now I am creating a game. For this game I wanted to create a good input system. The thing is I didn’t know where to start. I am a big fan of Ori and the Blind Forest, so I decided to decompile the game and see how the big guys did it. As expected, their code was huge, but I took only the parts for my needs.

Interfaces

There are 2 basic interfaces for taking raw input: IAxisInput and IButtonInput.

public interface IAxisInput
{
    float GetAxis();
}

public interface IButtonInput
{
    bool GetButton(); // When the button is held down
    bool GetButtonDown(); // Executed once on button down
    bool GetButtonUp(); // Executed once on button up
}

For the next interface you need to know exactly what the character can do. In my case the character can only move horizontally and jump, so the interface looks like this.

public interface IInputProvider
{
    IAxisInput HorizontalAxisInput { get; }
    IButtonInput JumpButtonInput { get; }
}

This interface provides us with input from different sources. For example, we can create a KeyboardAndMouseInputProvider, or a MobileInputProvider. Lets actually implement those two.

KeyboardAndMouseInputProvider

public class KeyboardAndMouseInputProvider : IInputProvider
{
    private IAxisInput horizontalAxisInput;
    private IButtonInput jumpButtonInput;

    public KeyboardAndMouseInputProvider()
    {
        this.horizontalAxisInput = new CHorizontalAxisInput();
        this.jumpButtonInput = new CJumpButtonInput();
    }

    public virtual IAxisInput HorizontalAxisInput
    {
        get
        {
            return this.horizontalAxisInput;
        }
    }

    public virtual IButtonInput JumpButtonInput
    {
        get
        {
            return this.jumpButtonInput;
        }
    }

    private class CHorizontalAxisInput : IAxisInput
    {
        public float GetAxis()
        {
            return Input.GetAxis("Horizontal");
        }
    }

    private class CJumpButtonInput : IButtonInput
    {
        public bool GetButton()
        {
            return Input.GetButton("Jump");
        }

        public bool GetButtonDown()
        {
            return Input.GetButtonDown("Jump");
        }

        public bool GetButtonUp()
        {
            return Input.GetButtonUp("Jump");
        }
    }
}

MobileInputProvider

public class MobileInputProvider : MonoBehaviour, IInputProvider
{
    [SerializeField]
    private VirtualJoystick leftJoystick = null;

    private IAxisInput horizontalAxisInput;
    private IButtonInput jumpButtonInput;

    public virtual IAxisInput HorizontalAxisInput
    {
        get
        {
            return this.horizontalAxisInput;
        }
    }

    public virtual IButtonInput JumpButtonInput
    {
        get
        {
            return this.jumpButtonInput;
        }
    }

    public void Init()
    {
        this.horizontalAxisInput = new CHorizontalAxisInput(this.leftJoystick);
        this.jumpButtonInput = new CJumpButtonInput();
    }

    private class CHorizontalAxisInput : IAxisInput
    {
        private VirtualJoystick leftJoystick;

        public CHorizontalAxisInput(VirtualJoystick leftJoystick)
        {
            this.leftJoystick = leftJoystick;
        }

        public float GetAxis()
        {
            return this.leftJoystick.GetAxes().x;
        }
    }

    private class CJumpButtonInput : IButtonInput
    {
        private int lastJumpTouchId;

        public bool GetButton()
        {
            if (Input.touchCount > 0)
            {
                foreach (var touch in Input.touches)
                {
                    if ((touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved) &&
                        (touch.position.x > Screen.width / 2f) &&
                        (touch.fingerId == this.lastJumpTouchId))
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        public bool GetButtonDown()
        {
            if (Input.touchCount > 0)
            {
                foreach (var touch in Input.touches)
                {
                    if (touch.phase == TouchPhase.Began &&
                        touch.position.x > Screen.width / 2f)
                    {
                        this.lastJumpTouchId = touch.fingerId;
                        return true;
                    }
                }
            }

            return false;
        }

        public bool GetButtonUp()
        {
            if (Input.touchCount > 0)
            {
                foreach (var touch in Input.touches)
                {
                    if (touch.phase == TouchPhase.Ended &&
                        touch.position.x > Screen.width / 2f &&
                        touch.fingerId == this.lastJumpTouchId)
                    {
                        return true;
                    }
                }
            }

            return false;
        }
    }
}

Another layer of abstraction

In Unity if we want to get an axis we just do it like this.

float horizontalAxis = Input.GetAxis("Horizontal");

But we can’t get the the horizontal axis like that if we are on a mobile device. We have a MobileInputProvider, we just need a class that uses it.

public static class PlayerInput
{
    public static IInputProvider InputProvider { get; set; }

    public static IAxisInput HorizontalAxisInput
    {
        get
        {
            return InputProvider.HorizontalAxisInput;
        }
    }

    public static IButtonInput JumpButtonInput
    {
        get
        {
            return InputProvider.JumpButtonInput;
        }
    }
}

 
Now we can get the horizontal axis from a mobile device like this.

PlayerInput.InputProvider = mobileInputProvider;
float horizontalAxis = PlayerInput.HorizontalAxisInput.GetAxis();

Compound Input Provider

But what if we want to be able to get input both from a keyboard and from a mobile device. Well we need a provider that gets input from both, but that will be kinda stupid, because we have them in separate, why create a third provider that is copy-paste from the first two? We just need to think of a smart way to combine both input providers. That is how we do it.
 
First we create an axis input that can get axes from many sources. We will call this one CompoundAxisInput. Here is the implementation.

public class CompoundAxisInput : IAxisInput
{
    private const float AXIS_DEAD_ZONE = 0.2f;

    private IAxisInput[] axisInputs;
    private int lastPressedIndex;

    public CompoundAxisInput() { }

    public CompoundAxisInput(params IAxisInput[] axisInputs)
    {
        this.axisInputs = axisInputs;
    }

    public virtual float GetAxis()
    {
        float positiveAxis = 0f;
        float negativeAxis = 0f;
        if (this.axisInputs != null)
        {
            for (int i = 0; i < this.axisInputs.Length; i++)
            {
                float value = this.axisInputs[i].GetAxis();
                if (Mathf.Abs(value) > AXIS_DEAD_ZONE)
                {
                    this.lastPressedIndex = i;
                }
                else
                {
                    continue;
                }

                if (value < 0f)
                {
                    negativeAxis = Mathf.Min(negativeAxis, value);
                }
                else
                {
                    positiveAxis = Mathf.Max(positiveAxis, value);
                }
            }
        }

        return positiveAxis + negativeAxis;
    }

    public IAxisInput GetLastPressed()
    {
        return this.axisInputs[this.lastPressedIndex];
    }

    public void AddAxisInput(IAxisInput axisInput)
    {
        if (this.axisInputs == null)
        {
            this.axisInputs = new IAxisInput[1];
            this.axisInputs[0] = axisInput;
        }
        else
        {
            Array.Resize(ref this.axisInputs, this.axisInputs.Length + 1);
            this.axisInputs[this.axisInputs.Length - 1] = axisInput;
        }
    }

    public void ClearAxisInputs()
    {
        this.axisInputs = null;
    }
}

It’s an axis input that internally has an array of axis inputs. When we call the GetAxis() method, we find the most negative one and most positive one from all of the axis inputs and return the sum of them. That way if we press left on a keyboard and right on a joystick for example, the character will stay in one place, because the horizontal axis will be zero.


Now we have to do the same for the button input. Lets call the class CompoundButtonInput.

public class CompoundButtonInput : IButtonInput
{
    private IButtonInput[] buttonInputs;
    private int lastPressedIndex;

    public CompoundButtonInput() { }

    public CompoundButtonInput(params IButtonInput[] buttonInputs)
    {
        this.buttonInputs = buttonInputs;
    }

    public virtual bool GetButton()
    {
        if (this.buttonInputs != null)
        {
            for (int i = 0; i < this.buttonInputs.Length; i++)
            {
                if (this.buttonInputs[i].GetButton())
                {
                    this.lastPressedIndex = i;
                    return true;
                }
            }
        }

        return false;
    }

    public virtual bool GetButtonDown()
    {
        if (this.buttonInputs != null)
        {
            for (int i = 0; i < this.buttonInputs.Length; i++)
            {
                if (this.buttonInputs[i].GetButtonDown())
                {
                    this.lastPressedIndex = i;
                    return true;
                }
            }
        }

        return false;
    }

    public virtual bool GetButtonUp()
    {
        if (this.buttonInputs != null)
        {
            for (int i = 0; i < this.buttonInputs.Length; i++)
            {
                if (this.buttonInputs[i].GetButtonUp())
                {
                    this.lastPressedIndex = i;
                    return true;
                }
            }
        }

        return false;
    }

    public IButtonInput GetLastPressed()
    {
        return this.buttonInputs[this.lastPressedIndex];
    }

    public void AddButtonInput(IButtonInput buttonInput)
    {
        if (this.buttonInputs == null)
        {
            this.buttonInputs = new IButtonInput[1];
            this.buttonInputs[0] = buttonInput;
        }
        else
        {
            Array.Resize(ref this.buttonInputs, this.buttonInputs.Length + 1);
            this.buttonInputs[this.buttonInputs.Length - 1] = buttonInput;
        }
    }

    public void ClearButtonInputs()
    {
        this.buttonInputs = null;
    }
}

Finally we create a CompoundInputProvider

public class CompoundInputProvider : IInputProvider
{
    private IInputProvider[] inputProviders;
    private CompoundAxisInput horizontalAxisInput;
    private CompoundButtonInput jumpButtonInput;

    public CompoundInputProvider()
        : this(null)
    { }

    public CompoundInputProvider(params IInputProvider[] inputProviders)
    {
        this.horizontalAxisInput = new CompoundAxisInput();
        this.jumpButtonInput = new CompoundButtonInput();

        if (inputProviders != null)
        {
            for (int i = 0; i < inputProviders.Length; i++)
            {
                this.AddInputProvider(inputProviders[i]);
            }
        }
    }

    public virtual IAxisInput HorizontalAxisInput
    {
        get
        {
            return this.horizontalAxisInput;
        }
    }

    public virtual IButtonInput JumpButtonInput
    {
        get
        {
            return this.jumpButtonInput;
        }
    }

    public void AddInputProvider(IInputProvider inputProvider)
    {
        if (this.inputProviders == null)
        {
            this.inputProviders = new IInputProvider[1];
            this.inputProviders[0] = inputProvider;
        }
        else
        {
            Array.Resize(ref this.inputProviders, this.inputProviders.Length + 1);
            this.inputProviders[this.inputProviders.Length - 1] = inputProvider;
        }

        this.horizontalAxisInput.AddAxisInput(inputProvider.HorizontalAxisInput);
        this.jumpButtonInput.AddButtonInput(inputProvider.JumpButtonInput);
    }

    public void ClearInputProviders()
    {
        this.inputProviders = null;
        this.horizontalAxisInput.ClearAxisInputs();
        this.jumpButtonInput.ClearButtonInputs();
    }
}

All that’s left is to provide our PlayerInput class with the right CompoundInputProvider. I do this in an InputManager script.

public class InputManager : MonoBehaviour
{
    [SerializeField]
    private MobileInputProvider mobileInputProvider = null;

    protected virtual void Awake()
    {
        this.InitInputProvider();
    }

    private void InitInputProvider()
    {
        CompoundInputProvider compoundInputProvider = new CompoundInputProvider();
        if (this.mobileInputProvider != null)
        {
            this.mobileInputProvider.Init();
            compoundInputProvider.AddInputProvider(this.mobileInputProvider);
        }

#if UNITY_EDITOR
        compoundInputProvider.AddInputProvider(new KeyboardAndMouseInputProvider());
#endif

        PlayerInput.InputProvider = compoundInputProvider;
    }
}

Now we are ready to use our PlayerInput class instead of the Input class that Unity gives us.