[Unity] 2D 이동, 점프

남이섬·2023년 3월 14일
0

이동

유니티 패키지 파일 : 원하는 파일들을 하나로 묶어 다른 프로젝트로 전달할 때 사용
패키지 파일 생성하기 : Project View에서 원하는 파일들을 선택한 후 마우스 오른쪽 클릭 - Export Package로 저장
패키지 파일 사용하기 : 파일을 적용하고 싶은 프로젝트의 Project View로 패키지 파일을 Drag & Drop

Rigidbody2D 컴포넌트의 Constraints
Freeze Position : 물리에 의한 이동 중지
Freeze Rotation : 물리에 의한 회전 중지

Input Manager (키 조작)
Edit -> Project Settings -> Input Manager -> Axes

이동 예제 코드

Movement2D

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

public class Movement2D : MonoBehaviour
{
    [SerializeField]
    private float speed = 5.0f; // 이동속도
    private Rigidbody2D rigid2D;

    private void Awake()
    {
        rigid2D = GetComponent<Rigidbody2D>();
    }

    public void Move(float x)
    {
        // x축 이동은 x * speed로, y축 이동은 기존의 속력 값 (현재는 중력)
        rigid2D.velocity = new Vector2(x * speed, rigid2D.velocity.y);
    }
}

PlayerComtroller

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

public class PlayerComtroller : MonoBehaviour
{
    private Movement2D movement2D;

    void Awake()
    {
        movement2D = GetComponent<Movement2D>();
    }

    void Update()
    {
        // left or a = -1 / right or d = 1
        float x = Input.GetAxisRaw("Horizontal");
        // 좌우 이동 방향 제어
        movement2D.Move(x);
    }
}

점프

rigid2D.gravityScale: 중력 계수
플레이어에게 가해지는 중력은 (0, -9.81, 0) * gravityScale
gravityScale이 1이면 transform.position += (0, -9.81, 0)의 연산이 추가
gravityScale이 2.5이면 transform.position += (0, -24.525, 0)의 연산이 추가

점프 예제 코드

Movement2D

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

public class Movement2D : MonoBehaviour
{
    [SerializeField]
    private float jumpForce = 8.0f; // 점프 힘 (클수록 높게 점프)
    private Rigidbody2D rigid2D;
    [HideInInspector]
    public bool isLongJump = false; // 낮은 점프, 높은 점프 체크

    private void FixedUpdate()
    {
        // 낮은 점프, 높은 점프 구현을 위한 중력 계수(gravityScale) 조절 (Jump Up일 때만 적용)
        // 중력 계수가 낮은 if 문은 높은 점프가 되고, 중력 계수가 높은 else 문은 낮은 점프가 된다
        if(isLongJump && rigid2D.velocity.y > 0)
        {
            rigid2D.gravityScale = 1.0f;
        }
        else
        {
            rigid2D.gravityScale = 2.5f;
        }
    }

    public void Jump()
    {
        // jumpForce의 크기만큼 윗쪽 방향으로 속력 설정
        rigid2D.velocity = Vector2.up * jumpForce;
    }
}

PlayerComtroller

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

public class PlayerComtroller : MonoBehaviour
{
    void Update()
    {
        // left or a = -1 / right or d = 1
        float x = Input.GetAxisRaw("Horizontal");
        // 좌우 이동 방향 제어
        movement2D.Move(x);

        // 플레이어 점프 (스페이스 키를 누르면 점프)
        if (Input.GetKeyDown(KeyCode.Space))
        {
            movement2D.Jump();
        }

        // 스페이스 키를 누르고 있으면 isLongJump = true
        if (Input.GetKey(KeyCode.Space))
        {
            movement2D.isLongJump = true;
        }

        // 스페이스 키를 때면 isLongJump = false
        else if (Input.GetKeyUp(KeyCode.Space))
        {
            movement2D.isLongJump = false;
        }
    }
}

점프 제어

점프 환경 설정

유니티 Layer의 역할 (변수 타입 LayerMask)

  • 오브젝트가 그려지는 순서를 설정할 수 있다
  • 오브젝트 충돌에서 지정한 레이어와의 충돌을 제외할 수 있다
    (Edit -> Project Settings -> Physics or Physics 2D에서 레이어끼리의 Collider 충돌 처리를 설정할 수 있다)

00Collider2D.bounds
capsuleCollider2D의 bounds 변수는 충돌 범위의 min, center, max

  • 충돌 범위의 min, center, max 위치 값
  • 2D 일땐 Vector2(x, y)
  • 3D 일땐 Vector3(x, y, z)

Physics2D.OverlapCircle()
범위와 레이어를 설정해 해당 범위에 충돌된 오브젝트를 검출하는 함수

Collider2D collider = Physics2D.OverlapCircle(Vector2 position, float radius, LayerMask layer);

  • position 위치에 radius 반지름 크기의 보이지 않는 원 충돌 범위를 생성
  • 원에 충돌하는 오브젝트(레이어가 layer이어야 한다)의 Collider2D 컴포넌트를 저장

Physics2D.OverlapCircle()의 반환 값을 bool로 설정하면 출돌하는 오브젝트가 있을 때 true, 없을 때 false를 반환하게 된다

Gizmos
화면에 보이지 않는 충돌 범위와 같은 것들을 내가 원하는 위치에 잘 배치했는지 확인하고 싶을 때 선, 사각형, 원 등을 그려서 확인하는 용도

Gizmos.color = Color.blue; -> 파란색
Gizmos.DrawSphere(footPosition, o.1f); -> 발의 위치에 0.1 반지름의 구 생성

Movement2D

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

public class Movement2D : MonoBehaviour
{
    [SerializeField]
    private int maxJumpCount = 2; // 땅을 밟기 전까지 할 수 있는 최대 점프 횟수
    private int currentJumpCount = 0; // 현재 가능한 점프 횟수

    private void Awake()
    {
        capsuleCollider2D = GetComponent<CapsuleCollider2D>();
    }

    private void FixedUpdate()
    {
        // 플레이어 오브젝트의 Collider2D min, center, max 위치 정보
        Bounds bounds = capsuleCollider2D.bounds;
        // 플레이어의 발 위치 설정
        footPosition = new Vector2(bounds.center.x, bounds.min.y);
        // 플레이어의 발 위치에 원을 생성하고, 원이 바닥과 닿아있으면 isGrounded = true
        isGrounded = Physics2D.OverlapCircle(footPosition, 0.1f, groundLayer);

        // 플레이어의 발이 땅에 닿아 있고, y축 속도가 0이하이면 점프 횟수 초기화
        // velocity.y <= 0을 추가하지 않으면 점프키를 누르는 순간에도 초기화가 되어
        // 최대 점프 횟수를 2로 설정하면 3번까지 점프가 가능하게 된다

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.blue;
        Gizmos.DrawSphere(footPosition, 0.1f);
    }

    public void Jump()
    {
        if (isGrounded)
        {
        // jumpForce의 크기만큼 윗쪽 방향으로 속력 설정
        rigid2D.velocity = Vector2.up * jumpForce;
        }
    }
}

점프 횟수

Movement2D

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

public class Movement2D : MonoBehaviour
{
    [SerializeField]
    private int maxJumpCount = 2; // 땅을 밟기 전까지 할 수 있는 최대 점프 횟수
    private int currentJumpCount = 0; // 현재 가능한 점프 횟수

    private void FixedUpdate()
    {
        // 플레이어의 발이 땅에 닿아 있고, y축 속도가 0이하이면 점프 횟수 초기화
        // velocity.y <= 0을 추가하지 않으면 점프키를 누르는 순간에도 초기화가 되어
        // 최대 점프 횟수를 2로 설정하면 3번까지 점프가 가능하게 된다
        if (isGrounded == true && rigid2D.velocity.y <= 0)
        {
            currentJumpCount = maxJumpCount;
        }

    public void Jump()
    {
        if (currentJumpCount > 0)
        {
            // jumpForce의 크기만큼 윗쪽 방향으로 속력 설정
            rigid2D.velocity = Vector2.up * jumpForce;
            // 점프 횟수 1 감소
            currentJumpCount--;
        }
    }
}

마찰

Physics Material 2D
Friction : 마찰력 (0에 가까울수록 더 미끄럽다)
Bounciness : 표면과 충돌햇을 때 튕기는 정도 (1에 가까울수록 탱탱볼처럼 통통 튀기게 된다)

profile
즐겁게 살자

0개의 댓글