0% found this document useful (0 votes)
4 views

Module 3 - Full Notes PPT

Module 3 covers game mechanics, focusing on player choices and risk/reward dynamics in game design. It details the implementation of subsystems like health managers, health modifiers, and combat systems, as well as principles of animation that enhance character movement and interaction. The document also provides a step-by-step guide on creating basic animations within Unity, emphasizing the importance of keyframes and tweening for effective animation.

Uploaded by

manjunathkn300
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
0% found this document useful (0 votes)
4 views

Module 3 - Full Notes PPT

Module 3 covers game mechanics, focusing on player choices and risk/reward dynamics in game design. It details the implementation of subsystems like health managers, health modifiers, and combat systems, as well as principles of animation that enhance character movement and interaction. The document also provides a step-by-step guide on creating basic animations within Unity, emphasizing the importance of keyframes and tweening for effective animation.

Uploaded by

manjunathkn300
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/ 88

Module 3 - Game Mechanics and Systems

 In game design, almost every scenario can be simplified down into a core
choice that the user must make. In chess, it’s what piece to move and where to
move it. In a side scrolling video game, it’s timing when to make that jump.
 All these choices require the player to balance the Risks and Rewards of a
situation.
 When designing a game, much of the player’s enjoyment comes from weighing
these Risk/Reward situations and acting on them intelligently.
 When your hearts get too low, health bar depletes, or HP gets in the single digits
- it raises the stakes for the player.
Subsystems

 Whenever you have a large, important gameplay system like Combat, it’s
bound to require the implementation of various subsystems that will work
together in harmony.
 Our initial implementation of a combat system will be built on the following
subsystems

1. Health manager: This will be a new component that we can attach to


objects that can take damage and be destroyed.
2. Health modifiers: We will be making components that can modify the
data contained within the health manager.
3. Bullets: One of the easiest types of weapons to implement is a projectile
weapon (gun, hammer, axe). By spawning bullet sub objects, we can
easily give players a way to fight off the hazards.
4. Game Session manager: We will need an object that is keeping track of
the game win / loss conditions. we’ll be focusing on a ‘lives’ system and the
respawning of the player when they lose all their health.
5. Weapons: We need objects that the player can equip. Everything from
guns, swords, and whips.
6. UI: The health of the player is one of the most important things to display in
the UI, using it to display the necessary information.
Health Managers and Modifiers
 This is a component that can be added to any object that can take damage and
be destroyed.
 Go to the Project window and open the Assets>Scripts folder. Once there, use
the right-click menu to select Create > C# Script, and use HealthManager as our
script name.

Health Manager Keywords

_healthMax
This is the maximum health of the object we’re managing. we’ll set the default
health of any object to 10.
_healthCur
This is the current health of the object whose health we’re managing. By default, it
starts at the maximum health level. When this reaches zero, the object will be set to
‘Is Dead’.

_invincibilityFramesMax
Invincibility frames represent an amount of time, in seconds, that an object is
invincible after taking damage.
_invincibilityFramesCur
This is the current invincibility frame countdown. If this is anything other than zero,
incoming damage will be ignored.

_isDead
Whether or not this object’s health has depleted. Because there may be some data
cleanup, or perhaps an animation to play after dying, we will store the object death
as a Boolean value.
Almost as important as the onDeath function is a public IsDead() function,
which will allow other scripts to know whether or not this object should be
active.
Another function we’ll eventually need is Reset(), which will set all the
data of this player back to its default state.

 The final bit of logic we’ll be adding is in the Update() function, where we’ll be
adjusting the invincibility frame counter if necessary. We’ll also put in some
temporary code to simply destroy the object when it’s been set to _isDead.
 With the HealthManager component made, let’s return to Unity and add
it to our PlayerObj_Sphere object.
Spikes: Your First Hazard
 Let’s start building our first hazard by creating three new objects in the Hierarchy
window: one empty GameObject (created using the “Create Empty” option) and two 3D
Cubes (created using the “3D Object > Cube” option).
 Rename the empty GameObject to EnemyObj_Spikes.
 Select the first Cube, then rotate and flatten it in the transform panel. Set the rotation to
45 on the X-Axis, and set the scale to 0.2, also on the X - Axis.

 Next, select the second Cube - likely named Cube (1) - and flatten it with a scale of
0.05 on the X-Axis. This should result in a thin Cube sittinginside the thicker rotated
Cube.
If you haven’t already made a red enemy material, let’s make one now by creating a new
Materials folder in our Assets window. Open this folder and right-click to select the New >
Material option.

With your new material ready, drag it from your assets folder to the larger rotated Cube. This
fresh coat of paint should instantly make it look more dangerous.
Start by renaming the larger Red Cube to “RedCube” and the smaller White Cube to
“WhiteSpikes”. Staying in the hierarchy window, you’ll want to drag the white spikes
entry onto the Red Cube entry.
In addition to the WhiteSpikes, you’ll also want to drag the RedCube entry on to the
EnemyObj_Spikes entry. The Spikes should now be a parent object with two nested sub
objects.

Select the Red Cube, and Duplicate it using the hotkey CTRL + D. Do it a second time to
ensure you have the original red tube and two copies. Note the (1) and (2) now appended
to the names of these duplicated objects.
Select the first duplicate, named “RedCube (1)”. In its Transform panel, set its rotation
values to 45, 90, 0. Then select the second duplicate, “RedCube (2)’, and set it’s rotation
values to 0, 45, 90.
The last step is to add a ‘Sphere Collider’ component to the
EnemyObj_Spikes parent object. Select EnemyObj_Spikes in the
Hierarchy window, then add a Sphere Collider using the Inspector.

Select the “Is Trigger” option, then reduce the radius of the sphere to
0.75. With the Spike object made, it’s time to make a component that
can deal some damage!
The Health Modifier Component

 The HealthModifier component will be a script added to objects that can alter the
health of objects they collide with. Our spikes, for instance, will have a health
modifier that decreases the health of the Player object.
 Bullets spawned by the player, on the other hand, will have health modifiers that
lower the health of enemies. And power-up items will have health modifiers that
increase the player’s health.
 Let’s make the script by going to your Projects > Assets window, opening your
Scripts folder, and adding a new script named “HealthModifier”.

 Open the new script in Visual Studio and give it the following members.
float _healthChange = 0;
DamageTarget _applyToTarget = DamageTarget.Player;
public enum DamageTarget
{
Player,
Enemies,
All,
None
}
bool _destroyOnCollision = false;
_healthChange
This is the amount of damage that will be applied when a valid target is collided
with.
_applyToTarget
The _applyToTarget member, along with the DamageTarget, will be used to
determine the validity of the collided object.

_destroyOnCollision
this object will destroy itself when a valid object is collided with. This will be
TRUE for bullets, but FALSE for Spikes.
void onCollisionEnter(Collision collision)
{
GameObject hitObj = collision.gameObject;
HealthManager healthManager = hitObj.GetComponent<HealthManager>();
if ( healthManager && IsValidTarget(hitObj))
{
healthManager.AdjustCurHealth(_healthChange);
if ( _destroyOnCollision )
GameObject.Destroy(gameObject);
}
}
bool IsValidTarget( GameObject possibleTarget )
{
if (_applyToTarget == DamageTarget.All)
return true;
else if (_applyToTarget == DamageTarget.None)
return false;
else if (_applyToTarget == DamageTarget.Player && possibleTarget.GetComponent<PlayerController>())
return true;
else if (_applyToTarget == DamageTarget.Enemies && possibleTarget.GetComponent<AIBrain>())
return true;
return false;
}
 Let’s take Unity, make sure the Spike object is selected. In the Inspector window, scroll
down and press Add Component > New Script to add a component named AIBrain. Our
Spike now has an empty component that we can check against, and we can deal with the
actual implementation of AIBrain in a later chapter.
 Now that the compiler error is fixed, we can now add our finished HealthModifier
component to the Spike hazard. Make sure the object EnemyObj_Spikes is still selected,
and again press Add Component to add the HealthModifier script to the Spike.
Now make the prefab by dragging the spike from the Hierarchy panel into the prefabs folder
of our projects asset directory.

We now have a dangerous Spike prefab that can be placed throughout the level. The player
will have to time jumps and movement to ensure they don’t take too much damage.
With everything in place, it’s time to press Play and put our new systems to the test. If we did
everything correctly, colliding with a spike twice will result in your player object being
destroyed. Press the Play button again to stop the game, reset the scene, and re-spawn our
player.
Principles of Animation

 Animation, as we know it today, is a relatively new art form. It means ‘to


give life’ and is a process that tricks the brain into thinking something
inherently lifeless is anything but.
 Early 2D animators would breathe life into a series of still images, while modern
3D animators infuse digital geometry with life.

 There are 10 key Principles of Animation that can be applied across both
2D and 3D mediums. By making use of these rules, you can ensure your
heroes, enemies, NPCs, and even environments exude their intended
personality
1. Squash and Stretch
When an object collides with something, or quickly accelerates in a given direction, Its shape will
change in a concept known as Squash and Stretch. It has to do with the inherent elasticity, or
malleability, of most objects.

2. Anticipation
The time spent ‘building up’ to a given action is known as Anticipation. It could be a weightlifter,
struggling with a dumbbell before eventually lifting it. This could be a snake coiling up before
striking its prey.

3. Staging
Making sure the viewer (or player) understands what’s important in a scene is the primary goal of
Staging. This can be achieved through camera positioning, scene lighting, or even character
posing.
4. Exaggeration
Always push your animation to be as readable as possible. This often means you’ll need to
Exaggerate shapes and sizes in a way that isn’t realistic.

5. Slow In / Slow Out


Every movement requires acceleration or deceleration. In animation, This is a concept known as
Slow In / Slow Out, where it takes time for an object to start, or stop, moving.

6. Arc
Similar to the concept of Slow In / Slow Out, Arcs in animation mimic the smooth movement
curves caused by inertia.

7. Timing
The number of frames between two poses, or Timing, has a massive effect on how an animation
feels.
The Unity editor makes use of a Timeline to allow us to easily manage the number of frames
spent in a given pose.

8. Secondary Action
You can add extra appeal to an animation by introducing a Secondary Action, an extra bit of
movement that infuses your main action with extra personality.

9. Follow Through / Overlapping Action


When an object is attached to another, and follows behind the main action at a slower rate, this is
known as Secondary Action. Perhaps its hair, flowing behind a character as they run.

10. Appeal
While all the above concepts are concerned with movement in animation, Appeal focuses on a
character’s design. It’s important that the personality of a character is bold: readable at a glance.
Making A Basic Animation

1. In the Unity Editor, open the scene and create a new folder Assets ->
Prefabs.
2. In the Prefabs folder Right click and create empty 3D object and renamed
it as PlayerObj_Sphere. Drag the PlayerObj_Sphere into scene window.
3. place a new 3D Object > Plane at Position 0,0,0
4. Remove the Mesh Renderer component and set the SphereCollider’s
Center and Radius values.
In the hierarchy window, right-click on the PlayerObj_Sphere. Select
3D Object > Sphere to add the body sphere.
2. Name this new sphere Hero1_Body.
3. Disable the Sphere Collider component on the body.
4. Again, right-click the PlayerObj_Sphere and use 3D Object > Sphere
twice to add two new feet spheres.
5. Name these two new spheres Foot_L and Foot_R.
6. Disable the Sphere Collider components on the feet
In the hierarchy window, right-click on Hero1_Body. Select 3D Object
> Sphere twice to add two Arm spheres.
2. Name one sphere Arm_L and the other Arm_R.
3. Remove the Sphere Collider script from both of these new objects.
In the hierarchy window, right-click on Hero1_Body. Select 3D Object
> Sphere twice to add two spheres for our Eyes.
2. Name one sphere Eye_R, and the other Eye_L.
3. Remove the Sphere Collider script from both of these.
4. Right-Click on each of these eye objects and add a sphere child to
each.
5. Name both child spheres WhiteGlare.
In the hierarchy window, right-click on Hero1_Body. Select 3D Object
> Sphere to create our first Hair object.
2. Name this object Hair_1 and remove the Sphere Collider component.
3. Right-click on Hair_1 and add a child sphere named Hair_2.
4. Right-click on Hair_2 and add a child sphere named Hair_3.
5. Right-click on Hair_3 and add a child sphere named Hair_4.
6. Make sure all these hair objects have their Sphere Collider scripts
disabled or removed.
The Animation View
1. Animation tools are hidden by default. Let’s unhide the Animation View
now: go to the top menu bar to select Window > Animation > Animation
2. Once open, drag this new window down into the bottom panel, where it
will become an additional tab next to the ‘Project’ and ‘Console’ options.

3. The next step is to select the root object that you’ll be animating. In this
case, that would be PlayerObj_Sphere. Select that object in the Hierarchy
window, then select the Create Button In the middle of the Animation View
window.

4. This performs several actions. First, it attaches a new Animator component


to your object. It will also create our first animation file, which we’ll name
SphereHero_Idle. These files (which use the filename extension .anim)
hold all the data for a specific animation.
5. With our empty Idle animation created, it’s time to specify the sub-objects
we’ll be moving around. These will be listed on the left side of the
Animation View, similar to how the Hierarchy Window lists objects.

Go to the left side of this window and press the Add Property button. Select
Hero1_Body > Transform > Rotation and press the + button, now add the
Hero1_Body > Transform > Position parameter.
Keyframes and Inbetweening
1. We have specified the objects and properties we will be animating, a
diamond shaped dot to the right of each parameter. These are called
Keyframes a specified value at a specified time.
2. A Keyframe stores the position, rotation, scale, (or any other parameter) at a
given frame.
3. When there are two keyframes present, the computer performs a process
known as Inbetweening or Tweening for short.
4. Tweening is the interpolation of values between one keyframe and the next.
5. All of this is managed on the Dopesheet - the grid on the right side of the
Animation View window.
6. Using both Keyframes and Tweening, the animation system allows us to
create complex, multi-frame animations by simply setting poses that get
interpolated at runtime.

Let’s start our idle animation by defining its Length, which we’ll make 6
seconds long. Position your cursor over the Dopesheet, and use the Mouse
Wheel to expand the timeline.
Keep scrolling the mouse-wheel until you see 6:00 appear at the top, then
do the following
1. Click and drag to select all keyframes at the 0:00 mark and press ctrl+c
2. Go to the 6:00 mark and click on it and press ctrl+v

Note: When making a looping animation, you’ll always want the first frame and last
frame to have the same keyframes.
Since keyframes are necessary when making an animation, we should cover
the various ways you can add them to your timeline. Using the Animation
View, there are three preferred ways to add keyframes to your animation.
Copy and Paste (which we performed above)
2. Right Click on the Dopesheet, then select “Add Keyframe”
3. Automatically adding keyframes with Recording Mode

To start recording, press the small Red Circle button in the upper left corner
of the Animation View window.
Our Idle animation will simply be our hero looking around. This should only
require us to add two keyframes.
Select the Hero1_Body object, either from the Animation View or the
Hierarchy Window.
2. Switch to the Rotation Tool by pressing the [E] hotkey.
3. Go to the 2:00 mark on the timeline. Rotate the head to look towards the
right, or use the Transform panel to set the rotation to (30, -40, -5).
5. Go to the 4:00 mark on the timeline. Rotate the head to look towards the left
or use the Transform panel to set the rotation to (25, 20, 3).
6. Click anywhere on the Dopesheet, then press [Spacebar] to Play our
animation. You should see the hero look slowly to the right, then to the left.
7. Since we copied the starting keyframes to match the last keyframes, this will
continue in a seamless loop. Press [Spacebar] again to Stop the animation.

Another useful way to test your animation is by Scrubbing: manually setting


the current frame by dragging the mouse along the timeline.
Let’s place some additional keyframes to add even more life, We will start with
the eyes, adding some quick Press blinking movements.
Click on the timeline and Scrub to frame 130 (Shown in a small white
box to the right of the Fast Forward button)
2. Use the Add Property button to add Eye_L and Eye_R Scale properties
3. Right click on these entries and select Add Key
4. Scrub to the frame 136
5. Again, Right click on the eye entries and select Add Keys6. Scrub to frame
133
7. Use the [R] keyframe to switch to the Scale Tool. Drag the Scale tool’s green
bar (Y-Axis) to make the hero’s eyes nice and squinty.
Run Cycles
A Run Cycle is the animation clip used when the player is moving and
grounded. It tends to be short: normally a 30 frame looping animation.

Since our hero is bipedal (ie. only has two feet) the cycle is broken up
where 15 frames are spent on the Right foot, and 15 frames spent on the
Left foot.

In the upper left corner of the Animation View, you will see a dropdown menu
with the name of the current Animation clip (look for “SphereHero_Idle”).
Click this area and select Create New Clip from the drop down menu. Name
the new animation SphereHero_Run.
Since the Body object is first on our list, let’s start by adding parameters for
the Position, Rotation, and Scale of Hero1_Body
Now we need to do some keyframe management. Use the following steps to
set up our initial Running keyframes…
1. Move the keyframes for each of the properties from the 1:00 mark to the
0:30 mark. Because Unity determines animation length by the timestamp of the
last keyframe, we’re telling Unity that our run cycle is 30 seconds long.
2. Enable Keyframe Recording Mode (the little red dot next to the rewind
button).
3. Scrub to frame 8 (timestamp 0:8) and move the body upwards (Y position
should be around 0.9).
4. Scrub to frame 15 and move the body back down (Y position around 0.6).
5. Scrub to frame 23 and move the body upwards (Y position around 0.9).
Press the play button (or use the [Spacebar] hotkey). The body of our hero
should now be bobbing up and down, with the eyes, hands, and hair
following it.
At this point the body should be bouncing nicely. Play your animation, or
scrub the timeline, to see how it looks. You should notice some appealing
squash-and-stretch now that we’ve added the Scale and Rotation
keyframes, with frames 8 and 23 stretching the hero vertically, and frame 15
squishing the hero horizontally.
It’s a subtle effect, but important when making a satisfying movement.

Now we’ll move onto the feet. Use the Add Property button to add Position
and Rotation parameters for Foot_R and Foot_L.
Notice there is no data listed for Frame 30. This is because, whenever you
have a looping animation, the last frames should always match the first
frames.

Let’s polish our Run by adding some keyframes to the arms. Use Add Property
to add the Position of Arm_L and Arm_R.
Animations in Action
Press the Play button to start the game and use the Arrow Keys to move your
updated hero around the scene.
when we want to freeze the rotation of a Rigid Body, all we have to do is toggle
the appropriate boxes.

Open the PlayerController script and add the following code at the bottom of the
Update() function.
transform.LookAt(transform.position + new
Vector3(_curFacing.x, 0f, _curFacing.z));
Next, we need to add some code to make our player swap between the Idle
and Run animation states. Select PlayerObj_Sphere, locate the Animator
component’s Controller parameter.
Now you can return to the PlayerController in Visual Studio. Add two new
members at the top of the script.

bool _moveInput = false;


Animator _myAnimator;
void Start()
{
_rigidBody = GetComponent<Rigidbody>();
_myCollider = GetComponent<Collider>();
_myAnimator = GetComponent<Animator>();
}
_moveInput = false;
You’ll then need to set this _moveInput value to true if input has been received this frame.
_moveInput = true;

UpdateAnimation();
void UpdateAnimation()
{
if (_myAnimator == null)
return;
if (_moveInput)
_myAnimator.Play(“Run”);
else
_myAnimator.Play(“Idle”);
}
This function first checks to see if we have a valid Animator component. If
so, it will set either the Run or Idle animation based on whether movement
keys are being pressed by the player.

Our final step is to update the player prefab. We’ve made several changes to
this object, and we want those changes to be applied to other instances of
the prefab.

To do this, select PlayerObj_Sphere and find the Overrides dropdown in


the Inspector. Click Overrides and select Apply All.
Cleaning Up
Let’s start our clean-up process by creating a new folder in your Assets
directory. Name this folder “Animations”.
Next, use the Project window tosearch for the newly created animation files.
Once you find them, drag them into your empty Animations folder.
Design of AI components

 Programmatically speaking, Enemy objects aren’t that much different than the Player object.
 They both have health associated with them. They both components that dictate how fast they
can run, how high they can jump, and what weapons and items they can use.
 For the player object, all decisions are made by the user - the gamer pressing the buttons on the
keyboard or controller. Enemy objects, on the other hand, are driven by Artificial Intelligence
(AI) - code that tells them what to do and how to do it.
 We’ll be creating a component called AI Brain which will observe the game world (location of
the player, obstacles in the area, etc.) and make decisions based on that data.
Our Basic Enemy

 Make an empty GameObject named EnemyObj_BasicFoe, then add the following


child objects:
3D Object > Cube named CubeHead
3D Object > Sphere named YellowEye
3D Object > Sphere named EyePupil
3D Object > Cube named Eyebrow_L
3D Object > Cube named Eyebrow_R
Our Basic Enemy

 Apply the matColorRed material to CubeHead and matBlack to EyePupil, Eyebrow_L, and
Eyebrow_R.
 Then make a new matYellow material and apply it to the YellowEye object.
Our Basic Enemy

New Component: AIBrain


 It’s time to infuse it with a little artificial intelligence. To do that, we will be
creating a new component called AIBrain.

 This script will manage what the enemy wants to do, also known as the AI State.
Each possible State will have a series of actions that can be assigned to it.
 Select the BasicFoe object and select Add Component > New Script to add a component called AIBrain.
Open this Script in Visual Studio and add the following members.

#region ** members **
UnityEvent _curAIDirective;
UnityEvent _defaultActions;
UnityEvent _alertedActions;
UnityEvent _huntActions;
public UnityEvent _miscPattern1Actions;
public UnityEvent _miscPattern2Actions;
public UnityEvent _miscPattern3Actions;
float _pauseTimer = 0;
PlayerController _playerObject = null;
#endregion
 First off, you probably noticed the use of a new set of tags: #region and #endregion. These lines of
code specify a block of data that can be collapsed within Visual Studio.
 Second, you probably noticed several UnityEvent members being added. These will hold the
Actions associated with the various AI states, and we’ll be talking about them in the next section.
 Thirdly, the last few members dealt with the pausing of AI and the storing of a player object. The
member _pauseTimer can be set to pause the movements of any enemy, in an important way to
give the player time to react to a situation.
 The _playerObject allows us to cache the player’s information for quick retrieval. This is because
almost every AI decision will be based on the location and status of the player. Which direction to
face, whether to patrol or chase, and when to fire a weapon are all based on the player’s location in
relation to the enemy’s.
private void Start()
{
_playerObject = GameObject.FindObjectOfType<PlayerController>
_curAIDirective = _defaultActions;
}
void Update()
{
if (UpdatePausedAI())
return;
_curAIDirective.Invoke();
}
bool UpdatePausedAI()
{
if (_pauseTimer > 0)
{
_pauseTimer -= Time.deltaTime;
_pauseTimer = Mathf.Max(_pauseTimer, 0f);
}
return (bool)(_pauseTimer > 0f);
}
The Start() functions find the player object and initialize the current AI directive to use the default actions.
 The UpdatePausedAI() function determines if the AI should be running this frame. And, if it SHOULD be
run, the Update() function will Invoke the current UnityEvents (call all the functions associated with the
current State of the AI).
 Since so much of our AIBrain relies on these UnityEvent objects, let’s take a moment to learn more about
these powerful data types.

UnityEvents and AI Actions


 UnityEvents - This Is a Unity-Specific type that lets you queue up function calls directly from the editor.
This leverages power and flexibility in a way that’s perfect for our AI system.
 A UnityEvent is a List of function calls associated with a specific object in the scene. When hooking up our
UI, for instance, buttons all made use of unity events to trigger functions when they were pressed.
 Our AIBrain script will Handle States in a similar way: If an enemy is in a given state, it will trigger a set of
unity events assigned to that state.
#region *** AI State ***
public void SetState_Default()
{
_curAIDirective = _defaultActions;
}
public void SetState_Hunt()
{
_curAIDirective = _huntActions;
}
public void SetState_MiscPattern(int pattern)
{
}
#endregion
 These functions should look fairly straight-forward, with each SetState function assigning a new group of actions as our
_curAIDirective (the UnityEvents that get Invoked every Update call).

#region *** AI Events ***


public void Jump( float force )
{
GetComponent()?.AddForce( new Vector3(0, force, 0) );
}
public void AlertIfPlayerNearby(float distance)
{
if (CalcDistanceToPlayer() < distance)
_alertedActions?.Invoke();
}
public void PauseAI( float timeInMS )
{
_pauseTimer = timeInMS;
}
public void UseWeapon()
{
}
#endregion
Hunting Down the Player
 In most games, the primary goal of an enemy object is to serve as a mobile hazard that the player has to deal with.
It’s something to jump over, attack, or simply avoid before moving onto the next area.
 There are certain enemies, however, that strike considerably more fear in the player. By adding some additional
code, we can make our enemy hunt the player - chasing them around the level, forcing the player to make a move.
 With ‘murdering the player’ as this enemy’s top priority, it’s vital that the AIBrain keeps track of the players
location. This information can be used to aim weapons, chase the player, or even retreat if a situation turns
hopeless

#region *** Player Hunting ***


float CalcDistanceToPlayer()
{
return Vector3.Distance( transform.position, _playerObject.transform.position );
}
Vector3 CalcPlayerPos( bool ignoreY = false )
{
Vector3 playerPos = _playerObject.gameObject.transform.position;
if (ignoreY)
playerPos.y = transform.position.y;
Hunting Down the Player
return playerPos;
}
public void LookAtPlayer()
{
transform.LookAt(CalcPlayerPos(true));
}
public void MoveTowardsPlayer( float speed )
{ // move towards the player
Vector3 playerPos = CalcPlayerPos(true);
Vector3 newPos = transform.position; playerPos.y = transform.position.y;
newPos += (playerPos - transform.position).normalized * (speed * Time.deltaTime); transform.position = newPos;
transform.LookAt(playerPos);
}
#endregion
Setting up the AI Component
 When you select the enemy object, Each of these lists represents a different State that the AI will manage. We’ll
start by filling the default actions of this enemy.
 Do this by clicking on the small plus button in the lower right corner of the Default Actions () panel
Setting up the AI Component

Each event in this list is composed of three parts, each of which we’ll need to set.

 First, we need to specify the game object that this event will be acting upon.
 Second, we’ll need to set the Component and Function being called by this event.
 And third, we’ll need to specify any parameters required by the selected function.

 Setting the object associated with this event is as simple as dragging that object from the Hierarchy
window to where it says None (Object) in the event panel.

 Once an object has been assigned, Unity will search through all the possible components and
functions we can call upon that subject. Click on the drop down menu that currently says ‘No
Function’ to see all the possible functions the AI can trigger.
Setting up the AI Component
Setting up the AI Component

 Now back to our Basic Foe. The default action of this enemy will be to sit and wait until the player gets too
close. To accomplish this, we’ll use the function AlertIfPlayerNearby() that we added to AIBrain. All we
have to do now is assign that function in our default action list.

 The alert function we’re calling takes a distance value, which serves as our Alert radius. Once the player gets
this close the enemy, the AIBrain will enter its Alerted state. In this case, we’ve set this Distance to 5, meaning
the player needs to keep their distance if they don’t want to alert the enemy.

 Once alerted, however, our Basic Enemy should perform the following functions:

Turn to LOOK at the player.


Perform a short, startled JUMP (using a force of 200).
PAUSE to consider their response (for around 1.5 seconds).
Begin to HUNT the player down.
Setting up the AI Component

 Luckily for us, we’ve written corresponding functions for all these actions. Add four new events to the alerted
actions panel, and set the functions to be triggered.
Setting up the AI Component

 The last function that we trigger that’s the AI state to be in ‘Hunt the player’ mode. This logic has only one
required action: keep moving towards the player.

 Our Basic Foe will sit there until the player gets close. Once they’re alerted, the enemy will jump, turn to the
player, then start chasing them after a brief pause.

 There will be situations, however, where complex level design will require a more sophisticated AI. When you
need more intelligence in your AI, Unity has the perfect tool for the job: the Navigation Mesh.
NavMesh

 In most cases, our simple implementation of ‘Hunt the Player’ will be good enough. has
adding the complexity for other reasons, this basic movement logic will not be enough.

 This is where Unity’s Navigation Mesh becomes necessary. The Navigation Mesh (or
NavMesh) Is a generated piece of geometry that can tell your enemy where it can and
cannot move.

 Couple this with integrated Pathfinding - code that figures out how to get from point A to
point B - And suddenly your enemy’s hunting skills will receive a considerable upgrade.
Bring up the navigation window by selecting Window > AI > Navigation.

 It should automatically dock itself as a tab within the Inspector window. The navigation
window has 4 categories to work with as mentioned below:
1. Agents
This tab lets you specify various character sizes that will be used your game. By default there’s only
one - Humanoid. Even if you don’t specify a new character category, all the settings available here can
also be tweaked later, directly in the NavMesh Agent component.

2. Areas
This tab presents a list of the various movement areas cut your levels will consist of. By default there
are only three: Walkable, Blocked, and Jump. In most cases, these three will be enough, though adding
more is as easy as entering a new name into the list.

3. Bake
This is the most important tab in the navigation window. With all your level geometry selected,
generating a NavMesh is as easy as pressing the Bake button in the lower right corner. Forgetting this
step will result in broken AI Behavior, so always remember to bake your NavMesh after editing a level.

4. Object
The Object tab gives you NavMesh related information about the selected piece of geometry. Use this
to specify what Area category is assigned to each part of your level.
NavMesh Agents

 Before an object will make use of our generated NavMesh, it’ll first need to
be assigned as a NavMesh Agent.

 Like most systems in Unity, this is done by assigning a component to the object that
needs to perform the AI Pathfinding.

 Select the EnemyObj_BasicFoe object and press Add Component > Navigation >
NavMesh Agent to apply the necessary component.
 while using NavMesh is mostly automated, we do need to add a special AIBrain function to hunt the
player using the navigation system. Open the AIBrain script in Visual Studio, and add this line to the top
of the file.

using UnityEngine.AI;

 Then, at the bottom of the file, add a new #region for NavMesh specific logic, as well as this new
function.

#region *** NavMesh ***


public void MoveTowardsPlayerUsingNavMesh()
{
NavMeshAgent agent = GetComponent<NavMeshAgent>();
if ( agent )
agent.SetDestination( _playerObject.transform.position );
}
#endregion
 The function is only three lines long, but they’re a powerful three lines. First we grab the Agent
component, which we just added to our enemy. If that’s valid, we then tell the agent to
SetDestination() to the player’s position.

 Once the function is ready, go into the AI component and assign Hunt Actions to use our new
Nav Mesh logic.

 As always, our last step is to press the PLAY button to see how it all works. The enemy should
sit there patiently, then become startled when the player gets too close, then start chasing the
player as before.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy