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.
Google+ Community: https://plus.google.com/communities/108584850180626452949
Twitter: https://twitter.com/Devination3D
Facebook: https://www.facebook.com/unity3Dtutorialsbydevin

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



Support Further Tutorial Development
Comments?
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
* Google+ Community: https://plus.google.com/communities/108584850180626452949
* Twitter: https://twitter.com/Devination3D
* Facebook Page: https://www.facebook.com/unity3Dtutorialsbydevin
/*/
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();
				}
			}
		}
	}
}