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

[챗GPT게임개발17] ChatGPT를 활용하여 벽 타기 로직 추가하기

by 인텔리노마드라이프 2024. 5. 8.
728x90

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

오늘은 ChatGPT를 활용하여 Unity 플랫포머 게임에서 벽 타기 로직을 추가해볼께요.

- 오늘의 목표 : 플레이어 벽 타기 로직 구현 
- 필요한 기능 

    1. 플레이어가 벽에 닿았는 지를 감지 및 슬라이딩 기능 추가 
    2. 점프 상태 추가

 

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

벽 타기 로직을 추가할 스크립트를 먼저 학습 시켜요.

좀 더 코딩을 정확히 하기 위해 수정할 코드를 챗GPT에 학습을 시켰어요.

[질문] 안녕 ChatGPT, 아래 코드를 정확히 학습해줘
* 코드는 기존 PlayerController 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Platformer.Gameplay;
using static Platformer.Core.Simulation;
using Platformer.Model;
using Platformer.Core;

namespace Platformer.Mechanics
{
    /// <summary>
    /// This is the main class used to implement control of the player.
    /// It is a superset of the AnimationController class, but is inlined to allow for any kind of customisation.
    /// </summary>
    public class PlayerController : KinematicObject
    {
        public AudioClip jumpAudio;
        public AudioClip respawnAudio;
        public AudioClip ouchAudio;

        /// <summary>
        /// Max horizontal speed of the player.
        /// </summary>
        public float maxSpeed = 7;
        /// <summary>
        /// Initial jump velocity at the start of a jump.
        /// </summary>
        public float jumpTakeOffSpeed = 7;

        public JumpState jumpState = JumpState.Grounded;
        private bool stopJump;
        /*internal new*/ public Collider2D collider2d;
        /*internal new*/ public AudioSource audioSource;
        public Health health;
        public bool controlEnabled = true;

        bool jump;
        Vector2 move;
        SpriteRenderer spriteRenderer;
        internal Animator animator;
        readonly PlatformerModel model = Simulation.GetModel<PlatformerModel>();

        public Bounds Bounds => collider2d.bounds;

        void Awake()
        {
            health = GetComponent<Health>();
            audioSource = GetComponent<AudioSource>();
            collider2d = GetComponent<Collider2D>();
            spriteRenderer = GetComponent<SpriteRenderer>();
            animator = GetComponent<Animator>();
        }

        protected override void Update()
        {
            if (controlEnabled)
            {
                move.x = Input.GetAxis("Horizontal");
                if (jumpState == JumpState.Grounded && Input.GetButtonDown("Jump"))
                    jumpState = JumpState.PrepareToJump;
                else if (Input.GetButtonUp("Jump"))
                {
                    stopJump = true;
                    Schedule<PlayerStopJump>().player = this;
                }
            }
            else
            {
                move.x = 0;
            }
            UpdateJumpState();
            base.Update();
        }

        void UpdateJumpState()
        {
            jump = false;
            switch (jumpState)
            {
                case JumpState.PrepareToJump:
                    jumpState = JumpState.Jumping;
                    jump = true;
                    stopJump = false;
                    break;
                case JumpState.Jumping:
                    if (!IsGrounded)
                    {
                        Schedule<PlayerJumped>().player = this;
                        jumpState = JumpState.InFlight;
                    }
                    break;
                case JumpState.InFlight:
                    if (IsGrounded)
                    {
                        Schedule<PlayerLanded>().player = this;
                        jumpState = JumpState.Landed;
                    }
                    break;
                case JumpState.Landed:
                    jumpState = JumpState.Grounded;
                    break;
            }
        }

        protected override void ComputeVelocity()
        {
            if (jump && IsGrounded)
            {
                velocity.y = jumpTakeOffSpeed * model.jumpModifier;
                jump = false;
            }
            else if (stopJump)
            {
                stopJump = false;
                if (velocity.y > 0)
                {
                    velocity.y = velocity.y * model.jumpDeceleration;
                }
            }

            if (move.x > 0.01f)
                spriteRenderer.flipX = false;
            else if (move.x < -0.01f)
                spriteRenderer.flipX = true;

            animator.SetBool("grounded", IsGrounded);
            animator.SetFloat("velocityX", Mathf.Abs(velocity.x) / maxSpeed);

            targetVelocity = move * maxSpeed;
        }

        public enum JumpState
        {
            Grounded,
            PrepareToJump,
            Jumping,
            InFlight,
            Landed
        }
    }
}

[답변]
이 코드는 Unity의 2D 플랫폼 게임에서 플레이어 움직임과 점프 로직을 구현하는 PlayerController 클래스입니다. 다음은 이 코드의 각 부분을 분석한 내용입니다.

주요 기능 요약

  1. 플레이어의 오디오 및 애니메이션 관리:
    • jumpAudio, respawnAudio, ouchAudio: 점프, 부활, 데미지 소리 재생에 사용되는 오디오 클립.
    • audioSource: 오디오 클립을 재생하는 데 사용되는 오디오 소스 컴포넌트.
    • animator: 플레이어 애니메이션을 제어하는 애니메이터.
  2. 점프 및 움직임 속성:
    • maxSpeed: 플레이어의 최대 수평 속도.
    • jumpTakeOffSpeed: 점프 시작 시 플레이어가 위로 올라가는 속도.
  3. 플레이어의 점프 상태:
    • JumpState: 플레이어의 점프 상태를 나타내는 열거형으로, 상태 값은 Grounded, PrepareToJump, Jumping, InFlight, Landed가 있습니다.
  4. 움직임 제어 로직:
    • move: 플레이어의 수평 움직임을 나타내는 2D 벡터.
    • jump, stopJump: 점프와 점프 중지에 대한 상태 변수.
  5. 플레이어의 콜라이더 및 물리 속성:
    • collider2d: 플레이어의 충돌을 감지하기 위한 Collider2D 컴포넌트.
    • Bounds: 플레이어의 콜라이더 경계를 나타내는 프로퍼티.
  6. 플레이어 제어 로직:
    • Update(): 매 프레임마다 호출되어 플레이어의 수평 이동, 점프 입력 및 상태를 업데이트합니다.
    • UpdateJumpState(): 현재 점프 상태를 기반으로 점프, 비행, 착륙 상태를 업데이트합니다.
    • ComputeVelocity(): 플레이어의 현재 속도와 애니메이션 상태를 계산합니다.

코드 흐름

  • Awake(): 초기화 메서드로, 관련 컴포넌트를 가져오고 기본 속성을 설정합니다.
  • Update():
    • 수평 움직임을 Input.GetAxis("Horizontal")로 가져와 move에 설정합니다.
    • 점프 입력(Jump 키)을 감지해 점프 상태로 전환합니다.
    • UpdateJumpState() 메서드를 호출해 점프 상태를 갱신합니다.
  • UpdateJumpState():
    • PrepareToJump 상태에서 Jumping 상태로 전환하고, 점프를 시작합니다.
    • Jumping 상태에서 지면에 닿지 않으면 InFlight 상태로 전환합니다.
    • InFlight 상태에서 지면에 닿으면 Landed 상태로 전환하고, 다시 Grounded 상태로 돌아옵니다.
  • ComputeVelocity():
    • jump가 활성화되면 플레이어의 수직 속도를 설정해 점프를 수행합니다.
    • stopJump가 활성화되면 수직 속도를 줄입니다.
    • 플레이어의 수평 속도를 targetVelocity로 설정합니다.

이 코드를 바탕으로 추가 기능을 구현하거나 수정하려면 주로 Update()와 ComputeVelocity()에서 플레이어의 움직임과 점프 상태를 변경하면 됩니다.

 

학습이 완료되면 이제 기능 추가를 요청해요.

수정대상인 스크립트를 학습시키고 난 다음 원하는 기능을 추가해달라고 하면 되요.

[질문] 안녕 ChatGPT, 학습된 코드를 가지고 플레이어가 벽을 타는 기능을 추가해줘

[답변]
플레이어가 벽을 타는 기능을 추가하려면 벽 감지 로직을 작성하고, 점프 상태에 벽 타기 상태를 추가해야 합니다. 다음은 벽 타기 기능을 포함하도록 수정된 코드입니다.

수정된 코드

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Platformer.Gameplay;
using static Platformer.Core.Simulation;
using Platformer.Model;
using Platformer.Core;

namespace Platformer.Mechanics
{
    public class PlayerController : KinematicObject
    {
        public AudioClip jumpAudio;
        public AudioClip respawnAudio;
        public AudioClip ouchAudio;

        public float maxSpeed = 7;
        public float jumpTakeOffSpeed = 7;

        // 벽 타기 관련 변수 추가
        public LayerMask wallLayer;
        public float wallSlideSpeed = 1.5f;
        public float wallJumpXSpeed = 5f;
        public float wallJumpYSpeed = 7f;

        private bool isTouchingWall;
        private bool wallSliding;
        private bool wallJumping;

        public JumpState jumpState = JumpState.Grounded;
        private bool stopJump;
        public Collider2D collider2d;
        public AudioSource audioSource;
        public Health health;
        public bool controlEnabled = true;

        bool jump;
        Vector2 move;
        SpriteRenderer spriteRenderer;
        internal Animator animator;
        readonly PlatformerModel model = Simulation.GetModel<PlatformerModel>();

        public Bounds Bounds => collider2d.bounds;

        void Awake()
        {
            health = GetComponent<Health>();
            audioSource = GetComponent<AudioSource>();
            collider2d = GetComponent<Collider2D>();
            spriteRenderer = GetComponent<SpriteRenderer>();
            animator = GetComponent<Animator>();
        }

        protected override void Update()
        {
            if (controlEnabled)
            {
                move.x = Input.GetAxis("Horizontal");
                if (jumpState == JumpState.Grounded && Input.GetButtonDown("Jump"))
                    jumpState = JumpState.PrepareToJump;
                else if (Input.GetButtonUp("Jump"))
                {
                    stopJump = true;
                    Schedule<PlayerStopJump>().player = this;
                }
            }
            else
            {
                move.x = 0;
            }

            UpdateWallSlide();
            UpdateJumpState();
            base.Update();
        }

        // 벽 슬라이딩 상태를 업데이트하는 로직
        void UpdateWallSlide()
        {
            // 벽 감지 (OverlapCircle 또는 BoxCast 사용)
            isTouchingWall = Physics2D.OverlapCircle(collider2d.bounds.center, collider2d.bounds.extents.x + 0.1f, wallLayer);

            // 벽 슬라이딩 상태 확인
            if (isTouchingWall && !IsGrounded && move.x != 0)
            {
                wallSliding = true;
                velocity.y = Mathf.Clamp(velocity.y, -wallSlideSpeed, float.MaxValue);
            }
            else
            {
                wallSliding = false;
            }
        }

        // 점프 상태 업데이트
        void UpdateJumpState()
        {
            jump = false;
            switch (jumpState)
            {
                case JumpState.PrepareToJump:
                    if (wallSliding)
                    {
                        jumpState = JumpState.WallJumping;
                        wallJumping = true;
                        jump = true;
                        stopJump = false;
                    }
                    else
                    {
                        jumpState = JumpState.Jumping;
                        jump = true;
                        stopJump = false;
                    }
                    break;
                case JumpState.Jumping:
                    if (!IsGrounded)
                    {
                        Schedule<PlayerJumped>().player = this;
                        jumpState = JumpState.InFlight;
                    }
                    break;
                case JumpState.InFlight:
                    if (IsGrounded)
                    {
                        Schedule<PlayerLanded>().player = this;
                        jumpState = JumpState.Landed;
                    }
                    break;
                case JumpState.WallJumping:
                    if (!wallJumping)
                    {
                        jumpState = JumpState.InFlight;
                    }
                    break;
                case JumpState.Landed:
                    jumpState = JumpState.Grounded;
                    break;
            }
        }

        protected override void ComputeVelocity()
        {
            if (jump)
            {
                if (wallJumping)
                {
                    // 벽 점프 로직
                    velocity.x = wallJumpXSpeed * (spriteRenderer.flipX ? 1 : -1);
                    velocity.y = wallJumpYSpeed;
                    wallJumping = false;
                }
                else if (IsGrounded)
                {
                    velocity.y = jumpTakeOffSpeed * model.jumpModifier;
                }
                jump = false;
            }
            else if (stopJump)
            {
                stopJump = false;
                if (velocity.y > 0)
                {
                    velocity.y = velocity.y * model.jumpDeceleration;
                }
            }

            if (move.x > 0.01f)
                spriteRenderer.flipX = false;
            else if (move.x < -0.01f)
                spriteRenderer.flipX = true;

            animator.SetBool("grounded", IsGrounded);
            animator.SetFloat("velocityX", Mathf.Abs(velocity.x) / maxSpeed);

            targetVelocity = move * maxSpeed;
        }

        // 벽 점프 상태를 추가
        public enum JumpState
        {
            Grounded,
            PrepareToJump,
            Jumping,
            InFlight,
            WallJumping,
            Landed
        }
    }
}

추가된 벽 타기 로직

  • UpdateWallSlide: 플레이어가 벽과 접촉하고 있는지 확인하고, 벽에 접촉할 때 천천히 미끄러지게 합니다.
  • JumpState.WallJumping: 벽 점프 상태를 추가해 플레이어가 벽에서 점프할 수 있도록 합니다.
  • ComputeVelocity: 벽에서 점프할 때 플레이어의 수평 및 수직 속도를 설정합니다.

사용 방법

  1. 벽 레이어 설정: Inspector에서 wallLayer 필드에 벽 레이어를 지정하세요.
  2. 감지 범위 조절: OverlapCircle의 범위가 벽을 감지하는 데 충분한지 확인하세요.

 

벽 레이어 설정하기 

수정된 스크립트를 적용하기 위해 벽 레이어를 만들었어요.

 

Player 에 wallLayer 적용하기 

이제 만들어진 wallLayer 를 Player 오브젝트에 추가했어요.

 

코드를 저장하고 실행을 했어요.

그런데 플레이어가 슬라이딩 될때 점프가 되지 않았어요.

슬라이딩 될 때 점프 로직을 수정해줘 

그래서 플레이어가 벽에 슬라이딩 될 때 점프 로직을 수정하라고 했어요.

[질문] 안녕 ChatGPT, 플레이어가 벽에 슬라이딩될때 점프를 할 수 있게 코드를 수정해줘.
 

[답변]

벽에 슬라이딩될 때 점프할 수 있도록 기능을 구현하려면 UpdateWallSlide에서 벽에 접촉했을 때 jump 키 입력을 받아 벽 점프 상태로 전환해야 합니다. 이를 위해서는 UpdateJumpState에서 벽 점프 상태를 확인하고 ComputeVelocity에서 벽 점프 로직을 구현해야 합니다.

아래는 수정된 코드입니다:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Platformer.Gameplay;
using static Platformer.Core.Simulation;
using Platformer.Model;
using Platformer.Core;

namespace Platformer.Mechanics
{
    public class PlayerController : KinematicObject
    {
        public AudioClip jumpAudio;
        public AudioClip respawnAudio;
        public AudioClip ouchAudio;

        public float maxSpeed = 7;
        public float jumpTakeOffSpeed = 7;

        // 벽 타기 관련 변수 추가
        public LayerMask wallLayer;
        public float wallSlideSpeed = 1.5f;
        public float wallJumpXSpeed = 5f;
        public float wallJumpYSpeed = 7f;

        private bool isTouchingWall;
        private bool wallSliding;
        private bool wallJumping;

        public JumpState jumpState = JumpState.Grounded;
        private bool stopJump;
        public Collider2D collider2d;
        public AudioSource audioSource;
        public Health health;
        public bool controlEnabled = true;

        bool jump;
        Vector2 move;
        SpriteRenderer spriteRenderer;
        internal Animator animator;
        readonly PlatformerModel model = Simulation.GetModel<PlatformerModel>();

        public Bounds Bounds => collider2d.bounds;

        void Awake()
        {
            health = GetComponent<Health>();
            audioSource = GetComponent<AudioSource>();
            collider2d = GetComponent<Collider2D>();
            spriteRenderer = GetComponent<SpriteRenderer>();
            animator = GetComponent<Animator>();
        }

        protected override void Update()
        {
            if (controlEnabled)
            {
                move.x = Input.GetAxis("Horizontal");
                if ((jumpState == JumpState.Grounded || wallSliding) && Input.GetButtonDown("Jump"))
                {
                    jumpState = JumpState.PrepareToJump;
                }
                else if (Input.GetButtonUp("Jump"))
                {
                    stopJump = true;
                    Schedule<PlayerStopJump>().player = this;
                }
            }
            else
            {
                move.x = 0;
            }

            UpdateWallSlide();
            UpdateJumpState();
            base.Update();
        }

        void UpdateWallSlide()
        {
            // 벽 감지 (OverlapCircle 또는 BoxCast 사용)
            isTouchingWall = Physics2D.OverlapCircle(collider2d.bounds.center, collider2d.bounds.extents.x + 0.1f, wallLayer);

            // 벽 슬라이딩 상태 확인
            if (isTouchingWall && !IsGrounded && move.x != 0)
            {
                wallSliding = true;
                velocity.y = Mathf.Clamp(velocity.y, -wallSlideSpeed, float.MaxValue);
            }
            else
            {
                wallSliding = false;
            }
        }

        void UpdateJumpState()
        {
            jump = false;
            switch (jumpState)
            {
                case JumpState.PrepareToJump:
                    if (wallSliding)
                    {
                        jumpState = JumpState.WallJumping;
                        wallJumping = true;
                        jump = true;
                        stopJump = false;
                    }
                    else
                    {
                        jumpState = JumpState.Jumping;
                        jump = true;
                        stopJump = false;
                    }
                    break;
                case JumpState.Jumping:
                    if (!IsGrounded)
                    {
                        Schedule<PlayerJumped>().player = this;
                        jumpState = JumpState.InFlight;
                    }
                    break;
                case JumpState.InFlight:
                    if (IsGrounded)
                    {
                        Schedule<PlayerLanded>().player = this;
                        jumpState = JumpState.Landed;
                    }
                    break;
                case JumpState.WallJumping:
                    if (!wallJumping)
                    {
                        jumpState = JumpState.InFlight;
                    }
                    break;
                case JumpState.Landed:
                    jumpState = JumpState.Grounded;
                    break;
            }
        }

        protected override void ComputeVelocity()
        {
            if (jump)
            {
                if (wallJumping)
                {
                    // 벽 점프 로직
                    velocity.x = wallJumpXSpeed * (spriteRenderer.flipX ? 1 : -1);
                    velocity.y = wallJumpYSpeed;
                    wallJumping = false;
                }
                else if (IsGrounded)
                {
                    velocity.y = jumpTakeOffSpeed * model.jumpModifier;
                }
                jump = false;
            }
            else if (stopJump)
            {
                stopJump = false;
                if (velocity.y > 0)
                {
                    velocity.y = velocity.y * model.jumpDeceleration;
                }
            }

            if (move.x > 0.01f)
                spriteRenderer.flipX = false;
            else if (move.x < -0.01f)
                spriteRenderer.flipX = true;

            animator.SetBool("grounded", IsGrounded);
            animator.SetFloat("velocityX", Mathf.Abs(velocity.x) / maxSpeed);

            targetVelocity = move * maxSpeed;
        }

        // 벽 점프 상태를 추가
        public enum JumpState
        {
            Grounded,
            PrepareToJump,
            Jumping,
            InFlight,
            WallJumping,
            Landed
        }
    }
}

코드 설명

  • Update(): 벽 슬라이딩 상태에서 점프 버튼이 눌리면 JumpState.PrepareToJump 상태로 전환하도록 코드를 변경했습니다.
  • UpdateWallSlide(): 플레이어가 벽과 접촉하는지 확인하는 로직을 사용해 벽 슬라이딩 상태를 확인하고, 이를 기반으로 속도를 조절합니다.
  • ComputeVelocity(): 벽 점프 로직을 추가해 벽에서 점프할 수 있도록 합니다.

이렇게 하면 플레이어가 벽에 슬라이딩되면 점프를 할 수 있게 됩니다.

 

스크립트를 게임을 실행해서 플레이어가 잘 동작하는 지 확인했어요. 

 

잘 동작하네요. 그런데 한 가지 궁금한 점이 생겼어요.

기존 소스와 변경된 소스를 비교해줄래?

궁금했어요. 두 개의 소스를 어떻게 비교할지.

[질문] 안녕 ChatGPT, 벽타는 로직 부분 즉 추가된 코드를 기존 코드와 비교를 해줄래?

[답변]

네, 벽 타기 로직 부분을 기존 코드와 비교해 드리겠습니다.

기존 코드

기존 코드는 플레이어의 기본 점프와 움직임 로직을 다루는 코드입니다. 플레이어는 지면에서 점프하거나 이동할 수 있고, 점프 상태를 관리합니다.

protected override void Update()
{
    if (controlEnabled)
    {
        move.x = Input.GetAxis("Horizontal");
        if (jumpState == JumpState.Grounded && Input.GetButtonDown("Jump"))
            jumpState = JumpState.PrepareToJump;
        else if (Input.GetButtonUp("Jump"))
        {
            stopJump = true;
            Schedule<PlayerStopJump>().player = this;
        }
    }
    else
    {
        move.x = 0;
    }

    UpdateJumpState();
    base.Update();
}

void UpdateJumpState()
{
    jump = false;
    switch (jumpState)
    {
        case JumpState.PrepareToJump:
            jumpState = JumpState.Jumping;
            jump = true;
            stopJump = false;
            break;
        case JumpState.Jumping:
            if (!IsGrounded)
            {
                Schedule<PlayerJumped>().player = this;
                jumpState = JumpState.InFlight;
            }
            break;
        case JumpState.InFlight:
            if (IsGrounded)
            {
                Schedule<PlayerLanded>().player = this;
                jumpState = JumpState.Landed;
            }
            break;
        case JumpState.Landed:
            jumpState = JumpState.Grounded;
            break;
    }
}

protected override void ComputeVelocity()
{
    if (jump && IsGrounded)
    {
        velocity.y = jumpTakeOffSpeed * model.jumpModifier;
        jump = false;
    }
    else if (stopJump)
    {
        stopJump = false;
        if (velocity.y > 0)
        {
            velocity.y = velocity.y * model.jumpDeceleration;
        }
    }

    if (move.x > 0.01f)
        spriteRenderer.flipX = false;
    else if (move.x < -0.01f)
        spriteRenderer.flipX = true;

    animator.SetBool("grounded", IsGrounded);
    animator.SetFloat("velocityX", Mathf.Abs(velocity.x) / maxSpeed);

    targetVelocity = move * maxSpeed;
}

수정된 코드 (벽 타기 로직 포함)

수정된 코드에서는 벽에 슬라이딩하는 상태를 감지하고, 슬라이딩 상태에서 점프할 수 있도록 구현되었습니다. 이 추가된 기능을 위해 벽 감지, 벽 슬라이딩, 벽 점프 상태 등을 처리합니다.

void UpdateWallSlide()
{
    // 벽 감지 (OverlapCircle 사용)
    isTouchingWall = Physics2D.OverlapCircle(collider2d.bounds.center, collider2d.bounds.extents.x + 0.1f, wallLayer);

    // 벽 슬라이딩 상태 확인
    if (isTouchingWall && !IsGrounded && move.x != 0)
    {
        wallSliding = true;
        velocity.y = Mathf.Clamp(velocity.y, -wallSlideSpeed, float.MaxValue);
        Debug.Log("Wall Sliding");
    }
    else
    {
        wallSliding = false;
    }
}

void UpdateJumpState()
{
    jump = false;
    switch (jumpState)
    {
        case JumpState.PrepareToJump:
            if (wallSliding)
            {
                jumpState = JumpState.WallJumping;
                wallJumping = true;
                jump = true;
                stopJump = false;
                Debug.Log("Jump State: WallJumping");
            }
            else
            {
                jumpState = JumpState.Jumping;
                jump = true;
                stopJump = false;
                Debug.Log("Jump State: Jumping");
            }
            break;
        case JumpState.Jumping:
            if (!IsGrounded)
            {
                Schedule<PlayerJumped>().player = this;
                jumpState = JumpState.InFlight;
                Debug.Log("Jump State: InFlight");
            }
            break;
        case JumpState.InFlight:
            if (IsGrounded)
            {
                Schedule<PlayerLanded>().player = this;
                jumpState = JumpState.Landed;
                Debug.Log("Jump State: Landed");
            }
            break;
        case JumpState.WallJumping:
            if (!wallJumping)
            {
                jumpState = JumpState.InFlight;
                Debug.Log("Jump State: InFlight (from WallJumping)");
            }
            break;
        case JumpState.Landed:
            jumpState = JumpState.Grounded;
            Debug.Log("Jump State: Grounded");
            break;
    }
}

protected override void ComputeVelocity()
{
    if (jump)
    {
        if (wallJumping)
        {
            // 벽 점프 로직
            velocity.x = wallJumpXSpeed * (spriteRenderer.flipX ? 1 : -1);
            velocity.y = wallJumpYSpeed;
            wallJumping = false;
            Debug.Log("Wall Jump Performed");
        }
        else if (IsGrounded)
        {
            velocity.y = jumpTakeOffSpeed * model.jumpModifier;
            Debug.Log("Regular Jump Performed");
        }
        jump = false;
    }
    else if (stopJump)
    {
        stopJump = false;
        if (velocity.y > 0)
        {
            velocity.y = velocity.y * model.jumpDeceleration;
            Debug.Log("Jump Stopped");
        }
    }

    if (move.x > 0.01f)
        spriteRenderer.flipX = false;
    else if (move.x < -0.01f)
        spriteRenderer.flipX = true;

    animator.SetBool("grounded", IsGrounded);
    animator.SetFloat("velocityX", Mathf.Abs(velocity.x) / maxSpeed);

    targetVelocity = move * maxSpeed;
}

비교 분석

  1. 벽 감지 및 슬라이딩:
    • UpdateWallSlide 메서드를 통해 벽에 접촉 중인지 확인하고, 접촉 중이면 속도를 제한하여 슬라이딩 상태로 전환합니다.
  2. 점프 상태 추가:
    • JumpState.WallJumping을 추가하여 벽에서 점프할 수 있는 상태를 구현했습니다.
  3. 점프 상태 업데이트:
    • UpdateJumpState에서 벽 슬라이딩 상태라면 WallJumping 상태로 전환합니다.
  4. 속도 조정:
    • ComputeVelocity에서 벽 점프 시 플레이어의 수평 및 수직 속도를 설정해 벽에서 점프하는 기능을 추가했습니다.

이러한 로직을 통해 벽에 슬라이딩되는 동안 벽 점프를 수행할 수 있도록 수정되었습니다.

 

오늘은 ChatGPT를 활용하여 Unity 플랫포머 게임에서 벽 타기 로직을 추가해봤어요.

[요리 중인 인텔리원스튜디오 CEO. 인텔리노마드라이프와 함께 행복하세요 from IntelliOneStudio ]

 

 

지금까지,

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

감사합니다.

728x90