๐ ์ ๋ํฐ ํจํค์ง ํ์ผ ์์ฑ ๋ฐฉ๋ฒ
- ์ ๋ํฐ ํจํค์ง ํ์ผ : ์ํ๋ ํ์ผ๋ค์ ํ๋๋ก ๋ฌถ์ด ๋ค๋ฅธ ํ๋ก์ ํธ๋ก ์ ๋ฌํ ๋ ์ฌ์ฉ
- ํจํค์ง ํ์ผ ์์ฑํ๊ธฐ : Project View์์ ์ํ๋ ํ์ผ๋ค์ ์ ํํ ํ ๋ง์ฐ์ค ์ค๋ฅธ์ชฝ ํด๋ฆญ - Export Package๋ก ์ ์ฅ
- ํจํค์ง ํ์ผ ์ฌ์ฉํ๊ธฐ : ํ์ผ์ ์ ์ฉํ๊ณ ์ถ์ ํ๋ก์ ํธ์ Project View๋ก ํจํค์ง ํ์ผ์ Drag & Drop
์์ ๊ฐ์์์ ์ ๊ณตํด์ค ์ ๋ํฐ ํจํค์ง ํ์ผ์ ๋ค์ด๋ก๋ ๋ฐ๊ณ ์ ๋ํฐ ํ๋ก์ ํธ์ ๋ฃ์ด์ค๋ค.
์ด๋, ์ ๋ํฐ ํจํค์ง ํ์ผ์ ๊ฒฝ์ฐ ํ์ฅ์ ๋ช ์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ .unitypackage๋ก ๋ณ๊ฒฝํด์ฃผ์ด์ผ ํ๋ค. ์ด๋ฅผ ๋ณ๊ฒฝํด์ฃผ์ง ์์์ ํจํค์ง ํ์ผ์ด ์๊ฒจ๋์ง ์์ ๊ณ์ ์ค๋ฅ๊ฐ ์๊ฒผ๋ค...
๋ค์์ผ๋ก ํ๋ ์ด์ด๋ฅผ ์ค์ ํด์ฃผ์ด์ผ ํ๋ค.
Player ์ค๋ธ์ ํธ๋ฅผ ๋ฃ์ด์ฃผ๊ณ ํด๋น ์ค๋ธ์ ํธ์ ์ค๋ ฅ์ ๋ฐ์ ์ ์๋๋ก Rigidbody 2D ์ปดํฌ๋ํธ๋ฅผ ์ค์ ํด์ฃผ๊ณ Z์ถ์ผ๋ก ํ์ ํ์ง ์๋๋ก Contraints ์ต์ ์์ Freeze Rotation๋ถ๋ถ์ Z์ ์ฒดํฌํ์๋ฅผ ํด๋ฆญํด์ฃผ์๋ค.
๊ทธ๋ฆฌ๊ณ ์์ ๊ฐ์ด 'Capsule Collider 2D'๋ฅผ ์ค์ ํด์ฃผ๋ฉด ๊ฒ์์ ์คํํ์ ๋, ํ๋ ์ด์ด ์ค๋ธ์ ํธ๊ฐ ์ถฉ๋์ฒ๋ฆฌ ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
01 ํ๋ ์ด์ด ์ค๋ธ์ ํธ ์ด๋
ํ๋ ์ด์ด ์ค๋ธ์ ํธ ์ด๋์ ์ ์ดํ๋ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ๊ณ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํด์ฃผ์๋ค.
๋ค์์ผ๋ก ํ๋ ์ด์ด๋ฅผ ์ ์ดํ๋ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ๊ณ ์๋์ ๊ฐ์ด ์์ฑํด์ค ์ ์๋ค.
์ด๋ ๊ฒ ์์ฑํ ์คํฌ๋ฆฝํธ๋ฅผ ํ๋ ์ด์ด ์ค๋ธ์ ํธ์ ๋ฃ์ด์ฃผ๊ณ ์คํ์ ํ๋ฉด, ์๋ ์์๊ณผ ๊ฐ์ด ์ค๋ ฅ์ ๋ฐ์ ์๋๋ก ๋จ์ด์ง๊ณ , ์ถฉ๋์ฒ๋ฆฌ๊ฐ ๋ ์ดํ, ์ข์ฐ ๋ฐฉํฅํค๋ฅผ ๋๋ฅด๋ฉด ํ๋ ์ด์ด๊ฐ ์ด๋ํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
02 ํ๋ ์ด์ด ์ค๋ธ์ ํธ ์ ํ
์ค๋ธ์ ํธ ๊ธฐ๋ณธ ์ ํ๋ฅผ ์ํด ์ ํ ํ๋งํผ y์ถ ๋ฐฉํฅ์ผ๋ก ๋ฐ์ด์ฃผ๋ Jump() ๋ฉ์๋๋ฅผ ์์ฑํ์ฌ ์๋์ ๊ฐ์ด ์ฝ๋๋ฅผ ์ถ๊ฐํด์ฃผ์๋ค.
์ดํ PlayerController ํด๋์ค์์ ํ๋ ์ด์ด๊ฐ ์คํ์ด์ค ํค๋ฅผ ๋๋ ์ ๋ ํธ์ถ๋๋๋ก ์ค์ ํ์๋ค.
์ ์ฉํ ์ฝ๋๋ฅผ ์ ์ฅํ๊ณ ๊ฒ์์ ์คํํ๋ฉด ์์ ๊ฐ์ด ์คํ์ด์ค ํค๋ฅผ ๋๋ฅด๋ฉด JumpForce ๊ฐ ๋งํผ ํ๋ ์ด์ด ์ค๋ธ์ ํธ๊ฐ ์ ํํ๋ ๊ฒ์ ๋ณผ ์ ์์๋ค.
03 ๋ฎ์ ์ ํ, ๋์ ์ ํ
๋ฎ์ ์ ํ, ๋์ ์ ํ ๊ตฌํ์ ์ํ ์ค๋ ฅ ๊ณ์๋ฅผ ์ ์ดํ๊ธฐ ์ํด ์๋์ ๊ฐ์ด Movement2D.cs ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ์์ฑํด์ฃผ์๋ค.
๐ rigid2D.gravityScale : ์ค๋ ฅ ๊ณ์
- ํ๋ ์ด์ด์๊ฒ ๊ฐํด์ง๋ ์ค๋ ฅ์ (0, -9.81, 0) * gravityScale
- gravityScale์ด 1์ด๋ฉด transform.position += (0, -9.81, 0)์ ์ฐ์ฐ ์ถ๊ฐ
- gravityScale์ด 2.5์ด๋ฉด transform.position += (0, -24.525, 0)์ ์ฐ์ฐ ์ถ๊ฐ
๋ค์์ผ๋ก ์ ํ ํค๋ฅผ ๋๋ฅด๊ณ ์์ ๋์ ๋๋ฅด์ง ์์ ๋๋ฅผ ์ค์ ํด์ฃผ๊ธฐ ์ํด PlayerController ์คํฌ๋ฆฝํธ๋ฅผ ์๋์ ๊ฐ์ด ์์ ํด์ค ์ ์๋ค.
์ด๋ ๊ฒ ์์ฑํ ์ฝ๋๋ฅผ ์ ์ฅํ๊ณ ๊ฒ์์ ์คํ์์ผ ๋ณด๋ฉด, ์๋ ์์๊ณผ ๊ฐ์ด ์คํ์ด์ค๋ฅผ ๊ธธ๊ฒ ๋๋ ์ ๋๋ ๋ ์๋ก ์ฌ๋ผ์ค๊ณ ์งง๊ฒ ๋๋ ์ ๋๋ ์ ํ๊ฐ ์๊ฒ ๋๋ ๊ฒ์ ํ์ธํ ์ ์์๋ค.
โถ ์ ํ์ ๊ธธ์ด์ ๋ฐ๋ผ Gravity Scale์ ํ์ธํด๋ณด๋ฉด ๊ฐ๊ฐ 2.5์ 1๋ก ๋ณํํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
04 ๋ฐ๋ฅ ํ์ ๋ฐ ์ ํ ์ ์ด
๐ ์ ๋ํฐ Layer์ ์ญํ (๋ณ์ ํ์ LayerMask)
- ์ค๋ธ์ ํธ๊ฐ ๊ทธ๋ ค์ง๋ ์์๋ฅผ ์ค์ ํ ์ ์๋ค.
- ์ค๋ธ์ ํธ ์ถฉ๋์์ ์ง์ ํ ๋ ์ด์ด์์ ์ถฉ๋์ ์ ์ธํ ์ ์๋ค.
โถ Tip. Edit - Project Settings - Physics of Physics 2D์์ ๋ ์ด์ด๋ผ๋ฆฌ์ Collider ์ถฉ๋ ์ฒ๋ฆฌ๋ฅผ ์ค์ ํ ์ ์๋ค.
ํ๋ ์ด์ด์ ๋ฐ์ด ๋ฐ๋ฅ์ ๋ถ์ด์๋์ง ํ๋จํ๊ธฐ ์ํด ์๋์ ๊ฐ์ด Movement2D ์คํฌ๋ฆฝํธ๋ฅผ ์์ ํ์๋ค.
๐ Movement2D.cs
using UnityEngine; public class Movement2D : MonoBehaviour { [SerializeField] private float speed = 5.0f; // ์ด๋ ์๋ [SerializeField] private float jumpForce = 8.0f; // ์ ํ ํ private Rigidbody2D rigid2D; [HideInInspector] public bool isLongJump; // ๋ฎ์ ์ ํ, ๋์ ์ ํ ์ฒดํฌ [SerializeField] private LayerMask groundLayer; // ๋ฐ๋ฅ ์ฒดํฌ๋ฅผ ์ํ ์ถฉ๋ ๋ ์ด์ด private CapsuleCollider2D capsuleCollider2D; // ์ค๋ธ์ ํธ์ ์ถฉ๋ ๋ฒ์ ์ปดํฌ๋ํธ private bool isGrounded; // ๋ฐ๋ฅ ์ฒดํฌ (๋ฐ๋ฅ์ ๋ฟ์์์ ๋ true) private Vector3 footPosition; // ๋ฐ์ ์์น private void Awake() { rigid2D = GetComponent<Rigidbody2D>(); capsuleCollider2D = GetComponent<CapsuleCollider2D>(); } private void FixedUpdate() { Bounds bounds = capsuleCollider2D.bounds; // ํ๋ ์ด์ด ์ค๋ธ์ ํธ์ Collider2D min, ceneter, max ์์น ์ ๋ณด footPosition = new Vector2(bounds.center.x, bounds.min.y); // ํ๋ ์ด์ด์ ๋ฐ ์์น ์ค์ isGrounded = Physics2D.OverlapCircle(footPosition, 0.1f, groundLayer); if (isLongJump && rigid2D.velocity.y > 0) { rigid2D.gravityScale = 1.0f; } else { rigid2D.gravityScale = 2.5f; } } private void OnDrawGizmos() { Gizmos.color = Color.blue; Gizmos.DrawSphere(footPosition, 0.1f); } public void Move(float x) { rigid2D.velocity = new Vector2(x * speed, rigid2D.velocity.y); } public void Jump() { if (isGrounded == true) { rigid2D.velocity = Vector2.up * jumpForce; } } }โ
โถ OnDrawGizmos() ๋ฉ์๋
Unity Event Functions์ผ๋ก Scene View์๋ง ๋ณด์ด๋ ์ , ๋ํ ๋ฑ์ ๊ทธ๋ฆด ๋ ์ฌ์ฉํ๋ค. (Gizmos์ ์๋ ๋ณ์, ๋ฉ์๋๋ฅผ ์ด์ฉํ๋ค) ์ฆ, ํ๋ฉด์ ๋ณด์ด์ง ์๋ ์ถฉ๋ ๋ฒ์์ ๊ฐ์ ๊ฒ๋ค์ ๋ด๊ฐ ์ํ๋ ์์น์ ์ ๋ฐฐ์นํ๋์ง ํ์ธํ๊ณ ์ถ์ ๋, ์ , ์ฌ๊ฐํ, ์ ๋ค์ ๊ทธ๋ ค์ ํ์ธํ๋ ์ฉ๋๋ก ์ฌ์ฉ๋๋ค.
์ฝ๋ ์์ ํ, ๊ฒ์ ์คํ์ ์์ ๋ฐ๋ฅ ์ค๋ธ์ ํธ์ ์ถฉ๋ ์ฒ๋ฆฌ๋ฅผ ์ํ Layer ์์ฑ ๋ฐ ์ค์ ์ ํด์ฃผ์ด์ผ ํ๋ค.
๋ ์ ๊ตฌ๋ถํ๊ธฐ ์ํ Ground Layer๋ฅผ ์์ฑํ๊ณ
๋ ์ผ๋ก ์ฌ์ฉ๋๊ณ ์๋ ์ฆ, ํ๋ ์ด์ด๊ฐ ๋ฐ์ ์ ์๋ ๋ชจ๋ ์ค๋ธ์ ํธ์ Layer๋ฅผ Ground๋ก ๋ณ๊ฒฝํด์ฃผ์ด์ผ ํ๋ค.
๊ทธ๋ฆฌ๊ณ Payer ์ค๋ธ์ ํธ์ Movement2D ์ปดํฌ๋ํธ์ Ground Layer๋ฅผ Ground๋ก ์ค์ ํด์ฃผ์ด์ผ ํ๋ค.
์ค์ ์ด ์๋ฃ๋ ์ดํ, ๊ฒ์์ ์คํํ๋ฉด ์๋ฌด๋ฆฌ ์คํ์ด์ค๋ฐ๋ฅผ ์ฌ๋ฌ๋ฒ ๋๋ฌ๋ ์ ํ๊ฐ ๋ ํฌ๊ฒ ๋์ง ์๊ณ ๊ฐ์ ํฌ๊ธฐ๋งํผ ์ ํ๊ฐ ๋๋ ๊ฒ์ ๋ณผ ์ ์์๋ค. ์ฆ, ๋ ์ ๋ฟ์ ์์ ๋ ํ๋ฒ๋ง ์ ํ๊ฐ ๊ฐ๋ฅํ๋ค.
05 ์ต๋ ์ ํ ํ์ ์ค์
์ต๋ ์ ํ ํ์ ์ค์ ๋ฐ ๋ฐ๋ฅ์ ๋ฟ์ ์ ํ์๋ฅผ ์ด๊ธฐํํ๊ธฐ ์ํด ์๋์ ๊ฐ์ด Movement2D ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ์์ ํ ์ ์๋ค.
์ ํ ๊ฐ๋ฅ ํ์์ ๊ฒฝ์ฐ ํ๋ ์ด์ด๊ฐ ์ ํ ํค๋ฅผ ๋๋ฅผ ๋๋ง๋ค ์ ํ ๊ฐ๋ฅ ํ์๊ฐ 1์ฉ ์ค์ด๋ค๊ณ , 0์ด ๋๋ฉด ์ ํ๊ฐ ๋ถ๊ฐ๋ฅํ๋ฉฐ, ํ๋ ์ด์ด๊ฐ ๋ฐ๋ฅ์ ์ฐฉ์งํ๋ฉด ์ ํ ๊ฐ๋ฅ ํ์๊ฐ ๋ค์ ์ต๋์น๋ก ์ฑ์์ง๋ ๊ฒ์ ์๋ฏธํ๋ค.
๐ Movement2D.cs
using UnityEngine; public class Movement2D : MonoBehaviour { [SerializeField] private float speed = 5.0f; // ์ด๋ ์๋ [SerializeField] private float jumpForce = 8.0f; // ์ ํ ํ private Rigidbody2D rigid2D; [HideInInspector] public bool isLongJump; // ๋ฎ์ ์ ํ, ๋์ ์ ํ ์ฒดํฌ [SerializeField] private LayerMask groundLayer; // ๋ฐ๋ฅ ์ฒดํฌ๋ฅผ ์ํ ์ถฉ๋ ๋ ์ด์ด private CapsuleCollider2D capsuleCollider2D; // ์ค๋ธ์ ํธ์ ์ถฉ๋ ๋ฒ์ ์ปดํฌ๋ํธ private bool isGrounded; // ๋ฐ๋ฅ ์ฒดํฌ (๋ฐ๋ฅ์ ๋ฟ์์์ ๋ true) private Vector3 footPosition; // ๋ฐ์ ์์น [SerializeField] private int maxJumpCount = 2; private int currentJumpCount = 0; private void Awake() { rigid2D = GetComponent<Rigidbody2D>(); capsuleCollider2D = GetComponent<CapsuleCollider2D>(); } private void FixedUpdate() { Bounds bounds = capsuleCollider2D.bounds; // ํ๋ ์ด์ด ์ค๋ธ์ ํธ์ Collider2D min, ceneter, max ์์น ์ ๋ณด footPosition = new Vector2(bounds.center.x, bounds.min.y); // ํ๋ ์ด์ด์ ๋ฐ ์์น ์ค์ isGrounded = Physics2D.OverlapCircle(footPosition, 0.1f, groundLayer); if (isGrounded == true && rigid2D.velocity.y <= 0) { currentJumpCount = maxJumpCount; } if (isLongJump && rigid2D.velocity.y > 0) { rigid2D.gravityScale = 1.0f; } else { rigid2D.gravityScale = 2.5f; } } private void OnDrawGizmos() { Gizmos.color = Color.blue; Gizmos.DrawSphere(footPosition, 0.1f); } public void Move(float x) { rigid2D.velocity = new Vector2(x * speed, rigid2D.velocity.y); } public void Jump() { //if (isGrounded == true) if (currentJumpCount > 0) { rigid2D.velocity = Vector2.up * jumpForce; currentJumpCount --; } } }โ
โถ ์ฝ๋๋ฅผ ์์ฑํ ์ดํ, ๊ฒ์์ ์คํํด๋ณด๋ฉด ์ต๋ 2ํ๊น์ง ์ ํ๊ฐ ๊ฐ๋ฅํ ๊ฒ์ ํ์ธํ ์ ์๋ค.
06 ์ค๋ธ์ ํธ ๋ง์ฐฐ๋ ฅ ์ค์
ํ์ฌ ๊ฒ์์ ๊ฒฝ์ฐ ๋ง์ฐฐ๋ ฅ์ ์ํด ํ๋ ์ด์ด๊ฐ ๋ฒฝ๋ฉด์ ๋ถ์ด๋ฒ๋ฆฌ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ ์ด๋ฏธ์ง๋ ์ ํํ๋ค๊ฐ ๋ด๋ ค์ฌ ๋, ์๊ฐ์ ์ผ๋ก ์บก์ณํ ๊ฒ์ด ์๋ ์ค์ ๋ฐฉํฅํค๋ฅผ ์ด๋ํ ๊ณผ์ ์์ ๋ฒฝ๋ฉด์ ๋ถ์ด์๋ ๊ฒ์ ์บก์ณํ ์ด๋ฏธ์ง์ด๋ค.
๋ฐ๋ผ์, ๋ง์ฐฐ๋ ฅ ์ค์ ์ ํด์ฃผ์ด ๋ฒฝ์ ๋ถ๋ชํ์ ๋ ๋ฏธ๋๋ฌ์ง๊ฒ ๋ง๋ค๊ธฐ ์ํด Material์ ์ค์ ํด์ผ ํ๋ค. ํ๋ก์ ํธ ๋ทฐ์ ํ๋ฌ์ค ๋ฒํผ์ ๋๋ฅธ ํ, Physics Material 2D๋ฅผ ํด๋ฆญํ๋ฉด ์ค์ ํ ์ ์๋ค.
๐ Physics Material 2D
- Friction : ๋ง์ฐฐ๋ ฅ (0 ์ ๊ฐ๊น์ธ์๋ก ๋ฏธ๋๋ฌ์ง๋ค)
- Bounciness : ํ๋ฉด๊ณผ ์ถฉ๋ํ์ ๋ ํ๊ธฐ๋ ์ ๋ (1์ ๊ฐ๊น์ธ์๋ก ๊ณต์ฒ๋ผ ํตํต ํ๊ธฐ๊ฒ ๋๋ค)
Friction๊ณผ Bounciness๋ฅผ ๋ชจ๋ 0์ผ๋ก ๋ณ๊ฒฝํด์ฃผ๊ณ ๋ ์ ์ญํ ์ ํ๊ณ ์๋ ์ค๋ธ์ ํธ์ ๋ชจ๋ ๋ฃ์ด์ฃผ์๋ค.
ํด๋น ์ค์ ์ ์ ์ฉํ ์ดํ, ๊ฒ์์ ์คํ์์ผ๋ณด๋ฉด ๋ฒฝ์ ๊ณ์ ๋ฟ์ผ๋ ค๊ณ ํด๋ ๋ง์ฐฐ๋ ฅ์ ์ํด ๋ฒฝ์ ๋ถ์ง ์๋ ์ฆ, ๋ฏธ๋๋ฌ์ง๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ์ถ๊ฐ์ ์ผ๋ก, Bounciness๋ฅผ ํฌ๊ฒ ์ค๋ค๋ฉด(1๋ก ์ค์ ) ๋ฒฝ์ ๋ถ๋ชํ์ ๋ ๋ถ๋ชํ ํ ๋งํผ ํตํต ํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ถ์ฒ : ๋ฐ๋ผํ๋ฉด์ ๋ฐฐ์ฐ๋ ๊ณ ๋ฐ์ฌ์ ์ ๋ํฐ ๊ธฐ์ด(https://inf.run/sgcy)
'Study > Unity' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Unity 2D Basic] 2D Animation ์ค์ต (0) | 2024.05.01 |
---|---|
[Unity 2D Basic] 2D Sprite / Animation (0) | 2024.05.01 |
[Unity 2D Basic] ๊ฒ์์ค๋ธ์ ํธ ์ญ์ ํจ์ (0) | 2024.04.16 |
[Unity 2D Basic] Instantiate() ํ์ฉ ์์ (0) | 2024.04.16 |
[Unity 2D Basic] ๊ฒ์ ์ค๋ธ์ ํธ ์์ฑ ํจ์ (0) | 2024.04.16 |