An exception has been encountered. This may be caused by an extension. 에러 발생시 해결 방법

 

 

유니티에 비주얼 스튜디오(Visual Studio)로 스크립트 작업을 하려고 스크립트 파일을 더블 클릭해서 열었는데 비주얼 스튜디오가 실행된 이후에 위와 같은 에러 메시지가 떴다. 이 현상은 비주얼 스튜디오를 켤 때마다 지속적으로 반복되었다. 유니티 작업을 하는데는 큰 문제가 없었지만 비주얼 스튜디오를 실행할 때마다 메시지 박스가 팝업되니 여간 불편한게 아니었다.

 

에러 로그를 검색해보니 이 문제는 캐시 충돌 문제로 발생하는 것이라고 한다. 이 문제를 해결하는 방법은 아래의 경로 아래에 있는 캐시 파일들을 삭제하고 비주얼 스튜디오를 재실행 해주면 캐시 파일들이 새로 생성되면서 문제가 해결된다고 한다.

 

C:\Users\[UserName]\AppData\Local\Microsoft\VisualStudio\14.0\ComponentModelCache

 

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

로딩 씬(Loading Scene) 구현하기

 

 

 


이 글은 과거 버전의 글로 최신 버전의 글로 다시 작성되었다. 최신 버전의 글은 씬 교체 방식커튼 방식, 두 가지로 구현되었다.

본문

게임의 장르와 배경들의 종류는 많고도 많지만 그 어떤 종류의 게임이던간에 아주 가벼운 게임이 아닌 이상 반드시 등장하는 장면이 있다. 그 장면은 바로 로딩 씬이다. 다들 로딩 씬이 등장하면 언제쯤 지나가려나 하며 로딩 바에 마우스를 올리고 정말로 바가 채워지고 있는지 확인해본 경험이 있을 것이다. 내가 컴퓨터 게임을 처음으로 접했던 어린 시절에는 이런 로딩 씬이 왜 필요한지도 몰랐고 그냥 재미있는 게임을 할 시간을 잡아먹는 나쁜 녀석이라는 생각만 가득했다.

 


하지만 게임 개발을 시작한 이후로 이 로딩 씬만큼 중요한 씬이 또 없다는 것을 깨달을 수 있었다. 로딩 씬의 역할은 단지 시간만 잡아먹는 것이 아니라 게임의 씬이 전환될 때 다음 씬에서 사용될 리소스들을 물리적인 저장소에서 읽어와서 메모리에 올리는 등의 게임을 하기 위한 준비를 하는 작업이었다.

 

만약에 게임에 로딩 장면이 존재하지 않는다면 어떻게 될까? 아마 플레이어는 다음 씬으로 넘어가는 동안 가만히 게임이 멈춘 화면을 보고 있거나 까만 화면을 보고 있어야 한다. 그런 일이 발생한다면 로딩이 얼마나 진행되었는지 알 수 없고 이 게임이 로딩 중인지 정지한 것인지 구분할 수도 없어서 너무 답답할 것이다. 그렇기 때문에 씬이 전환될 때에는 로딩 씬을 만들어서 플레이어에게 로딩이 얼마나 진행되었는지 알려주는 것이 좋다.

 

 

 

구현하기

앞에서는 로딩 씬의 필요성에 대해서 이야기했다면 이제는 실제로 로딩씬을 유니티에서 구현하는 방법을 알아보자.

 

 

로딩 씬을 위의 이미지와 같이 구성하자. 초록색 막대는 다음 씬이 얼마나 로딩되었는지 알려주는 진행막대(Progress Bar)이다. 배경은 아무런 이미지 없이 카메라가 찍고 있는 텅 빈 씬을 보여주고 있지만, 실제의 게임에서는 그 게임의 일러스트나 게임 장면 등을 넣을 수 있고, 덤으로 게임 팁(Tip)이나 게임의 배경이 되는 스토리를 보여줄 수도 있다. 그렇게 하면 엘리베이터에 거울을 달아두면 엘리베이터 탑승자들이 거울을 보느라 엘리베이터가 조금 느려도 속도에 신경을 덜 쓰게 되는 것처럼 로딩을 기다리는 유저들 또한 배경 이미지나 팁, 배경 스토리를 읽으면서 로딩의 지루함을 덜어낼 수 있게 되는 것이다.

 

 

진행막대로 사용되는 이미지의 경우에는 스케일을 조정해서 로딩의 진행도를 표시할 수도 있지만, 만약 위의 이미지처럼 단색의 이미지를 사용하는 것이 아닌 경우에는 이미지가 찌그러져 출력될 것이기 때문에 가능하다면 Image Type을 Filled를 사용할 것을 권장한다. Fill Method를 Horizontal로 설정하면 수평으로 채워지고 Fill Origin를 Left로 하면 이미지가 왼쪽부터 채워진다. 그리고 Fill Amount를 이용해서 로딩이 얼마나 진행되었는지 표시할 수 있다.

 

다음의 코드는 로딩 씬을 불러오고 관리하는 LoadingSceneManager 클래스이다.

 

public class LoadingSceneManager : MonoBehaviour
{
    public static string nextScene;
    [SerializeField]    Image progressBar;

    private void Start()
    {
        StartCoroutine(LoadScene());
    }

    public static void LoadScene(string sceneName)
    {
        nextScene = sceneName;
        SceneManager.LoadScene("LoadingScene");
    }

    IEnumerator LoadScene()
    {
        yield return null;
        AsyncOperation op = SceneManager.LoadSceneAsync(nextScene);
        op.allowSceneActivation = false;
        float timer = 0.0f;
        while (!op.isDone)
        {
            yield return null;
            timer += Time.deltaTime;
            if (op.progress < 0.9f)
            {
                progressBar.fillAmount = Mathf.Lerp(progressBar.fillAmount, op.progress, timer);
                if (progressBar.fillAmount >= op.progress)
                {
                    timer = 0f;
                }
            }
            else
            {
                progressBar.fillAmount = Mathf.Lerp(progressBar.fillAmount, 1f, timer);
                if (progressBar.fillAmount == 1.0f)
                {
                    op.allowSceneActivation = true;
                    yield break;
                }
            }
        }
    }
}

 

처음 씬을 불러오는 방법을 배우는 유니티 게임 제작자의 경우에는 대부분 SceneManager.LoadScene()을 사용하지만, 로딩 씬을 만들기 위해서는 SceneManager.LoadSceneAsync()를 사용해야 한다. LoadScene()의 경우에는 동기 방식으로 불러올 씬을 한꺼번에 불러오고 다른 모든 것이 불러오는 동안 기다리는 방식이지만 LoadSceneAsync()의 방식은 비동기 방식으로 일시 중지가 발생하지 않는 방식이다. 로딩의 진행 정도는 LoadSceneAsync() 함수가 AsyncOperation 클래스 형식으로 반환한다.

 

 

코드의 작성을 완료했다면 로딩 씬에 하나의 게임 오브젝트를 생성하고 그 오브젝트에 방금 만든 LoadingSceneManager 스크립트를 추가한뒤 Progress Bar에 ProgressBar 이미지를 넣어주면 된다.

 

위의 과정을 모두 마쳤다면 두 개의 씬을 새로 만들고 하나의 씬에는 다음과 같은 스크립트를 가진 오브젝트를 추가한다.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestCode : MonoBehaviour
{

    // Use this for initialization
    void Start ()
    {
        LoadingSceneManager.LoadScene("Scene2");
    }
}

 

그런 후에 첫 번째 씬에서 플레이 버튼을 눌러 게임을 실행하면 첫 번째 씬에서 로딩 씬으로 넘어간 후에 아래쪽 로딩 바가 자연스럽게 차오른뒤에 두 번째 씬으로 넘어가는 것을 확인할 수 있다.

 

위의 예시에서는 씬의 로딩 진행도 만을 이용해서 진행 정도를 체크했지만, 유니티에서는 다음 씬에서 사용될 애셋 번들을 불러오는 것 또한 로딩에 포함될 수 있고, 만약 네트워크 게임을 제작한다면 네트워크 동기화 정도도 포함될 수 있다.

 

여담으로 일부 게임 제작자의 경우에는 로딩 시간이 너무 짧아서 로딩 시간동안 보여주고자 하는 팁이나 스토리 등이 너무 빠르게 스쳐지나간다고 생각하는 경우에는 일부러 로딩 속도를 늦추거나 페이크 로딩 시간을 넣어서 로딩 시간을 일부러 길게 만드는 경우도 있다.

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

애니메이터 컨트롤러 동작 변경 문제

 

이전까지 게임을 제작을 시작할 때, 5.3.5 버전의 유니티를 사용하다가, 변경된 파티클 시스템을 사용하기 위해 유니티를 5.6.0으로 업데이트를 진행했었다. 엔진을 업데이트하면서 변경점으로 인해서 프로젝트에 어느 정도 문제가 발생할 것이라고 생각은 하고 있었지만, 예상외로 별다른 문제없이 유니티 업데이트가 진행되었었다.

 

문제는 애니메이션 쪽에서 발생했다. 제작 중인 게임은 최적화를 위해서 오브젝트 풀링(Object pooling) 기법을 사용하고 있었는데, 이 기법을 간단하게 설명하자면 유니티 상에서 게임 오브젝트를 생성(Instantiate)하고 삭제(Destory)하는 과정에서 발생하는 부하를 줄이기 위해, 게임에 필요한 게임 오브젝트를 미리 생성해서 컨테이너에 저장해두고, 필요하면 게임 오브젝트의 활성화해서 사용하고 죽음이나 파괴 등으로 필요없어진 게임 오브젝트의 비활성화 시키는 방법으로 비활성화 시킨 오브젝트라도 같은 종류의 오브젝트가 필요하면 다시 활성화 시켜서 재활용할 수 있다. 이렇게 하면 빠르게 작동해야하는 게임 도중에 무거운 Instantiate() 함수의 호출이나 이후에 가비지 컬렉터(Gabage Collector) 호출로 이어지는 Destory() 함수의 호출을 최소화할 수 있다.

 

이 오브젝트 풀링 기법과 유니티가 버전업되면서 변경된 애니메이터 컨트롤러의 동작이 만나면서 문제가 발생했다. 이전에 사용하던 5.3.5의 애니메이터 컨트롤러의 경우에는 동작중이던 게임오브젝트를 비활성화 시키고 난 이후에 해당 오브젝트를 재사용하기 위해서 다시 활성화 시키면 애니메이터 컨트롤러의 상태가 초기로 자동으로 돌아갔다.

 

 

그렇기 때문에 애니메이터를 위의 그림과 같이 구성해두면 캐릭터가 사망하면서 Die 트리거가 작동해서 Die 애니메이션이 작동한 이후에 죽은 캐릭터의 게임 오브젝트를 비활성화 시키고, 나중에 이 오브젝트를 재사용하기 위해 다시 활성화 시키면 애니메이터 컨트롤러의 상태는 자동으로 Idle 상태로 돌아오는 방식으로 동작했었다.

 

하지만 유니티를 5.6.0으로 업데이트한 이후에는 게임 오브젝트를 비활성화 시켰다가 다시 활성화 시키면 애니메이터 컨트롤러의 상태가 처음으로 돌아오지 않고 비활성화 시키던 당시의 상태를 유지하는 것으로 애니메이터 컨트롤러의 동작이 변경되었다(5.3.5와 5.6.0 사이의 어느 버전에서 동작이 변경되었을 것이다. 정확한 릴리즈 노트를 찾아보지는 않아서 변경된 정확한 버전은 알지 못한다).

 

그렇기 때문에 죽은 캐릭터의 게임 오브젝트를 재활용하려고 게임 오브젝트를 다시 활성화 시키면 Die 애니메이션이 끝난 상태로 나타나는 버그가 발생하게 되었다.

 

이러한 문제해결하기 위해서는 애니메이터 컨트롤러에서 상태 노드들의 연결을 약간 변경해 주어야 했다.

 

 

애니메이션이 종료된 이후에 제일 처음의 상태로 돌아가야 한다면 위의 그림처럼 그 상태는 반드시 Exit 노드로 연결되어야 한다. 애니메이션의 상태를 Exit 노드와 연결해 주면 그 애니메이션이 끝난 이후에 Exit 노드로 이동한 후 다시 Entry로 돌아가서 제일 처음 애니메이션을 다시 출력한다. 하지만 Die 같은 애니메이션의 경우 아무런 제약 없이 Exit 노드와 연결해주면 캐릭터가 죽어서 넘어진 다음에 다시 벌떡 일어나는 불상사가 발생할 수도 있다. 그런 종류의 불상사를 막아야 하는 경우에는 Exit 노드로 가는 트랜지션(Transition)에 하나의 트리거를 추가해 준 다음, 다시 돌아갈 상황이 되었을 때, 스크립트에서 트리거를 호출해서 애니메이션 상태를 처음으로 돌릴 수 있다.

 

결론적으로 최신 버전의 유니티에서는 애니메이터 컨트롤러가 끊임없이 흘러가게 하기 위해서는 마지막 애니메이션을 절대로 고립된 상태로 두지말고 Exit 노드에 연결해 주어야 한다.

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

유니티 애니메이션 레이어(Animation Layer) 사용하기

 

 

 

지난 애니메이션 섹션에서는 비슷하지만 방향성이 다른 동작, 혹은 비슷하지만 속도가 다른 동작을 섞는데 사용하는 애니메이션 블랜드(Animation Blend)에 대해서 이야기해 보았다. 이번 섹션에서는 애니메이션 위에 일정 부분에 애니메이션을 덮어씌우는 애니메이션 레이어(Animation Layer)에 대해서 배울 것이다.

 

지난 애니메이션 블랜드 섹션 :: http://wergia.tistory.com/54

 

애니메이션 레이어는 여러 종류의 게임에서 이용될 수 있지만, 대표적으로는 FPS나 TPS 형식의 게임에서 주로 이용될 수 있다. 이러한 형식의 게임의 경우 캐릭터는 한 순간에 한 가지 행동만을 하는 것이 아니라, 하나 이상, 일반적으로는 두 개 정도의 행동을 하는 일이 많다. 간단하게 예를 들자면 총 같은 화기를 사용하는 FPS 게임이라면 캐릭터는 달리거나 걷는 동시에 총을 쏠 수도 있고, 단검을 휘두를 수도 있으며, 탄창을 교체하기도 한다. 앞서 이야기한 행동들을 하기 위해서 걸음을 멈추는 경우는 거의 없다. 평소에는 상체와 하체 모두 달리는 애니메이션을 취하지만, 달리는 도중에 다른 행동을 취한다면 하체는 여전히 달리는 모션을 출력하지만, 상체는 총을 쏘거나, 단검을 휘두르거나, 탄창을 교체하는 애니메이션을 출력하게 되는 것이다.

 

물론 이러한 애니메이션들을 일일이 만들어 내는 방법도 있지만 이것은 너무 비효율적인 일이다. 만약에 애니메이션 레이어를 사용하지 않고 모든 애니메이션을 만든다면, 가만히 서서 위의 세 가지 행동을 하는 애니메이션, 걸으면서 다른 행동을 하는 애니메이션, 달리면서 행동을 하는 애니메이션 등을 모두 만들어내야 할 뿐만 아니라, 만약 점프하면서 폭탄을 던지는 모션을 만들고자 한다면 점프하는 모션 중 어느 타이밍에 폭탄을 던지는 모션을 추가해야할지 골머리를 앓게 될 것이다.

 

하지만 애니메이션 레이어를 사용하게 된다면, 걷는 애니메이션, 달리는 애니메이션, 서있는 애니메이션, 점프 애니메이션, 그리고 각각의 행동을 취하는 애니메이션 정도만 만든다면 위에서 설명한 표현들을 손쉽게 할 수 있게 된다.

 

 

이번 예시를 들기 위해서 지난 애니메이션 블랜드 섹션에서 사용했던 달리기 모션과 함께 이번에 간단하게 만든 팔을 휘두르는 애니메이션을 사용할 것이다. 공격이라고 보기엔 귀엽지만 공격 모션이다. 애니메이션 레이어와 달리는 모션, 그리고 가만히 서서 공격하는 모션만 있다면 달리면서 공격하는 모션을 만들 수 있다.

 

애니메이션 레이어 사용법을 배우기 위해 다음의 튜토리얼을 따라해보도록 하자.

 

 

 

1. 애니메이션 레이어에 사용할 Animator Controller를 생성하고 그 이름을 Animation Layer라고 짓도록 하자.

 

 

2. 생성한 애니메이터 컨트롤러를 열면 다음과 같이 빈 애니메이터 컨트롤러 창이 보일 것인데 그 중에 Layers라는 항목이 있을 것이다. 그 항목을 선택하면 Base Layer가 있는데 이 레이어는 애니메이션에서 기본적으로 제공하는 레이어이다. 이 레이어의 이름을 바꿀 수도 있고 나중에 다른 레이어를 추가한다면 기본 레이어를 삭제할 수도 있다.

 

3. 기본적인 달리기 애니메이션을 애니메이터 컨트롤러에 추가한다. 그리고 이 애니메이터 컨트롤러를 씬에 추가한 캐릭터의 애니메이터 컴포넌트에 넣고 플레이 버튼을 누르면 이 박스맨은 계속해서 달리기만 할 것이다.

 

4. 이 다음 작업은 아바타 마스크(Avatar Mask)를 생성하는 것이다. 이 아바타 마스크는 애니메이션 레이어를 사용할 때, 위에 덮어쓴 애니메이션이 적용될 본을 지정하는 것으로, 해당 레이어에서 원하는 본만 애니메이션이 작동하고 그 외의 본은 그 아래 레이어의 애니메이션을 작동하도록 만드는 것이다.

 

5. 생성한 아바타 마스크를 열어보면 Humanoid 방식과 Transform 방식이 있는 것을 알 수 있다. 휴머노이드 방식의 경우는 사진을 보면 알다시피 일반적인 사람형태의 본에 대해서 손쉽게 마스크를 지정할 수 있게 하는 것이고, 트랜스폼 방식은 직접 만든 특별한 형태의 본을 가져와서 원하는 애니메이션이 적용될 본을 직접 선택하는 방식이다.

 

6. 이번엔 None이라고 비어있는 Avatar 란에 직접 만든 박스맨의 본을 가져와야 한다. 이 본은 BoxMan@Attack을 열어보면 목각인형 상체 모양의 BoxMan@AttackAvatar를 볼 수 있는데 이것을 끌어와서 넣어주면 된다. 그리고 Import skeleton 버튼을 클릭하면 박스맨에 적용된 본들이 아바타 마스크의 인스펙터 창에 표시된다.

 

7. 이번 섹션의 작업에서 우리가 동작하기 바라는 것은 왼팔 하나뿐이다. 박스맨의 본들 중에 왼팔에 해당하는 본은 Bone005(mirrored)이다. 이 본만이 움직이길 원하기 때문에 Bone005(mirrored)를 제외한 모든 본의 체크를 꺼준다.

 

8. 이제 아까 만든 AnimationLayer 애니메이터 컨트롤러로 돌아와서 Layers 항목의 아래 쪽에 +버튼을 클릭하여 새 레이어를 만들고 그 이름을 UpperBody로 변경한다.

 

9. 잠시 Parameters 항목으로 넘어가서 애니메이터 컨트롤러의 매개변수에 "Attack"라는 이름의 트리거를 생성한다.

 

10. UpperBody 레이어에 NoneAttack 상태를 만들고 애니메이션은 비워둔다. 아무것도 하지 않는 동작이기 때문에 비워두는 것이다. 만약 아무것도 하지 않는 동작이기 때문에 아래쪽의 베이스 레이어와 맞춰서 달리는 동작으로 해줘야 한다고 생각할 수 있는데 그런 식으로 달리는 애니메이션을 넣었다가는 하체의 달리는 모션과 상체의 팔 휘두르는 모션의 싱크가 일치하지 않게되는 현상을 겪을 수도 있다.

 

11. Attack 상태를 추가하고 Attack 애니메이션을 넣어준 다음에 NoneAttack 상태에서 Attack 상태로 넘어가는 조건에 아까 만든 Attack 트리거를 넣어준다. 이렇게 함으로서 이제 애니메이션 컨트롤러에 Attack 트리거 신호가 들어오면 캐릭터는 어택 모션을 취하게 될 것이다(설정에 실수를 했는데 Inspector 창에서 Has Exit Time의 체크는 해제해야 한다).

 

12. 다음 작업은 레이어 설정을 해주는 것이다. 레이어 이름 옆에 톱니바퀴 버튼을 클릭하면 레이어 옵션을 볼 수 있는데 여기서 두 가지를 설정해주면 된다. 첫 번째는 Weight 값인데 이 값은 현재 레이어와 아래 레이어의 애니메이션 비중을 의미한다. 1에 가까울 수록 캐릭터는 현재 레이어에 가까운 모션을 취한다. 즉, 1값이면 캐릭터는 현재 레이어의 애니메이션만 취한다. 그리고 Mask 옵션인데 이것은 애니메이션을 출력하고자 하는 부위만 출력하도록 해주는 것이다. 아까 전에 만든 왼팔만 적용되는 마스크를 넣어준다.

 

애니메이션 레이어에 필요한 모든 설정을 끝냈다. 이제 플레이 버튼을 클릭하고 캐릭터의 달리는 모션이 출력되는 도중에 Attack 트리거를 켜보면 다음 이미지와 같이 박스맨 캐릭터가 달리기 모션을 취하면서도 왼팔만은 정상적으로 휘두르는 것을 볼 수 있다.

 

 

 

 

이것처럼 애니메이션 레이어를 사용하면 애니메이션 작업양을 획기적으로 줄이면서도 다양한 동작을 취하도록 할 수 있다. 하지만 이 예시는 매우 간단하게 제작된 본과 모델링을 사용하는 것으로, 일반적으로 게임 제작에 사용되는 복잡한 형태의 본과 모델을 사용하는 경우에는 본의 구조나 리깅된 면의 정상적인 움직임을 위한 면밀한 연구가 필요할 것이다.

 

마지막으로 다음의 링크에서 위의 예시로 제작된 간단한 애니메이션 레이어 예제를 받을 수 있다.

 

AnimaitonLayerExample.zip
다운로드

 

 

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

Visual Studio 2017 Community 설치 실패 문제 해결하기(Error 0x80004003:)

 

Visual Studio에 추가적인 워크로드를 설치하는 도중에 실수로 컴퓨터를 재부팅하게 되었는데 그 이후로 추가 워크로드를 설치할 수 없는 문제가 발생했다. 그래서 Visual Studio를 완전히 제거하고 다시 설치해야 했는데, Visual Studio를 제어판에서 삭제한 이후에 Microsoft Download Center에서 vs_Community 설치 파일을 받아서 설치할 때 문제가 발생했다.

 

vs_Community 부트스트랩이 설치 파일들을 받아오는데까지는 성공하지만 이후에 Visual Studio를 설치하는데는 계속해서 실패하는 문제였다. 그래서 로그를 확인해보니 다음과 같은 내용이었다.

 

[----:----][2017-06-09T10:54:38] Error 0x80004003:
   위치: Microsoft.VisualStudio.Setup.Cache.InstanceRepository.GetInstance()
   위치: Microsoft.VisualStudio.Setup.Cache.CacheRepository.<GetInstances>d__28.MoveNext()
   위치: System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   위치: Microsoft.VisualStudio.Setup.Engine.VerifyInstallationPath(IServiceProvider services, String installationPath, IInstance instance, IQuery query)
   위치: Microsoft.VisualStudio.Setup.Engine.Install(Product product, String destination, CancellationToken token)개체 참조가 개체의 인스턴스로 설정되지 않았습니다.

 

 

해결법

 

위의 로그에서 발견한 에러 코드를 구글에 검색한 결과 다음과 같은 해결 방법을 찾았고, 해결 방법대로 수행한 결과로 성공적으로 Visual Studio 2017 Community의 설치를 마칠 수 있었다. 해결책은 다음과 같다.

 

1) 현재 설치되어 있는 Visual Studio가 있다면 제어판에서 언인스톨할 것.

2) Program Files 폴더 내 혹은 Visual Studio가 설치된 경로에 있는 Microsoft Visual Studio 폴더를 삭제할 것.

3) C:\ProgramData\Microsoft\Visual Studio\Setup 폴더를 삭제할 것.

4) C:\ProgramData\Microsoft\Visual Studio\Packages 폴더를 삭제할 것.

 

위의 과정을 모두 진행했다면, Visual Studio의 재설치를 진행하면 문제없이 재설치가 가능할 것이다.

 


 

해결법의 출처

 

Error 0x80004003 during VS 2017 RC install

I'm running Windows 10, no pending updates, I've run sfc /scan now and DISM.exe /Online /Cleanup-image /Restorehealth neither of which reported issues. I've tried installing enterprise, profession...

stackoverflow.com

 

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

유니티에서 애니메이션 블랜드 사용하기

 

작성 기준 버전 :: 5.6 - 2019.4

 

[이 포스트의 내용은 유튜브 영상으로도 시청하실 수 있습니다]

 

게임에서 자연스러운 애니메이션은, 캐릭터에 생명을 불어넣어 주는 요소 중에 하나이다. 다양한 종류의 애니메이션을 제작하면 캐릭터의 움직임은 더욱 자연스러워 질 것이다. 예를 들어 캐릭터가 움직이는 방향에 따라서 정면으로 움직일 때는 바르게 걷고 정면을 본체로 왼쪽으로 움직이면 왼쪽으로 옆걸음을 하는 방식으로 제작한다면 만약 왼쪽 정면 대각선 방향을 향해서 이동하면 어색한 움직임을 보일 것이다. 그것을 자연스럽게 처리하려면 왼쪽 정면 대각선 방향으로 움직이는 애니메이션을 만들어주어야 하고, 또 거기서 더 자연스러운 애니메이션을 만들고자 한다면 그 정면과 왼쪽 정면 대각선 사이, 왼쪽과 왼쪽 정면 대각선 사이의 애니메이션을 만들어서 추가해주어야 하는 것이다. 하지만 그렇다고 해서 게임 제작자가 모든 경우의 애니메이션을 일일이 다 만들 수는 없다. 그런 작업은 쉽지 않을 뿐만 아니라 게임제작에 들어가는 자원과 시간이 부족하다.

 

이러한 문제를 해결하기 위해서 사용되는 기능이 바로 애니메이션 블랜드이다.

 

이번 예시를 설명하기 위해 간단한 박스맨을 제작했고, 걷기 모션과 달리기 모션을 만들었다. 이동속도에 따른 걷기/달리기 애니메이션 블랜드는 가장 대표적이고 유용한 예제이다. 캐릭터의 이동 속도에 따라서 캐릭터의 보폭이나 발걸음 이동속도 역시 유동적으로 변하는 편이 자연스럽게 보일 것이다.

 

 

 

간단하게 걷는 모션과 달리는 모션의 차이를 주기 위해서 걷는 모션은 팔다리를 가볍게 움직이고 달리는 모션은 팔다리를 격하게 흔들도록 만들어 보았다.

 

 

 

애니메이션 블랜드를 사용하기 위해서는 우선 캐릭터의 애니메이션을 관리할 애니메이터 컨트롤러(Animator Controller)를 생성해야 한다.

 

 

애니메이터를 생성해서 열어보면 텅 빈 애니메이터 화면이 보일 것이다.

 

 

빈 화면에 우클릭해서 Create State > From New Blend Tree 항목을 선택하면 다음과 같이 Blend Tree라는 이름의 애니메이션 스테이트가 생성되고 Parameters에는 Blend라는 이름의 float 형식의 매개변수가 생성될 것이다 :

 

 

이 Blend라는 이름의 매개변수는 애니메이션 블랜드에서 두 여러 애니메이션이 섞일 때, 어느 애니메이션으로 치우쳐서 출력될 것인지를 결정하는데 도움을 줄 것이다. 현재는 캐릭터의 이동 모션에 따라 걷기/달리기 모션 블랜드를 할 것이기 때문에 이 변수의 이름을 "MoveSpeed"로 변경하도록 하자.

 

 

그리고 애니메이터 창에서 Blend Tree 스테이트를 더블 클릭해보면 다음과 같이 블랜드 트리로 내려가게 될 것이다.

 

 

위의 그림에서처럼 블랜드 트리를 선택하고 인스펙터 창(Inspector View)을 보면 Blend Type과 Parameter 그리고 Motion을 볼 수 있다. 우선 블랜드 타입은 파라메타의 변화에 따라서 어떻게 애니메이션이 블랜드 될 것인지를 정하는 것이다. 그리고 파라메터는 현재 애니메이션의 파라메터 중에 이 블랜드 트리에서 사용할 값을 정하는 것이며, 모션은 이 블랜드 트리에서 섞을 애니메이션을 정하는 것이다.

 

 

지금은 이동 속도의 변화에 따라서 모션을 블랜드할 것이기 때문에 가만히 정지 > 걷기 > 달리기 이 세 가지 모션을 추가하겠다. 모션 밑에 있는 + 버튼을 누르고 Add Motion Field 항목을 선택하면 다음과 같이 화면이 변한다. 이제 모션들을 추가해보자.

 

 

각 모션에 애니메이션들을 추가해주면 위의 그림처럼 각 애니메이션 노드가 생성되서 블랜드 트리와 연결되는 것을 볼 수 있다. 여기서 또 조정할 수 있는 옵션은 Threshold이다. Threshold는 한계점이나 역치라는 의미로 여기서는 각 애니메이션의 그래프 상의 위치를 의미한다. 위의 그림에서는 Stand의 Threshold는 0, Walk의 threshold는 0.5, Run의 threshold는 1이다. 이 의미는 MoveSpeed의 값이 0~1사이에서만 움직일 것이고 0~0.5 값이면 Stand와 Walk 모션이 블랜드가 되고 0.5~1 값이면 Walk와 Run 모션이 블랜드된다는 것이다. 하지만 일반적으로 게임에서는 이동 속도 값을 0~1로 사용하지 않기 때문에 그럴 때는 Automate Thresholds 체크를 풀어주면 값을 적절하게 조절해줄 수 있게 된다.

 

만약에 최대 이동 속도가 50이고 걷는 속도가 10이라고 한다면 그 값을 아래와 같이 입력해주면 된다. 이렇게 설정해주고 캐릭터의 스크립트에서 이동 모션을 출력하면서 이동 속도에 따라서 animator.SetFloat("MoveSpeed", moveSpeed);를 호출해주면 애니메이터는 자동으로 변화하는 이동 속도에 따라 어느 애니메이션들을 얼마나 출력할지 결정하고 출력해줄 것이다.

 

 

 

 

애니메이션 블랜드를 사용할 때, 주의할 점은 블랜드된 애니메이션이 자연스럽게 보이기 위해서는 블랜드 되는 모션들이 비슷한 동작을 취해야하고 타이밍이 비슷해야 한다는 것이다. 하지만 예외적으로 애니메이션의 길이가 다른 것은 블랜드의 결과에 영향을 미치지 않는다. 그 이유는 정확한 블랜드를 위해서 두 애니메이션의 길이를 똑같게 맞추는 정규화 작업을 한 이후에 블랜드를 하기 때문이다.

 

간단한 위의 예제는 다음 링크에서 다운로드 받아서 실행해볼 수 있다.

 

AnimationBlendPractice.zip
다운로드

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

유니티에서 XML 사용하기

 

게임을 제작할 때에, 여러 가지 데이터들을 저장하고 불러와야하는 경우가 많다. 게임 진행 상황을 저장하는 경우도 있을 수 있고, 맵이 랜덤으로 생성되는 게임의 경우에는 현재 생성된 맵의 데이터를 저장해뒀다가 다음에 다시 불러와야 할 수도 있다. 또는 게임의 아이템 정보들의 목록을 저장해둬야 할 수도 있다. 위와 같은 경우에 XML을 사용하면 저런 기능들을 쉽게 구현할 수 있게 된다.

 

XML은 마크업 언어를 정의하기 위한 확장성 마크업 언어라고 하는데, 여기서는 조작하기 쉬운 일종의 로컬 데이터베이스나 데이터를 저장하기 위한 파일로 사용될 것이다.

 

이번 섹션의 예시에서는 게임의 캐릭터 정보를 저장하기 위해서 XML을 사용한다고 가정하고 진행 해보겠다.

 

1. XML 파일 생성하여 저장하기

첫 번째로 알아볼 것은 XML 파일을 생성하는 것이다. 만약 게임을 시작하고 처음으로 저장을 하는 경우라면 아직 데이터를 저장하기 위한 파일이 생성되어 있지 않을 것이다. 물론 미리 XML 파일을 만들어두고 사용하는 것도 가능하지만, XML 파일을 생성하는 법에 대해서 알아두는 것도 나쁘지 않다.

 

다음이 XML을 생성하여 저장하는 코드의 전체이다 :

 

public class XmlTest : MonoBehaviour
{
    void Start()
    {
        CreateXml();
    }

    void CreateXml()
    {
        XmlDocument xmlDoc = new XmlDocument();

        // Xml을 선언한다(xml의 버전과 인코딩 방식을 정해준다.)
        xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "yes"));

        // 루트 노드 생성
        XmlNode root = xmlDoc.CreateNode(XmlNodeType.Element, "CharacterInfo", string.Empty);
        xmlDoc.AppendChild(root);

        // 자식 노드 생성
        XmlNode child = xmlDoc.CreateNode(XmlNodeType.Element, "Character", string.Empty);
        root.AppendChild(child);

        // 자식 노드에 들어갈 속성 생성
        XmlElement name = xmlDoc.CreateElement("Name");
        name.InnerText = "wergia";
        child.AppendChild(name);

        XmlElement lv = xmlDoc.CreateElement("Level");
        lv.InnerText = "1";
        child.AppendChild(lv);

        XmlElement exp = xmlDoc.CreateElement("Experience");
        exp.InnerText = "45";
        child.AppendChild(exp);

        xmlDoc.Save("./Assets/Resources/Character.xml");
    }
}

 

저장할 캐릭터 데이터의 내용은 캐릭터의 이름과 레벨, 경험치라고 가정하고 진행했다. 위의 코드를 실행하면 지정된 경로에 Character.xml 파일이 생성된다.

 

 

생성된 xml 파일은 다음과 같은 내용이다 :

 

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<CharacterInfo>
  <Character>
    <Name>wergia</Name>
    <Level>1</Level>
    <Experience>45</Experience>
  </Character>
</CharacterInfo>

 

작성한 대로 캐릭터의 이름, 레벨, 경험치 값이 저장되었다.

 

 

2. XML 파일에서 데이터 불러와서 사용하기

데이터를 저장하는데 성공했다면 이 다음에는 저장된 데이터를 불러와서 사용해야할 것이다. 다음의 코드가 저장된 XML 데이터를 불러오는 것이다.

 

using System.Xml;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class XmlTest : MonoBehaviour
{
    void Start()
    {
        LoadXml();
    }

    void LoadXml()
    {
        TextAsset textAsset = (TextAsset)Resources.Load("Character");
        Debug.Log(textAsset);
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(textAsset.text);

        XmlNodeList nodes = xmlDoc.SelectNodes("CharacterInfo/Character");

        foreach (XmlNode node in nodes)
        {
            Debug.Log("Name :: " + node.SelectSingleNode("Name").InnerText);
            Debug.Log("Level :: " + node.SelectSingleNode("Level").InnerText);
            Debug.Log("Exp :: " + node.SelectSingleNode("Experience").InnerText);
        }
    }

}

 

위의 코드를 실행해보면 XML에 저장해둔 캐릭터 데이터가 잘 불러와졌음을 알 수 있다.

 

 

불러온 데이터를 캐릭터 오브젝트를 생성해서 그 값을 다시 넣어준다면 캐릭터는 저장되기 직전의 캐릭터와 같은 상태를 가지게 될 것이다.

 

 

3. 이미 존재하는 XML 파일에 데이터 덮어씌워 저장하기

게임에서 이미 저장하기 기능을 사용해서 XML 파일이 생성되어 있고, 그 XML파일에 덮어 씌워 저장하는 경우도 있을 수 있다. 그럴 땐 다음 코드와 같이 이미 존재하는 XML 파일을 불러온 후에 그 안의 값을 수정하고 저장해주면 된다 :

 

using System.Xml;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class XmlTest : MonoBehaviour
{
    void Start()
    {
        SaveOverlapXml();
    }

    void SaveOverlapXml()
    {
        TextAsset textAsset = (TextAsset)Resources.Load("Character");
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(textAsset.text);

        XmlNodeList nodes = xmlDoc.SelectNodes("CharacterInfo/Character");
        XmlNode character = nodes[0];

        character.SelectSingleNode("Name").InnerText = "wergia";
        character.SelectSingleNode("Level").InnerText = "5";
        character.SelectSingleNode("Experience").InnerText = "180";

        xmlDoc.Save("./Assets/Resources/Character.xml");
    }

}

 

위 코드를 실행해보면 다음과 같이 XML 파일이 변경되어 있는 것을 볼 수 있다 :

 

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<CharacterInfo>
  <Character>
    <Name>wergia</Name>
    <Level>5</Level>
    <Experience>180</Experience>
  </Character>
</CharacterInfo>

 

위의 예시처럼 덮어씌워 저장하는 방법 이외에도 새로 노드를 덧붙여서 추가적인 내용을 저장한다던가, 아니면 여러 개의 저장 슬롯을 만들어서 저장하는 방법을 사용할 수 있다.

 

 

4. 취약점

저장 방식으로 사용하기 굉장히 편리한 XML이지만 이것도 굉장한 단점이 하나 있다. 이 XML을 그대로 사용하면 그냥 텍스트 편집기로도 열리기 때문에 사용자들이 쉽게 그 값을 변조할 수 있게 된다. 이것은 하나의 에디터나 다름없는 것이기 때문에 만약 제작하는 게임이 데이터가 변조되면 안되는 경우에는 심각한 문제가 될 수 있다. 만약 XML에 게임 데이터를 저장하고 불러와야 되는 경우에는 별도의 암호화/복호화 기능을 덧붙여서 기능을 만드는 것을 추천한다.

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

악마의 문법, goto

 

프로그래밍을 공부하면 여러가지 프로그래밍 문법과 기능과 그것을 다루는 기술들을 배우게 된다. 그렇게 배우는 문법들의 중의 하나가 바로 goto 인데, 이 goto 문에 대해서는 여러 프로그래머들의 부정적인 시각이 강하다. 오죽하면 이 goto 문을 알려주고 나서 하는 제일 첫 마디가 "가급적 사용하지 말라"이겠는가?

 

이 goto 문의 사용을 권장하지 않는 이유는 하나다. 코드의 가독성을 심각하게 해친다는 것이다. 물론 goto를 사용한다고 해서 무조건 코드의 가독성을 해치는 것은 아니지만 다음처럼 사용하게 된다면 많은 문제가 발생하게 될 것이다 :

 

void f()
{
    int i = 10;

    if (i > 100)
    {
        I100:
        if (i < 200)
        {
            goto I200;
        }
        else if (i < 300)
        {
            goto I300;
        }
    }
    goto I100;

I200:
    cout << 1 << endl;
    return;
I300:
    cout << 2 << endl;
    return;
}

 

위의 예시처럼 코드 이곳저곳을 뛰어넘게 되는 goto 문이 많을 경우나 goto I100; 부분처럼 조건에 맞지 않는 상황에서 조건문 안으로 강제 진입하게 만드는 goto 문이 있을 경우는 심각한 문제가 된다. 다른 작업자가 작업하게 되거나 작성자 자신이 재작업할 때, 코드의 흐름을 읽어내기가 어려워지고 조건문과 코드를 신뢰할 수 없게 될 것이다.

 

그렇다면 적절한 goto 문의 사용법이란 무엇인가? 사실 모든 프로그램은 goto 문 없이도 작성이 가능하다. 그렇기 때문에 goto문을 사용하지 않도록 권장하는 것이기도 하다. 하지만 이 goto 문 역시 적절하게 사용하면 기존의 방식보다 편하게 코드를 작성이 가능하다.

 

그 첫 번째 예시는 2중 이상의 반복문에서 탈출할 때이다. 반복문에서 탈출할 때 주로 사용되는 문법은 break인데, 이 break는 한 번에 단 하나의 반복문만을 탈출할 수 있다. 그래서 break로 2중 이상의 반복문을 탈출할 때는 다음과 같이 코드를 작성해야 한다 :

 

int main()
{
    bool isBreak = false;
    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; i < 10; j++)
        {
            if (/*탈출조건*/)
            {
                isBreak = true;
                break;
            }
        }
        if (isBreak)
            break;
    }
}

 

위의 예제처럼 goto 문을 사용하지 않아도 2중 반복문을 탈출할 수 있지만, 하나의 논리 변수를 추가로 사용하고 분기문 역시 추가로 사용해야 한다. 그리고 이것은 반복문의 깊이가 깊어질 수록 사용되는 분기문의 숫자 역시 늘어나게 될 것이다(흔하지 않은 경우이기는 하다). 하지만 다음과 같이 goto 문을 사용하면 논리 변수와 반복문을 추가로 사용하지 않고도 단번에 다중 반복문을 탈출할 수 있게 된다 :

 

int main()
{
    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; i < 10; j++)
        {
            if (/*탈출조건*/)
            {
                goto BREAK;
            }
        }
    }
BREAK:
}

 

 

두 번째 예시는 재입력 처리이다. 만약 1-3 값 만을 입력해야 하는 프로그램이 있다면,  그 이외의 값이 들어온다면 사용자가 값을 다시 입력하도록 프로그래밍해야할 것이다. 여기에 사용되는 일반적인 방법은 do-while 문을 사용하는 방법과 무한 loop에 진입시킨 이후에 옳은 값을 입력했다면 루프에서 탈출시키는 방법이다.

 

int main()
{
    int i = 0;

    // do-while 문을 사용하는 방법
    do
    {
        cout << "값을 입력하세요(1~3)(do-while) :: ";
        cin >> i;
    } while (i < 1 || i > 3);

    // 무한 loop를 사용하는 방법
    while (true)
    {
        cout << "값을 입력하세요(1~3)(무한루프) :: ";
        cin >> i;
        if (i > 0 && i < 4)break;
    }
}

 

이 경우에도 충분히 goto 문이 사용될 수 있다.

 

int main()
{
    int i = 0;

WRONGINPUT:
    cout << "값을 입력하세요(1~3)(무한루프) :: ";
    cin >> i;
    if (i < 1 || i > 3)
        goto WRONGINPUT;
}

 

이렇듯 충분히 가독성을 해치지 않는 선을 지키면서도 goto 문을 사용할 수 있다. 프로그래밍을 하면서 중요한 점은 바로 이것이다. 프로그래밍에 필요한 모든 것을 최대한 활용하되 과하게 사용하지 말고 적절한 위치에 적절하게 사용하라는 것이다. 그것만으로도 코드는 충분히 깔끔해지고 작업 효율성이 상승하게 될 것이다.

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

+ Recent posts