{"id":524,"date":"2019-11-30T14:49:51","date_gmt":"2019-11-30T14:49:51","guid":{"rendered":"https:\/\/www.danielparente.net\/en\/2019\/11\/30\/2d-platformer-character-controller-sharp-coder\/"},"modified":"2019-11-30T14:49:51","modified_gmt":"2019-11-30T14:49:51","slug":"2d-platformer-character-controller-sharp-coder","status":"publish","type":"post","link":"https:\/\/www.danielparente.net\/en\/2019\/11\/30\/2d-platformer-character-controller-sharp-coder\/","title":{"rendered":"2D Platformer Character Controller &#8211; Sharp Coder"},"content":{"rendered":"<p> [ad_1]<br \/>\n<\/p>\n<div id=\"item-body-wrapper\">\n<p>In this post I will be showing how to make a Character Controller for 2D Platformer using Physics 2D components in <a href=\"http:\/\/prf.hn\/click\/camref:1011l4LKS\/destination:https:\/\/store.unity.com\/products\/unity-plus\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Unity<\/a>. The controller will handle movement, jumping and Camera follow.<\/p>\n<p><strong>So let&#8217;s begin!<\/strong><\/p>\n<h2>Steps<\/h2>\n<ul>\n<li>Open Scene with your 2D level (Make sure that sprites have 2D colliders attached so the player won&#8217;t fall throug them)<\/li>\n<p>&#13;<\/p>\n<li>Create new Game Object and call it &#8220;Player&#8221;<\/li>\n<p>&#13;<\/p>\n<li>Create another Game Object, call it &#8220;player_sprite&#8221; and add Sprite Renderer component to it<\/li>\n<p>&#13;<\/p>\n<li>Assign your sprite and move &#8220;player_sprite&#8221; inside the &#8220;Player&#8221; Object<\/li>\n<p>&#13;\n<\/ul>\n<p><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/sharpcoderblog.com\/public\/images\/130\/1309e5931321fa48a1a4d9da68926f82.png\" alt=\"\" width=\"327\" height=\"330\"\/><\/p>\n<ul>\n<li>Create new script, call it &#8220;CharacterController2D&#8221; and paste the code below inside it:<\/li>\n<p>&#13;\n<\/ul>\n<p><strong>CharacterController2D.cs<\/strong><\/p>\n<pre class=\"language-csharp\"><code>using System.Collections;&#13;\nusing System.Collections.Generic;&#13;\nusing UnityEngine;&#13;\n&#13;\n[RequireComponent(typeof(Rigidbody2D))]&#13;\n[RequireComponent(typeof(CapsuleCollider2D))]&#13;\n&#13;\npublic class CharacterController2D : MonoBehaviour&#13;\n{&#13;\n    \/\/ Move player in 2D space&#13;\n    public float maxSpeed = 3.4f;&#13;\n    public float jumpHeight = 6.5f;&#13;\n    public float gravityScale = 1.5f;&#13;\n    public Camera mainCamera;&#13;\n&#13;\n    bool facingRight = true;&#13;\n    float moveDirection = 0;&#13;\n    bool isGrounded = false;&#13;\n    Vector3 cameraPos;&#13;\n    Rigidbody2D r2d;&#13;\n    Collider2D mainCollider;&#13;\n    \/\/ Check every collider except Player and Ignore Raycast&#13;\n    LayerMask layerMask = ~(1 &lt;&lt; 2 | 1 &lt;&lt; 8);&#13;\n    Transform t;&#13;\n&#13;\n    \/\/ Use this for initialization&#13;\n    void Start()&#13;\n    {&#13;\n        t = transform;&#13;\n        r2d = GetComponent&lt;Rigidbody2D&gt;();&#13;\n        mainCollider = GetComponent&lt;Collider2D&gt;();&#13;\n        r2d.freezeRotation = true;&#13;\n        r2d.collisionDetectionMode = CollisionDetectionMode2D.Continuous;&#13;\n        r2d.gravityScale = gravityScale;&#13;\n        facingRight = t.localScale.x &gt; 0;&#13;\n        gameObject.layer = 8;&#13;\n&#13;\n        if(mainCamera)&#13;\n            cameraPos = mainCamera.transform.position;&#13;\n    }&#13;\n&#13;\n    \/\/ Update is called once per frame&#13;\n    void Update()&#13;\n    {&#13;\n        \/\/ Movement controls&#13;\n        if ((Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.D)) &amp;&amp; (isGrounded || r2d.velocity.x &gt; 0.01f))&#13;\n        {&#13;\n            moveDirection = Input.GetKey(KeyCode.A) ? -1 : 1;&#13;\n        }&#13;\n        else&#13;\n        {&#13;\n            if (isGrounded || r2d.velocity.magnitude &lt; 0.01f)&#13;\n            {&#13;\n                moveDirection = 0;&#13;\n            }   &#13;\n        }&#13;\n&#13;\n        \/\/ Change facing direction&#13;\n        if (moveDirection != 0)&#13;\n        {&#13;\n            if (moveDirection &gt; 0 &amp;&amp; !facingRight)&#13;\n            {&#13;\n                facingRight = true;&#13;\n                t.localScale = new Vector3(Mathf.Abs(t.localScale.x), t.localScale.y, transform.localScale.z);&#13;\n            }&#13;\n            if (moveDirection &lt; 0 &amp;&amp; facingRight)&#13;\n            {&#13;\n                facingRight = false;&#13;\n                t.localScale = new Vector3(-Mathf.Abs(t.localScale.x), t.localScale.y, t.localScale.z);&#13;\n            }&#13;\n        }&#13;\n&#13;\n        \/\/ Jumping&#13;\n        if (Input.GetKeyDown(KeyCode.W) &amp;&amp; isGrounded)&#13;\n        {&#13;\n            r2d.velocity = new Vector2(r2d.velocity.x, jumpHeight);&#13;\n        }&#13;\n&#13;\n        \/\/ Camera follow&#13;\n        if(mainCamera)&#13;\n            mainCamera.transform.position = new Vector3(t.position.x, cameraPos.y, cameraPos.z);&#13;\n    }&#13;\n&#13;\n    void FixedUpdate()&#13;\n    {&#13;\n        Bounds colliderBounds = mainCollider.bounds;&#13;\n        Vector3 groundCheckPos = colliderBounds.min + new Vector3(colliderBounds.size.x * 0.5f, 0.1f, 0);&#13;\n        \/\/ Check if player is grounded&#13;\n        isGrounded = Physics2D.OverlapCircle(groundCheckPos, 0.23f, layerMask);&#13;\n&#13;\n        \/\/ Apply movement velocity&#13;\n        r2d.velocity = new Vector2((moveDirection) * maxSpeed, r2d.velocity.y);&#13;\n&#13;\n        \/\/ Simple debug&#13;\n        Debug.DrawLine(groundCheckPos, groundCheckPos - new Vector3(0, 0.23f, 0), isGrounded ? Color.green : Color.red);&#13;\n    }&#13;\n}<\/code><\/pre>\n<ul>\n<li>Attach CharacterController2D script to &#8220;Player&#8221; Object (You&#8217;ll notice it also added other components called Rigidbody2D and CapsuleCollider2D)<\/li>\n<p>&#13;<\/p>\n<li>Tweak Capsule Collider 2D dimensions until they match the player Sprite<\/li>\n<p>&#13;\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/sharpcoderblog.com\/public\/images\/898\/898222dbc9206e60104a67fb19b250f2.png\" alt=\"\" width=\"329\" height=\"327\"\/><\/p>\n<p>In CharacterController2D you have an option to assign the Main Camera variable which could be any Camera that will follow the player:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/sharpcoderblog.com\/public\/images\/fd7\/fd74c82ff42e0edafff7ee247032452e.png\" alt=\"\" width=\"342\" height=\"110\"\/><\/p>\n<p>The 2D Character Controller is now ready!<\/p>\n<\/p><\/div>\n<p>[ad_2]<br \/>\n<br \/><a href=\"https:\/\/sharpcoderblog.com\/blog\/2d-platformer-character-controller\" target=\"_blank\" rel=\"noopener\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>[ad_1] In this post I will be showing how to make a Character Controller for 2D Platformer using Physics 2D components in Unity. The controller will handle movement, jumping and Camera follow. So let&#8217;s begin! Steps Open Scene with your 2D level (Make sure that sprites have 2D colliders attached so the player won&#8217;t fall [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":525,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","jetpack_post_was_ever_published":false},"categories":[1],"tags":[],"class_list":["post-524","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"blocksy_meta":[],"jetpack_featured_media_url":"https:\/\/e928cfdc7rs.exactdn.com\/info\/uploads\/sites\/3\/2019\/11\/2D-Platformer-Character-Controller-Sharp-Coder-scaled.jpg?strip=all","jetpack_shortlink":"https:\/\/wp.me\/p2TFCd-8s","jetpack_sharing_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/posts\/524","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/comments?post=524"}],"version-history":[{"count":0,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/posts\/524\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/media\/525"}],"wp:attachment":[{"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/media?parent=524"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/categories?post=524"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/tags?post=524"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}