Obstacles are static/non-moving objects which appear on platforms with increasing frequency as the game progresses.
They are there to provide an extra challenge for the player and give a little more variety to the game.
Should a player collide with an obstacle, it’s instant death – game over – & so should be avoided at all costs.
The code itself it pretty straight forward – (Obstacles are created, they scroll left then are destroyed) – it’s a modified/simplified version of the code written to handle pickups.
For in-game obstacles I initially wanted to use a pyramid (Tetrahedron) shape – Since these are pointy and seem like the sort of thing a player should avoid. Unfortunately Unity doesn’t provide tetrahedrons as part of the basic 3D objects.
My first attempt at a workaround was to use cubes – Rotating them, and placing them halfway into the platform top – They looked okay-ish; but didn’t quite work out.
My second attempt was to use spheres – These looked much better – I nearly stuck with them – I just wasn’t convinced they looked dangerous enough.
Looking for an alternative – I found an article in Morten Nobel’s Blog detailing how to create a tetrahedron in code (rather than importing a model) – I used the code pretty much as-is – only making two very minor tweaks; 1. To make them self-construct when initialised & 2. To auto build a collision mesh.
Since I’m a big fan of procrastination, the code currently has all three obstacles types in place, setup as prefabs.
ObstacleCube – A 3D object Cube with default settings – implemented as as a prefab. A obstacle c# script is attached (used to manage collision response).
ObstacleSphere – A 3D object Sphere with default settings – implemented as a prefab. A obstacle c# script is attached (used to manage collision response).
ObstacleTetrahedron – A custom object. Defined as a prefab, it contains the same components as ObstacleCube and ObstacleSphere – Except that the MeshFilter is empty. In addition it includes two extra C# scripts; obstacle – used to manage collision response & TetraHedron – Used to construct the object at runtime.
ObstacleManager;
ObstacleManager is a C# script which manages all obstacles in game, covering their entire lifespan (initalisation, update & removal).
The public method AddObstacles is used to instantiate new obstacles (called externally by the PlatformManager script).
Once created they are then add to a list (List obstacles). Each frame the positions of all obstacles are updated.
Once an obstacle moves offscreen it is destroyed by ObstacleManager to free up space.
AddObstacles;
public void AddObstacles(Vector3 inPosition, float inWidth) { Vector3 obstaclePosition = new Vector3(inPosition.x, inPosition.y, inPosition.z-4.5f); float obstacleHalfWidth = obstacle.transform.localScale.x * 0.6f; float halfWidth = (inWidth / 2f)-obstacleHalfWidth; obstaclePosition.x = Random.Range(obstaclePosition.x - halfWidth, obstaclePosition.x + halfWidth); for (int counter=0; counter<9; counter++) { obstacles.Add(Instantiate(obstacle, obstaclePosition, Quaternion.identity) as GameObject); obstacles[obstacles.Count - 1].transform.position = obstaclePosition; obstaclePosition.z += 1; } }
AddObstacles is called by the platformManager script. When called it creates a column of obstacles – Even though, only the centre obstacle is need (since the player doesn’t move on the Y axis) – a row is more visually appealing.
It receives two parameter values inPosition & inWidth. inPosition is the source/base position for obstacles it is about to instantiate. This can be used to add new obstacles to the middle of the platform. This is fine, looks good and works as an extra challenge in-game. However to keep things interesting I wanted to position the obstacles randomly along the platforms X axis. For this I use the inWidth variable.
Update;
Every loop the position of instantiated obstacles is updated, moving them from right to left; destroying any which move out of the game area;
// Update is called once per frame void Update() { //--- if (GameController.gameState == GameController.GameState.InGame) { //--- ScrollSpeed(); //set movement speed UpdatePositions(); //update platforms positions //--- } //--- } //--- //--- //set movement speed void ScrollSpeed() { speed = 0.1f + (GameController.scrollSpeed * 0.004f); if (speed > maxSpeed) speed = maxSpeed; }
Obstacle;
All obstacles have an attached script -all called Obstacle.
It’s is a simple script containing two methods;
Start – Which sets the obstacles colour after initialisation.
OnCollisionEnter – Checks to see if the player has collided with the obstacles – If a collision has occurred – PlayerDie() method is called.
Start;
Start defines the colour of the obstacle (currently they are all set to black);
void Start() { //--- Renderer rend = GetComponent(); //Ensure the obstacle's colour is set to black Color whichColour = Color.black; rend.material.SetColor("_Color", whichColour); rend.material.SetColor("_SpecColor", whichColour); rend.material.SetColor("_EmissionColor", whichColour); rend.material.SetColor("_ReflectColor", whichColour); //--- }
OnCollisionEnter;
OnCollisionEnter checks for collision with the player – Since obstacles are deadly, if a collision is found, I call the player.PlayDie method;
void OnCollisionEnter(Collision collision) { if (collision.gameObject.CompareTag("Player")) //Ensure we are checking aginst the player. { Player player = collision.gameObject.GetComponent(); //Grab the player player.PlayDie(); } }
That’s pretty much it. I may expand obstacles a little in the future – But for now it gives me a framework to work from.
Grab a copy of the project here
Next post: 1.9 Tighten & Tidy
Last post: 1.7e Highscores (Add)