- 유니티 패키지 파일 : 원하는 파일을 하나로 묶어 다른 프로젝트로 전달할 때 사용
- 패키지 파일 생성하기 : Project View에서 원하는 파일들을 선택한 후 마우스 오른쪽 클릭 - Export Package로 저장
- 패키지 파일 사용하기 : 파일을 적용하고 싶은 프로젝트의 Project View로 패키지 파일을 Drag&Drop
Player를 생성하고 Rigidbody2D를 추가하여 z축으로 회전하지 않도록 선택한다.
또한 Capsule Collider 2D를 추가하면 게임을 실행했을 때 충돌처리가 되는 것을 확인할 수 있다.
Rigidbody2D 컴포넌트의 Constraints
- Freeze Position : 물리에 의한 이동 중지
- Freeze Rotation : 물리에 의한 회전 중지
01 플레이어 오브젝트 이동
플레이어의 이동 구현
만든 스크립트를 Player에 적용시키고 실행하면 중력을 받아 아래로 떨어지고 충돌처리가 된다. 또한 좌우방향키로 Player가 움직인다.
02 플레이어 오브젝트 점프
스페이스 바를 눌렀을 때 점프하도록 작성한다.
실행 결과이다.
스페이스 바를 누르면 점프하고 Jump Force 값을 3으로 줄이면 더 낮게 점프하는 것을 확인할 수 있다.
03 낮은 점프, 높은 점프
gravityScale 값을 제어해서 낮은 점프, 높은 점프를 구현한다.
gravityScale은 중력 계수로, 같은 힘으로 점프해도 값이 더 크면 더 낮게 점프된다.
if문장이 점프키를 계속 누르고 있을 때, else 문장이 점프키를 계속 누르고 있지 않을 때 동작하는 것이다.
점프키를 눌렀는지 판단하는 isLongJump 변수는 PlayerController 스크립트에서 작동한다.
rigid2D.gravityScale: 중력 계수
- 플레이어에게 가해지는 중력은 (0, -9.81, 0)* gravityScale
- gravityScale이 1이면 transform.position += (0, -9.81, 0)의 연산이 추가
- gravityScale이 2.5이면 transform.position += (0, -24.525, 0)의 연산이 추가
[HideInInspector]
public 타입의 변수를 Inspector View에 보이지 않게 설정
isLongJump 변수가 true 또는 false가 되도록 설정한다.
게임을 실행하고 점프를 하면 두 번째 플랫폼까지 위치하는 것을 알 수 있다. 점프키를 누르고 있으면 더 높게 점프를 한다.
이때 gravityScale 값을 확인하면 1과 2.5로 점프에 따라 변하는 것을 확인할 수 있다.
04 바닥 판정 및 점프 제어
지금까지는 플레이어가 공중에서 무한하게 점프할 수 있었다.
플레이어가 바닥에 닿아있는지 검사하고 바닥에 닿아있을 때만 점프할 수 있도록 설정한다.
바닥에 닿아있는지 검사하기 위해서는 플레이어의 발 위치를 알아야 한다.
충돌이 일어나면 isGrounded 변수가 true가 될 것이고, Player가 바닥을 밟고 있다는 의미이다.
유니티 Layer의 역할 (변수 타입 LayerMask)
- 오브젝트가 그려지는 순서를 설정할 수 있다
- 오브젝트 충돌에서 지정한 레이어와의 충돌을 제외할 수 있다
- (Tip. Edit - Project Settings - Physics or Physics 2D에서 레이어끼리의 Collider 충돌 처리를 설정할 수 있다)
Collider2D collider = Physics2D.OverlapCircle(Vector2 position, float radius, LayerMask layer);
- position 위치에 radius 반지름 크기의 보이지 않는 원 충돌 범위를 생성
- 원에 충돌하는 오브젝트(레이어가 layer이어야 한다)의 Collider2D 컴포넌트를 저장
isGrounded 변수가 true 일 때만 점프하도록 Jump 함수에 조건문을 추가한다.
화면에 보이지 않는 충돌 범위와 같은 것들을 내가 원하는 위치에 잘 배치했는지 확인하고 싶을 때 선, 사각형, 원 등을 그려서 확인한느 용도
실행하기 전에 Ground 레이어를 추가하여 적용해야 한다.
게임을 실행하면 바닥에 닿았을 때만 점프할 수 있게 변경된 것을 확인했다.
05 최대 점프 횟수 설정
점프 가능 횟수를 조절할 수 있도록 코드를 수정한다.
플레이어가 점프키를 누를 때마다 점프가능 횟수가 1씩 줄어든다. 0이면 점프가 불가능하고 바닥에 닿으면 다시 점프할 수 있도록 코드를 작성해야 한다.
현재 maxJumpCount는 2로 설정되어 있다.
06 오브젝트 마찰력 설정
벽 쪽에 오브젝트가 붙어버리는 문제가 발생한다.
이것을 해결하기 위해 Collider의 Material 설정을 해야 한다.
Project View에서 Physics Material 2D를 추가한다.
Physics Material 2D
- Friction : 마찰력 (0에 가까울수록 더 미끄럽다)
- Bounciness : 표면과 충돌했을 때 튕기는 정도 (1에 가까울수록 탱탱볼처럼 통통 튀기게 된다)
만든 Physics Material를 Ground와 CircleObstacle에 적용하고 게임을 실행하면 벽에 닿아도 미끄러지는 것을 확인할 수 있다.
Movement2D
using UnityEngine;
public class Movement2D : MonoBehaviour
{
[SerializeField]
private float speed = 5.0f; //이동 속도
[SerializeField]
private float jumpForce = 8.0f; //점프 힘(클수록 높게 점프)
private Rigidbody2D rigid2D;
[SerializeField]
public bool isLongJump = false; // 낮은/높은 점프 체크
[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()
{
//플레이어 오브젝트의 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번까지 점프가 가능하게 된다
if (isGrounded == true && rigid2D.velocity.y <= 0)
{
currentJumpCount = maxJumpCount;
}
//낮은 점프, 높은 점프 구현 위한 중력 계수 조절 Jump Up일 때만 적용)
//중력 계수가 낮은 if문은 높은 점프가 되고, 중력 계수가 높은 else문은 낮은 점프가 됨.
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)
{
//x축 이동은 x*speed로, y축 이동은 기존의 속력 값(현재는 중력)
rigid2D.velocity = new Vector2(x * speed, rigid2D.velocity.y);
}
public void Jump()
{
//if (isGrounded == true)
if (currentJumpCount > 0)
{
//jumpForce의 크기만큼 윗쪽 방향으로 속력 설정
rigid2D.velocity = Vector2.up * jumpForce;
// jump 횟수 1 감소
currentJumpCount--;
}
}
}
PlayerController
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private Movement2D movement2D;
private void Awake()
{
movement2D = GetComponent<Movement2D>();
}
private 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;
}
}
}
'PBL > Unity' 카테고리의 다른 글
유니티 2D 기초 - 2D Animation 실습 (0) | 2024.04.30 |
---|---|
유니티 2D 기초 - 2D Sprite / Animation (0) | 2024.04.30 |
유니티 2D 기초 - 게임오브젝트 삭제 함수 (0) | 2024.04.14 |
유니티 2D 기초 - Instantiate() 활용 예제 (0) | 2024.04.14 |
유니티 2D 기초 - 게임 생성 함수 (0) | 2024.04.13 |