vrijdag 3 juli 2015

Top Down Dungeon Crawler in Unity3D with C# - Player Character

Alright, let's get started on our game! First, we'll probably need a player character. After all, we do want to be able to play the game and being able to play as early as possible allows for rapid testing of the gameplay and tweaking variables so the game feels just right.

Let's start by making a list of what we want the player character to be able to do.

We want the player to be able to move. We want the player to be able to attack. We want the player to be able to get hit. So:
  • Move
  • Attack
  • Get hit
  • Die
The first one is the easiest, movement. Just create a new GameObject, this can be anything from a cube to a sprite, and stick some code on there. Just remember to replace the colldier with a 2D one if it doesn't already have one as we'll be writing the code based on 2D colliders and physics.

We'll have the player move by using Unity's 2D physics, this will make it easier to do fun stuff when interacting with other objects and will feel nicer for the player to move.

Character.cs:

using UnityEngine;
using System.Collections;

public class Character : MonoBehaviour 
{
 public float moveForce; // Amount of force added to move the player.
 public float rotForce; // Amount of force added to rotate the player.
 [SerializeField] private Animation anim; // Reference to the player's animator component.
 private Rigidbody2D myRigidbody; // Reference to the player's rigidbody component.
 private AudioSource audioSource; // Reference to the player's audiosource component.

 // Use this for initialization
 void Start () 
 {
  myRigidbody = GetComponent();
  audioSource = GetComponent();
 }
 
 // Update is called once per frame
 void Update () 
 {
  Move ();
 }

 void Move ()
 {
  // Cache the horizontal input.
  float h = Input.GetAxis("Horizontal");
  
  // Cache the vertical input.
  float v = Input.GetAxis("Vertical");
  
  // Cache the turn input.
  float r = Input.GetAxis("Turn");
  
  // Call the animation function.
  //Animate(h,v,r); // This is not necesarry unless you want to animate the character. Preferably using Mecanim ofcourse!
  
  // Rotate the player.
  transform.Rotate(Vector3.forward,r * rotForce);

  // Just to make it easier in case you want to do other things while moving. This way the AddForce isn't called when there is no input. You can also use this to give a minimum value required before the player starts moving
  if(Mathf.Abs(h) > 0)
  {
   // ... add a force to the player.
   myRigidbody.AddForce(transform.right * h * moveForce);
  }
  
  // Just to make it easier in case you want to do other things while moving. This way the AddForce isn't called when there is no input. You can also use this to give a minimum value required before the player starts moving!
  if(Mathf.Abs(v) > 0)
  {
   // ... add a force to the player.
   myRigidbody.AddForce(transform.up * v * moveForce);
  }
 }
//


Don't forget to add the correct inputs to your game!

Now you should have a functioning main character! Note that you can change everything to your liking, this tutorial is just to give a you general idea of how you could make a top down dungeon crawler.

Now, let's start with setting up the combat. First of all, the player should be able to get hit by enemies, projectiles and the like.

// Getting Hit
 public bool hitInvul, alive;
 public float health;
 [SerializeField] private float hitInvulTime;
 private float currentInvulTime;

 public void Damage (int damage, Vector3 damager)
 {
  if (!hitInvul && alive)
  {
   Knockback(damager);
   hitInvul = true;
   currentInvulTime = Time.time + hitInvulTime;
   health -= damage;
  }
 }


If you want to add a little more "umph" to getting hit you can also add knockback. Here's an example of the knockback I used.

// Knockback
[SerializeField] private float knockbackForce

private void Knockback(Vector3 damager)
 {
  Vector2 direction = new Vector2 (damager.x - transform.position.x,damager.y - transform.position.y);
  myRigidbody.AddForce(direction * -knockbackForce,ForceMode2D.Impulse);
 }


As the player is now able to get hit, we can also kill him! Let's do that right now!

// Dying
 [SerializeField] private AudioClip deathSound;

 public void Death ()
 {
  alive = false;

  // If you want to give the player dying a special sound effect.
  audioSource.clip = deathSound;
  audioSource.Play();
 }

if (alive)
  {
   if (health <= 0)
   {
    Death();
   }

   if (hitInvul)
   {
    if (currentInvulTime <= Time.time)
    {
     hitInvul = false;
    }
   }
  }


As attacking is a little more complicated, let's continue with that part in another post. As for now, you have a basic character for games without combat! Have fun!

Geen opmerkingen:

Een reactie posten