Class hours: 9:40 – 2:05
Mr. Bohmann
wbohmann@ewsd.org
Today’s Notes
- Today is an EHS A Day
- Friday the 13th!
- WorkKeys Testing – all done! Thanks for putting up with the week.
- Laptops – Loaners – please return
- Owen Laptop
- Hiro Laptop, Tablet
- Ryan Laptop
- PE meet outside by the red shed next to the Childcare playground
9:40 Attendance
9:45 Unity – Quick Quiz
Quiz, what? Not cool man. Jump on to Socrative and let’s review a couple concepts from this week. We were discussing materials in Unity.
9:55 Using Instantiate() to Create PreFabs
We’ve seen how we can write code to destroy gameObjects. We can also use code to create gameObjects too. This is really handy with PreFabs, spawning enemies, handling bullets managing random power-ups – I could go on. Let’s start basic then add some heavy lifting:
- Open your Lunar Lander game.
- Add an asteroid sprite to the hierarchy
- Add circle collider 2D
- If you have a rotation script, pop that on as well
- Drag to your PreFabs folder – you now have a prefab
- Delete your PreFab from the hierarchy
- Open your LunarLander Script and
- Create a Public GameObject asteroidPreFab variable
- Populate that new variable slot with your PreFab from the PreFabs folder
- In the void Start method of your LunarLander add in the following line of code
public GameObject asteroidPreFab;
void Start ()
{
Instantiate(asteroidPreFab); // create a new copy of the prefab
}
We have chosen to call Instantiate() in the Start() function of this script, because we want the asteroid to be created right away when the game starts. But, you can call Instantiate() from anywhere that makes sense for your game! For example, if you are firing bullets from a gun, you might call Instantiate() from inside the Update() function when you detect the trigger key.
Level Up – Round 1
What happens if we run this script – where do the Asteroids go?
public GameObject asteroidPreFab;
void Start ()
{
Instantiate(asteroidPreFab); // create a new copy of the prefab
Instantiate(asteroidPreFab); //copy 2
Instantiate(asteroidPreFab); // copy 3
Instantiate(asteroidPreFab); // copy 4
Instantiate(asteroidPreFab); // copy 5
Instantiate(asteroidPreFab); // copy 6
}
You can actually call Instantiate() with one or more additional parameters to configure the cloned object. This version lets us add a new position and rotation to the new object.
Instantiate (asteroidPreFab, new Vector3(4.0F,2.0F,0), Quaternion.identity);
The Vector3 parameter contains the X, Y, and Z coordinates of the new object in world units. You can get a good sense of the X and Y units by looking at the grid lines within the camera rectangle on the scene. Each grid line is 1 world unit, so if your camera is showing 5 boxes vertically and 8.5 horizontally in every direction from the center.
The third parameter is a Quaternion that represents the rotation angles in the X, Y, and Z directions. A Quaternion is actually a complex object that you don’t want to try and modify yourself. Fortunately, if you don’t want your new object to be rotated, you can pass in the value Quaternion.identity, and the object will be created with no rotation.
Level Up – Round 2 – Heavier Lifting
Positioning New Objects in Random Locations
Your game may want to simply position new objects in random locations on the screen. This is easily done with a small amount of code. We just need some way to automatically calculate the size of the scene in world coordinates, so our random locations can be calculated within that visible area.
Recall that the main camera defines the visible area on the screen. All scripts have a reference to the main camera (Camera.main). We can use the camera to calculate the width and height of the currently visible area, in world coordinates.
A 2D (“orthographic”) camera like the one we are using has two handy properties that we can read to find the size of the screen. The orthographicSize property shows us half of the screen height, in world coordinates. The aspect property gives us the ratio of width and height. So, we can easily calculate the screen dimensions as shown below.
// calculate the size of the screen, in world units
float worldHeight = Camera.main.orthographicSize * 2.0F;
float worldWidth = worldHeight * Camera.main.aspect;
We can get a new random value by simply writing Random.value as part of an expression. Random.value is a Unity property that will return a random number between 0.0 and 1.0 (including both 0.0 and 1.0 in the possible range). Let’s use this random value and some math to calculate random positions on the visible scene in world coordinates.
// calculate random starting location
float randomX = (worldWidth * Random.value) - worldWidth / 2.0F;
float randomY = (worldHeight * Random.value) - worldHeight / 2.0F
Each line will get a random number and then multiply that by the width or height of the screen. So if a screen is 14 world units wide, for example, we will have a random number between 0 and 14. We then subtract out half the width or height because the origin (0, 0) is in the middle of the screen. Subtracting half of 14 from a random number between 0 and 14 would give us a random number between -7 and +7.
Confused Yet? Probably with the math. So just copy the code and its Saul Goodman.
void Start ()
{
// clone 3 asteroidss at random locations
CreateAsteroid();
CreateAsteroid();
CreateAsteroid();
}
void CreateAsteroid()
{
// calculate the size of the screen, in world units
float worldHeight = Camera.main.orthographicSize * 2.0F;
float worldWidth = worldHeight * Camera.main.aspect;
// calculate random starting location
float randomX = (worldWidth * Random.value) - worldWidth / 2.0F;
float randomY = (worldHeight * Random.value) - worldHeight / 2.0F;
Instantiate(asteroidPreFab, new Vector3(randomX,randomY,0), Quaternion.identity);
}
10:35 Break
10:45 Game Dev Continued….
Level Up – Round 3 – It’s getting heavy now –
Controlling Object Lifespans with Invoke and Coroutines
Can you think of some objects in your game that should have a limited lifespan? Power up, bullets, enemies spawning.
The word “invoke” means to cause or request something to happen. Within the Unity engine, invoke is used to mean “run a function“. You can define your own functions that contain script logic that needs to be run at a later time or regular intervals. Unity will then invoke that function based on the timing information you provide.
Invoke("CreateAsteroid", 3.0F); //you need a string of the method name and then the delay
The Invoke() function will only call the target function one time. But how can you cause a function to be
called repeatedly on a regular schedule? Unity has a second function called InvokeRepeating() that does the job!
InvokeRepeating(string functionName, float secondsDelay, float rate)
//for example this will create an asteroid after 3 seconds and 1 every second after
InvokeRepeating("CreateAsteroid", 3.0F, 1.0F);
Let’s save Coroutines for Monday. A coroutine is when you create something and then you may want some other task to be performed on that object later. Like asteroids being created and then later they get smaller and disappear, or blow up or….. whatever we want.
Your Turn:
In your Lunar Lander game, create some Aliens to appear at the start of your game. Can you do more than one kind of alien. Try using Instantiate and Invoke. Write your own method and then call that method in the Start(). Ask questions – don’t close your game if you have errors.
11:15 Publishing Your Karting Game
Let’s go through the steps to get your game published. We’ll be publishing to Simmer.io. You will want to make an account there.
Follow along:
- Go to Project Settings and Change Publishing Settings to Disabled Compression Format (found under player)
- Go to Edit, Build Settings
- Change to the WebGL Platform
- Add Open Scenes to capture the scene you want to turn into a game
- Choose Build
- Create A Folder called WebGLBuild, select it and choose Build.
- It will take 5 minutes or so.
- Go to Simmer.io and create an account. Upload your WebGLBuild folder.
- Boom – Done!
- Fill in the meta details, add a screen shot, etc…
- Upload your finished and published game to this dropbox
11:30 Cawd Fun Games Studio Work Time
Use the remainder of the day to work on your final project. Remember, we are planning stages.
GDD Rough Draft Due on Monday. One per game.
12:15 Lunch
12:45 Focus on Literacy
1:05 Mask Break
1:15 Production Time & Guided Support
Week 34 Agency is now assigned. Due Monday, May 16th
Overdue work – yes there is much of it out there
GDD Rough Draft Due Monday
Trello Boards, share with me