100% found this document useful (5 votes)
44 views72 pages

C# Game Programming Cookbook for Unity 3D 2nd edition by Jeff Murray 9781000359725 1000359727 - Get instant access to the full ebook with detailed content

The document provides information on various ebooks related to game programming, particularly using C# and Unity 3D, available for instant download at ebookball.com. It includes details about multiple titles, their authors, and links to access them. Additionally, it features a comprehensive overview of the contents of the 'C# Game Programming Cookbook for Unity 3D' by Jeff Murray, which covers essential programming concepts and practical game development techniques.

Uploaded by

gmoodysomrak
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (5 votes)
44 views72 pages

C# Game Programming Cookbook for Unity 3D 2nd edition by Jeff Murray 9781000359725 1000359727 - Get instant access to the full ebook with detailed content

The document provides information on various ebooks related to game programming, particularly using C# and Unity 3D, available for instant download at ebookball.com. It includes details about multiple titles, their authors, and links to access them. Additionally, it features a comprehensive overview of the contents of the 'C# Game Programming Cookbook for Unity 3D' by Jeff Murray, which covers essential programming concepts and practical game development techniques.

Uploaded by

gmoodysomrak
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 72

Instant Ebook Access, One Click Away – Begin at ebookball.

com

C# Game Programming Cookbook for Unity 3D 2nd


edition by Jeff Murray 9781000359725 1000359727

https://ebookball.com/product/c-game-programming-cookbook-
for-unity-3d-2nd-edition-by-jeff-
murray-9781000359725-1000359727-18762/

OR CLICK BUTTON

DOWLOAD EBOOK

Get Instant Ebook Downloads – Browse at https://ebookball.com


Your digital treasures (PDF, ePub, MOBI) await
Download instantly and pick your perfect format...

Read anywhere, anytime, on any device!

Introduction to Game Programming Using C and Unity 3D 1st


edition by Vahe Karamian 0997148403 978-0997148404

https://ebookball.com/product/introduction-to-game-programming-using-
c-and-unity-3d-1st-edition-by-vahe-
karamian-0997148403-978-0997148404-25168/

ebookball.com

(Ebook PDF) Learn Unity 2017 for iOS Game Development


Create Amazing 3D Games for iPhone and iPad 2nd edition by
Allan Fowler, Philip Chu 1484231740 9781484231746 full
chapters

https://ebookball.com/product/ebook-pdf-learn-unity-2017-for-ios-game-
development-create-amazing-3d-games-for-iphone-and-ipad-2nd-edition-
by-allan-fowler-philip-chu-1484231740-9781484231746-full-
chapters-22692/
ebookball.com

(Ebook PDF) Mathematics for 3D Game Programming and


Computer Graphics 2nd edition by Eric Lengyel 1584502770
978-1584502777 full chapters

https://ebookball.com/product/ebook-pdf-mathematics-for-3d-game-
programming-and-computer-graphics-2nd-edition-by-eric-
lengyel-1584502770-978-1584502777-full-chapters-22672/

ebookball.com

(EBook PDF) Unity 2D Game Development Cookbook Over 50


hands on recipes that leverage the features of Unity to
help you create 2D games and game prototypes 1st edition
by Scolastici Claudio 9781783553600 full chapters

https://ebookball.com/product/ebook-pdf-unity-2d-game-development-
cookbook-over-50-hands-on-recipes-that-leverage-the-features-of-unity-
to-help-you-create-2d-games-and-game-prototypes-1st-edition-by-
scolastici-claudio-978178355360/
ebookball.com
(EBook PDF) Building a Game and Unity and Blender Learn
how to build a complete 3D game using the industry leading
Unity game development engine and Blender the graphics
software that gives life 1st edition by Lee Zhi Eng
1785280740 9781785280740 full chapters

https://ebookball.com/product/ebook-pdf-building-a-game-and-unity-and-
blender-learn-how-to-build-a-complete-3d-game-using-the-industry-
leading-unity-game-development-engine-and-blender-the-graphics-
software-that-gives-life-1st-edi/
ebookball.com

3D Game Programming All in One 1st Edition by Kenneth


Finney ISBN 159200136X 9781592001361

https://ebookball.com/product/3d-game-programming-all-in-one-1st-
edition-by-kenneth-finney-isbn-159200136x-9781592001361-23550/

ebookball.com

Introduction to 3D Game Programming with DirectX 11 1st


edition by Frank Luna 1937585964 9781937585969

https://ebookball.com/product/introduction-to-3d-game-programming-
with-directx-11-1st-edition-by-frank-
luna-1937585964-9781937585969-25192/

ebookball.com

Beginning C++ Game Programming 1st Edition by Michael


Dawson ISBN 1592002056 9781592002054

https://ebookball.com/product/beginning-c-game-programming-1st-
edition-by-michael-dawson-isbn-1592002056-9781592002054-12450/

ebookball.com

(Ebook PDF) Mastering Unity 2017 Game Development and C


Create professional games and solid gameplay features and
professional 2nd edition by Alan Thorn 1788398394
9781788398398 full chapters

https://ebookball.com/product/ebook-pdf-mastering-unity-2017-game-
development-and-c-create-professional-games-and-solid-gameplay-
features-and-professional-2nd-edition-by-alan-
thorn-1788398394-9781788398398-full-chapters-22602/
ebookball.com
C# Game Programming
Cookbook for Unity 3D
C# Game Programming
Cookbook for Unity 3D
Second Edition

Jeff W. Murray
Second Edition published 2021
by CRC Press
6000 Broken Sound Parkway NW, Suite 300, Boca Raton, FL 33487-2742

and by CRC Press


2 Park Square, Milton Park, Abingdon, Oxon, OX14 4RN

First Edition published by CRC Press 2014


CRC Press is an imprint of Taylor & Francis Group, LLC

© 2021 Taylor & Francis Group, LLC

The right of Jeff W. Murray to be identified as author of this work has been asserted by him/ in
accordance with sections 77 and 78 of the Copyright, Designs and Patents Act 1988.

Reasonable efforts have been made to publish reliable data and information, but the author and
publisher cannot assume responsibility for the validity of all materials or the consequences of their
use. The authors and publishers have attempted to trace the copyright holders of all material
reproduced in this publication and apologize to copyright holders if permission to publish in this
form has not been obtained. If any copyright material has not been acknowledged please write and let
us know so we may rectify in any future reprint.

Except as permitted under U.S. Copyright Law, no part of this book may be reprinted, reproduced,
transmitted, or utilized in any form by any electronic, mechanical, or other means, now known or
hereafter invented, including photocopying, microfilming, and recording, or in any information
storage or retrieval system, without written permission from the publishers.
For permission to photocopy or use material electronically from this work, access www.copyright.co
m or contact the Copyright Clearance Center, Inc. (CCC), 222 Rosewood Drive, Danvers, MA
01923, 978-750-8400. For works that are not available on CCC please contact mpkbookspermissions
@tandf.co.uk

Trademark notice: Product or corporate names may be trademarks or registered trademarks and are
used only for identification and explanation without intent to infringe.

ISBN: 978-0-367-32170-3 (hbk)


ISBN: 978-0-367-32164-2 (pbk)
ISBN: 978-0-429-31713-2 (ebk)

Typeset in Minion
by SPi Global, India
This book is dedicated to my
amazing wife, Tori, and to
my boys, Ethan and William.
Boys, be nice to the cat and
the cat will be nice to you!
Contents

Acknowledgments
Introduction
Prerequisites

1. Making Games in a Modular Way

1.1 Important Programming Concepts


1.1.1 Manager and Controller Scripts Manager and Controller
Scripts
1.1.1.1 Managers
1.1.1.2 Controllers
1.1.1.3 Communication between
1.1.1.4 Public Static
1.1.1.5 Private Static
1.1.2 The Singleton
1.1.2.1 Using the Singleton in Unity
1.1.3 Inheritance
1.1.4 Coroutines
1.1.5 Namespaces
1.1.6 Finite State Machines (FSM)
1.2 Naming Conventions
1.3 Where to Now?
2. Making a 2D Infinite Runner Game

2.1 Anatomy of a Unity Project


2.2 Open Unity, Then the Example Project for This Chapter
2.2.1 A Few Notes on the Example Project
2.2.2 Sprites
2.2.3 Animation
2.3 Open the Main Game Scene
2.4 The Game Manager
2.5 Making Platforms to Run On
2.6 Building the Player, RunMan
2.6.1 Adding the RunMan Sprite
2.6.2 Adding Physics and Collisions to RunMan
2.6.3 Player Scripts
2.6.4 RunMan Sounds
2.6.5 Animating RunMan
2.6.6 Scoring
2.7 The Game Loop and the Game Manager
2.7.1 Game States
2.7.2 The Main Loop of RunMan_GameManager.cs
2.7.3 Setting Up the RunMan_Game Manager Component in t
he Editor
2.8 The Demise of RunMan
2.9 Adding the User Interface
2.9.1 Main Menu Setup

3. Building the Core Game Framework

3.1 Controllers and Managers


3.1.1 Managers
3.1.2 Controllers
3.2 Core Framework Scripts
3.2.1 BaseGameManager
3.2.2 ExtendedCustomMonoBehaviour
3.2.3 BaseCameraController

4. Player Structure
4.1 A Player Controller
4.2 Dealing with Input
4.3 User Data
4.3.1 The UserData Class
4.3.2 The BaseUserManager Class
4.4 The BasePlayerStatsController Class
4.5 Managing Players

5. Recipes: Common Components

5.1 Introduction
5.2 AI
5.3 Camera
5.3.1 Third-Person Camera
5.3.2 Top-Down Camera
5.4 Game Control
5.4.1 GlobalRaceManager
5.4.2 RaceController
5.5 Input
5.5.1 Mouse Input
5.6 Level Loading
5.7 ScriptableObjects
5.7.1 ProfileScriptableObject
5.8 Spawning
5.8.1 A Spawner Component
5.8.2 Trigger Spawning
5.8.3 Timed Spawning
5.9 User Interface
5.9.1 CanvasManager
5.9.2 ScreenandAudioFader
5.9.3 MenuWithProfiles
5.10 Utility
5.10.1 AlignToGround
5.10.2 AutomaticDestroyObject
5.10.3 AutoSpinObject
5.10.4 FaceCamera
5.10.5 LookAtCamera
5.10.6 PretendFriction
5.10.7 TimerClass
5.10.7.1 Modifying the Timer to Update Automatically.
5.10.8 WaypointsController
5.11 Weapons

6. Player Movement Controllers

6.1 Humanoid Character


6.2 Wheeled Vehicle
6.3 Wheel Alignment
6.4 2D Platform Character Controller

7. Weapon Systems

7.1 Building the Scripts


7.1.1 The BaseWeaponController Class
7.1.2 BaseWeaponScript
7.1.3 Switching between Weapons

8. Waypoints Manager

8.1 Waypoint System

9. Recipe: Sound and Audio

9.1 Audio Mixers and Mixing Audio in Unity


9.1.1 Mixing Audio
9.1.2 Exposing Mixer Properties to Modify Them with Scripts
9.1.3 Audio Effects
9.2 The BaseSoundManager Class
9.3 Adding Sound to Weapons

10. AI Manager

10.1 AI States
10.2 The BaseAIController Class – Base AI Control
10.3 Enemy Stats
10.4 The AIBotController Class – Making an Enemy Bot Controller
10.5 The AISteeringController Class – An AI Steering Controller
10.6 Adding Weapon Control to the AI Controller
10.6.1 Attack States
10.6.2 Base Enemy Weapon Controller

11. Menus and User Interface

11.1 Canvas Manager Class/Canvas Management


11.2 The Main Menu
11.2.1 Designing the Main Menu
11.2.2 The BaseMainMenuManager Script
11.2.3 Combining BaseMainMenuManager to Use the Profile
Manager Script for Saving and Loading Audio Setting
s
11.3 In-Game User Interface

12. Saving and Loading Profiles

12.1 The Save Profile ScriptableObject


12.2 The BaseProfileManager Class

13. Loading Level Scenes

13.1 A Script for Loading Levels: LevelLoader.cs


13.2 Multiple Level Loading
13.3 Building a Multi-Scene Level Loader in Unity

14. Racing Game

14.1 Ingredients
14.2 Main Menu Scene Overview
14.3 Level Select Scene Overview
14.4 The Core Scene Overview
14.4.1 Game Manager – The RaceGameManager Class
14.4.2 Race Control – The GlobalRaceManager Class
14.4.3 Race Control – The RaceController Class
14.4.4 Race Control – RacePlayerController Class
14.4.5 Audio
14.4.5.1 Vehicle Audio.
14.4.5.2 Incidental Sounds
14.4.6 User Interface

15. Blaster Game Example

15.1 Ingredients
15.2 Main Menu Scene Overview
15.3 The Core Scene Overview
15.3.1 The BlasterGameManager Class
15.3.2 The BlasterPlayer Class
15.3.3 Enemy Bots and the BlasterEnemyBot Class
15.3.4 Weapons and Projectiles
15.3.5 User Interface
15.4 Level Scenes
15.4.1 Spawning Enemies
Index
Acknowledgements

Thanks to all of my family, friends and everyone who has helped me with
my books, games and projects over the years: Brian Robbins, Chris Hanney,
Technicat, Molegato, NoiseCrime, Quantum Sheep, Mickael Laszlo, Juanita
Leatham, CoolPowers, Dave Brake, Sigurdur Gunnarsson, Kevin Godoy R.,
Lister, Wim Wouters, Edy (VehiclePhysics), IdeaFella, Liam Twose,
RafaEnd, Lynxie, Alistair Murphy, McFunkypants, Dani Moss, Malcolm
Evans, Vinh, Scott Wilson, Jon Keon, Dunky, Huck Z, Paradise Decay,
Kryten, Silverware Games, Pete Patterson, Dr. Not Oculus VR, Say
Mistage, Andy Hatch, Lydia, RT Warner, GermanRifter VR, Sylvain
Demers, Kenneth Seward Jr, Dancer (Space Dad), Steve Fulton, Paul
Bettner, Derek Scottishgeeks, Jonny Gorden, Edward Atkin, Ottawa Pete,
Sam W., Dylan Stout, Shane McCafferty, Will Goldstone, Sanborn VR,
Gary Riches, J. Dakota Powell, Mayonnaise Boy, Stephen Parkes, Ram
Kanda, Alex Bethke, Itzik Goldman, Joachim Ante, Robert Scoble, Tony
Walsh, Andreas ‘BOLL’ Aronsson, Cat, Darrel Plant, Mike Baker, Rimsy,
Cassie, Christopher Brown, Phil Nolan, Pixel Hat Studio, Marcus Valles,
Trev, Karyl, Tami Quiring, Nadeem Rasool, Dwayne Dibley, Liz and Pete
Smyth, Isaac and Aiden, David Helgason, VR Martin, James Gamble,
Vasanth Mohan, Simona Ioffe, Alexander Kondratskiy, Tim and Paul, The
Oliver Twins, Jeevan Aurol, Rick King, Aldis Sipolins, Ric Lumb, Craig
Taylor, Rob Hewson, Dani Moss, Jayenkai (JNK), Matthew Kirubakaran,
Elliot Mitchell, Ethan and William, Pablo Rojo, Paul Bettner, AdrellaDev,
Gordon Little, Ryan Evans, Sasha Boersma, Matt Browning at Perfect
Prototype, Hermit, Dirty Rectangles and the whole Ottawa game dev
community.
I would also like to sincerely thank Anya Hastwell, Thivya Vasudevan
and the team at SPI Global, the whole team at Routledge/CRC Press/AK
Peters, including Randi Cohen, Jessica Vega and Rick Adams, for making
this book a reality.
Thank you for buying this book and for wanting to do something as cool
as to make games. I wish I could tell you how awesome it feels to know that
someone else is reading this right now. I cannot wait to see your games and
I sincerely hope this book helps you in your game making adventures. Have
fun making games!
Introduction

The overall goal of this book is to provide a library of C# code with which
to jumpstart your projects and to help you with the overall structure of your
games. Many development cookbooks focus on only providing snippets of
code, but, here, we take a different approach. What you are holding in your
hands right now (or on your screen) is a cookbook for game development
that has a highly flexible core framework designed to speed up development
of just about any type of Unity project.
You might think of the framework as a base soup and the scripting
components as ingredients. We can mix and match script components and
we can share the same core scripts in many of them. The framework takes
care of the essentials and we add a little extra code to pull it all together the
way we want it to work.
The framework is optional, however – you can use a lot the components
individually. If you intend on using the components in this book for your
own games, the framework could either serve as a base to build your games
on or simply as a tutorial test bed for you to rip apart and see how it all
works. Perhaps you can develop a better framework or maybe you already
have a solid framework in place. If you do find a way to develop your own
framework, I say do it. The key to game development is to do what works
for you and your game projects – whatever it takes to cross the finish line.
I hope it helps you to make your games and tell your stories. I also hope
you remember to try to have fun doing it!
Prerequisites

You can get up and running with the required software for the grand total of
zero dollars. Everything you need can be downloaded free of charge with
no catches. All you need is:

Unity Personal or Unity Pro version

C# programming knowledge.

This is not a book about learning how to program. You will need to know
some C# and there are several other books out there for that purpose, even
if I have tried to make the examples as simple as possible!
What this book doesn’t cover
This is not a book about learning to program from scratch. We assume that
the reader has some experience of the C# programming language. Know
that I am a self-taught programmer and I understand there may be better or
alternative ways to do things. Techniques and concepts offered in this book
are meant to provide foundation and ideation, not to be the final word on
any subject.
Making Games in a
1 Modular Way

1.1 Important Programming Concepts


There are some things you will need to know to utilize this book fully. For a
lot of programmers, these concepts may be something you were taught in
school. As a self-taught coder who did not find out about a lot of these
things until long after I had been struggling on without them, I see this
section as a compilation of ‘things I wish I’d known earlier’!

1.1.1 Manager and Controller Scripts


Sometimes, even I get confused about the difference between a manager
and a controller script. There is no established protocol for this, and it varies
depending on who you ask. Like some readers of the first edition of this
book, I find it a little confusing and I will try to clear that up.

1.1.1.1 Managers
Managers deal with overall management, in a similar way to how a
Manager would work in a workplace situation.

1.1.1.2 Controllers
Controllers deal with systems that the managers need to do their jobs. For
example, in the racing game example game for this book, we have race
controller scripts and a global race manager script. The race controller
scripts are attached to the players and track their positions on the track,
waypoints, and other relevant player-specific race information. The global
race manager script talks to all the race controller scripts attached to the
players to determine who is winning and when the race starts or finishes.

1.1.1.3 Communication between Classes


An important part of our modular structure is how scripts are going to
communicate with each other. It is inevitable that we will need to access our
scripts from different areas of the game code, so you will need to know how
to do that in Unity.

1. Direct referencing scripts via variables set in the editor by the


Inspector window.

The easiest way to have script Components talk to each other (that is,
scripts attached to GameObjects in the Scene as Components) is to have
direct references, in the form of public variables within your code. They can
then be populated in the Inspector window of the Unity editor with a direct
link to another Component on another GameObject.

2. GameObject referencing using SendMessage.

SendMessage sends a message to a GameObject or Transform and calls a


function within any of its attached script Components. It only works one
way, so it is only useful when we do not need any kind of return result. For
example:

someGameObject.SendMessage(“DoSomething”);

Above, this would call the function DoSomething() on any of the script
Components attached to the GameObject referenced by someGameObject.

3. Static variables.
The static variable type makes a variable accessible to other scripts
without a direct reference to the GameObject it is attached to. This is
particularly useful behavior where several different scripts may want to
manipulate a variable to do things like adding points to a score or set the
number of lives of a player, and so on.
An example declaration of a static variable might be:

public static GameManager aManager;

You can have private or public static variables:

1.1.1.4 Public Static


A public static variable exists everywhere and may be accessed by any
other script.
For example, imagine a player script which needs to tell the Game
Manager to increase the current score by one:

1. In our GameManager.cs Game Manager script, we set up a variable,


public static typed:

public static gameScore;

2. In any other script, we can now access this static variable and alter
the score as needed:

GameController.gameScore++;

1.1.1.5 Private Static


A private static variable is accessible only to any other instances of the
same type of class. Other types of class will not be able to access it.
As an example, imagine all players need to have a unique number when
they are first spawned into the game. The player class declares a variable
named uniqueNum like this:

Private static int uniqueNum;

When a player script is first created, it uses the value of uniqueNum for
itself and increases uniqueNum by one:

myUniqueNum = uniqueNum;
uniqueNum++;

The value of uniqueNum will be shared across all player scripts. The next
player to be spawned will run the same start up function, getting
uniqueNum again – only this time it has been increased by one, thanks to
the player spawned earlier. This player again gets its own unique number
and increases the static variable ready for the next one.

1.1.2 The Singleton


A singleton is a commonly used method for allowing access to an instance
of a class, accessible to all other scripts. This pattern is ideal for code that
needs to communicate with the entire game, such as a Game Manager.

1.1.2.1 Using the Singleton in Unity


The most straightforward way to achieve singleton-like behavior is to use a
static variable and, when Unity calls the Awake() function, set the instance
variable to become a reference to the script instance it represents. The
keyword ‘this’ refers to the instance of the script it is a part of.
For example:
public class MyScript : Monobehaviour
{
private static MySingleton instance;
void Awake()
{
if (instance != null)
Destroy(this);
instance = this;
}
}

The singleton instance of our script can be accessed anywhere, by


practically any script, with the following syntax:

MySingleton.Instance.SomeFunctionInTheSingleton();

1.1.3 Inheritance
Inheritance is a complex concept, which calls for some explanation here
because of its key role within the scripts provided by this book. Have a read
through this section but don’t worry if you don’t pick up inheritance right
away. Once we get to the programming it will probably become clearer.
The bottom line is that inheritance is used in programming to describe a
method of providing template scripts that may be overridden, or added to,
by other scripts. As a metaphor, imagine a car. All cars have four wheels
and an engine. The types of wheels may vary from car to car, as will the
engine, so when we say ‘this is a car’ and try to describe how our car
behaves; we may also describe the engine and wheels.
These relationships may be shown in a hierarchical order:

Car–

–Wheels

–Engine

Now try to picture this as a C# script:


Car class.

Wheels function

Engine function

If we were building a game with lots of cars in it, having to rewrite the car
class for each type of car would be silly. A far more efficient method might
be to write a base class and populate it with virtual functions. When we
need to create a car, rather than use this base class, we build a new class,
which inherits the base class. Because our new class is inherited, it is
optional whether we choose to override wheels or engine functions to make
them behave in ways specific to our new class. That is, we can build
‘default’ functions into the base class and if we only need to use a default
behavior for an engine, our new class doesn’t need to override the engine
function.
A base class might look something like this:

public class BaseCar : MonoBehaviour {

public virtual void Engine () {


Debug.Log(“Vroom”);
}

public virtual void Wheels () {


Debug.Log(“Four wheels”);
}
}

There are two key things to notice in the above script. One is the class
declaration itself and the fact that this class derives from MonoBehaviour.
MonoBehaviour is itself a class – the Unity documentation describes it as
“the base class every script derives from” – this MonoBehaviour class
contains many engine-specific functions and methods such as Start(),
Update(), FixedUpdate(), and more. If our script didn’t derive from
MonoBehaviour it would not inherit those functions and the engine
wouldn’t automatically call functions like Update() for us to be able to work
with. Another point to note is that MonoBehaviour is a class that is built
into the engine and not something we can access to edit or change.
The second point to note is that our functions are both declared as virtual
functions. Both are public, both are virtual. Making virtual functions means
that the behavior in our base class may be overridden by any scripts that
derive from it. The behavior we define in this base class could be thought of
as its default behavior. We will cover overriding in full a little further on in
this section.
Let’s take a look at what this script actually does: if we were to call the
Engine() function of our BaseCar class, it would write to the console
“Vroom.” If we called Wheels, the console would read “Four wheels.”
Now that we have our BaseCar class, we can use this as a template and
make new versions of it like this:

public class OctoCar : BaseCar {


public override void Wheels () {
Debug.Log(“Eight wheels”);
}
}

The first thing you may notice is that the OctoCar class derives from
BaseCar rather than MonoBehaviour. This means that OctoCar inherits
functions and methods belonging to our BaseCar script. As the functions
described by BaseCar were virtual, they may be overridden. For OctoCar,
we override Wheels with the line:

public override void Wheels () {

Let’s take a look at what this script actually does: In this case, if we were
to call the Engine() function on OctoCar, it would do the same as the
BaseCar class; it would write “Vroom” to the console. It would do this
because we have inherited the function but have not overridden it, which
means we keep that default behavior. In OctoCar, however, we have
overridden the Wheels() function. The BaseCar behavior of Wheels would
print “Four wheels” to the console but if we call Wheels() on OctoCar, the
overridden behavior will write “Eight wheels,” instead.
Inheritance plays a huge part in how our core game framework is
structured. The idea is that we have basic object types and specific
elaborated versions of these objects inheriting the base methods, properties,
and functions. By building our games in this manner, the communication
between the different game components (such as game control scripts,
weapon scripts, projectile controllers, etc.) becomes universal without
having to write out the same function declarations over and over again for
different variations of script. For the core framework, our main goal is to
make it as flexible and extensible as possible and this would be a much
more difficult if we were unable to use inheritance.

1.1.4 Coroutines
Unity lets you run a function known as a coroutine, outside of the regular
built in functions like Update, FixedUpdate, LateUpdate, and so on. A
coroutine is self-contained code that will just go off and do its own thing
once you have told it to run. As it is running on its own, you can do some
cool stuff like pause it for a set amount of time and then have it start again,
and coroutines are ideally suited to time-based actions like fade effects or
animations.
Here is an example of a coroutine (this example code comes from the
Unity engine documentation):

IEnumerator Fade() {
for (float ft = 1f; ft > = 0; ft -= 0.1f)
{
Color c = renderer.material.color;
c.a = ft;
renderer.material.color = c;
yield return null;
}
}

This code loops the value of ft from 1 to 0 and sets the alpha value of a
color on a material to that value. This will fade out whatever renderer this
script is attached to, fading more as the alpha channel gets closer to 0.
Notice the strange line:
yield return null;

Do not be alarmed by this odd code above! All it does is tell the engine
that, at this point, the coroutine is ready to end this update and go on to the
next one. You need this in your code, but don’t worry too much about why
at this stage. I will go into some more detail below, but for now let us
continue by looking at how you would start this coroutine running:

StartCoroutine("Fade");

StartCoroutine() takes the name of the coroutine as a string. Once called


to start, the coroutine will do its thing and you do not need to do anything
else. It will either run until we tell it to stop, or it will run until the object is
destroyed.
A key thing to note here is that the function is declared as type
IEnumerator. At first, I found this confusing, but it turns out that Unity
coroutines use C#’s built in system for iterator blocks. IEnumerator (Iterator
Enumerator) was intended to be a method for iterating through collections
of objects. Coroutines instead use IEnumerator to iterate through your
coroutine code, starting or stopping it between updates.
Another key point is that statement:

yield return null;

You can think of IEnumerator like a cursor making its way through your
code. When the cursor hits a yield statement, that tells the engine that this
update is done and to move the cursor on to the next block.
Another thing you can do with coroutines is to pause the code inline for a
certain amount of time, like this:

yield return new WaitForSeconds(1.0f);

Using WaitForSeconds(), you can quite literally pause the coroutine


script execution inline. For example:
IEnumerator DebugStuff()
{
Debug.Log("Start.");
yield return new WaitForSeconds(1.0f);
Debug.Log("Now, it’s one second later!");

Earlier in this section, I mentioned that the yield statement is used to tell
Unity the current update is done and to move on to the next. In the code
above, rather than just telling Unity to move on to the next bit of code, it
tells Unity to wait for the specified number of seconds first.

1.1.5 Namespaces
Namespaces compartmentalize chunks of code away from each other. You
can think of a namespace as a box to put your own scripts in, so that they
can stay separated from other code or code libraries. This helps to prevent
possible overlaps between code libraries (APIs and so on) and your own
code, such as duplicate function names or variables.
To use namespaces, you wrap the entire class in a namespace declaration
like this:

namespace MyNamespace
{
public class MyClass() : Monobehaviour
{
}

When you want to refer to the code from another class, you need to be
either wrapped in the same namespace or to have the using keyword at the
top of the script, like:

using MyNamespace;
1.1.6 Finite State Machines (FSM)
A finite state machine is a commonly used system for tracking states. In
video games, they are used to track game states. Example states might be
GameLoaded, GameStarting, LevelStarting, and so on. The term finite state
machine sounds a lot more complicated than it usually is. The actual code
often takes the form of a long case statement that will execute code or call
functions based on the current game state. For example:

Switch(currentGameState)
{
Case GameStates.GameLoaded:
GameLoaded();
Break;
Case GameStates.GameStarting:
GameStart();
Break;

Having code in each case statement can get unruly. To counter this, I like
to split all of the code out into individual functions. This keeps the code
tidy, easier to manage, and easier to debug when things do not go to plan.

1.2 Naming Conventions


Naming conventions vary from programmer to programmer and even
between companies. Some games companies have strict guidelines on how
code is constructed and how to name variables, where they can and cannot
be used, and so on, which is mostly in place to make it easier for other
programmers to be able to understand the code and pick it up when they
might need to. You may not need to take it that far, but I do feel that some
organization of your naming helps. In this book, I follow a very loose set of
rules for naming variables – just enough to make it easier for me to know
quickly what type of variable I am looking at or what its purpose might be.
Those are:
Object references (Transforms, Components, GameObjects, and so forth)
are prefixed by an underscore (_) symbol. For example, a variable to hold a
reference to a Transform might be named _TR. A variable used to talk to a
Game Manager might be named _GameManager.
Most of the objects in this book (players, enemies, and more) derive from
the ExtendedMonoBehaviour class, which contains a few variables that are
used more commonly than others:

_RB Used to reference a Rigidbody attached to this object.

_RB2D For a 2D Rigidbody reference.

_TR The Transform of the object.

_GO The GameObject.

Where scripts need to be initialized before they can be used, in this book
we always use a Boolean variable named didInit which gets set to true after
initialization. You can use didInit to make sure initialization has completed.
Many programmers frown on the idea of declaring temporary variables,
but I like to have _tempVEC and _tempTR variables available for whenever
I need to refer to a quick Vector3 or another Transform inline. Having these
variables already declared is just a little quicker than having to declare a
new Vector3 each time, or to make a new Transform variable.

1.3 Where to Now?


Think about how your objects work together in the game world and how
their scripts need to communicate with each other. I find it helps to make
flow diagrams or to use mind-mapping software to work things out
beforehand. A little planning early on can reduce a whole lot of code
revisions later. That said, it is perfectly O.K. for your structure to grow and
evolve as you develop it further. The framework shown in this book went
through many iterations before reaching its final form.
Try to break up your scripts into smaller components to help debugging
and flexibility. Also try to design for re-useability; hard-coding references
to other scripts reduces the portability of the script and increases the amount
of work you will need to do in the future when you want to carry it over
into another project.
Making a 2D Infinite
2 Runner Game

This chapter is different from the rest of the book and a dramatic diversion
from what you may have seen in its first edition. Elsewhere in the text, I
focus mainly on the code behind the games. This chapter offers up a step by
step tutorial to using the framework to make a 2D infinite runner game. The
goal of this chapter is to demonstrate two things: 1) How quickly you can
turn around a game when you have a framework in place that takes care of a
lot of the repetitive tasks. 2) The basics of how this books framework fits
together to give you some background knowledge before we get down into
nitty gritty of the framework code in Chapter 3.
This infinite runner (Figure 2.1) has a character that can move left, right,
and jump. Platforms are spawned off-screen and moved to the left to create
the illusion of movement.
I have already set up animations and imported the required graphics into
the example project to get things going quickly. As the focus of this book is
more toward code, project structure, and programming, I want to avoid
using up too many pages on making graphics or on Unity editor-specifics.
The Unity documentation features plenty of content on this.
Players jump and move to stay on the platforms if possible, with the
score incremented at timed intervals. If the player falls off the bottom of the
screen, the game ends.
To accomplish this, we will need:

1. The C# Game Programming Cookbook (GPC) framework, which is


included as part of this book as a download from Github at https://gi
thub.com/psychicparrot/CSharpUnityCookbookExampleFiles
2. A platformer character capable of running left, right, and jumping

3. Platforms (auto moving to the left) and a method to spawn platforms


off screen

Figure 2.1 In the Infinite Runner example game, players jump and run to try to stay on
the platforms for as long as possible.

4. A Game Manager script to keep track of game state and deal with
scoring and so forth

5. Sounds for jumping and the game ending

6. An animated character

With just the framework and assets, by the end of this chapter, we will
have a working game.

2.1 Anatomy of a Unity Project


Unity projects are made up of lots and lots of files. A game is made up of
Scenes full of GameObjects. GameObjects are all the objects that make up a
game. GameObjects may take the form of anything from an empty
placeholder to a fully animated 3d model. Every GameObject has
something called a Transform, which holds information on the rotation,
position, and scale of the GameObject.
Scenes are essentially just files that hold information about which objects
to load at runtime. They can contain GameObjects, or they can contain
Prefabs. Prefabs are essentially files containing information about one or
more GameObjects to load as though they are combined. By using Prefabs,
you can reduce the time it takes to build multiple Scenes by combining
multiple GameObjects into one, single, Prefab. Think of Prefabs as
templates you make yourself by arranging GameObjects in the Scene and
then creating Prefabs from them as templates to load and use elsewhere.
When you drag a Prefab into a Unity Scene, it will appear as one or more
GameObjects – replicating the original structure you created when you
made the original Prefab. Since game projects are made up of many files, a
lot of your time in Unity will be spent manipulating files, turning them into
GameObjects, and Prefabs and then organizing and laying them out in
Scenes. In the next section, we look at how Unity helps you to do this and
how the editor is structured for exactly these kinds of tasks.

2.2 Open Unity, Then the Example Project fo


r This Chapter
Open Unity. At the splash screen, choose to open an existing project and
browse to the folder named Chapter2_UnComplete_ProjectFiles, which
contains the example project for this chapter. Open the project. If you have
any trouble along the way, or you just want to try out the completed game,
you can find the complete example as a part of the other example project
found in the folder named All_Completed_ProjectFiles.
Figure 2.2 The Unity editor as seen in a 2 by 3 layout.

To keep everything in line with the information in this section, you


should change the editor layout. In the top right of the editor, find the
Layout dropdown button. Click on it and choose 2 by 3. After a short delay,
the editor should arrange its panels into the default 2 by 3 layout.
Now that we have the editor laid out in similar ways, let’s look through
each panel to make sure we are using the same terminology. Check out Figu
re 2.2 – outlined below are the different sections shown in the figure, what
those sections are and what they are for:

A. Scene
The Scene panel is your drag and drop visual window into a Unity
Scene. You can manipulate GameObjects directly inside the
currently loaded Scene.

B. Game
The Game panel shows a preview of the game. When you press
Play, the editor runs the game inside the Game panel as if it were
running in a standalone build. There are also a few extra features,
such as Gizmos, that the Game preview offers to help you build out
and debug your games.

C. Project
The Project panel is very similar to a file browser, in that it lists out
all the files that go up to make your project. You can click and drag
them, right click, and access a menu, use shortcuts, and delete them
– almost all the regular functionality of a Windows Explorer
window right inside the editor.

D. Hierarchy
The Hierarchy works in a similar way to the Project panel, only
instead of being an interface to manipulate project files, it’s there to
manipulate GameObjects inside the current Scene.

Figure 2.3 The Transform tools.

Figure 2.4 The playback tools.

E. Inspector
Whenever you have a GameObject selected in the Scene panel, or
highlighted in the Hierarchy, the Inspector window shows you
editable properties of the GameObject and any Components
attached to it. Whatever you can’t do with the Scene panel, you can
probably do here instead.

Another point of interest in the main Unity editor are along the toolbar
across the top of the editor, below the menus.
In the top left, find the Transform toolbar (Figure 2.3). This toolbar is to
manipulate objects in the Scene panel. Tools, from left to right:
The Hand Tool Allows you to pan the view around the Scene.
Move Selection and movement of GameObjects.
Rotate Selection and rotation of GameObjects.
Scale Selection and scaling of GameObjects.
Rect Modify a GameObjects boundaries as a Rect (combined scaling and
Transform movement).
Transform A method to manipulate scale, position, and rotation in a single, combined tool.
Custom This tool allows access to custom Editor tools and will not be covered in this
book.

At the center of the toolbar, find the Play, Pause and Step buttons (Figure 2.
4) which are used to preview your game and to control what happens in the
Game panel.

2.2.1 A Few Notes on the Example Project


Unity uses something called packages to extend the functionality of the
editor in an officially supported and controlled way. To facilitate editing and
set up of the 2D (two dimensional) sprites in this project, a package named
2D Sprite Package had to be imported. Accessing packages is done via the
Package Manager – found in the menu Window/Package Manager. Check in
Package Manager regularly, for updates to any libraries you download.

2.2.2 Sprites
2D sprites may be found in the projects Assets/Games/RunMan/Sprites
folder. The sprites were made with a sprite editing program called Aesprite
and exported as sprite sheets. Sprite sheets are groups of sprites which are
split up into individual sprites by the engine. We tend to use sprite sheets
for animations, exporting multiple frames of animation in a single image to
save memory and having the engine take care of cutting them up to display.
The import settings for all of the game images are set to their default values,
the Sprite Mode is set to Multiple to accommodate the sprite sheets
(Multiple allows you to slice up those images) and the Filter Mode has been
set to Point (no filter) so that Unity does not try to filter images to make
them smooth. For this type of visual style, we want the pixels to be defined
and visible without filtering. The only other deviation from the defaults is
the Compression level, which is set to None just to be sure to avoid any
artifacts or anomalies that might stem from compressing small images.

2.2.3 Animation
Animation is a complicated subject and outside the scope of this book, but
this section acts as a quick guide on how the animations for this game
works.
Look out for RunMan_Animator in the Sprites folder. You can open it to
view by double clicking on the RunMan_Animator file in the Project pane.
An Animator contains a state machine graph (Figure 2.5) which controls the
flow of animation. When an animated GameObject is initialized, the state
machine graph begins in its Entry state and will transition to the default
state. In Figure 2.5, you can see that RunMan_Animator has a default state
of RunMan_Idle (that is, an arrow goes from Entry to RunMan_Idle) – this
will play an idle animation for whenever RunMan is standing still. The
animation is looped and there is no further flow (no more arrows pointing to
boxes!) out from RunMan_Idle in the Animator graph; so, until told
otherwise, the animation will stay in the idle state.
In the graph (Figure 2.5) look for the Any State state – this literally
means any state in that this state can be triggered from any animation. The
Any State has two arrows coming off it; one pointing to RunMan_Jump
state and the other to a RunMan_Run state. So, how do we get the
animation to change to run or jump when the Animator graph has no link
from the endlessly looping RunMan_Idle state? Parameters are the answer!
Parameters are variables that can be set and modified through code and
used as Conditions by the Animator graph to control flow. In the case of
Any State, whenever a Jump parameter is triggered the Animator will
transition from Any State (that is, whatever state the graph is currently in)
to RunMan_Jump. Whenever a Run parameter is triggered, the Animator
will transition from Any State to RunMan_Run. RunMan_Run is a looping
animation that, again, will play until the Animator graph is told to do
otherwise.
In conclusion, the animation system for this game is set up to be as
straightforward as possible. The Animator can be controlled by two
parameters: Jump and Run. In our code, to transition to a run animation we
just set the Run parameter. To play a jump animation, we set the Jump
parameter.

Figure 2.5 The Animator graph for the RunMan character.

2.3 Open the Main Game Scene


In the Project panel, there are a lot of folders. Most of them are sub-folders
inside the GPC_Framework folder. We do not need to get into these just yet,
but you should know that the files in GPC_Framework make up the
framework and they are separated from everything else to keep framework
files and your games files separated and neat.
Find the Games folder and click the little arrow next to it to expand out
the folder to show its contents. It is intended that, whenever you build a
game with the framework, you use the Games folder to put the assets that
are specific to your game only.
The folder structure under Games looks like this:
Games

RunMan

Audio

Prefabs

Scenes

Scripts

Sprites

Stay as organized as possible as you move forward with game projects. This
will help a lot as your project grows (and, often, they grow much bigger
than you might expect!) to stay on course and to spend less time looking for
lost assets.
In the Project panel, click on the Scene folder to show its contents. There
is a single Scene inside that folder, named runMan_core. This is the Scene
that will contain the main game. There will also be a main menu Scene,
which we will add later in this chapter.
Double click on the runMan_core Scene in the Project panel, to open it.
The Game panel will show the user interface already set up (Figure 2.6) but
there’s no other logic in the Scene yet, so pressing Play will do nothing. By
using the framework, at the end of this chapter you will have a fun infinite
runner game to play here instead. The books game framework takes care of
most of the heavy lifting and the bulk of the work is going to be to
connecting existing scripts together to form the GameObject, logic, and
physics for this game. You may be surprised to learn that it only takes four
custom scripts.
Figure 2.6 To save time, the User Interface is already set up in the game Scene of the example
project for this chapter.

2.4 The Game Manager


At the core of this game is the Game Manager. This is where the state of our
game is tracked and the convergence point of all the game’s objects and
logic. We will be revisiting the Game Manager throughout this chapter, but
what we need to do in this section is to set up the basic structure and a few
variables for our other objects to access and use. For example, platforms
will need to know how fast to move. We need all platforms to move at the
same speed, so it makes sense to store the speed value in the Game
Manager. Storing the platform speed also means that we can change the
speed of the game easily from right inside the script that deals with game
logic.
With the RunMan_core Scene open in Unity, click the plus sign at the top
of the Hierarchy panel to show the Add menu. Choose Create Empty from
the dropdown.
TIP: You can also access the Add GameObject menu by right clicking in an
empty space in the Hierarchy panel or via the menu GameObject at the top
of the editor.

In the Inspector, with the new GameObject selected, change the name
from GameObject to GameManager.
Click Add Component. In the text box that appears after clicking that
button, type RunMan_GameManager. Once you have finished typing, press
enter on the keyboard. The Add Component window will automatically
switch to show New Script (Figure 2.7). Click Create and Add. This creates
a new C# script Component and adds it to the GameObject you just created.
After a little time for the compiler to update, the Component should appear
in the Inspector as a Component named (Script). The next step is to open
the script and add some code to it.
Still in the Inspector, double click on the Script name inside the
Component to open your default script editor (normally Visual Studio,
unless you chose something different when you installed Unity). If you
have any issues opening the script, you can get to it via the Project panel.
Unity will have automatically placed the new script in the Assets folder.
Click on the Assets folder in the Project panel and you should be able to see
RunMan_GameManager on the right side of the split Project pane. Double
click the script file to open it.
The default C# script Unity adds when you create new file looks like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RunMan_GameManager: MonoBehaviour

{
// Start is called before the first frame update
void Start()
{

}
// Update is called once per frame
void Update()
{

}
}
Figure 2.7 Naming and creating a new Component in the Inspector’s Add Component panel.

The framework in this book exists within a namespace called GPC, so the
first thing we need to do to be able to access everything inside the
framework is to add a using statement to the top of the script. Below using
UnityEngine, add the following line:
using GPC;

The framework includes a base version of a Game Manager script that


we can inherit (see Chapter 1 for a brief guide to inheritance) to give this
script some of the useful functionality we will need as the game grows.
Let’s change our new Game Manager script. The base script is called
BaseGameManager. Change:

public class RunMan_GameManager : MonoBehaviour

To:

public class RunMan_GameManager : BaseGameManager

Press CTRL+S to save the script, or save the script via the menus
File>Save.
Remember when we first created the GameManager through the Add
Component button in the Inspector and the new Component appeared as
something called (Script)? Flip back to the editor and you will see we now
have a whole host of new things in the Inspector. The BaseGameManager
script contains lots of useful things to help manage your game. We will go
into the script in full detail in Chapter 3, Section 3.2.1.
In the Inspector now, there are three dropdown menu fields for Current
Game State, Target Game State, and Last Game State. Below those, a whole
lot of events that will be fired by our state machine entering states like
loaded, game started, and so forth. We will deal with game states in full,
further in this chapter in Section 2.7.1.
Before anything else, we do need to add a few variables. Place this code
just after the class declaration, above void Start():

public float runSpeed = 1f;


public float distanceToSpawnPlatform = 2f;
public bool isRunning;

runSpeed will be used by platform movement code to determine how fast


to move the platforms across the screen to simulate running.
distanceToSpawnPlatform contains a float value representing the gap (in
3d units) between platforms.
isRunning is a Boolean used by platforms to know whether they should
be moving or not. The main use for isRunning is at the start of the game,
before the player starts running as it sits in its idle animation state. We will
use it again at the end of the game, just to stop the platforms moving when
we show the final score game over messages.
Now that we have these variables set up in the Game Manager, we need
to make this class accessible from everywhere so that other scripts can
access it. To do that, we will take a basic Singleton approach. See Chapter
1, Section 1.4 for more information on this.
Beneath the variables you just added, right after the line:

public bool isRunning;

Add the following code:

public static RunMan_GameManager instance { get; private


set; }
// set instance in this script's constructor
public RunMan_GameManager()
{
instance = this;
}

What this does is to make a variable that is accessible from anywhere


because it’s public and static. As the constructor runs when a
GameManager instance gets created, our public static variable gets
populated with a reference to ‘this’ instance. Other scripts can now talk to
this instance by referring to its static variable like this:

RunMan_GameManager.instance

Going in via this instance variable, any other script in your game can call
functions on RunMan_GameManager, access public variables, or set public
variables. Just make sure that only one instance of RunMan_GameManager
ever exists at any time, otherwise you may find a script trying to access the
wrong object. If you do find yourself making more complicated scenarios
that could lead to multiple instances you may want to add check to see if the
instance variable is already populated before setting it. In the case of this
game, we only ever need this single instance to be attached to a single
GameObject in a single Scene and this is enough.
For now, that is as far as we need to take the Game Manager. There will
be more later in the chapter, but this is enough to get going with and enough
to provide the game platforms with the information they need to move.

2.5 Making Platforms to Run On


At the core of this game are platforms to run on, so that is a great starting
point. As the platforms do not require any game specific code, we can go
ahead, and figure out a method to spawn them and move them before
adding game logic.
Right now, the user interface may get in the way of seeing everything
clearly as you set up game elements. To hide the interface, look in the
Hierarchy panel and find the UI_Canvases object. UI_Canvases is an empty
GameObject with the actual user interfaces below, parented to it. If you
cannot see the three Canvas GameObjects under UI_Canvases, click on the
little arrow next to UI_Canvases to expand it out. Now, click the first one –
the GetReadyMessageCanvas GameObject – to highlight it. Hold shift on
the keyboard and click the GameUICanvas GameObject. This should select
all three canvases at the same time. Over in the Inspector, find the
Component named Canvas Group and set the value in the Alpha field to 0.
All the user interface should now be hidden.
In the Project panel, find the Games/RunMan/Sprites folder. In Sprites,
find the RunMan_Platform sprite. Left click and drag it into an empty part
of the Hierarchy panel. If all goes well, you should see the platform appear
in the center of the Game panel.
With RunMan_Platform GameObject selected in the Hierarchy, move the
mouse so that it is hovering over the Scene panel. Press F on the keyboard.
This will focus on the currently selected object, moving the Scene view to
the center of the object to make editing easier. You may want to use the
mouse wheel to zoom out a little at this point, too. Just enough so that there
is space around the platform to move it around without it going off the edge
of the screen.
In the Scene view, click and hold to grab the red arrow of the Gizmo
Unity overlays on the platform. With the red arrow selected, you will only
be able to move the platform along its X axis – left or right in the Game
panel. Drag the platform to the left so that the left side of the platform is
touching the left side of the Game panel.
Next, grab the green arrow of the gizmo to move the platform on its Y
axis. Hold down the mouse and move the platform so that the bottom of it
touches the bottom of the Game panel.
This platform is going to be a starting platform for the player to stand on
when the game first starts. To stop the player falling right through it, we
need to add a Collider.
With RunMan_Platform still selected, look to the Inspector, and click
Add Component. In the search box that appears after you click the button,
type Edge and choose Edge Collider 2D from the dropdown to add an Edge
Collider 2D Component to the GameObject.
With RunMan_Platform still selected in the Hierarchy, go back to
hovering over the Scene panel and press F on the keyboard to focus the
platform in the center of the view. Now that the Edge Collider 2D
Component has been added to this GameObject, you should see a thin green
line running lengthwise across the platform. This line will become the solid
physics surface that the player will stand on. It needs to align with the top
of the platform rather than where it is now. On the Edge Collider 2D
Component, click the Edit Collider button (Figure 2.8). In the Scene panel,
the green line can now be moved around. Hover the mouse over the green
line and a small gizmo block appears. By clicking and dragging the block,
the green line will move. First, grab a point at the left side and move it up.
Then, grab a point on the right and do the same so that the green line aligns
perfectly with the top of the platform.
Figure 2.8 In Unity, some Colliders such as the Edge Collider 2D have an Edit button.

To complete the platform set up, just two more Components need to be
added to it. In the Inspector, click Add Component, and find and add an
Auto Destroy Object Component. In the field labeled Time Before Object
Destroy, type 10. We want this object to delete itself after 10 seconds. The
RunMan_Platform Components should now look like those in Figure 2.8.
The second Component we are going to build ourselves. Click Add
Component and type AutoTransformMove. Click New Script and then
Create and Add to create a new C# script and add it to the GameObject.
Once the new script is attached to the GameObject and visible in the
Inspector, double click on the name of the script to open it in your script
editor. In your script editor, add the following line just above the class
declaration and below the existing using statements:

using GPC;

To move the platforms, this script requires three variables. Add these just
inside the class declaration:

public float moveSpeed;


public Vector3 moveVector;
private Transform _TR;

When the script first starts, we need to grab a reference to the


GameObject’s Transform. A Transform is a built-in Component we use for
modifying position, rotation, and scale.
Scripts that derive from Monobehaviour (on any level) can contain
functions that will be automatically called by the game engine. The Start()
function will be called when the game starts. Change the Start() function to
look like this:
void Start()
{
// cache the transform ref
_TR = GetComponent<Transform>();
}

The GetComponent will search for a Component, of whatever type is


within the angled brackets, on the current GameObject. GetComponent() is
a useful built in function, but it can be a little slow, so it is best to keep any
calls to GetComponent() out of the main loop and called as least as
possible.
Another Monobehaviour specific built-in function that will be called
automatically by the engine is Update(). It will be called every frame (yes,
30 times per second when the frames per second speed is 30, or 60 at 60 fps
and so on). It is the ideal place to put our movement code. Replace the
placeholder Update function already in your script with this:

void Update()
{
// keep move speed updated from game manager
moveSpeed = RunMan_GameManager.instance.runSpeed;

// move the transform


_TR.Translate((moveVector * moveSpeed) *
Time.deltaTime);
}

In the code above, moveSpeed gets its value from the runSpeed variable
you made in RunMan_GameManager earlier in this chapter. It uses that
Singleton variable instance, to gain access to it.
Beneath that, we use the Translate function (part of Transform) to move
the platform. moveVector is a Vector3 typed variable which holds a
direction vector used to define the direction of movement of the object. This
gets multiplied by the moveSpeed to give us a Vector suitable for Translate
that will change with the speed in RunMan_GameManager. It is then
multiplied by Time.deltaTime. Unity provides some a helper class named
Time to help track or manipulate how the engine deals with time. deltaTime
is a variable holding the amount of time that has passed since the last frame
Update, so we can use that deltaTime amount to make movement that
adapts to time rather than being locked to framerates. This is a better idea
than just move x amount each frame, because if the system does something
in the background that causes the game to stall or if your game is running
slower than it should on another system, the movement won’t work as
intended. By having movement that adapts to time elapsed, if things run
slow or there are glitches it will move the same amount even if it needs to
jump a bit.
Finally, add this function below the Update() function above the final
curly bracket in the script:

public void SetMoveSpeed(float aSpeed)


{
// provide method to adjust speed from other
scripts
moveSpeed = aSpeed;
}

Above, we just add a simple method for another script to tell this script
how fast or slow to move. This will be used a little further in this chapter,
called at the start of the game to tell the starting platforms to move once the
game begins.
Press CTRL+S to save your script and go back to Unity.
With RunMan_Platform selected in the Hierarchy, look to the Auto
Transform Move Component you made, leave Move Speed at 0 but change
Move Vector so that X is –1, leaving Y and Z at 0.
Finally, we need to set up the Layer of the platform so that it can be
detected as ground. In the top right of the Inspector, just below the name of
the GameObject to the right, there is a dropdown menu labeled Layer (Figur
e 2.9). Click the dropdown and choose Ground from the list.
Press Play in the editor. The platform should zip off to the left of the
screen. If it did, nice job! That is how it is supposed to behave. Stop
playback by clicking the Stop button in the editor.
Another Random Document on
Scribd Without Any Related Topics
subject, as influenced by general and common causes, may not be
deemed improper. At New-Orleans, Baton-Rouge, Natchez, and
perhaps, generally upon the Mississippi, as high as the latter place,
the same species of fever seems to have prevailed with great
mortality. Natchez and New-Orleans, it is understood, have suffered
beyond any former examples; and in fact, almost all our cities upon
the sea coast, from Maine to Louisiana, appear to have suffered in a
greater or less degree from the same species of fever; though they
were favoured by a long established and well regulated police.
In the interior of the country, upon the waters of the Tombecbe
and Alabama, the sickness and mortality was greater than was ever
known before. At St. Stephens, Jackson, Fort Claiborne, and other
places on those rivers, bilious fevers, of the worst grade prevailed;
and in many instances we are warranted in saying, that in type and
symptoms it differed little from the fever, which prevailed in this
town.
The season has been a very uncommon one, and has produced as
uncommon effects; and wherever it has operated upon local causes,
it appears to have produced malignant fevers. In the town of Mobile,
[1]
art and labour could scarcely have combined a more destructive
mass, for the production of malignant fever, under the operation of
such a season, than is found to have been laboriously collected
together in filling up lots, streets, and wharves: and the committee
would do injustice to their own feelings, and their sense of the duty
they owe their fellow-citizens, were they to suppress a warning voice
of the danger that yet awaits them: if they be not zealous and active
in removal of the numerous causes of disease, daily trodden under
their feet, daily presented to their view. While they walk the streets,
disease will assail them in every quarter, while they slumber in their
beds, they will breathe the poison of death, until the yards and
enclosures are cleansed—until the streets and wharves are radically
reformed; and then, by the blessing of God, we shall prosper in
health.
JACOB
LUDLOW,
DAVID RUST,
H. V.
CHAMBERLAIN,
ADDIN LEWIS,
Dr. MAJOR,
} Committee.

EDWARD
HALL,
PHILIP
M’LOSKEY.

1. Limits of the town—three miles in circumference.


TRANSCRIBER’S NOTES
1. Silently corrected typographical errors and variations in
spelling.
2. Archaic, non-standard, and uncertain spellings retained
as printed.
*** END OF THE PROJECT GUTENBERG EBOOK REPORT OF THE
COMMITTEE APPOINTED TO INVESTIGATE THE CAUSES AND
EXTENT OF THE LATE EXTRAORDINARY SICKNESS AND MORTALITY
IN THE TOWN OF MOBILE ***

Updated editions will replace the previous one—the old editions


will be renamed.

Creating the works from print editions not protected by U.S.


copyright law means that no one owns a United States
copyright in these works, so the Foundation (and you!) can copy
and distribute it in the United States without permission and
without paying copyright royalties. Special rules, set forth in the
General Terms of Use part of this license, apply to copying and
distributing Project Gutenberg™ electronic works to protect the
PROJECT GUTENBERG™ concept and trademark. Project
Gutenberg is a registered trademark, and may not be used if
you charge for an eBook, except by following the terms of the
trademark license, including paying royalties for use of the
Project Gutenberg trademark. If you do not charge anything for
copies of this eBook, complying with the trademark license is
very easy. You may use this eBook for nearly any purpose such
as creation of derivative works, reports, performances and
research. Project Gutenberg eBooks may be modified and
printed and given away—you may do practically ANYTHING in
the United States with eBooks not protected by U.S. copyright
law. Redistribution is subject to the trademark license, especially
commercial redistribution.

START: FULL LICENSE


THE FULL PROJECT GUTENBERG LICENSE
PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK

To protect the Project Gutenberg™ mission of promoting the


free distribution of electronic works, by using or distributing this
work (or any other work associated in any way with the phrase
“Project Gutenberg”), you agree to comply with all the terms of
the Full Project Gutenberg™ License available with this file or
online at www.gutenberg.org/license.

Section 1. General Terms of Use and


Redistributing Project Gutenberg™
electronic works
1.A. By reading or using any part of this Project Gutenberg™
electronic work, you indicate that you have read, understand,
agree to and accept all the terms of this license and intellectual
property (trademark/copyright) agreement. If you do not agree
to abide by all the terms of this agreement, you must cease
using and return or destroy all copies of Project Gutenberg™
electronic works in your possession. If you paid a fee for
obtaining a copy of or access to a Project Gutenberg™
electronic work and you do not agree to be bound by the terms
of this agreement, you may obtain a refund from the person or
entity to whom you paid the fee as set forth in paragraph 1.E.8.

1.B. “Project Gutenberg” is a registered trademark. It may only


be used on or associated in any way with an electronic work by
people who agree to be bound by the terms of this agreement.
There are a few things that you can do with most Project
Gutenberg™ electronic works even without complying with the
full terms of this agreement. See paragraph 1.C below. There
are a lot of things you can do with Project Gutenberg™
electronic works if you follow the terms of this agreement and
help preserve free future access to Project Gutenberg™
electronic works. See paragraph 1.E below.
1.C. The Project Gutenberg Literary Archive Foundation (“the
Foundation” or PGLAF), owns a compilation copyright in the
collection of Project Gutenberg™ electronic works. Nearly all the
individual works in the collection are in the public domain in the
United States. If an individual work is unprotected by copyright
law in the United States and you are located in the United
States, we do not claim a right to prevent you from copying,
distributing, performing, displaying or creating derivative works
based on the work as long as all references to Project
Gutenberg are removed. Of course, we hope that you will
support the Project Gutenberg™ mission of promoting free
access to electronic works by freely sharing Project Gutenberg™
works in compliance with the terms of this agreement for
keeping the Project Gutenberg™ name associated with the
work. You can easily comply with the terms of this agreement
by keeping this work in the same format with its attached full
Project Gutenberg™ License when you share it without charge
with others.

1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside
the United States, check the laws of your country in addition to
the terms of this agreement before downloading, copying,
displaying, performing, distributing or creating derivative works
based on this work or any other Project Gutenberg™ work. The
Foundation makes no representations concerning the copyright
status of any work in any country other than the United States.

1.E. Unless you have removed all references to Project


Gutenberg:

1.E.1. The following sentence, with active links to, or other


immediate access to, the full Project Gutenberg™ License must
appear prominently whenever any copy of a Project
Gutenberg™ work (any work on which the phrase “Project
Gutenberg” appears, or with which the phrase “Project
Gutenberg” is associated) is accessed, displayed, performed,
viewed, copied or distributed:

This eBook is for the use of anyone anywhere in the United


States and most other parts of the world at no cost and
with almost no restrictions whatsoever. You may copy it,
give it away or re-use it under the terms of the Project
Gutenberg License included with this eBook or online at
www.gutenberg.org. If you are not located in the United
States, you will have to check the laws of the country
where you are located before using this eBook.

1.E.2. If an individual Project Gutenberg™ electronic work is


derived from texts not protected by U.S. copyright law (does not
contain a notice indicating that it is posted with permission of
the copyright holder), the work can be copied and distributed to
anyone in the United States without paying any fees or charges.
If you are redistributing or providing access to a work with the
phrase “Project Gutenberg” associated with or appearing on the
work, you must comply either with the requirements of
paragraphs 1.E.1 through 1.E.7 or obtain permission for the use
of the work and the Project Gutenberg™ trademark as set forth
in paragraphs 1.E.8 or 1.E.9.

1.E.3. If an individual Project Gutenberg™ electronic work is


posted with the permission of the copyright holder, your use and
distribution must comply with both paragraphs 1.E.1 through
1.E.7 and any additional terms imposed by the copyright holder.
Additional terms will be linked to the Project Gutenberg™
License for all works posted with the permission of the copyright
holder found at the beginning of this work.

1.E.4. Do not unlink or detach or remove the full Project


Gutenberg™ License terms from this work, or any files
containing a part of this work or any other work associated with
Project Gutenberg™.

1.E.5. Do not copy, display, perform, distribute or redistribute


this electronic work, or any part of this electronic work, without
prominently displaying the sentence set forth in paragraph 1.E.1
with active links or immediate access to the full terms of the
Project Gutenberg™ License.

1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form,
including any word processing or hypertext form. However, if
you provide access to or distribute copies of a Project
Gutenberg™ work in a format other than “Plain Vanilla ASCII” or
other format used in the official version posted on the official
Project Gutenberg™ website (www.gutenberg.org), you must,
at no additional cost, fee or expense to the user, provide a copy,
a means of exporting a copy, or a means of obtaining a copy
upon request, of the work in its original “Plain Vanilla ASCII” or
other form. Any alternate format must include the full Project
Gutenberg™ License as specified in paragraph 1.E.1.

1.E.7. Do not charge a fee for access to, viewing, displaying,


performing, copying or distributing any Project Gutenberg™
works unless you comply with paragraph 1.E.8 or 1.E.9.

1.E.8. You may charge a reasonable fee for copies of or


providing access to or distributing Project Gutenberg™
electronic works provided that:

• You pay a royalty fee of 20% of the gross profits you derive
from the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”

• You provide a full refund of any money paid by a user who


notifies you in writing (or by e-mail) within 30 days of receipt
that s/he does not agree to the terms of the full Project
Gutenberg™ License. You must require such a user to return or
destroy all copies of the works possessed in a physical medium
and discontinue all use of and all access to other copies of
Project Gutenberg™ works.

• You provide, in accordance with paragraph 1.F.3, a full refund of


any money paid for a work or a replacement copy, if a defect in
the electronic work is discovered and reported to you within 90
days of receipt of the work.

• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.

1.E.9. If you wish to charge a fee or distribute a Project


Gutenberg™ electronic work or group of works on different
terms than are set forth in this agreement, you must obtain
permission in writing from the Project Gutenberg Literary
Archive Foundation, the manager of the Project Gutenberg™
trademark. Contact the Foundation as set forth in Section 3
below.

1.F.

1.F.1. Project Gutenberg volunteers and employees expend


considerable effort to identify, do copyright research on,
transcribe and proofread works not protected by U.S. copyright
law in creating the Project Gutenberg™ collection. Despite these
efforts, Project Gutenberg™ electronic works, and the medium
on which they may be stored, may contain “Defects,” such as,
but not limited to, incomplete, inaccurate or corrupt data,
transcription errors, a copyright or other intellectual property
infringement, a defective or damaged disk or other medium, a
computer virus, or computer codes that damage or cannot be
read by your equipment.

1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except


for the “Right of Replacement or Refund” described in
paragraph 1.F.3, the Project Gutenberg Literary Archive
Foundation, the owner of the Project Gutenberg™ trademark,
and any other party distributing a Project Gutenberg™ electronic
work under this agreement, disclaim all liability to you for
damages, costs and expenses, including legal fees. YOU AGREE
THAT YOU HAVE NO REMEDIES FOR NEGLIGENCE, STRICT
LIABILITY, BREACH OF WARRANTY OR BREACH OF CONTRACT
EXCEPT THOSE PROVIDED IN PARAGRAPH 1.F.3. YOU AGREE
THAT THE FOUNDATION, THE TRADEMARK OWNER, AND ANY
DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE LIABLE
TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL,
PUNITIVE OR INCIDENTAL DAMAGES EVEN IF YOU GIVE
NOTICE OF THE POSSIBILITY OF SUCH DAMAGE.

1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you


discover a defect in this electronic work within 90 days of
receiving it, you can receive a refund of the money (if any) you
paid for it by sending a written explanation to the person you
received the work from. If you received the work on a physical
medium, you must return the medium with your written
explanation. The person or entity that provided you with the
defective work may elect to provide a replacement copy in lieu
of a refund. If you received the work electronically, the person
or entity providing it to you may choose to give you a second
opportunity to receive the work electronically in lieu of a refund.
If the second copy is also defective, you may demand a refund
in writing without further opportunities to fix the problem.

1.F.4. Except for the limited right of replacement or refund set


forth in paragraph 1.F.3, this work is provided to you ‘AS-IS’,
WITH NO OTHER WARRANTIES OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR ANY PURPOSE.

1.F.5. Some states do not allow disclaimers of certain implied


warranties or the exclusion or limitation of certain types of
damages. If any disclaimer or limitation set forth in this
agreement violates the law of the state applicable to this
agreement, the agreement shall be interpreted to make the
maximum disclaimer or limitation permitted by the applicable
state law. The invalidity or unenforceability of any provision of
this agreement shall not void the remaining provisions.

1.F.6. INDEMNITY - You agree to indemnify and hold the


Foundation, the trademark owner, any agent or employee of the
Foundation, anyone providing copies of Project Gutenberg™
electronic works in accordance with this agreement, and any
volunteers associated with the production, promotion and
distribution of Project Gutenberg™ electronic works, harmless
from all liability, costs and expenses, including legal fees, that
arise directly or indirectly from any of the following which you
do or cause to occur: (a) distribution of this or any Project
Gutenberg™ work, (b) alteration, modification, or additions or
deletions to any Project Gutenberg™ work, and (c) any Defect
you cause.

Section 2. Information about the Mission


of Project Gutenberg™
Project Gutenberg™ is synonymous with the free distribution of
electronic works in formats readable by the widest variety of
computers including obsolete, old, middle-aged and new
computers. It exists because of the efforts of hundreds of
volunteers and donations from people in all walks of life.

Volunteers and financial support to provide volunteers with the


assistance they need are critical to reaching Project
Gutenberg™’s goals and ensuring that the Project Gutenberg™
collection will remain freely available for generations to come. In
2001, the Project Gutenberg Literary Archive Foundation was
created to provide a secure and permanent future for Project
Gutenberg™ and future generations. To learn more about the
Project Gutenberg Literary Archive Foundation and how your
efforts and donations can help, see Sections 3 and 4 and the
Foundation information page at www.gutenberg.org.

Section 3. Information about the Project


Gutenberg Literary Archive Foundation
The Project Gutenberg Literary Archive Foundation is a non-
profit 501(c)(3) educational corporation organized under the
laws of the state of Mississippi and granted tax exempt status
by the Internal Revenue Service. The Foundation’s EIN or
federal tax identification number is 64-6221541. Contributions
to the Project Gutenberg Literary Archive Foundation are tax
deductible to the full extent permitted by U.S. federal laws and
your state’s laws.

The Foundation’s business office is located at 809 North 1500


West, Salt Lake City, UT 84116, (801) 596-1887. Email contact
links and up to date contact information can be found at the
Foundation’s website and official page at
www.gutenberg.org/contact
Section 4. Information about Donations to
the Project Gutenberg Literary Archive
Foundation
Project Gutenberg™ depends upon and cannot survive without
widespread public support and donations to carry out its mission
of increasing the number of public domain and licensed works
that can be freely distributed in machine-readable form
accessible by the widest array of equipment including outdated
equipment. Many small donations ($1 to $5,000) are particularly
important to maintaining tax exempt status with the IRS.

The Foundation is committed to complying with the laws


regulating charities and charitable donations in all 50 states of
the United States. Compliance requirements are not uniform
and it takes a considerable effort, much paperwork and many
fees to meet and keep up with these requirements. We do not
solicit donations in locations where we have not received written
confirmation of compliance. To SEND DONATIONS or determine
the status of compliance for any particular state visit
www.gutenberg.org/donate.

While we cannot and do not solicit contributions from states


where we have not met the solicitation requirements, we know
of no prohibition against accepting unsolicited donations from
donors in such states who approach us with offers to donate.

International donations are gratefully accepted, but we cannot


make any statements concerning tax treatment of donations
received from outside the United States. U.S. laws alone swamp
our small staff.

Please check the Project Gutenberg web pages for current


donation methods and addresses. Donations are accepted in a
number of other ways including checks, online payments and
credit card donations. To donate, please visit:
www.gutenberg.org/donate.

Section 5. General Information About


Project Gutenberg™ electronic works
Professor Michael S. Hart was the originator of the Project
Gutenberg™ concept of a library of electronic works that could
be freely shared with anyone. For forty years, he produced and
distributed Project Gutenberg™ eBooks with only a loose
network of volunteer support.

Project Gutenberg™ eBooks are often created from several


printed editions, all of which are confirmed as not protected by
copyright in the U.S. unless a copyright notice is included. Thus,
we do not necessarily keep eBooks in compliance with any
particular paper edition.

Most people start at our website which has the main PG search
facility: www.gutenberg.org.

This website includes information about Project Gutenberg™,


including how to make donations to the Project Gutenberg
Literary Archive Foundation, how to help produce our new
eBooks, and how to subscribe to our email newsletter to hear
about new eBooks.
Welcome to Our Bookstore - The Ultimate Destination for Book Lovers
Are you passionate about books and eager to explore new worlds of
knowledge? At our website, we offer a vast collection of books that
cater to every interest and age group. From classic literature to
specialized publications, self-help books, and children’s stories, we
have it all! Each book is a gateway to new adventures, helping you
expand your knowledge and nourish your soul
Experience Convenient and Enjoyable Book Shopping Our website is more
than just an online bookstore—it’s a bridge connecting readers to the
timeless values of culture and wisdom. With a sleek and user-friendly
interface and a smart search system, you can find your favorite books
quickly and easily. Enjoy special promotions, fast home delivery, and
a seamless shopping experience that saves you time and enhances your
love for reading.
Let us accompany you on the journey of exploring knowledge and
personal growth!

ebookball.com

You might also like