Wednesday, October 24, 2018

2D Platformer Character 3 / 4 - Win and Lose

This time, we are going to make a real game out of our little 2D cat project. First, lets enable player to lose our game by touching 'bad' platforms. We need a way to tell our scripts which platform we hit. There are many ways to do it, simplest is to create a Tag, lets call it 'Kill', and then assign it to every object that we want to cause player death.

Duplicate platform we have in the scene, change its color to red so it looks differently (or you can just use different bitmap if you have one). It's good idea to rename it too, for example to 'kill block'. When it's done, create new Tag 'Kill' and assign it to our new platform. Next, add these two methods to the PlyerCat.cs script
// What should happen if we collide with anything
private void OnCollisionEnter2D(Collision2D collision)
{
    // If we touched object with a 'Kill' Tag
    if (collision.collider.CompareTag("Kill"))
    {
        // Disable player GameObject
        gameObject.SetActive(false);
 
        // Restart after one second
        Invoke("Restart", 1);
    }
}
 
// Handy method for restarting current scene
private void Restart()
{
    SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
If Visual Studio haven't done it for you, add this clause at the beginning of the PlayerCat.cs script:
using UnityEngine.SceneManagement;
Now when you touch red platform, game should restart after one second.

Before we'll enable player to win our game, let's make more platforms. It's good idea to make prefab out of everything we are going to use multiple times in our scene. That way, if we'll need to change anything later, it will be enough to change one prefab, and every object created out of it will update automatically. Create prefab out of our block by dragging it from scene into Assets window. Now we can finally create more platforms to make our level more interesting. If you try to play now, you will notice that player has tendency to 'stick' to platforms sides. That's because platforms have friction, we need to disable it from sides. Select your platform prefab, add Platform Effector 2D and set everything like in following screenshot. That should prevent player from sticking to the sides.

Let's enable player to win our game! Like before, make another platform, change its color to green, create and assign 'Victory' Tag to it, and change it's name to 'victory block'. Let's also create some kind of victory screen so player knows they actually won. I just made simple sign for it by using www.textfx.co generator. When you put it in the scene, make sure to set 'Order in Layer' to some big number (like 100), that way it will be always displayed in front of everything. Now lets change PlayerCat.cs script to show our victory sign when player touches platform with 'Victory' Tag, and restart the game after 5 seconds.
using UnityEngine;
using UnityEngine.SceneManagement;
 
public class PlayerCat : MonoBehaviour
{
    // How strong force to apply for sidewise movement
    public float movementForce = 15;
 
    // How strong force to apply for jump
    public float jumpForce = 5;
 
    // Where should we check for ground
    public Transform groundCheck;
 
    // Are we standing on the ground?
    private bool grounded;
 
    // Victory Screen
    public GameObject victoryScreen;
 
    // References for various components to use later
    private SpriteRenderer sr;
    private Rigidbody2D rb;
    private Animator anim;
 
    // Use this for initialization
    void Start()
    {
        // Find our components
        sr = GetComponent<SpriteRenderer>();
        rb = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
 
        // Disable it initially
        victoryScreen.SetActive(false);
    }
 
    // Update is called once per frame
    void Update()
    {
        // Lets see if we are standing on something
        grounded = Physics2D.OverlapPoint(groundCheck.position) != null;
 
        // Jump only when we are grounded
        if (Input.GetButtonDown("Jump") && grounded)
        {
            anim.SetTrigger("Jump");
            rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
        }
 
        // Set Speed parameter to absolute value of our horizontal speed
        anim.SetFloat("Speed"Mathf.Abs(rb.velocity.x));
 
        // Set Grounded animator parameter
        anim.SetBool("Grounded", grounded);
    }
 
    // FixedUpdate is called every Time.fixedDeltaTime
    void FixedUpdate()
    {
        // Get value of horizontal axis (left/right arrow or a/d keys),
        // returns value in range [-1.0f, 1.0f]
        var h = Input.GetAxis("Horizontal");
 
        // Flip sprite depending on horizontal input
        if (h < 0.0f)
            sr.flipX = true;
        if (h > 0.0f)
            sr.flipX = false;
 
        // Move player according to horizontal axis
        rb.AddForce(Vector2.right * h * movementForce, ForceMode2D.Force);
    }
 
    // What should happen if we collide with anything
    private void OnCollisionEnter2D(Collision2D collision)
    {
        // If we touched object with a 'Kill' Tag
        if (collision.collider.CompareTag("Kill"))
        {
            // Disable player GameObject
            gameObject.SetActive(false);
 
            // Restart after one second
            Invoke("Restart", 1);
        }
 
        // If we touched object with a 'Victory' Tag
        if (collision.collider.CompareTag("Victory"))
        {
            // Stop player from moving
            rb.simulated = false;
            rb.velocity = Vector2.zero;
 
            // Show victory screen
            victoryScreen.SetActive(true);
 
            // Restart after five seconds
            Invoke("Restart", 5);
        }
    }
 
    // Handy method for restarting current scene
    private void Restart()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }
}
We still need to tell PlayerCat script where is our victory sign. Select our cat character, and then drag victory sign to 'Victory Screen' property of PlayerCat script. Congratulation, you now have fully functional game :3

No comments:

Post a Comment