0% found this document useful (0 votes)
47 views58 pages

Tycs GP Pract Journal

Di rhi dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk in my heart and I am a

Uploaded by

Atharva Pathak
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
47 views58 pages

Tycs GP Pract Journal

Di rhi dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk dunk in my heart and I am a

Uploaded by

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

PRACTICAL 1

Aim: Setup DirectX 11, Window Framework and Initialize Direct3D


Device, Loading models into DirectX 11 and rendering

Step 1:
i) Create new project, and select “Windows Forms Application”, select .NET Framework as
2.0 in Visuals C#.

ii) Right Click on properties Click on open click on build Select Platform Target and Select
x86.
Step 2: Click on View Code of Form 1.
Step 3:
Go to Solution Explorer, right click on project name, and select Add Reference. Click on
Browse and select the given .dll files which are “Microsoft.DirectX”,
“Microsoft.DirectX.Direct3D”, and “Microsoft.DirectX.DirectX3DX”.
Right click on "References" in Solution explorer. ►Add references ►Browse to the "DirectX
Managed Code" directory. ►Select these three files. ► Microsoft.DirectX.Direct3DX ►
Microsoft.DirectX.Direct3D.dll ► Microsoft.DirectX.dll and add.

Step 4:
Go to the Properties Section of Form, select Paint in the Event List and enter as Form1_Paint.

Step 5:
Edit the Form’s C# code file. Namespace must be the same as project name.
Code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
namespace GP_P1
{
public partial class Form1 : Form
{
Microsoft.DirectX.Direct3D.Device device;
public Form1()
{
InitializeComponent();
InitDevice();
}

public void InitDevice()


{
PresentParameters pp = new PresentParameters();
pp.Windowed = true;
pp.SwapEffect = SwapEffect.Discard;
device = new Device(0, DeviceType.Hardware, this,
CreateFlags.HardwareVertexProcessing, pp);
}

private void Render()


{
device.Clear(ClearFlags.Target, Color.Orange, 0, 1);
device.Present();
}

private void Form1_Paint(object sender, PaintEventArgs e)


{
Render();
}
}
}
Output:
PRACTICAL 2

Aim: Learn Basic Game Designing Techniques with Pygame

Steps to Install Pygame:

● Step 1: Install Python: Before installing Pygame, ensure that Python is installed on your
system. Visit the official Python website (python.org) and download the latest stable version
compatible with your operating system. Follow the installation instructions provided and
verify that Python is properly installed by running “python –version” in your terminal or
command prompt.

● Step 2: Install Pygame: To install Pygame, you need to use a package manager such as pip,
which is commonly bundled with Python installations. Run your terminal or command
prompt and execute the following command: “pip install pygame“. The command will
download and install the latest stable version of Pygame from the Python Package Index.

● Step 3: Verify the Installation: Run a simple test script to confirm that Pygame is installed
correctly. Create a new file in Python and import the Pygame module by adding the line
“import pygame”. Save the file with a “.py” extension and execute it. If no errors occur,
Pygame is successfully installed.
Part A
CODE:
import pygame
pygame.init()

# Define white color


white = (255, 255, 255)

# Window dimensions
height = 400
width = 400

# Create the display surface object of specific dimension


display_surface = pygame.display.set_mode((height, width))

# Set the window caption


pygame.display.set_caption('Image')

# Load the image


image = pygame.image.load("C:/gp/gp ims.jpg")

# Resize the image to fit the window size (or any desired dimensions)
image = pygame.transform.scale(image, (width, height)) # Scaling the image

# Infinite loop to keep the window open


while True:
display_surface.fill(white) # Fill the background with white
display_surface.blit(image, (0, 0)) # Draw the image at the top-left corner

# Event handling loop


for event in pygame.event.get():
if event.type == pygame.QUIT: # If user closes the window
pygame.quit()
quit()

# Update the display


pygame.display.update()
Output:
Part B
import pygame
from pygame.locals import *
from sys import exit

pygame.init()

screen = pygame.display.set_mode((400, 300))


rect = Rect(50, 60, 200, 80)
moving = False
running = True

while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == MOUSEBUTTONDOWN:
if rect.collidepoint(event.pos):
moving = True
elif event.type == MOUSEBUTTONUP:
moving = False
elif event.type == MOUSEMOTION and moving:
rect.move_ip(event.rel)

screen.fill((127, 127, 127))


pygame.draw.rect(screen, (255, 0, 0), rect, 4)
pygame.display.flip()

pygame.quit()
PRACTICAL 3
Aim: Develop Snake Game using Pygame
Code:
import pygame
import time
import random

# Snake speed
snake_speed = 10

# Window size
window_x = 720
window_y = 480

# Defining colors
black = pygame.Color(0, 0, 0)
white = pygame.Color(255, 255, 255)
red = pygame.Color(255, 0, 0)
green = pygame.Color(0, 255, 0)
blue = pygame.Color(0, 0, 255)

# Initializing pygame
pygame.init()

# Initialize game window


pygame.display.set_caption('Snake Game')
game_window = pygame.display.set_mode((window_x, window_y))

# FPS (frames per second) controller


fps = pygame.time.Clock()

# Defining snake default position


snake_position = [100, 50]

# Defining first 4 blocks of the snake body


snake_body = [[100, 50],
[90, 50],
[80, 50],
[70, 50]]

# Fruit position
fruit_position = [random.randrange(1, (window_x // 10)) * 10,
random.randrange(1, (window_y // 10)) * 10]
fruit_spawn = True

# Setting default snake direction towards right


direction = 'RIGHT'
change_to = direction

# Initial score
score = 0

# Displaying Score function


def show_score(choice, color, font, size):
score_font = pygame.font.SysFont(font, size)
score_surface = score_font.render('Score : ' + str(score), True, color)
score_rect = score_surface.get_rect()
if choice == 1:
score_rect.midtop = (window_x / 10, 15)
else:
score_rect.midtop = (window_x / 2, window_y / 1.25)
game_window.blit(score_surface, score_rect)

# Game Over function


def game_over():
my_font = pygame.font.SysFont('times new roman', 50)
game_over_surface = my_font.render(
'Your Score is : ' + str(score), True, red)
game_over_rect = game_over_surface.get_rect()
game_over_rect.midtop = (window_x / 2, window_y / 4)
game_window.blit(game_over_surface, game_over_rect)
pygame.display.flip()
time.sleep(2.5)
pygame.quit()
quit()
# Main Function
while True:
# Handling key events
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP and direction !=
'DOWN':
change_to = 'UP'
elif event.key == pygame.K_DOWN and direction != 'UP':
change_to = 'DOWN'
elif event.key == pygame.K_LEFT and direction != 'RIGHT':
change_to = 'LEFT'
elif event.key == pygame.K_RIGHT and direction != 'LEFT':
change_to = 'RIGHT'

# If two keys are pressed simultaneously, prevent the snake from moving into
two directions at once
direction = change_to

# Moving the snake


if direction == 'UP':
snake_position[1] -= 10
elif direction == 'DOWN':
snake_position[1] += 10
elif direction == 'LEFT':
snake_position[0] -= 10
elif direction == 'RIGHT':
snake_position[0] += 10

# Snake body growing mechanism


snake_body.insert(0, list(snake_position))
if snake_position[0] == fruit_position[0] and snake_position[1] ==
fruit_position[1]:
score += 10
fruit_spawn = False
else:
snake_body.pop()

if not fruit_spawn:
fruit_position = [random.randrange(1, (window_x // 10)) * 10,
random.randrange(1, (window_y // 10)) * 10]
fruit_spawn = True

# Drawing the snake and fruit on the window


game_window.fill(black)
for pos in snake_body:
pygame.draw.rect(game_window, green, pygame.Rect(pos[0], pos[1], 10,
10))
pygame.draw.rect(game_window, red, pygame.Rect(fruit_position[0],
fruit_position[1], 10, 10))

# Game Over conditions


if snake_position[0] < 0 or snake_position[0] > window_x-10 or
snake_position[1] < 0 or snake_position[1] > window_y-10:
game_over()
for block in snake_body[1:]:
if snake_position[0] == block[0] and snake_position[1] == block[1]:
game_over()

# Displaying the score continuously


show_score(1, white, 'times new roman', 20)

# Refreshing the game screen


pygame.display.update()

# Frame Per Second / Refresh Rate


fps.tick(snake_speed)
Output:
PRACTICAL 4
Aim: Create 2D Target Shooting Game
Code:
GameManger.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public GameObject WinText;
public GameObject target;
int score = 0;
public Text ScoreText;
bool win = false;
void Start()
{
InvokeRepeating("Spawn", 1f, 1f);
}
void Update()
{
if (win == true)
{
CancelInvoke("Spawn");
}
}
void Spawn()
{
float randomX = Random.Range(-9f, 9f);
float randomY = Random.Range(-3f, 3f);
Vector3 randomPosition = new Vector3(randomX, randomY, 0);
Instantiate(target, randomPosition, Quaternion.identity);
}
public void IncrementScore()
{
score++;
print(score);
ScoreText.text = score.ToString();
if (score >= 10)
{
win = true;
WinText.SetActive(true);
}
}
}

Target.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Target : MonoBehaviour {
public GameManager gameManager;
// Use this for initialization
void Start () {
gameManager = GameObject.Find("GameManager").GetComponent<GameManager>();
}
// Update is called once per frame
void Update () {
}
private void OnMouseDown()
{
gameManager.IncrementScore();
Destroy(gameObject);
}
}

Output:
PRACTICAL 5
Aim: Create 2D Infinite Scrolling Background
Code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class scroll : MonoBehaviour {

public float speed = 0.5f;


// Use this for initialization
void Start () {

// Update is called once per frame


void Update () {
Vector2 offset = new Vector2(Time.time * speed, 0);
GetComponent<Renderer>().material.mainTextureOffset = offset;
}
}

Output:
PRACTICAL 6
Aim: Create Camera Shake Effect in Unity
Code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraShake : MonoBehaviour


{
public Transform camTransform;
public float camShakeDuration;
public float camShakeAmount;
public float decrementFactor;

private Vector3 camOriginalPosition;

private void OnEnable()


{
camOriginalPosition = camTransform.position;
}

private void Update()


{
if (camShakeDuration > 0)
{
camTransform.localPosition = camOriginalPosition + Random.insideUnitSphere
*camShakeAmount;

camShakeAmount -= Time.deltaTime * decrementFactor;


}
else
{
camShakeDuration = 0f;
camTransform.localPosition = camOriginalPosition;
}

}
}
Output:
PRACTICAL 7
Aim: Design and Animate Game character in unity.

Using Humanoid Characters


In order to take full advantage of Mecanim’s humanoid animation system and retargeting, you need to
have a rigged and skinned humanoid type mesh.
1. A character model is generally made up of polygons in a 3D package or converted to polygon
or triangulated mesh, from a more complex mesh type before export.
2. A joint hierarchy or skeleton which defines the bones inside the mesh and their movement
in relation to one another, must be created to control the movement of the character. The
process for creating the joint hierarchy is known as rigging.
3. The mesh or skin must then be connected to the joint hierarchy in order to define which parts
of the character mesh move when a given joint is animated. The process of connecting the
skeleton to the mesh is known as skinning.

Stages
for preparing a character (modeling, rigging, and skinning)
How to obtain humanoid models
There are three main ways to obtain humanoid models for with the Mecanim Animation system:
1. Use a procedural character system or character generator such
as Poser, Makehuman or Mixamo. Some of these systems will rig and skin your mesh (eg,
Mixamo) while others will not. Furthermore, these methods may require that you reduce the
number of polygons in your original mesh to make it suitable for use in Unity.
2. Purchase demo examples and character content from the Unity Asset Store.
3. Also, you can of course prepare your own character from scratch.
Export & Verify
Unity imports a number of different generic and native 3D file formats. The format we recommend
for exporting and verifying your model is FBX 2012 since it will allow you to:
 Export the mesh with the skeleton hierarchy, normals, textures and animation
 Re-import into your 3D package to verify your animated model has exported as you expected
 Export animations without meshes
Preparing your own character
There are three main steps in creating an animated humanoid character from
scratch: modelling, rigging and skinning.
Modelling
This is the process of creating your own humanoid mesh in a 3D modelling package - 3DSMax,
Maya, Blender, etc. Although this is a whole subject in its own right, there are a few guidelines you
can follow to ensure a model works well with animation in a Unity project.
 Observe a sensible topology. The exact nature of a “sensible” structure for your mesh is
rather subtle but generally, you should bear in mind how the vertices and triangles of the
model will be distorted as it is animated. A poor topology will not allow the model to move
without unsightly distortion of the mesh. A lot can be learned by studying existing 3D
character meshes to see how the topology is arranged and why.
 Be mindful of the scale of your mesh. Do a test import and compare the size of your imported
model with a “meter cube” (the standard Unity cube primitive has a side length of one unit, so
it can be taken as a 1m cube for most purposes). Check the units your 3D package is using
and adjust the export settings so that the size of the model is in correct proportion to the cube.
Unless you are careful, it is easy to create models without any notion of their scale and
consequently end up with a set of objects that are disproportionate in size when they are
imported into Unity.
 Arrange the mesh so that the character’s feet are standing on the local origin or “anchor
point” of the model. Since a character typically walks upright on a floor, it is much easier to
handle if its anchor point (ie, its transform position) is directly on that floor.
 Model in a T-pose if you can. This will help allow space to refine polygon detail where you
need it (e.g. underarms). This will also make it easier to position your rig inside the mesh.
 Clean up your model. Where possible, cap holes, weld verts and remove hidden faces, this
will help with skinning, especially automated skinning processes.

Skin Mesh, textured and triangulated


Rigging
This is the process of creating a skeleton of joints to control the movements of your model.
3D packages provide a number of ways to create joints for your humanoid rig. These range from
ready-made biped skeletons that you can scale to fit your mesh, right through to tools for individual
bone creation and parenting to create your own bone structure. To work with Mecanim, the hips
should be the root element of the bone hierarchy. A minimum of fifteen bones are required in the
skeleton.
The joint/bone hierachy should follow a natural structure for the character you are creating. Given that
arms and legs come in pairs, you should use a consistent convention for naming them (eg, “arm_L”
for the left arm, “arm_R” for the right arm, etc). Possible structures for the hierarchy might be:-
* HIPS - spine - chest - shoulders - arm - forearm - hand
* HIPS - spine - chest - neck - head
* HIPS - UpLeg - Leg - foot - toe - toe_end

Biped Skeleton, positioned in T-pose


Skinning
This is the process of attaching the mesh to the skeleton.
Skinning involves binding vertices in your mesh to bones, either directly (rigid bind) or with blended
influence to a number of bones (soft bind). Different software packages use different methods, eg,
assigning individual vertices and painting the weighting of influence per bone onto the mesh. The
initial setup is typically automated, say by finding the nearest influence or using “heatmaps”.
Skinning usually requires a fair amount of work and testing with animations in order to ensure
satisfactory results for the skin deformation. Some general guidelines for this process include:
 Using an automated process initially to set up some of the skinning (see relevant tutorials on
3DMax, Maya, etc).
 Creating a simple animation for your rig or importing some animation data to act as a test for
the skinning. This should give you a quick way to evaluate whether or not the skinning looks
good in motion.
 Incrementally editing and refining your skinning solution.
 Sticking to a maximum of four influences when using a soft bind, since this is the maximum
number that Unity will handle. If more than four influences affect part of the mesh then at
least some information will be lost when playing the animation in Unity.
Interactive Skin Bind, one of many skinning methods
Non-humanoid Animations
The full power of Unity’s Animation system is most evident when you are working with humanoid
Animations. However, non-humanoid animations are also supported although without the avatar
system and other humanoid-specific features. Non-humanoid animations are referred to as Generic
Animations.
To start working with a generic skeleton, go to the Rig tab in the FBX importer and
choose Generic from the Animation Type menu.

Root node in generic animations


When working wth humanoid animations, Unity can determine the center of mass and orientation of
the rig. When working with Generic animations, the skeleton can be arbitrary, so you must specify
which bone is the Root node. The Root node allows Unity to establish consistency between
Animation clips for a generic model, and blend properly between Animations that have not been
authored “in place” (that is, where the whole model moves its world position while animating).
Specifying the root node also allows Unity to determine between movement of the bones relative to
each other, and motion of the Root node in the world (controlled from OnAnimatorMove).
Splitting Animations
An animated character typically has a number of different movements that are activated in the game
in different circumstances. These movements are called Animation Clips. For example, we might
have separate animation clips for walking, running, jumping, throwing, dying, etc. Depending on the
way the model was animated, these separate movements might be imported as distinct animation clips
or as one single clip where each movement simply follows on from the previous one. In cases where
there is only a single clip, the clip must be split into its component animation clips within Unity,
which will involve some extra steps in your workflow.
Working with models that have pre-split animations
The simplest types of models to work with are those that contain pre-split animations. If you have an
animation like that, the Animations tab in the Animation Importer Inspector will look like this:

You will see a list available clips which you can preview by pressing Play in the Preview
Window (lower down in the inspector). The frame ranges of the clips can be edited, if needed.
Working with models that have unsplit animations
For models where the clips are supplied as one continuous animation, the Animation tab in
the Animation Importer Inspector will look like this:
In cases like this, you can define the frame ranges that correspond to each of the separate animation
sequences (walking, jumping, etc). You can create a new animation clip by pressing (+) and selecting
the range of frames that are included in it.
For example:
 walk animation during frames 1 - 33
 run animation during frames 41 - 57
 kick animation during frames 81 - 97
The Import Settings Options for Animation
In the Import Settings, the Split Animations table is where you tell Unity which frames in your asset
file make up which Animation Clip. The names you specify here are used to activate them in your
game.
For further information about the animation inspector, see the Animation Clip component reference
page.
Animating objects and properties in Unity using Mecanim
You can create animation clips which animate any object or component property using Unity’s
animation window. These animation clips can then be arranged into a state machine in exactly the
same way as external animation clips such as character animations. For example, you could animate
the motion of a camera, the colour of a light, the individual frames of a sprite animation, or a public
property of a script.
To set up a Character or other GameObject for animation, you need to follow this process:
 Create a New Animator Controller
 Open the Animator Window to edit the Animator Controller
 Drag the desired animation clip into the Animator Controller Window
 Drag the model asset into the Hierarchy.
 Add the animator controller to the Animator component of the asset.
Importing Animations using multiple model files
Another way to import animations is to follow a naming scheme that Unity allows for the animation
files. You create separate model files and name them with the convention
‘modelName@animationName.fbx’. For example, for a model called “goober”, you could import
separate idle, walk, jump and walljump animations using files named “goober@idle.fbx”,
“goober@walk.fbx”, “goober@jump.fbx” and “goober@walljump.fbx”. Only the animation data
from these files will be used, even if the original files are exported with mesh data.

An example of four animation files for an animated


character (note that the .fbx suffix is not shown within Unity)
Unity automatically imports all four files and collects all animations to the file without the @ sign in.
In the example above, the goober.mb file will be set up to reference idle, jump, walk and wallJump
automatically.
For FBX files, simply export a model file with no animation ticked (eg, goober.fbx) and the 4 clips as
goober@_animname_.fbx by exporting the desired keyframes for each (enable animation in the FBX
dialog).
Looping animation clips
A common operation for people working with animations is to make sure they loop properly. It is
important, for example, that the animation clip representing the walk cycle, begins and ends in a
similar pose (e.g. left foot on the ground), to ensure there is no foot sliding, or strange jerky motions.
Mecanim provides convenient tools for this. Animation clips can loop based on pose, rotation, and
position.
If you drag the Start or End points of the animation clip, you will see the Looping fitness curves for
all of the paramers based on which it is possible to loop. If you place the Start / End marker in a place
where the curve for the property is green, it is more likely that the clip can loop properly. The loop
match indicator will show how good the looping is for the selected ranges.
Clip ranges with bad match for Loop Pose

Clip ranges with good match for Loop Pose


Once the loop match indicator is green, Enabling Loop Pose (for example) will make sure the
looping of the pose is artifact-free.
For more details on animation clip options, see Animation Clip reference.
Masking Imported Clips
Masking allows you to discard some of the animation data within a clip, allowing the clip to animate
only parts of the object or character rather than the entire thing. A good example of this would be a
character with a throwing animation. If you wanted to be able to use the throwing animation in
conjunction with various other body movements such as running, crouching and jumping, you could
create a mask for the throwing animation limiting it to just the right arm, upper body and head. This
portion of the animation can then be played in a layer over the top of the base running or jumping
animations.
Masking can be applied to animation clips either during import time, or at runtime. Masking during
import time is preferable, because it allows the discarded animation data to be omitted from your
build, making filesize and memory footprint smaller. It also makes for faster processing speed
because there is less animation data to be blended at runtime. In some cases, import masking may not
be suitable for your purposes, in which case you can apply a mask at runtime by using the layer
settings of the Animator Controller. This page relates to masking in the import settings.
To apply a mask to an imported animation clip, first select the imported animation file in your project
view, then in the import settings in the inspector, select the Animations button.

View the Animations section of the


Import Settings for your animation file
Then scroll all the way to the bottom of the inspector to find the Mask heading, among the four fold-
out headings as shown:

The Motion fold-out heading, along with the Curves,


Events and Motion headings
Expand the Mask heading to reveal the Mask options. When you open the menu, you’ll see three
options: Definition, Humanoid and Transform.

The
Mask Definition, Humanoid and Transform options
Definition
Allows you to specify whether you want to create a one-off mask in the inspector specially for this
clip, or whether you want to use an existing mask asset from your project.
If you want to create a one-off mask just for this clip, choose / Create From This Model /.
If you are going to set up multiple clips with the same mask, you should select / Copy From Other
Mask / and use a mask asset. This allows you to re-use a single mask definition for many clips.
When Copy From Other Mask is selected, the Humanoid and Transform options are unavailable,
since these relate to creating a one-off mask within the inspector for this clip.

Here,
the Copy From Other option is selected, and a Mask asset has been assigned
Humanoid
The Humanoid option gives you a quick way of defining a mask by selecting or deselecting the body
parts of a human diagram. These can be used if the animation has been marked as humanoid and has a
valid avatar.

The
Humanoid mask selection option
Transform
This option allows you to specify a mask based on the individual bones or moving parts of the
animation. This gives you finer control over the exact mask definition, and also allows you to apply
masks to non-humanoid animation clips.
The Humanoid mask selection option
Animation Curves on Imported Clips
Animation curves can be attached to imported animation clips in the Animations tab of
the Animation Import Settings.
These curves allow you to add additional animated data to an imported clip, which can allow you to
animate the timings of other items based on the the state of an animator. For example, in a game set in
icy conditions, an extra animation curve could be used to control the emission rate of a particle system
to show the player’s condensing breath in the cold air.
To add a curve to an imported animation, first select the imported animation file in your project view,
then in the import settings in the inspector, select the Animations button.
View the Animations section of the
Import Settings for your animation file
Then scroll all the way to the bottom of the inspector to find the Curves heading, among the four fold-
out headings as shown:

The curves fold-out heading, along with the Masks,


Events and Motion headings
Expand the curves heading, and click the plus icon to add a new curve to the current animation clip. If
your imported animation file is split into multiple animation clips, each clip can have its own custom
curves.

The curves on an imported animation clip


The curve’s X-axis represents normalized time and always ranges between 0.0 and 1.0 (corresponding
to the beginning and the end of the animation clip respectively, regardless of its duration).
Unity Curve
Editor
Double-clicking an animation curve will bring up the standard Unity curve editor (see Editing Value
Properties for further details) which you can use to add keys to the curve. Keys are points along the
curve’s timeline where it has a value explicitly set by the animator rather than just using an
interpolated value. Keys are very useful for marking important points along the timeline of the
animation. For example, with a walking animation, you might use keys to mark the points where the
left foot is on the ground, then both feet on the ground, right foot on the ground, etc. Once the keys
are set up, you can move conveniently between key frames by pressing the Previous/Next Key
Frame buttons. This will move the vertical red line and show the normalized time at the keyframe;
the value you enter in the text box will then set the value of the curve at that time.
Animation Curves and Animator Controller parameters
If you have a curve with the same name as one of the parameters in the Animator Controller, then that
parameter will take its value from the value of the curve at each point in the timeline. For example, if
you make a call to GetFloat from a script, the returned value will be equal to the value of the curve at
the time the call is made. Note that at any given point in time, there might be multiple animation clips
attempting to set the same parameter from the same controller. In that case, the curve values from the
multiple animation clips are blended. If an animation has no curve for a particular parameter then the
blending will be done with the default value for that parameter.
Animation events on imported clips
Animation events can be attached to imported animation clips in the Animations tab of
the Animation Import Settings.
These events allow you to add additional data to an imported clip which determines when certain
actions should occur in time with the animation. For example, for an animated character you might
want to add events to walk and run cycles indicating when the footstep sounds should play.
To add an event to an imported animation, first select the imported animation file in your project
view, then in the import settings in the inspector, select the Animations button.
View the Animations section of the
Import Settings for your animation file
Then scroll all the way to the bottom of the inspector to find the Events heading, among the four fold-
out headings as shown:

The Events fold-out heading, along with the Curves,


Masks, and Motion headings
Expand the events heading to reveal the events timeline for the current imported animation clip.

The Events time


line, before any events have been added
To move the playback head to a different point in the timeline, use the timeline in the preview pane of
the window:
Clicking in the
preview pane timeline allows you to control where your new event will be created in the event
timeline
Position the playback head at the point where you want to add an event, then click Add Event. A new
event is created, indicated by a small white marker on the timeline. In the Function field, fill in the
name of the function to call when the event is reached.
Make sure that any GameObject which uses this animation in its animator has a corresponding script
attached that contains a function with a matching event name.
The example below demonstrates an event set up to call the Footstep function in a script attached to
the Player GameObject. This could be used in combination with an AudioSource to play a footstep
sound synchronised with the animation.
An event which
calls the function “Footstep”
You can also choose to specify a parameter, which is sent to the function called by the event. There
are four different parameter types: Float, Int, String or Object.
By filling out a value in one of these fields, and implementing your function to accept a parameter of
that type, you can have the value specified in the event passed through to your function in the script.
For example, you might want to pass a float value to specify how loud the footstep should be during
different actions, such as quiet footstep events on a walking loop and loud footstep events on a
running loop. You could also pass a reference to an effect Prefab, allowing your script to instantiate
different effects at certain points during your animation.
Selecting a Root Motion Node
When root motion is contained within an imported animation clip, that motion will be used to drive
the movement and rotation of the GameObject that is playing the animation. Sometimes however it
may be necessary to manually select a different specific node within the hierarchy of your animation
file to act as the root motion node.
(example use case required here)
The Motion field within the Animation import settings allows you to use a hierarchical popup menu to
select any node (Transform) within the hierarchy of the imported animation and use it as the root
motion source. That object’s animated position and rotation will control the animated position and
rotation of the GameObject playing back the animation.
To select a root motion node for an animation, first select the imported animation file in your project
view, then in the import settings in the inspector, select the Animations button.

View the Animations section of the


Import Settings for your animation file
Then scroll all the way to the bottom of the inspector to find the Motion heading, among the four fold-
out headings as shown:
The Motion fold-out heading, along with the Mask,
Curves, and Events headings
Expand the motion heading to reveal the Root Motion Node menu. When you open the menu, you’ll
see the options * None , * Root Transform , and any objects that are in the root of the imported file’s
hierarchy. This may be your character’s mesh objects, as well as its root bone name, and a submenu
for each item that has child objects. Each submenu also contains the child object(s) itself, and further
sub-menus if / those / objects have child objects.

Traversing the hierarchy of objects to select a root motion node


Once the Root motion node has been selected, the object’s motion will now be driven by the
animation from that particular object.
Euler Curve Import
Rotations in 3D applications are usually represented in one of two ways, Quaternions or Euler angles.
For the most part, Unity uses Quaternions as its internal representation of rotations, however it’s
important to have a basic understanding of rotation and orientation in Unity.
When importing animation from external sources, these files usually contain keyframe animation in
Euler format. Unity’s default behavior is to resample these animations as Quaternion values and
generate a new Quaternion keyframe for every frame in the animation, in an attempt to minimise any
perceivable difference between the source animation and how it appears in Unity.
There are still some situations where - even with resampling - the quaternion representation of the
imported animation may not match the original closely enough, For this reason, in Unity 5.3 and
onwards there is the option to turn off animation resampling, so that you can instead use the original
Euler animation keyframes at runtime.
Using Euler Curve Support on Imported Animations
To enable support for using the original Euler Curve values in an animation file, you must turn
*off the “Resample Curves” option in the Animations Import Inspector:

The Resample Curves option in the


Animations Import Inspector
With this option enabled, rotations will be resampled to quaternions. This is the default behavior.
When disabled, rotation curves will not be resampled, and the rotation curve will be imported with its
original keyframes, in Euler or quaternion mode as appropriate for the curve type. Note: Any
rotation curve on a joint that has pre- or post-rotations will be automatically resampled by the
FBX SDK, and will automatically be imported as quaternion curves.
To support a maximum variety of imported files, and for maximum fidelity, Unity supports all normal
(non-repeating) euler rotation orders, and curves will be imported in their original rotation orders.
The primary reason for disabling rotation resampling and using the original euler curves is when the
default quaternion interpolation between frames gives faulty results, and causes issues.
The Results During Animation Playback
When using non-resampled rotations, there should be very little visual difference in the playback of
animations. Under the hood though, rotation curves that have been imported in Euler representation
will always be kept so, even at runtime.
Since the engine functions with quaternions, rotation values have to be converted to quaternion at
some point. Before Unity 5.3, this conversion always happened at import. In 5.3, when the Resample
Curves option is switched off in the Animation Import inspector, the rotation values are kept as euler
values up until they are applied to a Gameobject. This means that the end result should be as good as -
or better than - before.
Memory wise, for rotation curves that have not been baked in the authoring software, there should be
a net gain for rotation curves.
Non-Default Euler Orders in the Transform Inspector
The Euler angles used in Unity’s transform inspector are applied in the default order of Z,X,Y.
When playing back or editing imported animations that feature Euler curves with a rotation order
different from Unity’s default, an indication of the current rotation order will be shown next to the
rotation fields.

The inspector showing that a non-default


rotation order is being used for the rotation animation on this object
When editing multiple transforms with differing rotation orders, a warning will be shown to the users
to warn them that the same Euler rotation applied will give different results on curves with different
rotation orders.

The inspector showing that a mixture of


rotation orders are being used for the rotation animation on the selected group of objects
PRACTICAL 8
Aim:Create Snowfall Particle effect in Unity

Steps:

1. Import Assest
2. Right Click-> Create Empty ->Rename: GameObject

3. In GameObject -> Inspector -> Add Component-> Particle System.


4. Set Following Properties as follows:
● StartSpeed= 0
● GravityModifier= 1
● StartSize= 0.2-0.3
● RateOverTime= 50
● Shape= Box
● Linear-> select constant at two random at set coordinates.
5. Create a Material for Partical System: New Material

6. Set Tint white for Material:

7. Import the Material in Renderer in GameObject -> Partical System


Output:
PRACTICAL 9
Aim: Develop Android Game with unity.

Start by double clicking on Unity to launch it. Even the longest journey starts with a single step.
Now create a new project and make sure you choose ‘2D’. Once you’re in, you’ll be greeted with a
few different windows. These do stuff. We don’t have time to explain, so just follow my directions
and you’ll pick it up as we go.
The first thing you’ll want to do is to create a sprite to be your character. The easiest way to do that is
to draw a square. We’re going to give it a couple of eyes. If you want to be even faster still, you can
just grab a sprite you like from somewhere.

Save this sprite and then just drag and drop it into your ‘scene’ by placing it in the biggest window.
You’ll notice that it also pops up on the left in the ‘hierarchy’.
Advertisement
Now we want to create some platforms. Again, we’re going to make do with a simple square and
we’ll be able to resize this freehand to make walls, platforms and what have you.

There we go, beautiful. Drop it in the same way you just did.
We already have something that looks like a ‘game’. Click play and you should see a static scene for
now.
We can change that by clicking on our player sprite and looking over to the right to the window called
the ‘inspector’. This is where we change properties for our GameObjects.
Choose ‘Add Component’ and then choose ‘Physics 2D > RigidBody2D’. You’ve just added physics
to your player! This would be incredibly difficult for us to do on our own and really highlights the
usefulness of Unity.
We also want to fix our orientation to prevent the character spinning and freewheeling around. Find
‘constraints’ in the inspector with the player selected and tick the box to freeze rotation Z. Now click
play again and you should find your player now drops from the sky to his infinite doom.
Take a moment to reflect on just how easy this was: simply by applying this script called
‘RigidBody2D’ we have fully functional physics. Were we to apply the same script to a round shape,
it would also roll and even bounce. Imagine coding that yourself and how involved that would be!
To stop our character falling through the floor, you’ll need to add a collider. This is basically the solid
outline of a shape. To apply that, choose your player, click ‘Add Component’ and this time select
‘Physics 2D > BoxCollider2D’.
Take a moment to reflect on just how easy this was: simply by applying this script called
‘RigidBody2D’ we have fully functional physics.
Do the precise same thing with the platform, click play and then your character should drop onto the
solid ground. Easy!
One more thing: to make sure that the camera follows our player whether they’re falling or moving,
we want to drag the camera object that’s in the scene (this was created when you started the new
project) on top of the player. Now in the hierarchy (the list of GameObjects on the left) you’re going
to drag the camera so that it is indented underneath the player. The camera is now a ‘child’ of the
Player GameObject, meaning that when the player moves, so too will the camera.
Your first script
We’re going to make a basic infinite runner and that means our character should move right across the
screen until they hit an obstacle. For that, we need a script. So right click in the Assets folder down
the bottom and create a new folder called ‘Scripts’. Now right click again and choose ‘Create > C#
Script’. Call it ‘PlayerControls’.
For the most part the scripts we create will define specific behaviors for our GameObjects.
Now double click on your new script and it will open up in Visual Studio if you set everything up
correctly.
There’s already some code here, which is ‘boiler plate code’. That means that it’s code that you will
need to use in nearly every script, so its ready-populated for you to save time. Now we’ll add a new
object with this line above void Start():
Code
public Rigidbody2D rb;
Then place this next line of code within the Start() method to find the rigidbody. This basically tells
Unity to locate the physics attached to the GameObject that this script will be associated with (our
player of course). Start() is a method that is executed as soon as a new object or script is created.
Locate the physics object:
Code
rb = GetComponent<Rigidbody2D>();
Add this inside Update():
Code
rb.velocity = new Vector2(3, rb.velocity.y);
Update() refreshes repeatedly and so any code in here will run over and over again until the object is
destroyed. This all says that we want our rigidbody to have a new vector with the same speed on the y
axis (rb.velocity.y) but with the speed of ‘3’ on the horizontal axis. As you progress, you’ll probably
use ‘FixedUpdate()’ in future.
Save that and go back to Unity. Click your player character and then in the inspector select Add
Component > Scripts and then your new script. Click play, and boom! Your character should now
move towards the edge of the ledge like a lemming.
Note: If any of this sounds confusing, just watch the video to see it all being done – it’ll help!
Very basic player input
If we want to add a jump feature, we can do this very simply with just one additional bit of code:
Code
Copy Text
if (Input.GetMouseButtonDown(0)) {
rb.velocity = new Vector2(rb.velocity.x, 5);
}
This goes inside the Update method and it says that ‘if the player clicks’ then add velocity on the y
axis (with the value 5). When we use if, anything that follows inside the brackets is used as a kind of
true or false test. If the logic inside said brackets is true, then the code in the following curly brackets
will run. In this case, if the player clicks the mouse, the velocity is added.
Android reads the left mouse click as tapping anywhere on the screen! So now your game has basic
tap controls.
Finding your footing
This is basically enough to make a Flappy Birds clone. Throw in some obstacles and learn how to
destroy the player when it touches them. Add a score on top of that.
If you get this down, no challenge will be too great in future
But we have a little more time so we can get more ambitious and make an infinite runner type game
instead. The only thing wrong with what we have at the moment is that tapping jump will jump even
when the player isn’t touching the floor, so it can essentially fly.
Add the following code to your script above the Update() method:
Code
public Transform groundCheck;
public Transform startPosition;
public float groundCheckRadius;
public LayerMask whatIsGround;
private bool onGround;
Add this line to the Update method above the if statement:
Code
onGround = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround);
Finally, change the following line so that it includes && onGround:
Code
Copy Text
if (Input.GetMouseButtonDown(0) && onGround) {
The entire thing should look like this:
Code
Copy Text
public class PlayerControls : MonoBehaviour
{
public Rigidbody2D rb;
public Transform groundCheck;
public Transform startPosition;
public float groundCheckRadius;
public LayerMask whatIsGround;
private bool onGround;

void Start() {
rb = GetComponent<Rigidbody2D>();
}

void Update() {
rb.velocity = new Vector2(3, rb.velocity.y);
onGround = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius,
whatIsGround);
if (Input.GetMouseButtonDown(0) && onGround) {
rb.velocity = new Vector2(rb.velocity.x, 5);
}

}
What we’re doing here is creating a new transform – a position in space – then we’re setting its radius
and asking if it is overlapping a layer called ground. We’re then changing the value of the Boolean
(which can be true or false) depending on whether or not that’s the case.
So, onGround is true if the transform called groundCheck is overlapping the layer ground.
If you click save and then head back to Unity, you should now see that you have more options
available in your inspector when you select the player. These public variables can be seen from within
Unity itself and that means that we can set them however we like.
Right-click in the hierarchy over on the left to create a new empty object and then drag it so that it’s
just underneath the player in the Scene window where you want to detect the floor. Rename the object
‘Check Ground’ and then make it a child of the player just as you did with the camera. Now it should
follow the player, checking the floor underneath as it does.
Select the player again and, in the inspector, drag the new Check Ground object into the space where
it says ‘groundCheck’. The ‘transform’ (position) is now going to be equal to the position of the new
object. While you’re here, enter 0.1 where it says radius.

Finally, we need to define our ‘ground’ layer. To do this, select the terrain you created earlier, then up
in the top right in the inspector, find where it says ‘Layer: Default’. Click this drop down box and
choose ‘Add Layer’.
Now click back and this time select ‘ground’ as the layer for your platform (repeat this for any other
platforms you have floating around). Finally, where it says ‘What is Ground’ on your player, select
the ground layer as well.
You’re now telling your player script to check if the small point on the screen is overlapping anything
matching that layer. Thanks to that line we added earlier, the character will now only jump when that
is the case.
And with that, if you hit play, you can enjoy a pretty basic game requiring you to click to jump at the
right time.
With that, if you hit play you can enjoy a pretty basic game requiring you to click to jump at the right
time. If you set your Unity up properly with the Android SDK, then you should be able to build and
run this and then play on your smartphone by tapping the screen to jump.
The road ahead
Obviously there’s a lot more to add to make this a full game. The player should to be able to die and
respawn. We’d want to add extra levels and more.
PRACTICAL 10
Aim: Create Intelligent Enemies In Unity
Code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class EnemyController : MonoBehaviour


{

public enum AISTATE { PATROL,CHASE,ATTACK };

public Transform player;


public NavMeshAgent enemy;
public AISTATE enemyState = AISTATE.PATROL;
float DistanceOffset = 2f;
public List<Transform> waypoints = new List<Transform>();
Transform currentWaypoint;

private void Start()


{
currentWaypoint = waypoints[Random.Range(0, waypoints.Count)];
ChangeState(AISTATE.PATROL);
}

public void ChangeState(AISTATE newState)


{
StopAllCoroutines();
enemyState = newState;

switch (enemyState)
{
case AISTATE.PATROL:
StartCoroutine(PatrolState());
break;
case AISTATE.CHASE:
StartCoroutine(ChaseState());
break;
case AISTATE.ATTACK:
StartCoroutine(AttackState());
break;

}
}

public IEnumerator ChaseState()


{
while (enemyState == AISTATE.CHASE)
{
if (Vector3.Distance(transform.position, player.position) < DistanceOffset)
{
ChangeState(AISTATE.ATTACK);
yield break;
}
enemy.SetDestination(player.position);
yield return null;

}
public IEnumerator AttackState()
{
while (enemyState == AISTATE.ATTACK)
{
if (Vector3.Distance(transform.position, player.position) > DistanceOffset)
{
ChangeState(AISTATE.CHASE);
yield break;
}

print("Attack");
enemy.SetDestination(player.position);
yield return null;
}

yield break;

}
public IEnumerator PatrolState()
{
while (enemyState == AISTATE.PATROL)
{
enemy.SetDestination(currentWaypoint.position);

if (Vector3.Distance(transform.position, currentWaypoint.position) <


DistanceOffset)
{
currentWaypoint = waypoints[Random.Range(0, waypoints.Count)];
}

yield return null;

}
public void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Player"))
{
ChangeState(AISTATE.CHASE);
}
}
}

You might also like