Horizontal Movement

Vérifié avec version: 5.6

-

Difficulté: Intermédiaire

In this live training session we will learn how to create a character controller for a 2D platform game which uses custom physics instead of Unity’s built in 2D Physics.

Horizontal Movement

Intermédiaire 2D Game Creation

Download the asset package here

PhysicsObject

Code snippet

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PhysicsObject : MonoBehaviour {

    public float minGroundNormalY = .65f;
    public float gravityModifier = 1f;

    protected Vector2 targetVelocity;
    protected bool grounded;
    protected Vector2 groundNormal;
    protected Rigidbody2D rb2d;
    protected Vector2 velocity;
    protected ContactFilter2D contactFilter;
    protected RaycastHit2D[] hitBuffer = new RaycastHit2D[16];
    protected List<RaycastHit2D> hitBufferList = new List<RaycastHit2D> (16);


    protected const float minMoveDistance = 0.001f;
    protected const float shellRadius = 0.01f;

    void OnEnable()
    {
        rb2d = GetComponent<Rigidbody2D> ();
    }

    void Start () 
    {
        contactFilter.useTriggers = false;
        contactFilter.SetLayerMask (Physics2D.GetLayerCollisionMask (gameObject.layer));
        contactFilter.useLayerMask = true;
    }
    
    void Update () 
    {
        targetVelocity = Vector2.zero;
        ComputeVelocity (); 
    }

    protected virtual void ComputeVelocity()
    {
    
    }

    void FixedUpdate()
    {
        velocity += gravityModifier * Physics2D.gravity * Time.deltaTime;
        velocity.x = targetVelocity.x;

        grounded = false;

        Vector2 deltaPosition = velocity * Time.deltaTime;

        Vector2 moveAlongGround = new Vector2 (groundNormal.y, -groundNormal.x);

        Vector2 move = moveAlongGround * deltaPosition.x;

        Movement (move, false);

        move = Vector2.up * deltaPosition.y;

        Movement (move, true);
    }

    void Movement(Vector2 move, bool yMovement)
    {
        float distance = move.magnitude;

        if (distance > minMoveDistance) 
        {
            int count = rb2d.Cast (move, contactFilter, hitBuffer, distance + shellRadius);
            hitBufferList.Clear ();
            for (int i = 0; i < count; i++) {
                hitBufferList.Add (hitBuffer [i]);
            }

            for (int i = 0; i < hitBufferList.Count; i++) 
            {
                Vector2 currentNormal = hitBufferList [i].normal;
                if (currentNormal.y > minGroundNormalY) 
                {
                    grounded = true;
                    if (yMovement) 
                    {
                        groundNormal = currentNormal;
                        currentNormal.x = 0;
                    }
                }

                float projection = Vector2.Dot (velocity, currentNormal);
                if (projection < 0) 
                {
                    velocity = velocity - projection * currentNormal;
                }

                float modifiedDistance = hitBufferList [i].distance - shellRadius;
                distance = modifiedDistance < distance ? modifiedDistance : distance;
            }


        }

        rb2d.position = rb2d.position + move.normalized * distance;
    }

}

PlayerPlatformerController

Code snippet

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerPlatformerController : PhysicsObject {

    public float maxSpeed = 7;
    public float jumpTakeOffSpeed = 7;

    private SpriteRenderer spriteRenderer;
    private Animator animator;

    // Use this for initialization
    void Awake () 
    {
        spriteRenderer = GetComponent<SpriteRenderer> (); 
        animator = GetComponent<Animator> ();
    }

    protected override void ComputeVelocity()
    {
        Vector2 move = Vector2.zero;

        move.x = Input.GetAxis ("Horizontal");

        if (Input.GetButtonDown ("Jump") && grounded) {
            velocity.y = jumpTakeOffSpeed;
        } else if (Input.GetButtonUp ("Jump")) 
        {
            if (velocity.y > 0) {
                velocity.y = velocity.y * 0.5f;
            }
        }

        bool flipSprite = (spriteRenderer.flipX ? (move.x > 0.01f) : (move.x < 0.01f));
        if (flipSprite) 
        {
            spriteRenderer.flipX = !spriteRenderer.flipX;
        }

        animator.SetBool ("grounded", grounded);
        animator.SetFloat ("velocityX", Mathf.Abs (velocity.x) / maxSpeed);

        targetVelocity = move * maxSpeed;
    }
}

2D Game Creation

  1. 2D Game Development Walkthrough
  2. 2D Mode
  3. The Sprite Type
  4. Sprite Renderer
  5. The Sprite Editor
  6. Sorting Layers
  1. 2D Physics Overview
  2. Rigidbody 2D
  3. Collider 2D
  4. Hinge Joint 2D
  5. Area Effector 2D
  6. Distance Joint 2D
  7. Point Effector 2D
  8. Bouncing & Sliding in 2D
  1. Introduction to Unity from a 2D perspective
  2. 2D Character Controllers
  3. 2D Catch Game - Pt 1
  4. 2D Catch Game - Pt 2
  5. 2D Catch Game - Pt 3
  6. 2D Catch Game - Q&A / AMA
  7. 2D Scrolling Backgrounds
  8. Top Down 2D Game Basics
  9. 2D Physics: Fun with Effectors
  10. Making an "Angry Birds" style game - Part 1
  11. Making an "Angry Birds" style game - Part 2
  12. 2D Games for Non-Programmers
  1. Project Goals
  2. Adding Sprites
  3. The Bird Script
  4. Animating The Bird
  5. Score and GameOver UI Setup
  6. Adding The Game Controller
  7. Scrolling Repeating Backgrounds
  8. Adding Column Obstacles
  9. Recycling Obstacles With Object Pooling
  10. Questions and Answers
  1. Intro and Session Goals
  2. Scripting Gravity
  3. Detecting Overlaps
  4. Scripting Collision
  5. Horizontal Movement
  6. Player Controller Script
  7. Adding Player Animation
  8. Questions and Answers
  1. Introduction and Goals
  2. Sorting Layers and 9-Slice Sprites
  3. 2D Composite and Capsule Colliders
  4. Sorting Groups and Transparency Sort Axis
  5. 2D Physics Reference Project
  6. Questions and Answers
  1. Introduction to 2D Essentials
  2. 2D Character Setup with Corgi Engine
  3. 2D Follow Camera w/ Cinemachine
  4. Adding Enemies with Corgi Engine
  5. 2D Lighting with 2DDL Pro
  6. Tween Effects with DOTween Pro
  7. Easy UI with Doozy UI
  8. Questions and Answers for 2D Essentials
  1. Intro to 2D World building w/ Tilemap
  2. Core Tilemap Concepts
  3. Tilemap Collider 2D and Composite Collider 2D
  4. Confined Follow Camera with Cinemachine For 2D
  5. Using Rule Tiles With Tilemap
  6. Random and Animated Tilemap Tiles
  7. Custom Tilemap Brush To Spawn Prefabs
  8. Questions and Answers for 2D Worldbuilding
  1. Getting Started with SVG Importer