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

[AI기술비교] 생성형 AI를 활용해서 소스 코드 분석하기

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

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

오늘은 생성형 AI를 활용해서 소스 코드를 분석해볼께요.

ChatGPT, Unity Muse, Gemini 를 활용한 소스 코드 분석

생성형 AI를 통해 직접 코드를 만들기도 하지만 가끔 잘 짜여진 소스 코드가 궁금할 때가 있어요.

오늘은 ChatGPT(유료 4.0), Unity Muse(15일 무료 사용), Gemini(무료)를 사용해서 소스 코드를 얼마나 잘 설명하는 지 살펴볼까해요.

 

다음의 공통 질문을 ChatGPT, Unity Muse, Gemini에게 요청했어요.

공통 질문
아래 참고 소스 코드를 먼저 자세히 학습한 후 다음의 요청 사항을 처리해줘
[요청사항]
    1. 소스 코드를 아주 자세히 그리고 쉽게 설명해줘
    2. 소스 코드에 한글 주석을 만들어서 새로운 소스 코드를 만들어줘
[참고소스코드] *소스코드 출처는 소스 코드 끝에 있어요.
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 Asset 에 있는 Platform Microgame 소스 참고]

 

IntelliOneStudio 개발자가 답변 내용에 대해 지극히 개인적인 평가도 추가했어요. 

개인적인 평가이기 때문에 참고 사항으로만 봐주세요. 

공통 질문에 대한 ChatGPT 답변 내용

[답변내용]
1. 소스 코드 상세 설명


이 C# 코드는 Unity 게임 엔진을 사용하여 플랫포머 유형의 게임에서 플레이어 캐릭터를 제어하는 데 사용됩니다. 주요 클래스인 PlayerController는 KinematicObject 클래스를 상속받아 물리적 동작을 구현합니다.

주요 컴포넌트 설명:
● AudioClip: 플레이어의 다양한 행동(점프, 리스폰, 피해 입음)에 대응하는 사운드 클립입니다.
● maxSpeed: 플레이어의 최대 수평 속도를 정의합니다.
● jumpTakeOffSpeed: 점프 시작 시 초기 속도입니다.
● JumpState: 점프의 상태를 나타내는 열거형으로, 점프 준비부터 착지까지의 여러 단계를 포함합니다.
● Collider2D, AudioSource: 플레이어의 충돌과 오디오 출력을 관리하는 컴포넌트입니다.
● SpriteRenderer, Animator: 플레이어의 스프라이트와 애니메이션을 관리합니다.
● PlatformerModel: 게임의 모델 데이터에 접근하기 위해 사용됩니다.

메소드 설명:
● Awake(): Unity의 초기화 단계에서 컴포넌트를 가져오는 데 사용됩니다.
● Update(): 매 프레임마다 입력을 처리하고 점프 상태를 업데이트하는 데 사용됩니다.
● UpdateJumpState(): 점프 상태를 관리하고 관련 이벤트를 스케줄링합니다.
● ComputeVelocity(): 플레이어의 속도를 계산하고 애니메이션 상태를 업데이트합니다.

이 클래스는 플레이어의 입력을 받아 처리하고, 점프와 같은 동작을 실행하며, 필요한 오디오를 재생하는 등의 다양한 기능을 수행합니다.

2. 한글 주석이 포함된 소스 코드
아래는 기존 소스 코드에 한글 주석을 추가한 버전입니다.
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>
    /// 플레이어 제어를 구현하기 위한 주요 클래스입니다. AnimationController 클래스의 슈퍼셋이며, 커스터마이징을 허용하기 위해 인라인 처리되었습니다.
    /// </summary>
    public class PlayerController : KinematicObject
    {
        public AudioClip jumpAudio;  // 점프 소리
        public AudioClip respawnAudio;  // 리스폰 소리
        public AudioClip ouchAudio;  // 피해 입었을 때의 소리

        /// <summary>
        /// 플레이어의 최대 수평 속도.
        /// </summary>
        public float maxSpeed = 7;
        /// <summary>
        /// 점프 시작 시의 초기 점프 속도.
        /// </summary>
        public float jumpTakeOffSpeed = 7;

        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;  // 움직임 중지
            }
            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,
            In Flight,
            Landed
        }
    }
}​


이 코드를 사용하여 Unity 게임에서 플레이어의 동작을 제어하고, 애니메이션과 오디오를 관리할 수 있습니다. 각 기능과 로직의 역할이 주석으로 명확히 설명되어 있어, 소스 코드의 이해와 활용에 도움이 될 것입니다.

 

 

[평가결과] 공통 질문에 대한 ChatGPT 답변 내용 

[IntelliOneStudio 개발자 평가 결과]
간결하게 잘 설명해줬고 코드에 한글 주석을 적절히 잘 제공한 것 같아요.

많은 도움이 되는 것 같아요. ♥♥♥♥♥

[ChatGPT가 분석한 코드 결과를 보고 만족하는 IntelliOneStudio 개발자]

공통 질문에 대한 Unity Muse 답변 내용

[답변내용]
제공해주신 소스 코드는 Platformer 게임의 플레이어 캐릭터를 제어하는 데 사용되는 'PlayerController' 클래스를 포함하고 있습니다. 이 클래스는 캐릭터의 움직임과 점프, 그리고 애니메이션 상태 등을 제어합니다.

이 코드는 플레이어 캐릭터의 움직임과 점프를 제어하는 로직을 담고 있습니다. 몇 가지 주요 개념을 보면:
● Awake(): 이 메소드는 게임 오브젝트가 처음 활성화될 때 한 번만 호출됩니다. 이 메소드 내에서 필요한 컴포넌트를 가져와 변수에 저장하기 때문에, 이후 메소드에서는 이 변수를 바로 사용할 수 있어 편리합니다.
● Update(): 이 메소드는 매 프레임마다 호출됩니다. controlEnabled의 값에 따라 캐릭터의 움직임을 제어하고, 점프 버튼의 입력 상태에 따라 점프를 제어합니다.
● GetAxis("Horizontal"): 이 메소드는 수평방향의 입력을 받아 -1 ~ 1 사이의 값을 반환합니다. 이 값은 캐릭터의 움직임의 방향과 크기를 결정하는 데 사용됩니다.
● GetButtonDown("Jump")과 GetButtonUp("Jump"): 이 메소드들은 점프 버튼의 누름 상태와 뗌 상태를 감지합니다. 이를 통해 점프를 시작하거나 중지하는 로직을 구현합니다.
● UpdateJumpState(): 이 메소드는 점프 상태를 업데이트하는 데 사용됩니다. 점프 상태에 따라 캐릭터의 동작이 변경됩니다.
이상이 코드의 주요 부분에 대한 설명입니다. 더 궁금한 사항이 있으시다면 알려주세요!
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>
    /// 이 클래스는 플레이어의 제어를 구현하는 주요 클래스입니다.
    /// AnimationController 클래스의 상위 집합이지만, 모든 종류의 사용자 정의 가능성을 허용하기 위해 인라인으로 삽입되었습니다.
    /// </summary>
    public class PlayerController : KinematicObject
    {
        public AudioClip jumpAudio; // 점프 소리
        public AudioClip respawnAudio; // 재생성 소리
        public AudioClip ouchAudio; // 부상 소리

        /// <summary>
        /// 플레이어의 최대 수평 속도.
        /// </summary>
        public float maxSpeed = 7;
        /// <summary>
        /// 점프를 시작할 때의 초기 점프 속도.
        /// </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 Muse 답변 내용 

[IntelliOneStudio 개발자 평가 결과]
ChatGPT와 같이 간결하게 잘 설명해줬고 코드에 한글 주석을 적절히 잘 제공한 것 같아요.

많은 도움이 되는 것 같아요. ♥♥♥♥♥

[Unity Muse가 분석한 코드 결과를 보고 만족하는 IntelliOneStudio 개발자]

공통 질문에 대한 Gemini 답변 내용

[답변내용]
플랫포머 게임 플레이어 컨트롤러 코드 설명
이 코드는 2D 플랫포머 게임에서 플레이어 캐릭터의 이동, 점프, 게임 세계와의 상호 작용을 제어하는 데 사용됩니다.
코드 구조:
● 라이브러리 임포트:2D 물리, 오디오, 게임 메커니즘 작업에 필요한 라이브러리가 임포트됩니다.
● PlayerController 클래스:이 클래스는 KinematicObject에서 상속받아 플레이어 이동, 점프, 게임 세계와의 상호 작용을 담당합니다.
● 플레이어 속성:점프, 부활, 피격 시 재생되는 오디오 클립.플레이어의 최대 이동 속도.초기 점프 속도.현재 점프 상태 (땅에 있음, 점프 준비, 점프 중, 공중, 착지).점프 조기 종료 여부를 제어하는 플래그.충돌기, 오디오 소스, 체력 컴포넌트, 애니메이터에 대한 참조.플레이어 조작 가능 여부를 나타내는 부울 값.
● Awake 함수:플레이어 게임 오브젝트에 연결된 다양한 컴포넌트(체력, 오디오 소스, 충돌기, 스프라이트 렌더러, 애니메이터)에 대한 참조를 가져옵니다.
● Update 함수 (메인 루프):플레이어 조작이 가능한지 확인합니다."Horizontal" 축에서 수평 이동 입력을 읽습니다.점프 입력 처리:땅에 있고 점프 버튼을 누르면 점프 준비 상태로 전환합니다.점프 버튼을 놓으면 점프를 조기에 중단합니다.플레이어 조작이 불가능하면 이동을 비활성화합니다.현재 점프 상태와 땅 감지에 따라 점프 상태를 업데이트합니다.물리 계산을 위해 기본 클래스 Update 함수를 호출합니다.
● UpdateJumpState 함수:현재 점프 상태에 따라 점프 플래그를 설정하고 상태 간 전환을 처리합니다:점프 준비: 점프하고 점프 상태로 전환합니다.점프 중: 땅에 있는지 확인하고 필요한 경우 "Jumped" 이벤트를 트리거하고 InFlight 상태로 전환합니다.공중: 땅에 있는지 확인하고 필요한 경우 "Landed" 이벤트를 트리거하고 Landed 상태로 전환합니다.착지: 짧은 지연 후 땅에 있음 상태로 돌아갑니다.
● ComputeVelocity 함수:점프, 땅에 있는 상태, 이동 입력을 기반으로 플레이어의 속도를 계산합니다.점프 중이고 땅에 있으면 점프 힘을 적용합니다.점프 버튼을 일찍 놓으면 점프 속도를 점차적으로 줄입니다.이동 방향에 따라 스프라이트 렌더러를 뒤집습니다.땅에 있는 상태와 이동 속도 정보로 애니메이터를 업데이트합니다.이동 입력과 최대 속도를 기반으로 목표 속도를 설정합니다.
● JumpState 열거형:플레이어가 처할 수 있는 다양한 점프 상태를 정의합니다.

새로운 버전으로 한국어 주석 추가:
아래는 한국어 주석이 추가된 코드 버전입니다.
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>
    /// 플레이어 캐릭터를 조작하는 클래스입니다.
    /// 기존 AnimationController 클래스를 상속받지만, 더 많은 기능을 위해 별도로 구현되었습니다.
    /// </summary>
    public class PlayerController : KinematicObject
    {

 

[평가결과] 공통 질문에 대한 Gemini 답변 내용 

[IntelliOneStudio 개발자 평가 결과]
설명을 잘 되어있는데 무료 버젼이라 그런지 소스 코드는 끝까지 생성해주지 못했어요.

그래도 도움이 되는 것 같아요. ♥♥♥♥

[Gemini가 분석한 코드 결과를 보고 살짝 실망해하는 IntelliOneStudio 개발자]

 

오늘은 ChatGPT, Unity Muse, Gemini 를 사용해서 코드 분석을 해봤어요. 

평가는 개인적인 의견일뿐이니 참고만 해주세요. 이 글이 많은 도움이 되셨으면 해요.

 

지금까지,

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

감사합니다.

728x90