본문 바로가기
디지털노마드

[5분개발] ChatGPT를 활용하여 소스 코드 수정하기

by 인텔리노마드라이프 2024. 4. 25.
728x90

안녕하세요. 인텔리원스튜디오(IntelliOneStudio)입니다.

오늘은 ChatGPT를 활용하여 소스 코드 수정하는 방법을 살펴볼까해요. 

 

 ChatGPT 답변 내용 중 제가 별도로 표시한 파란색 내용을 기준으로 읽으시면 좀 더 이해가 쉽게 될거예요.

 

타앨맵과 플레이어 상호 작용하는 코드 만들기

지난 기사를 통해 만든 타일맵이 생각나실거예요. 

이번 시간에는 타일맵과 플레이어가 상호 작용하는 코드를 만들어볼께요.

 

[질문] 안녕 ChatGPT, 현재 코드에 필요한 사항은 다음과 같아 

            - 플레이어가 게임씬에 존재하고 있어
            - Idle, Run 애니메이션 생성은 완료했어 

이제 타일맵과 상호 작용하는 방법을 자세히 설명해주고 필요한 스크립터도 만들어줄래?

[답변]

플레이어 캐릭터가 타일맵과 상호작용하며 게임 씬에서 움직임을 구현하는 과정은 Unity에서 다루는 기본적이면서도 중요한 부분입니다. 이를 위해 플레이어가 타일맵의 물리적 환경과 올바르게 상호작용하도록 설정하고, 필요한 스크립트를 작성하는 방법을 아래에서 설명합니다.

1. 필요한 컴포넌트 추가

플레이어 게임 오브젝트에는 다음과 같은 컴포넌트가 추가되어야 합니다:

  • Rigidbody2D: 플레이어의 물리적 동작을 처리합니다. 이 컴포넌트는 플레이어에 중력을 적용하고, 이동 및 점프 등의 물리적 인터랙션을 가능하게 합니다.
  • Collider2D (예: BoxCollider2D): 플레이어의 충돌 경계를 정의합니다. 이는 플레이어가 타일맵의 타일과 충돌하거나, 다른 객체와 상호작용할 때 필요합니다.

2. Animator 설정 확인

  • Animator 컴포넌트: 이미 설정된 Idle과 Run 애니메이션 클립이 플레이어의 움직임에 따라 올바르게 전환되는지 확인합니다. 이는 Animator의 Parameters에 bool 타입의 isRunning 같은 파라미터를 추가하여 제어할 수 있습니다.

3. 플레이어 이동 스크립트 작성

다음은 플레이어가 타일맵과 상호작용하면서 이동할 수 있도록 하는 스크립트의 예시입니다:

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float speed = 5.0f; // 플레이어의 이동 속도
    private Rigidbody2D rb;
    private Animator animator;
    private float horizontalInput;
    private bool isRunning;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
    }

    void Update()
    {
        // 플레이어의 수평 입력을 받습니다.
        horizontalInput = Input.GetAxisRaw("Horizontal");

        // 입력에 따라 플레이어의 이동 속도를 조절하고 애니메이터 파라미터를 설정합니다.
        rb.velocity = new Vector2(horizontalInput * speed, rb.velocity.y);
        isRunning = horizontalInput != 0;
        animator.SetBool("isRunning", isRunning);

        // 플레이어의 방향 전환을 처리합니다.
        if (horizontalInput < 0)
        {
            transform.localScale = new Vector3(-1, 1, 1); // 왼쪽으로 이동
        }
        else if (horizontalInput > 0)
        {
            transform.localScale = new Vector3(1, 1, 1); // 오른쪽으로 이동
        }
    }
}

 

4. 게임에서 테스트

  • 스크립트를 플레이어 게임 오브젝트에 적용한 후, 게임을 실행하여 플레이어의 이동과 타일맵의 콜라이더와의 상호작용을 테스트합니다. 플레이어가 타일맵의 타일과 제대로 상호작용하는지 (예: 콜라이더에 막혀 이동할 수 없는 부분에서 정지하는지) 확인합니다.

이 과정을 통해 플레이어가 타일맵과의 상호작용을 원활하게 수행할 수 있도록 설정하며, 게임의 몰입도와 플레이어 경험을 향상시킬 수 있습니다. 게임 개발 과정에서 플레이어와 환경 간의 상호작용은 매우 중요하므로, 이 부분에 대한 충분한 테스트와 최적화가 필요합니다.

 

 

이제 기본 코드는 만들어졌어요. 

 

애니메이션 상태 전환 기능 수정

그런데 왼쪽으로 이동 시 애니메이션이 상태 전환이 바로 일어나지 않았어요.

 

[질문] 안녕 ChatGPT, 왼쪽으로 이동 시 Run 상태로 바로 변경되지 않고 Idle 상태로 약간 움직인 후 Run 상태로 변경되고 있어.
애니메이션 상태가 바로 변경이 될 수 있게 수정해줘 

[답변]

애니메이션 상태 전환이 즉시 일어나지 않고 지연되는 문제는 Unity의 Animator에서 Transition 설정 때문일 가능성이 높습니다. 특히, Exit Time이 설정되어 있을 경우, 애니메이션 상태가 완전히 끝난 후에야 다음 상태로 전환되기 때문에 이런 지연이 발생할 수 있습니다. 이를 수정하여 Run 상태로의 전환을 즉각적으로 만들기 위해 다음과 같은 절차를 따를 수 있습니다.

1. Animator Transition 수정하기

  1. Unity Editor에서 Animator 창 열기: Window > Animation > Animator를 열어서 플레이어의 Animator 컨트롤러를 확인합니다.
  2. Transition 설정 확인: Idle 상태에서 Run 상태로의 전환을 찾습니다. 이 전환을 클릭하고, Transition 세부 사항을 확인합니다.
  3. Exit Time 비활성화: Transition 설정에서 Has Exit Time 체크박스를 비활성화 (* 이 체크 박스를 비활성화하면 지연 문제는 해결되요.) 합니다. 이 설정을 비활성화하면 현재 상태의 재생이 완료될 때까지 기다리지 않고, 조건이 충족되는 즉시 다음 상태로 전환됩니다.
  4. Transition 조건 확인 및 조정: 전환 조건(Conditions)에서 IsRunning 변수가 true일 때 즉시 Run 상태로 전환되도록 설정합니다. 또한, 전환 지연(Transition Duration)을 최소로 조정하여 전환이 더 빠르게 발생하도록 설정할 수 있습니다.

2. 스크립트에서의 입력 처리 개선

플레이어의 움직임을 처리하는 스크립트에서도 입력을 더 민감하게 받아들여 즉시 반응하도록 다음과 같이 개선할 수 있습니다.

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float speed = 5.0f;
    private Rigidbody2D rb;
    private Animator animator;
    private float horizontalInput;
    private bool isRunning;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
    }

    void Update()
    {
        horizontalInput = Input.GetAxisRaw("Horizontal");
        isRunning = Mathf.Abs(horizontalInput) > 0; // 절대값을 사용하여 양의 방향 또는 음의 방향 입력을 즉시 감지

        // Rigidbody에 속도를 즉시 적용
        rb.velocity = new Vector2(horizontalInput * speed, rb.velocity.y);
        animator.SetBool("IsRunning", isRunning);

        // 방향 전환 처리
        if (horizontalInput != 0)
        {
            transform.localScale = new Vector3(Mathf.Sign(horizontalInput), 1, 1); // 입력 방향에 따라 캐릭터를 뒤집음
        }
    }
}

 

위 수정은 Mathf.Sign(horizontalInput)을 사용하여 입력 방향에 따라 캐릭터의 방향을 즉시 전환하도록 합니다. 이렇게 함으로써 캐릭터의 방향 전환과 애니메이션 상태 전환이 더욱 신속하게 이루어지게 됩니다.

3. 게임 테스트 및 디버깅

변경 사항을 적용한 후, 게임을 실행하여 캐릭터의 반응성과 애니메이션 상태 전환이 기대대로 작동하는지 확인합니다. 문제가 계속 발생한다면, 추가적인 디버깅을 통해 애니메이션 클립, Animator 설정, 또는 스크립트의 다른 부분을 점검할 필요가 있습니다.

 

 

하지만 코드에서 몇 가지 만족스럽지 못한 결과가 나와서 2-3번 수정을 했어요. 

 

현실 세계에서 플레이어가 움직이는 것처럼 부드럽게 달려가는 기능

그리고 현실 세계에서 사람이 움직이는 것처럼 수정하고 싶다는 생각이 들었어요.

다음과 같이 질문을 생각하고 전달했어요.

 

[질문] 안녕 ChatGPT, 현실 세계에서 플레이어가 움직이는 것처럼 부드럽게 달려가는 기능이 필요할 것 같아. 추가해줄래? 

[답변]
플레이어가 부드럽게 달리기 시작하고 멈추도록 만들기 위해, 가속도와 감속도를 구현하는 방법을 적용할 수 있습니다. 이렇게 하면 캐릭터의 움직임이 더 자연스럽고 현실적으로 보일 것입니다. 아래는 이를 위해 필요한 코드 수정 사항입니다.

코드 수정: 가속도 및 감속도 적용

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float speed = 5.0f; // 플레이어의 최대 이동 속도
    public float acceleration = 10.0f; // 가속도
    public float deceleration = 10.0f; // 감속도
    private Rigidbody2D rb;
    private Animator animator;
    private float horizontalInput;
    private bool isRunning;
    private float currentSpeed = 0.0f; // 현재 속도

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
    }

    void Update()
    {
        horizontalInput = Input.GetAxisRaw("Horizontal");
        isRunning = Mathf.Abs(horizontalInput) > 0;

        // 방향 전환을 처리합니다.
        if (horizontalInput != 0)
        {
            transform.localScale = new Vector3(Mathf.Sign(horizontalInput), 1, 1);
        }

        // 플레이어의 현재 속도를 계산합니다.
        if (isRunning)
        {
            // 가속도 적용
            currentSpeed = Mathf.MoveTowards(currentSpeed, speed * Mathf.Sign(horizontalInput), acceleration * Time.deltaTime);
        }
        else
        {
            // 감속도 적용
            currentSpeed = Mathf.MoveTowards(currentSpeed, 0, deceleration * Time.deltaTime);
        }

        // Rigidbody에 계산된 속도를 적용합니다.
        rb.velocity = new Vector2(currentSpeed, rb.velocity.y);

        // 애니메이션 상태 업데이트
        animator.SetBool("IsRunning", isRunning && Mathf.Abs(currentSpeed) > 0.1f); // 속도가 거의 0에 가까울 때는 달리는 애니메이션을 멈춤
    }
}

설명

  1. 가속도 및 감속도 변수 추가: acceleration과 deceleration을 정의하여, 캐릭터가 속도를 빠르게 붙이거나 늦추는 데 사용됩니다.
  2. 현재 속도 관리: currentSpeed 변수를 사용하여 실시간으로 캐릭터의 이동 속도를 관리합니다. 이 속도는 가속 또는 감속을 통해 점진적으로 변경됩니다.
  3. 가속 및 감속 로직: Mathf.MoveTowards 함수를 사용하여 현재 속도를 목표 속도까지 점진적으로 변경합니다. 이 함수는 현재 값에서 목표 값까지 지정된 최대 변화량만큼 값을 이동시킵니다.
  4. 애니메이션 상태 관리: 이동 속도가 거의 0에 가까울 때는 IsRunning을 false로 설정하여 달리는 애니메이션을 멈춥니다. 이는 불필요한 애니메이션 전환이 발생하는 것을 방지합니다.

이 변경을 통해 캐릭터의 이동이 부드러워지며, 시작과 멈춤이 현실적으로 보이게 됩니다. 게임을 플레이하면서 캐릭터의 이동이 자연스럽고 만족스러운지 확인하세요.

 

 

 

이번 수정 사항은 대체로 만족스러웠어요. 

 

플레이어가 멈출 때 미끄러져서 멈추는 부분 수정

추가로 플레이어가 멈출 때 미끄러져서 멈추는 부분이 수정이 필요할 것 같았어요

 

[질문] 안녕 ChatGPT, 플레이어가 바로 멈출 수 있도록 수정해줘
 

[답변]
플레이어가 바로 멈출 수 있도록 하는 방식으로 감속 로직을 수정하겠습니다. 여기서는 이동 중지 시 가속이나 점진적 감속 대신 즉시 멈춤을 적용하도록 변경합니다. 이렇게 하면 플레이어의 입력이 중단되면 즉시 정지할 수 있습니다.

코드 수정:즉시 멈춤 로직 적용

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float speed = 5.0f; // 플레이어의 최대 이동 속도
    public float acceleration = 10.0f; // 가속도
    private Rigidbody2D rb;
    private Animator animator;
    private float horizontalInput;
    private bool isRunning;
    private float currentSpeed = 0.0f; // 현재 속도

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
    }

    void Update()
    {
        horizontalInput = Input.GetAxisRaw("Horizontal");
        isRunning = Mathf.Abs(horizontalInput) > 0;

        // 방향 전환을 처리합니다.
        if (horizontalInput != 0)
        {
            transform.localScale = new Vector3(Mathf.Sign(horizontalInput), 1, 1);
        }

        // 플레이어의 현재 속도를 계산합니다.
        if (isRunning)
        {
            // 가속도 적용
            currentSpeed = Mathf.MoveTowards(currentSpeed, speed * Mathf.Sign(horizontalInput), acceleration * Time.deltaTime);
        }
        else
        {
            // 즉시 멈춤
            currentSpeed = 0;
        }

        // Rigidbody에 계산된 속도를 적용합니다.
        rb.velocity = new Vector2(currentSpeed, rb.velocity.y);

        // 애니메이션 상태 업데이트
        animator.SetBool("IsRunning", isRunning && Mathf.Abs(currentSpeed) > 0.1f); // 속도가 거의 0에 가까울 때는 달리는 애니메이션을 멈춤
    }
}

설명

  1. 즉시 멈춤 로직: isRunning이 false일 때 (즉, 플레이어가 어떤 방향키도 누르고 있지 않을 때), currentSpeed를 즉시 0으로 설정합니다. 이는 플레이어가 이동 중지를 요청하면 즉각적으로 멈추도록 보장합니다.
  2. 가속 로직 유지: 플레이어가 방향키를 누르고 있는 동안에는 currentSpeed가 점진적으로 증가하여 부드럽게 가속됩니다.
  3. 애니메이션 조건: IsRunning 애니메이션 플래그는 currentSpeed가 실질적으로 0이 아닐 때만 true가 됩니다. 이는 플레이어가 실제로 움직일 때만 달리는 애니메이션을 실행하도록 합니다.

이 코드 수정으로 플레이어가 입력을 중지하는 순간 캐릭터가 즉시 멈추게 됩니다. 이 변경을 통해 게임의 반응성이 향상되고, 플레이어의 조작감이 개선될 것입니다. 게임을 테스트하여 새로운 멈춤 로직이 의도대로 작동하는지 확인하세요.

 

 

타앨맵과 플레이어 상호 작용이 잘되네요.

아래 영상은 타일맵과 플레이어의 상호 작용이 잘 이루어지는 결과 영상이예요. 

[코드 수정 결과 영상]

 

 

코드를 만들기 위해 고민하고 생각하는 시간보다

ChatGPT와 어떻게 하면 빠르고 정확하게 소통할 수 있을까를 고민하게 되는 시간이예요.

 

물론 지금의 고민도 AI 가 해결하겠죠? 

 

[인텔리노마드라이프와 함께 행복하세요 from IntelliOneStudio]

 

지금까지,

언제나 성장하는 인텔리원스튜디오(IntelliOneStudio)입니다.

감사합니다.

728x90