본문 바로가기

기타/패스트캠퍼스 Unity

유니티 입문 패스트캠퍼스 챌린지 최종 후기

 패스트캠퍼스에서 다른 강의를 듣다가 우연히 환급 챌린지를 한다고해서 신청했었다. 참가 조건을 자세히 안읽어보고 신청했었는데 30일동안 쉬는날 없이 매일 강의를 들어야하는 조건이었다. 혹시 다음에 환급 챌린지에 참여해 보고 싶은 사람이 있다면 매일 들을 각오가 꼭 필요하다.

 

 비슷한 유니티 입문 강의는 사실 요즘 유튜브에도 많이 제공된다, 유튜브에서 유니티 무료 강의가 꽤 올라와있었고 본적도 있었는데 경험삼아 게임을 만들어보고 싶다 정도의 깊이로 접근한다면 우선 이런 강의를 따라해보는것을 추천한다. 이 강의는 실습하면서 생각한것 이상으로 깊이있는 부분까지 터치하기 때문이다. 그리고 강의자체가 '중급자'용으로 설정되어있다.

 

 처음에는 C# 입문 강의가 배치되어있는데 조금 보고나서 흥미가 생기지않는다면 스킵하는것을 추천하고싶다. 프로그래밍 언어라는것 자체가 몇시간 공부해서 입문이 가능한것도 아니고, 이미 프로그래밍 언어를 사용해본 사람이라면 마찬가지로 굳이 강의를 안보고 실습을 진행해도 크게 무리가없기때문이다. 실습은 최대한 언어에 dependency가 없는방향으로 진행된다. (C#을 아주 많이 활용하지는 않는다.) 유니티 자체가 C#만 지원하는게 아니다보니 여러 언어에서 동작되는걸 가정하고 나와있어서 그런게 아닌가 싶다. 나는 실습을 해 보면서 C#언어가 더 궁금해진다면 그 때 찾아서 보는방향으로 접근했다.

 

 아무튼 나는 강의 내용이 생각보다 너무 길어서 앞부분을 스킵하고 유니티 실습부분부터 진행했는데도 내용이 꽤 많았다. 예를들어 강의 길이가 30분이라면 30분만에 실습하는것은 무리가있다. 강의에서는 소스코드를 미리 준비해서 진행하는 경우도 있고 코드를 따라 작성하려면 일시정지를 여러번 하면서 작성하는경우가 많았다. 그리고 작성한 코드의 내용을 이해하기위해서는 그날 쳤던 코드를 일일이 분해해서 하나씩 어떤 동작을하는 코드인지 확인 해 봐야한다. 반복적으로 사용되는 코드는 자연스럽게 익숙해질 수 있는데 그런경우는 거의 없었다. 중요한 내용만 모아서 담았기 때문에 반복적으로 연습하는 느낌은 아니었고 스스로 복습하면서 습득하는 방향으로 접근해야했다.

 

https://craftpix.net/freebies 에서 무료 에셋을 가져다 사용해서 게임을 만드는방법을 알게된 점도 유용했다. 게임 제작 시 리소스를 어디서 구할지 잘 몰라서 유니티 에셋 스토어에 원하는 에셋이 없으면 디자인이나 에셋을 만드는법부터 공부해야하는거라 생각했는데 내가 원하던 고품질의 에셋을 그룹핑해서 보여주는 사이트가있다는게 나중에라도 활용할 가능성이 있을 것 같다.

 

그리고 중요 동작에대한부분은 외부 에셋에 의존해서 진행되지않았다는점은 칭찬하고싶다. 유튜브같은곳에서 게임 제작 강의를 보면 베이스 동작에대한 부분을 외부 에셋에 의존해서 작성하게된다, 예를들면 메뉴, 터치 ui 인터페이스 캐릭터를 움직이는 컨트롤러, 점수 계산 등등... 이 강의에서는 디자인 에셋을 제외하고는 모든것을 코드로 직접 작성한다. 비행기를 움직이기위한 코드, ugui를 사용한 버튼 터치 조작, 성능 튜닝을 위한 object 캐싱 시스템, 충돌 처리 등...

 

예를들어 총알의 충돌을 처리하기위해 사용된 코드는 아래와같은 내용을 작성했다.

    bool Hited = false;

    void UpdateMove()
    {
        if (!NeedMove)
            return;

        Vector3 moveVector = MoveDirection.normalized * Speed * Time.deltaTime;
        moveVector = AdjustMove(moveVector);

        transform.position += moveVector;
    }
    
    Vector3 AdjustMove(Vector3 moveVector)
    {
        RaycastHit hitInfo;

        if (Physics.Linecast(transform.position, transform.position + moveVector, out hitInfo))
        {
            moveVector = hitInfo.point - transform.position;
            OnBulletCollision(hitInfo.collider);
        }
        return moveVector;
    }

    void OnBulletCollision(Collider collider)
    {
        if (Hited)
            return;

        Collider myCollider = GetComponentInChildren<Collider>();
        myCollider.enabled = false;

        Hited = true;
        NeedMove = false;

        if(ownerSide == OwnerSide.Player)
        {
            Enemy enemy = collider.GetComponentInParent<Enemy>();
        }
        else
        {
            Player enemy = collider.GetComponentInParent<Player>();
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        OnBulletCollision(other);
    }

 

 단순히 게임의 콜리전(충돌) 시스템을 사용해서 총알끼리 부딫치는것이 아닌 총알이 움직이기 전과 움직이고 난 후의 위치 사이에 선을 그려서 그 선 사이에 충돌 물체가 있는지 정밀하게 검사하는 코드가 어떻게 동작하나 직접 다루어보게 된다.

 간혹 어떤 게임을하다보면 캐릭터가 너무 빨리움직이거나 총알이 너무 빠르면 충돌하지않고 지나쳐버리는 버그가 존재하는데 이런 버그를 방지하기위해 꼭 필요한 로직이다.

 

콜리전을 활용해서 아래와같이 비행기가 경계를 벗어나지않도록 만들어보기도 했다.

게임의 경계에 도달했을 때 플레이어의 움직임을 막는 코드

 [SerializeField]
    BoxCollider boxCollider;

    [SerializeField]
    Transform MainBGQuadTransform;
    
    void UpdateMove()
    {
        if (MoveVector.sqrMagnitude == 0)
            return;

        MoveVector = AdjustMoveVector(MoveVector);

        transform.position += MoveVector;
    }
    
    Vector3 AdjustMoveVector(Vector3 moveVector)
    {
        Vector3 result = Vector3.zero;

        result = boxCollider.transform.position + boxCollider.center + moveVector;

        if (result.x - boxCollider.size.x * 0.5f < -MainBGQuadTransform.localScale.x * 0.5f)
            moveVector.x = 0;
        if (result.x + boxCollider.size.x * 0.5f > MainBGQuadTransform.localScale.x * 0.5f)
            moveVector.x = 0;
        if (result.y - boxCollider.size.y * 0.5f < -MainBGQuadTransform.localScale.y * 0.5f)
            moveVector.y = 0;
        if (result.y + boxCollider.size.y * 0.5f > MainBGQuadTransform.localScale.y * 0.5f)
            moveVector.y = 0;

        return moveVector;
    }

단순히 경계면에 장애물을 배치해서 비행기와 충돌하도록 막아두면 경계면을 벗어나지않았겠지만 그보다 좌표를 계산해서 논리적으로 더 단순하게 경계면을 검사하도록 구현하기도 해 보았다.

 

아래는 마지막으로 HP 시스템을 직접 만들어 본 예시이다.

public class Actor : MonoBehaviour
{
    [SerializeField]
    protected int MaxHP = 100;

    [SerializeField]
    protected int CurrentHP;

    [SerializeField]
    protected int Damage = 1;

    // Start is called before the first frame update
    void Start()
    {
        Initialize();
    }

    protected virtual void Initialize()
    {
        CurrentHP = MaxHP;
    }

    // Update is called once per frame
    void Update()
    {
        UpdateActor();
    }

    protected virtual void UpdateActor()
    {

    }
}

플레이어와 적 비행기가 공통으로 사용할 코드를 작성하고 비행기 각자는 최대 체력, 현재 체력, 데미지의 정보를 유니티 인스펙터를 통해 따로 받아서 관리하도록 작성하기위한 베이스 코드이다.

단순한 숫자 계산에 불과하지만 소프트웨어 설계 경험이 없던 사람에게는 나름대로 중요한 실습이 되었던것 같다.

 

나는 게임의 기본 토대가 되는부분까지 커리큘럼을 완료했다, 다만 적 비행기가 단조롭게 나오고 플레이하면 점수가 오르기는 하는데 별로 재미있다는 느낌이 안든다. 뒷 내용에 게임의 멀티플레이 구현과 적 보스의 구현 파트를 완수하면 좀 더 나은 내용이 있지않을까 기대하고있다.

 

 결과적으로 좀 어려운 내용의 유니티 강의를 들어보고 싶어서 지원했다는 목적은 충분히 달성할 수 있었다. 유튜브에서 무료로 접근가능한 강의에비해 꼼꼼하게 준비해서 제공된다는점이 만족스러웠다. 

 

 하지만 처음에 언급했듯 잘 생각하고 30일 환급을 지원해야한다고 생각한다. 들으면서 아쉽거나 후회했던점이 없었던것은 아니다. 일단 30일동안 내가 매일 꾸준히 들을만한 각오가 덜 되어있었던게 좀 크다.

 

 그리고 아쉬웠던 점은 강의를 30일의 커리큘럼으로 듣는것이 아니라는것이다. 이미 존재하는 여러 강의중에 원하는 강의를 골라서 30일동안 쉬지않고 듣는것으로 그 강의의 내용이 7일짜리인지 100일짜리인지는 내가 들어보면서 페이스를 맞춰봐야 알 수 있다...

(이 부분은 나만 환급이벤트가 30일 커리큘럼에 맞춰져서 진행되는것으로 착각해서 그렇게 생각하는것 같다)

 

 내 분야가 아닌 생소한 유니티라는 강의를 택한것에 대해서도 반성하게되었는데 IOS개발 강의나 디자인 강의를 택했다면 평소 업무와 연관지어서 시너지도 효과도 내고 더 집중해서 잘 들었을것 같다는 생각이 들었다.

아마 환급 받을생각에 무료 강의라고 생각하고 충동적으로 유니티를 선택했던점도 약간 반성하게되었다. (강의 선택시 지출 금액 이전에 많은 시간을 투자하는것이 옳은지 잘 생각했어야했다)

 

 

 

https://bit.ly/3FVdhDa

 

수강료 100% 환급 챌린지 | 패스트캠퍼스

딱 5일간 진행되는 환급챌린지로 수강료 100% 환급받으세요! 더 늦기전에 자기계발 막차 탑승!

fastcampus.co.kr

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.