How to Make Video Games 16

Make Super Mario BrothersIn this video tutorial we completely finish our Mario Clone!!! It has been a ton of fun for me. I hope you have liked it as well? In this video we will Learn how to Program Wall Jumping, Use Raycasts, Animate Enemies, Create Enemies that Attack, Use Gizmos, Draw a Sprite Sheet, Slice Sprite Sheets and a whole bunch more.

Like always the code follows the video below. The Unity Project files are here

If you enjoy videos like this consider donating $1 or simply turn off AdBlock. Either helps a lot!

Code for Mario Clone

BrickBlock.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BrickBlock : MonoBehaviour {

// Used to change the sprite
private SpriteRenderer sr;

// The sprite to change into
public Sprite explodedBlock;

// Wait time before switching sprites
public float secBeforeSpriteChange = .2f;

void Awake(){
sr = GetComponent ();
}

// Called when something hits the BrickBlock
void OnCollisionEnter2D(Collision2D col){

// Check if the collision hit the bottom of the block
if (col.contacts [0].point.y < transform.position.y) { // Play sound SoundManager.Instance.PlayOneShot (SoundManager.Instance.rockSmash); // Change the Block sprite sr.sprite = explodedBlock; // Wait a fraction of a second and then destroy the BrickBlock DestroyObject (gameObject, secBeforeSpriteChange); } } } CameraMove.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraMove : MonoBehaviour {

// Put Manny here to track his movement
public Transform cameraTarget;

// How quickly the camera moves towards Manny
public float cameraSpeed;

// Min and max X and Y movements
public float minX;
public float minY;
public float maxX;
public float maxY;

// Update used when dealing with Rigid Bodies
void FixedUpdate(){

// Make sure the camera has a target
if (cameraTarget != null) {

// Lerp smoothes movement from the starting position
// to the targets position
var newPos = Vector2.Lerp (transform.position,
cameraTarget.position,
Time.deltaTime * cameraSpeed);

// Define the cameras new postion
var vect3 = new Vector3 (newPos.x, newPos.y, -10f);

// Clamp gets the cameras x position and clamps
// it between the min and max value
var clampX = Mathf.Clamp (vect3.x, minX, maxX);
var clampY = Mathf.Clamp (vect3.y, minY, maxY);

// Move the camera
transform.position = new Vector3(clampX, clampY, -10f);
}
}
}

Coin.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// Needed to manipulate the UI
using UnityEngine.UI;

public class Coin : MonoBehaviour {

// Called when something hits the Coin
void OnCollisionEnter2D(Collision2D col){

// Play coin sound
SoundManager.Instance.PlayOneShot (SoundManager.Instance.getCoin);

// Increase the Score Text component
increaseTextUIScore();

Destroy (gameObject);

}

// Increases the score the the text UI name passed
void increaseTextUIScore(){

// Find the Score UI component
var textUIComp = GameObject.Find(“Score”).GetComponent();

// Get the string stored in it and convert to an int
int score = int.Parse(textUIComp.text);

// Increment the score
score += 10;

// Convert the score to a string and update the UI
textUIComp.text = score.ToString();
}

}

Manny.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Manny : MonoBehaviour {

// Defines Mannys speed horizontally
public float speed = 5;

// Defines Mannys facing direction
public bool facingRight = true;

// Jump speed
public float jumpSpeed = 5f;

// Mannys components
// private SpriteRenderer sr;
private Rigidbody2D rb;
private Animator animator;

// Will flip depending if on ground
bool isJumping = false;

// Used to check if Manny is on the ground
// You draw a line out away from the sprite a defined
// distance and check if it collides with something
// If it hits nothing Raycast() returns null
private float rayCastLength = 0.005f;

// Sprite width and height
private float width;
private float height;

// How long is the jump button held
private float jumpButtonPressTime;

// Max jump amount
public float maxJumpTime = 0.2f;

// —– 1. NEW STUFF —–

// Special Y velocity value used when jumping off of a wall
public float wallJumpY = 10f;

// —– END OF NEW STUFF —–

void FixedUpdate(){

// Get horizontal movement -1 Left, or 1 Right
float horzMove = Input.GetAxisRaw (“Horizontal”);

// Need to get Mannys y
Vector2 vect = rb.velocity;

// Change x and keep y as is
rb.velocity = new Vector2 (horzMove * speed, vect.y);

// —– 1. NEW STUFF —–

// If Manny is jumping next to a wall his velocity will
// go up in the Y direction
if (IsWallOnLeftOrRight () && !IsOnGround () && horzMove == 1) {

rb.velocity = new Vector2 (-GetWallDirection () * speed * -.75f,
wallJumpY);
}

// —– END OF NEW STUFF —–

// Set the speed so the right Animation is played
animator.SetFloat(“Speed”, Mathf.Abs(horzMove));

// Makes sure Manny is facing the right direction
if (horzMove > 0 && !facingRight) {
FlipManny ();
} else if (horzMove < 0 && facingRight) { FlipManny (); } // Get vertical movement float vertMove = Input.GetAxis ("Jump"); if (IsOnGround () && isJumping == false) { if (vertMove > 0f) {
isJumping = true;
// —– NEW STUFF —–
SoundManager.Instance.PlayOneShot (SoundManager.Instance.jump);
// —– END OF NEW STUFF —–
}
}

// If button is held pass max time set
// vertical move to 0
if (jumpButtonPressTime > maxJumpTime) {
vertMove = 0f;
}

// If is jumping and we have a valid jump press length
// make Manny jump
if (isJumping && (jumpButtonPressTime < maxJumpTime)) { rb.velocity = new Vector2 (rb.velocity.x, jumpSpeed); } // If we have moved high enough make Manny fall // Set Mannys Rigidbody 2d Gravity Scale to 2 if (vertMove >= 1f) {
jumpButtonPressTime += Time.deltaTime;
} else {
isJumping = false;
jumpButtonPressTime = 0f;
}

}

// Makes sure components have been created when the
// game starts
void Awake(){
// sr = GetComponent ();
animator = GetComponent ();
rb = GetComponent ();

// Gets Mannys collider width and height and
// then adds more to it. Used to raycast to see
// if Manny is colliding with anything so we
// can jump
width = GetComponent ().bounds.extents.x + 0.1f;
height = GetComponent ().bounds.extents.y + 0.2f;
}

// When moving in a direction face in that direction
void FlipManny(){

// Flip the facing value
facingRight = !facingRight;

Vector3 scale = transform.localScale;
scale.x *= -1;
transform.localScale = scale;
}

public bool IsOnGround(){

// Check if contacting the ground straight down
bool groundCheck1 = Physics2D.Raycast (new Vector2 (
transform.position.x,
transform.position.y – height),
-Vector2.up, rayCastLength);

// Check if contacting ground to the right
bool groundCheck2 = Physics2D.Raycast (new Vector2 (
transform.position.x + (width – 0.2f),
transform.position.y – height),
-Vector2.up, rayCastLength);

// Check if contacting ground to the left
bool groundCheck3 = Physics2D.Raycast (new Vector2 (
transform.position.x – (width – 0.2f),
transform.position.y – height),
-Vector2.up, rayCastLength);

if (groundCheck1 || groundCheck2 || groundCheck3)
return true;

return false;

}

// If Manny falls off the screen destroy the game object
void OnBecameInvisible(){
Debug.Log (“Manny Destroyed”);
Destroy (gameObject);
}

// —– 1. NEW STUFF —–

public bool IsWallOnLeft(){

// -Vector2.right checks to the left with a raycast
// for a wall
return Physics2D.Raycast (new Vector2 (transform.position.x – width,
transform.position.y),
-Vector2.right,
rayCastLength);
}

public bool IsWallOnRight(){

// Vector2.right checks to the left with a raycast
// for a wall
return Physics2D.Raycast (new Vector2 (transform.position.x + width,
transform.position.y),
Vector2.right,
rayCastLength);
}

// Verifies if walls are on left or right for wall jumping
public bool IsWallOnLeftOrRight(){

if (IsWallOnLeft() || IsWallOnRight()) {
return true;
} else {
return false;
}
}

// Gets the wall direction if it exists
// Multiply the results against Manny’s X velocity
public int GetWallDirection(){
if (IsWallOnLeft ()) {
return -1;
} else if (IsWallOnRight ()) {
return 1;
} else {
return 0;
}
}

// —– END OF NEW STUFF —–

}

PrizeBlock.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// Needed to manipulate the UI
using UnityEngine.UI;

public class PrizeBlock : MonoBehaviour {

public AnimationCurve anim;

public int coinsInBlock = 5;

void OnCollisionEnter2D(Collision2D col){

// Check if the collision hit the bottom of the block
if (col.contacts [0].point.y < transform.position.y) { // Calls RunAnimation which will be paused // and resumed over time StartCoroutine (RunAnimation()); } // If block contains coins if (coinsInBlock > 0) {

// Play coin sound
SoundManager.Instance.PlayOneShot (SoundManager.Instance.getCoin);

// Increase the Score Text component
increaseTextUIScore();

coinsInBlock–;
}
}

IEnumerator RunAnimation(){

// Get starting position of PrizeBlock
Vector2 startPos = transform.position;

// Cycle through all the keys in the animation curve
for (float x = 0; x < anim.keys[anim.length-1].time; x += Time.deltaTime) { // Change the block position to what is defined // on the AnimationCurve transform.position = new Vector2 (startPos.x, startPos.y + anim.Evaluate (x)); // Continue looping at next update yield return null; } } // Increases the score the the text UI name passed void increaseTextUIScore(){ // Find the Score UI component var textUIComp = GameObject.Find("Score").GetComponent();

// Get the string stored in it and convert to an int
int score = int.Parse(textUIComp.text);

// Increment the score
score += 10;

// Convert the score to a string and update the UI
textUIComp.text = score.ToString();
}
}

Snail.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Snail : MonoBehaviour {

// Snail speed
public float speed = 2;

// Snail Direction
Vector2 direction = Vector2.right;

void FixedUpdate(){

// Move the snail
GetComponent ().velocity = direction * speed;

}

void OnTriggerEnter2D(Collider2D col){

// If you hit SnailStart & SnailEnd flip direction
transform.localScale = new Vector2 (-1 * transform.localScale.x,
transform.localScale.y);

direction = new Vector2 (-1 * direction.x, direction.y);

}

// If Manny hits the top of the snail kill the snail
// and otherwise kill Manny
void OnCollisionEnter2D(Collision2D col){
if (col.gameObject.name == “Manny”) {

// If hit from above play dead animation, remove
// the collider so the snail falls off the screen
// and kill Snail after 3 seconds
if (col.contacts [0].point.y > transform.position.y) {

GetComponent ().SetTrigger (“Dead”);
GetComponent ().enabled = false;
direction = new Vector2 (direction.x, -1);
DestroyObject (gameObject, 3);

} else {
// Kill manny

SoundManager.Instance.PlayOneShot (SoundManager.Instance.mannyDies);

DestroyObject (col.gameObject, .5f);
}
}
}

}

SoundManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SoundManager : MonoBehaviour {

// Holds the single instance of the SoundManager that
// you can access from any script
public static SoundManager Instance = null;

// All sound effects in the game
// All are public so you can set them in the Inspector
public AudioClip jump;
public AudioClip getCoin;
public AudioClip rockSmash;

// —– NEW STUFF —–
public AudioClip mannyDies;
// —– END OF NEW STUFF —–

// Refers to the audio source added to the SoundManager
// to play sound effects
private AudioSource soundEffectAudio;

// Use this for initialization
void Start() {

// This is a singleton that makes sure you only
// ever have one Sound Manager
// If there is any other Sound Manager created destroy it
if (Instance == null) {
Instance = this;
} else if (Instance != this) {
Destroy (gameObject);
}

AudioSource theSource = GetComponent ();
soundEffectAudio = theSource;
}

// Other GameObjects can call this to play sounds
public void PlayOneShot(AudioClip clip) {
soundEffectAudio.PlayOneShot(clip);
}
}

Leave a Reply

Your email address will not be published.

Google+