Week 04 / Period 03 / Input practice

점프 구현과 발판 구간 구성

2교시의 이동 코드에 점프를 추가하고, 상자와 돌 발판으로 자신만의 이동 경로를 구성합니다. 단계별 필수 코드를 연결해 새 입력마다 점프하고, 공중에서 다시 점프하는 동작을 확인합니다.

60분 / 개별 실습 / 점프 구현과 공간 구성

기존 캐릭터와 잔디 바닥, 돌과 수풀을 배치한 Unity Scene
2교시에서 구성한 출발 장면입니다. 이 장면에 점프 기능과 새로운 발판을 추가합니다.
이 페이지에서

점프를 구현하고 이동 경로 구성하기

2교시에서 완성한 좌우 이동과 충돌을 유지하고 Space를 새로 누를 때마다 위쪽 속도를 주는 점프를 추가합니다. 이후 상자와 돌 발판으로 출발 지점에서 도착 표지판까지 이동하는 구간을 만듭니다.

  1. Update에서 점프 요청을 저장하고 FixedUpdate에서 위쪽 속도 적용
  2. 공중에서 다시 눌러 연속 점프하고 입력과 속도 변화 관찰
  3. 상자와 돌 발판을 하나씩 배치하며 이동 경로 구성

이번 실습의 점프 규칙

공중에서도 키를 놓았다가 다시 누르면 점프합니다. 두 번뿐 아니라 세 번 이상도 가능합니다. 누르고 있는 동안 자동으로 반복되지는 않습니다. 점프할 수 있는 조건과 횟수 제한은 이후 학습에서 추가합니다.

STEP 2~4의 필수 코드를 순서대로 적용합니다. 각 단계에서 추가할 필드와 교체할 메서드를 구분하고 저장합니다. 전체 파일을 대조하려면 STEP 4의 전체 코드를 확인합니다. 첫 실행은 STEP 4에서 코드와 Inspector 연결을 모두 마친 뒤 진행합니다.

완성할 장면

점프 구간의 완성 화면. 왼쪽 출발 깃발 옆에 캐릭터가 있고, 긴 잔디 바닥에 크기가 다른 나무 상자들이 놓여 있습니다. 오른쪽으로 높아지는 돌 발판 두 개와 마지막 발판의 별 표지판, 공중의 보석 세 개, 양끝의 바위 벽과 수풀이 보입니다.
3교시 점프 구간의 완성 화면입니다. 왼쪽 출발 지점에서 나무 상자와 높이가 다른 돌 발판 두 개를 거쳐 오른쪽 위의 별 표지판까지 이동하는 경로를 구성했습니다. 발판의 높이와 간격은 직접 점프하며 조정합니다. 이미지를 선택하면 원본 크기로 볼 수 있습니다.

출발 바닥, 낮은 상자 하나 이상, 돌 발판 두 개, 도착 표지판을 한 화면 안에 배치합니다. 아래에는 2교시의 긴 Ground를 유지해 발판에서 떨어져도 다시 시도할 수 있게 합니다.

완성 화면에서 구현할 범위
구분이번 실습의 기준
필수 동작좌우 이동, 새 입력마다 점프, 공중에서 다시 점프, 바닥·상자·발판에 착지
필수 배치기존 Player·Ground·좌우 벽에 낮은 상자, 돌 발판 두 개, 도착 표지판을 추가합니다.
선택 장식추가 상자, 출발 깃발, 보석, 수풀은 선택입니다. 보석 수집이나 점수는 구현하지 않습니다.

상자와 발판은 고정 지형입니다. 도착 표지판은 위치만 표시하며, 클리어 판정이나 장면 전환은 이번 실습에 포함하지 않습니다. 먼저 필요한 지형으로 경로를 완성하고 장식을 추가합니다. 완성 이미지와 장식 개수까지 똑같이 맞출 필요는 없습니다.

01 · 2교시 장면 이어서 사용

시작 상태: 좌우 이동·낙하·착지가 작동하는 2교시 Scene입니다.

  1. Play 모드를 종료하고 Scene을 Week04_JumpCourse로 Save As 합니다.
  2. 기존 PlayerController.cs를 계속 수정합니다. 2교시 코드를 보관하려면 프로젝트 밖에 복사합니다. Scene을 다른 이름으로 저장해도 스크립트 파일은 공유됩니다.
  3. Player의 Rigidbody2D는 Dynamic, Gravity Scale 1, Linear Damping 0, Freeze Rotation Z를 유지합니다. 위치 축은 고정하지 않습니다.
  4. 2교시에서 맞춘 Player와 Ground의 Collider2D를 유지합니다. 이번 예시의 Player는 Box Collider 2D이며 Is Trigger는 해제합니다. 발바닥과 바닥 윗면의 경계를 확인합니다.

2교시의 using UnityEngine;, using UnityEngine.InputSystem;, 기존 필드와 Awake()는 유지합니다. 이후 단계에서 지정하는 메서드만 교체합니다.

CHECK 01

Player에 이동 스크립트가 하나만 있고, 시작 위치가 바닥이나 벽과 겹치지 않습니다. 기존 좌우 이동과 낙하를 확인한 뒤 Play 모드를 종료했습니다.

다음 단계: STEP 02

02 · Jump Action과 필드 준비

시작 상태: 기존 Move Action이 연결되어 있고 Play 모드는 종료되어 있습니다.

  1. PlayerControls 에셋의 Player Action Map에서 Jump Action을 추가합니다. Action Type은 Button으로 설정합니다.
  2. Binding을 추가하고 Path를 <Keyboard>/space로 지정합니다. Interactions는 비워 두고 에셋을 저장합니다. 컨트롤러를 사용하면 같은 Jump에 <Gamepad>/buttonSouth도 추가합니다.
  3. Move의 WASD와 방향키 두 묶음의 Mode가 모두 Digital인지 확인합니다. W/S는 점프에 사용하지 않습니다.

필수 코드 1 · 필드 세 개 추가

기존 PlayerController 클래스 안에서 메서드 밖, 기존 필드 아래에 다음 세 줄을 추가합니다. 이번에 추가하는 필드가 이미 있다면 중복으로 작성하지 않습니다.

PlayerController · 추가할 필드
[SerializeField] private InputActionReference jumpAction;
[SerializeField, Min(0f)] private float jumpSpeed = 7f;
private bool jumpRequested;
추가하는 필드의 역할
필드보관하는 내용지정하는 곳
jumpAction점프 입력을 읽을 Action의 참조STEP 4에서 Inspector의 Jump Action에 Player/Jump를 연결합니다.
jumpSpeed점프 순간에 지정할 위쪽 속도초깃값은 7입니다. 점프 높이 자체가 아니라 속도입니다.
jumpRequested새 점프 입력이 들어왔는지 나타내는 true/false 값Update가 true로 저장하고 FixedUpdate가 처리한 뒤 false로 지웁니다.

필수 코드 2 · Action 활성화 메서드 교체

기존 OnEnable()과 OnDisable()을 각각 아래 내용으로 교체합니다. 같은 이름의 메서드는 클래스 안에 하나씩만 둡니다. Move와 Jump를 함께 활성화하고, 컴포넌트가 꺼질 때 처리하지 않은 요청도 지웁니다.

OnEnable · OnDisable 교체
private void OnEnable()
{
    if (moveAction == null || jumpAction == null)
    {
        Debug.LogError("PlayerController: Move Action과 Jump Action을 연결하세요.", this);
        enabled = false;
        return;
    }
    moveAction.action.Enable();
    jumpAction.action.Enable();
}

private void OnDisable()
{
    if (moveAction != null) moveAction.action.Disable();
    if (jumpAction != null) jumpAction.action.Disable();
    jumpRequested = false;
}

파일을 저장하고 Unity의 컴파일이 끝나면 Console 오류가 0개인지 확인합니다. Player의 PlayerController에 Jump Action과 Jump Speed가 나타나는지 확인합니다. 항목이 없다면 필드의 위치, 저장 여부, Console의 첫 번째 오류를 확인합니다. 아직 Play하지 않습니다.

CHECK 02

Jump가 Button이고 Space Binding이 저장되어 있습니다. 필드 세 개와 Action 활성화 코드를 적용했으며, Inspector에 새 항목이 보입니다.

다음 단계: STEP 03

03 · 점프 입력을 읽어 요청 저장

시작 상태: Jump Action과 필드 세 개를 준비했고 코드가 컴파일되었습니다.

2교시에는 Move의 방향값을 저장했습니다. 이번에는 점프 버튼을 새로 누른 순간도 읽어 다음 물리 업데이트까지 보관합니다.

필수 코드 3 · Update 교체

기존 Update() 전체를 아래 코드로 교체합니다. Move 입력과 관찰용 속도를 읽는 줄은 계속 사용합니다.

Update · 입력 읽기와 요청 저장
private void Update()
{
    moveInput = moveAction.action.ReadValue<Vector2>();
    if (jumpAction.action.WasPressedThisFrame())
    {
        jumpRequested = true;
    }
    observedVelocity = body.linearVelocity;
}
한 번 누른 입력을 다음 물리 업데이트까지 보관합니다
코드의미
WasPressedThisFrame()이번 프레임에 새로 눌렀는지 확인합니다. 키를 계속 누르는 것과 구분합니다.
jumpRequested = true;점프 입력이 있었다는 사실을 저장합니다. 이 줄에서 캐릭터를 움직이지는 않습니다.
요청을 저장하는 이유Update와 FixedUpdate의 호출 횟수가 다르므로, 다음 FixedUpdate가 읽을 때까지 입력을 기억해야 합니다.

Update에서 매번 jumpRequested를 false로 덮어쓰지 않습니다. 아직 FixedUpdate가 읽지 않은 요청을 지울 수 있기 때문입니다. 요청을 처리하고 지우는 코드는 다음 단계에서 작성합니다.

파일을 저장하고 컴파일 오류가 없는지 확인합니다. 이 단계는 입력을 저장하는 단계이므로 아직 위쪽 속도를 바꾸지 않습니다. 다음 STEP 4까지 마친 뒤 실행합니다.

CHECK 03

Update는 클래스 안에 하나만 있습니다. 새 점프 입력이 들어오면 jumpRequested에 true를 저장하며, 기존 Move 입력도 계속 읽습니다.

다음 단계: STEP 04

04 · 점프 속도 적용과 실행 확인

시작 상태: Update가 Move 입력과 점프 요청을 저장하도록 수정되었습니다.

점프 요청이 있으면 현재 위치와 관계없이 y 속도를 Jump Speed로 지정합니다. 요청이 없으면 현재 y 속도를 유지해 중력에 의한 낙하가 이어지게 합니다.

필수 코드 4 · FixedUpdate 교체

기존 FixedUpdate() 전체를 아래 코드로 교체합니다. 먼저 현재 속도를 가져오고, 가로 입력을 반영한 뒤 점프 요청이 있을 때만 세로 속도를 바꿉니다.

FixedUpdate · 속도 지정과 요청 지우기
private void FixedUpdate()
{
    Vector2 velocity = body.linearVelocity;
    velocity.x = moveInput.x * moveSpeed;

    if (jumpRequested)
    {
        velocity.y = jumpSpeed;
    }

    body.linearVelocity = velocity;
    jumpRequested = false;
}

velocity.y = jumpSpeed;는 현재 세로 속도에 더하는 것이 아니라 위쪽 속도를 새로 지정합니다. Jump Speed가 7이면 낙하 중 y속도가 -3이어도 점프 직후 지정값은 +7입니다. velocity.x는 Move 입력으로 정하므로 공중에서도 A/D로 움직일 수 있습니다.

마지막의 jumpRequested = false;는 같은 요청을 한 번만 처리하기 위해 필요합니다. 이 줄이 없으면 한 번 누른 뒤에도 매 물리 업데이트마다 위쪽 속도를 다시 지정합니다. 새로 누르면 Update가 다시 true를 저장합니다.

전체 코드 · PlayerController.cs

연결한 코드를 대조하거나, 부분 코드 연결이 어렵다면 기존 PlayerController.cs의 내용을 아래 전체 코드로 교체합니다. 별도의 두 번째 PlayerController 클래스를 만들지 않습니다. 전체 코드를 적용해도 아래 Inspector 연결은 해야 합니다.

PlayerController.cs · 전체 코드
using UnityEngine;
using UnityEngine.InputSystem;

[RequireComponent(typeof(Rigidbody2D))]
public class PlayerController : MonoBehaviour
{
    [SerializeField] private InputActionReference moveAction;
    [SerializeField, Min(0f)] private float moveSpeed = 5f;

    private Rigidbody2D body;
    [SerializeField] private Vector2 moveInput;
    [SerializeField] private Vector2 observedVelocity;

    [SerializeField] private InputActionReference jumpAction;
    [SerializeField, Min(0f)] private float jumpSpeed = 7f;
    private bool jumpRequested;

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

    private void OnEnable()
    {
        if (moveAction == null || jumpAction == null)
        {
            Debug.LogError("PlayerController: Move Action과 Jump Action을 연결하세요.", this);
            enabled = false;
            return;
        }
        moveAction.action.Enable();
        jumpAction.action.Enable();
    }

    private void OnDisable()
    {
        if (moveAction != null) moveAction.action.Disable();
        if (jumpAction != null) jumpAction.action.Disable();
        jumpRequested = false;
    }

    private void Update()
    {
        moveInput = moveAction.action.ReadValue<Vector2>();
        if (jumpAction.action.WasPressedThisFrame())
        {
            jumpRequested = true;
        }
        observedVelocity = body.linearVelocity;
    }

    private void FixedUpdate()
    {
        Vector2 velocity = body.linearVelocity;
        velocity.x = moveInput.x * moveSpeed;

        if (jumpRequested)
        {
            velocity.y = jumpSpeed;
        }

        body.linearVelocity = velocity;
        jumpRequested = false;
    }
}

전체 코드 다운로드

실행 전 Inspector 연결

파일을 저장하고 Unity의 컴파일이 끝날 때까지 기다립니다. Console 오류가 0개이면 Play 모드가 종료된 상태에서 다음 표와 비교합니다.

Play 전에 확인할 설정
대상설정 위치값 또는 연결
PlayerPlayerController → Move ActionPlayerControls / Player / Move
PlayerPlayerController → Jump ActionPlayerControls / Player / Jump
PlayerPlayerController → Move Speed / Jump Speed5 / 7로 시작합니다.
PlayerRigidbody 2DDynamic, Gravity Scale 1, Linear Damping 0, Freeze Rotation Z
Player·Ground각 Collider 2D활성화하고 Is Trigger의 선택을 해제합니다.
PlayerPlayerController 제목 왼쪽 체크박스활성화합니다. 참조 누락으로 꺼졌다면 참조를 먼저 연결한 뒤 다시 켭니다.

Jump Action 슬롯의 선택 버튼에서 Input Actions 에셋 속 Player/Jump를 지정합니다. 목록에서 찾을 수 없다면 STEP 2의 에셋 저장 여부를 확인합니다.

새로 누르기와 누른 채 유지를 비교합니다

  1. Play 후 Game 뷰를 클릭합니다. Ground에 착지한 상태에서 Space를 한 번 누르고 놓습니다. 올라갔다가 중력으로 내려오는지 확인합니다.
  2. 다시 점프한 뒤 공중에서 Space를 놓았다가 다시 누릅니다. 착지하기 전에도 다시 위로 올라가면 정상입니다. 세 번 이상 새로 눌러도 점프할 수 있습니다.
  3. Space를 누른 채 유지했을 때에는 처음 한 번만 점프하고 내려오는지 비교합니다. 새로 누를 때마다 점프하는 것과 구분합니다.
  4. 공중에서 A/D로 이동하고, 모든 키를 놓으면 가로 이동은 멈추고 낙하는 계속되는지 확인합니다.

점프 횟수는 이번 코드에서 제한하지 않습니다. 더블 점프를 포함한 공중 연속 점프를 사용해도 됩니다. 확인 후 Play 모드를 종료합니다. Jump Speed 등을 실행 중 바꿨다면 편집 상태에서 원하는 값을 다시 지정하고 저장합니다.

CHECK 04

한 번 누르면 점프하고, 공중에서 새로 누르면 다시 점프합니다. 누른 채 유지하면 자동 반복되지 않으며, 키를 놓으면 중력에 따라 내려옵니다.

다음 단계: STEP 05

05 · 공간 구성 스프라이트 가져오기

시작 상태: 점프가 작동합니다.

기존 잔디 타일과 함께 사용할 수 있는 투명 배경 PNG 세 장입니다. 이미지 생성 도구로 제작했습니다. 개별 이미지 또는 잔디 타일까지 포함한 묶음을 다운로드합니다.

Ground + Crate + StonePlatform + GoalSign / PNG 4장스프라이트 묶음 다운로드
횡스크롤용 나무 상자 픽셀 아트Crate.png 다운로드
나무 상자낮은 장애물과 첫 번째 발판
횡스크롤용 돌 발판 픽셀 아트StonePlatform.png 다운로드
돌 발판높이와 간격을 조정하는 고정 발판
횡스크롤용 도착 표지판 픽셀 아트GoalSign.png 다운로드
도착 표지판최종 도착 위치를 표시하는 장식

기존 잔디 타일 Ground.png 다운로드

  1. 압축을 풀고 새 PNG를 Assets/Sprites로 가져옵니다. Ground를 이미 가져왔다면 기존 에셋을 사용합니다.
  2. Texture Type은 Sprite (2D and UI), Sprite Mode는 Single, Filter Mode는 Point (no filter), Compression은 None으로 설정하고 Apply 합니다.
  3. Pixels Per Unit은 기존 캐릭터와 같은 값으로 시작합니다. 이미지 해상도와 투명 여백이 서로 다르므로 Scene에서 캐릭터와 비교하며 Transform의 X·Y Scale을 같은 비율로 조절합니다.

CHECK 05

새 스프라이트 세 장이 Project 창에 있고 배경이 투명하게 표시됩니다.

다음 단계: STEP 06

06 · 점프로 통과할 구간 배치

시작 상태: 새 스프라이트를 가져왔고, 바닥과 공중에서 점프가 작동합니다.

상자 하나에 착지한 뒤 발판을 하나씩 추가합니다. Play 중 배치를 시험했다면 종료 후 편집 상태에서 다시 적용하고 Scene을 저장합니다.

처음에는 낮고 가까운 구간으로 시작합니다

Space를 한 번만 누르고 놓았을 때, 바닥 윗면에서 최고점의 발바닥까지 올라간 높이를 화면에서 비교합니다. 첫 배치는 이 높이의 약 1/4 정도씩 높아지도록 시작합니다. 화면에서 눈으로 비교하며 첫 점프로 닿기 쉬운 높이를 잡습니다.

첫 배치의 기준 · 실제 점프 결과를 보고 조절합니다
대상시작할 크기와 위치확인할 결과
Crate_01바닥 위에 배치합니다. 윗면은 한 번 점프한 높이의 약 1/4, 폭은 Player 몸통보다 넓게 시작합니다.바닥에서 올라가 상자 위에 착지합니다.
StonePlatform_01상자 오른쪽에 놓습니다. 윗면은 상자보다 점프 높이의 약 1/4 높게, 가로 틈은 Player 몸통 폭 정도로 시작합니다.상자에서 첫 발판으로 이동해 착지합니다.
StonePlatform_02첫 발판 오른쪽에 같은 기준으로 배치합니다. 두 발판 모두 폭을 Player 몸통의 두 배 이상으로 시작합니다.첫 발판에서 두 번째 발판으로 이동합니다.
GoalSign두 번째 발판 위에 배치합니다. Collider2D는 추가하지 않습니다.캐릭터가 표지판 위치까지 도달합니다.

위 기준은 시작용 예시입니다. 캐릭터 크기와 점프 속도에 따라 닿기 어렵다면 발판을 더 낮추거나 가로 틈을 줄입니다. 먼저 각 구간의 착지를 확인한 뒤 높이와 간격을 하나씩 늘립니다. 공중에서 다시 점프해 넘어가는 경로를 만들어도 됩니다.

  1. 긴 Ground 왼쪽에 Player의 출발 위치를 정합니다. Project의 Crate 스프라이트를 Scene으로 드래그하고 이름을 Crate_01로 지정합니다. Transform의 X·Y Scale은 같은 비율로 조절합니다.
  2. 상자에 Box Collider 2D를 추가하고 Is Trigger를 해제합니다. Edit Collider로 투명 여백을 제외하고 실제 윗면에 경계를 맞춥니다. Rigidbody2D는 추가하지 않습니다. Play해 상자 위에 착지하는지 확인하고 종료합니다.
  3. StonePlatform 스프라이트를 Scene으로 드래그해 StonePlatform_01을 만듭니다. 같은 방식으로 Collider를 맞추고 점프로 올라갈 수 있는지 확인합니다. 성공하면 복제해 StonePlatform_02를 오른쪽에 배치하고 다시 확인합니다.
  4. 마지막 발판 위에 GoalSign을 배치합니다. 새 상자와 발판을 위한 별도 Layer 설정은 필요하지 않습니다. 기본 충돌 설정에서 각 Collider2D가 움직임을 막고 캐릭터를 받칩니다.
  5. Main Camera의 Game 뷰에서 출발 위치와 도착 표지판이 모두 보이는지 확인합니다. 긴 바닥은 발판 아래에 유지합니다. 기존 좌우 벽도 유지합니다.
  6. 전체 경로가 작동하면 수풀·보석·추가 상자를 선택해 꾸밉니다. 보석과 수풀 같은 장식은 이동 경로를 막지 않도록 Collider 설정을 확인합니다.

이번 돌 발판은 모든 방향에서 충돌하는 고정 발판입니다. 아래에서 통과할 수 없으므로 옆에서 위로 올라갈 공간을 확보합니다. 점프 속도를 변경했다면 전체 경로를 다시 확인합니다.

CHECK 06

출발 바닥에서 상자와 두 발판에 차례로 착지하고 도착 표지판까지 이동할 수 있습니다. 필요하면 공중 연속 점프를 사용합니다.

다음 단계: STEP 07

07 · 동작 확인과 저장

시작 상태: 발판과 도착 표지판을 배치했습니다. 앞의 완성 예시와 필요한 지형을 비교한 뒤 아래 네 가지 동작을 확인합니다.

  1. 바닥 점프: Ground에서 Space를 한 번 누르고 놓으면 점프하고 다시 착지합니다.
  2. 공중 연속 점프: 공중에서 Space를 놓았다가 다시 누르면 두 번째, 세 번째 점프가 가능합니다. 누른 채 유지하면 새 점프가 자동 반복되지 않습니다.
  3. 공중 이동: A/D로 좌우 이동할 수 있습니다. 모든 키를 놓으면 가로 이동은 멈추고 중력에 따라 내려옵니다.
  4. 구간 통과: 상자와 두 발판 위에 착지하고 도착 표지판에 도달합니다. 공중에서 다시 점프하는 것도 허용합니다.

Play 모드를 종료한 뒤 편집 상태의 배치를 확인합니다. 실행 중 변경한 위치나 속도는 종료하면 되돌아가므로 필요한 값을 편집 상태에서 다시 적용합니다. PlayerController.cs, PlayerControls 에셋, Week04_JumpCourse Scene을 저장합니다.

CHECK 07

새 입력마다 점프하고 공중에서도 다시 점프할 수 있습니다. 전체 경로를 통과했고 코드·입력 에셋·Scene을 저장했습니다.

문제 해결

Space를 눌러도 점프하지 않음

Game 뷰의 포커스, Jump의 Button 설정과 Space Binding, Jump Action 참조를 확인합니다. Jump Speed가 0보다 큰지, PlayerController가 활성화되어 있는지 확인합니다. Update가 요청을 true로 저장하고 FixedUpdate가 그 요청으로 y속도를 지정하는지 차례로 읽습니다.

키를 놓아도 계속 위로 올라감

FixedUpdate 마지막에 jumpRequested = false;가 있는지 확인합니다. Update는 WasPressedThisFrame()으로 새 입력만 저장해야 합니다. 요청이 없을 때에는 현재 y속도를 유지하고, Gravity Scale은 1로 둡니다. 공중에서 키를 새로 누를 때 다시 점프하는 것은 이번 실습의 정상 동작입니다.

상자나 발판에서 발이 뜨거나 옆면에 걸림

Play 모드를 종료하고 Edit Collider로 투명 여백을 제외합니다. Player 아래 경계는 발바닥, 지형 위 경계는 실제 윗면에 맞춥니다. 발판 옆면에서 위로 올라갈 공간을 확보하고, 옆면을 향해 계속 누르던 이동 키도 놓아 봅니다.

컴파일 오류 또는 참조 오류

Console의 첫 번째 오류부터 확인합니다. 중복된 필드나 Update·FixedUpdate, 클래스 밖에 붙인 코드를 점검합니다. 전체 코드는 기존 파일을 교체하는 용도입니다. Clear는 표시된 기록을 지우는 기능이며 오류의 원인을 해결하지 않습니다. 참조 누락 오류라면 Play를 종료하고 Move Action·Jump Action을 연결한 뒤 PlayerController를 다시 활성화합니다.

참고 자료

질문이 남았다면

발생한 현상과 확인한 값을 함께 제시합니다. 예: “Space를 한 번 누르고 놓았는데 계속 위로 올라갑니다. FixedUpdate 마지막에서 요청을 지우는 줄을 확인했습니다.”

다음 학습Collision과 Trigger, 수집·위험·목표
5주차 1교시 →