유니티에서 2D 이단점프를 구현해보았다. 우선 전체 코드를 보자.
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Animations;
using UnityEngine;
public class PlayerMove : MonoBehaviour
{
public float maxSpeed;
public float jumpPower;
Rigidbody2D rb;
SpriteRenderer sprite;
Animator anim;
public int jumpCount;
void Awake() {
rb = GetComponent<Rigidbody2D>();
sprite = GetComponent<SpriteRenderer>();
anim = GetComponent<Animator>();
}
void Update() {
if (Input.GetButtonDown("Jump") && jumpCount < 2) {
rb.velocity = Vector2.zero;
rb.AddForce(Vector2.up * jumpPower, ForceMode2D.Impulse);
jumpCount++;
anim.SetBool("Jump", true);
}
else if (Input.GetButtonUp("Jump") && rb.velocity.y > 0) {
rb.velocity = rb.velocity * 0.5f;
}
if (Input.GetButtonUp("Horizontal") && jumpCount == 0) {
rb.velocity = Vector2.zero;
}
if (Input.GetButton("Horizontal")) {
sprite.flipX = Input.GetAxisRaw("Horizontal") == -1;
}
if(Mathf.Abs(rb.velocity.x) < 0.3f) {
anim.SetBool("Run", false);
}
else {
anim.SetBool("Run", true);
}
}
void FixedUpdate() {
float x = Input.GetAxisRaw("Horizontal");
rb.AddForce(Vector2.right * x, ForceMode2D.Impulse);
if(rb.velocity.x > maxSpeed) {
rb.velocity = new Vector2 (maxSpeed, rb.velocity.y);
}
else if(rb.velocity.x < -maxSpeed) {
rb.velocity = new Vector2 (-maxSpeed, rb.velocity.y);
}
}
void OnCollisionEnter2D(Collision2D collision) {
if (collision.contacts[0].normal.y > 0.6f) {
anim.SetBool("Jump", false);
if(jumpCount > 0) rb.velocity = Vector2.zero;
jumpCount = 0;
Debug.Log("Ground");
}
else {
Debug.Log("Ceil");
rb.velocity = Vector2.zero;
}
}
void OnCollisionExit2D(Collision2D collision) {
anim.SetBool("Jump", true);
}
}
jumpCount는 0이 기본이다. 이 상태에서 점프키를 누르면
if (Input.GetButtonDown("Jump") && jumpCount < 2) {
rb.velocity = Vector2.zero;
rb.AddForce(Vector2.up * jumpPower, ForceMode2D.Impulse);
jumpCount++;
anim.SetBool("Jump", true);
}
이 코드에서 점프가 실행되며 jumpCount가 하나 늘게된다. 따라서 빠박하고 점프키를 누르면 두 번 높게 점프가 된다. 이때 점프의 세기를 정해주는 방법도 있다.
else if (Input.GetButtonUp("Jump") && rb.velocity.y > 0) {
rb.velocity = rb.velocity * 0.5f;
}
rb.velocity.y가 양수 일때 즉 올라가고 있을 때 점프키에서 손을 때면 그 즉시 속도가 반으로 줄어든다. 점프키를 길게 누르면 계속 올라가게 되고 점프키를 짧게 누르면 올라가다가 속도가 반이 되며 곧 중력에 의해 rb.velocity.y가 음수가 된다.
여기서 의문이 든다. 점프카운트를 언제 0으로 만들지?? 계속 ++만해주고 있는데. 바로 이 코드에서 0으로 만들어준다.
void OnCollisionEnter2D(Collision2D collision) {
if (collision.contacts[0].normal.y > 0.6f) {
anim.SetBool("Jump", false);
if(jumpCount > 0) rb.velocity = Vector2.zero;
jumpCount = 0;
Debug.Log("Ground");
}
else {
Debug.Log("Ceil");
rb.velocity = Vector2.zero;
}
}
이 때 collision은 ground라고 생각하자. 점프 후에 떨어지면서 ground에 접촉하게 되면 collision.contacts[0].normal.y >0.6f를 통해 제대로 접촉한 것이 맞는지 확인한다. 제대로 땅위에 접촉했다면 속도를 0으로 바꾸고 애니메이션을 설정해주고 jumpCount를 0으로 만들어준다.
되게 자연스럽게 작동이 잘된다.