Saturday, January 16, 2016

Unity 2D Platformer Tutorial - Part 5a - Combat Player Health

See the previous parts here:
Check out the code below the videos




In part 5a of this Unity3D tutorial we add Player Damage and Death. The player will take damage from touching enemies but become invincible for a short time afterwards. If the player takes 3 hits, then the player dies and the level restarts.

Twitter: https://twitter.com/Devination3D

Time Breakdown:
0:55 - Fixing a couple of issues with the enemy
3:00 - Setting up the damage animation for our player
4:56 - Setting up the script for player damage
9:16 - Adding our level to the build settings so we can restart the game on death
10:12 - Playing the hurt animation when we take damage
16:12 - Making the player ignore collision with the enemy after getting hurt
19:50 - Demonstration of player damage working as intended

Check out the videos above to hear the explanation and see the code in action
/*/
* Script by Devin Curry
* www.Devination.com
* www.youtube.com/user/curryboy001
* Please like and subscribe if you found my tutorials helpful :D
* Twitter: https://twitter.com/Devination3D
/*/
using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour
{
 public static PlayerController instance;

 //Movement
 public float speed = 10, jumpVelocity = 10;
 public LayerMask playerMask;
 public bool canMoveInAir = true;

 //Combat
 public int health = 3;
 public float invincibleTimeAfterHurt = 2;

 [HideInInspector]
 public Collider2D[] myColls;

 Transform myTrans, tagGround;
 Rigidbody2D myBody;
 bool isGrounded = false;
 float hInput;
 AnimatorController myAnim;

 void Start ()
 {
  instance = this;
  myColls = this.GetComponents<Collider2D>();
  myBody = this.GetComponent<Rigidbody2D>();
  myTrans = this.transform;
  tagGround = GameObject.Find (this.name + "/tag_ground").transform;
  myAnim = AnimatorController.instance;
 }
 void FixedUpdate ()
 {
  isGrounded = Physics2D.Linecast (myTrans.position, tagGround.position, playerMask);
  myAnim.UpdateIsGrounded (isGrounded);
  #if !UNITY_ANDROID && !UNITY_IPHONE && !UNITY_BLACKBERRY && !UNITY_WINRT || UNITY_EDITOR
  hInput = Input.GetAxisRaw("Horizontal");
  myAnim.UpdateSpeed(hInput);
  if(Input.GetButtonDown("Jump"))
   Jump();
  #endif
  
  Move(hInput);
 }
 void Move(float horizonalInput)
 {
  if(!canMoveInAir && !isGrounded)
   return;
  Vector2 moveVel = myBody.velocity;
  moveVel.x = horizonalInput * speed;
  myBody.velocity = moveVel;
 }
 public void Jump()
 {
  if(isGrounded)
   myBody.velocity += jumpVelocity * Vector2.up;
 }
 public void StartMoving(float horizonalInput)
 {
  hInput = horizonalInput;
  myAnim.UpdateSpeed(horizonalInput);
 }

 void Hurt()
 {
  health--;
  if (health <= 0)
   Application.LoadLevel(Application.loadedLevel);
  else
   myAnim.TriggerHurt(invincibleTimeAfterHurt);
 }
 void OnCollisionEnter2D(Collision2D collision)
 {
  Enemy enemy = collision.collider.GetComponent<Enemy>();
  if(enemy != null)
  {
   foreach(ContactPoint2D point in collision.contacts)
   {
    Debug.Log(point.normal);
    Debug.DrawLine(point.point, point.point + point.normal, Color.red, 10);
    if( point.normal.y >= 0.9f )
    {
     Vector2 velocity = myBody.velocity;
     velocity.y = jumpVelocity;
     myBody.velocity = velocity;
                    enemy.Hurt();
    }
    else
    {
     Hurt();
    }
   }
  }
 }
}