C# Game Programming Cookbook for Unity 3D 2nd edition by Jeff Murray 9781000359725 1000359727 - Get instant access to the full ebook with detailed content
C# Game Programming Cookbook for Unity 3D 2nd edition by Jeff Murray 9781000359725 1000359727 - Get instant access to the full ebook with detailed content
com
https://ebookball.com/product/c-game-programming-cookbook-
for-unity-3d-2nd-edition-by-jeff-
murray-9781000359725-1000359727-18762/
OR CLICK BUTTON
DOWLOAD EBOOK
https://ebookball.com/product/introduction-to-game-programming-using-
c-and-unity-3d-1st-edition-by-vahe-
karamian-0997148403-978-0997148404-25168/
ebookball.com
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
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
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
https://ebookball.com/product/3d-game-programming-all-in-one-1st-
edition-by-kenneth-finney-isbn-159200136x-9781592001361-23550/
ebookball.com
https://ebookball.com/product/introduction-to-3d-game-programming-
with-directx-11-1st-edition-by-frank-
luna-1937585964-9781937585969-25192/
ebookball.com
https://ebookball.com/product/beginning-c-game-programming-1st-
edition-by-michael-dawson-isbn-1592002056-9781592002054-12450/
ebookball.com
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
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.
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
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.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
7. Weapon Systems
8. Waypoints Manager
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
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.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:
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.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.
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.
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:
2. In any other script, we can now access this static variable and alter
the score as needed:
GameController.gameScore++;
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.
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
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:
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:
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:
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");
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:
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.
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.
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:
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
6. An animated character
With just the framework and assets, by the end of this chapter, we will
have a working game.
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.
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.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.
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.
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;
{
// 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;
To:
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():
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.
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:
void Update()
{
// keep move speed updated from game manager
moveSpeed = RunMan_GameManager.instance.runSpeed;
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:
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.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.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.
• 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 comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.
1.F.
Most people start at our website which has the main PG search
facility: www.gutenberg.org.
ebookball.com