Ragdoll 사용하기

 

어떤 게임을 보면 죽은 캐릭터가 특정한 사망 애니메이션 없이 흐느적거리면서 쓰러지거나 날아가는 모습을 볼 수 있다. 고정된 사망 애니메이션이 아니라 물리적인 처리로 다양한 사망 모션을 연출하기 위한 기법으로 이것을 rag doll(랙돌, 래그돌)이라고 부른다. 래그돌의 단어적인 의미는 헝겊 인형, 봉제 완구라는 뜻인데, 캐릭터가 힘을 잃고 날아가거나 흐느적거리는 모습이 마치 헝겊 인형 같다고 해서 붙여진 이름이다.

 

이 기능을 사용하면 앞서 말했듯이 캐릭터가 사망시 특정한 애니메이션만 나오는 것이 아니라 다양한 각도나 힘으로 넘어지는 것을 연출할 수 있게 된다.

 

 

 

구현하기

 

이 래그돌 기능을 사용하기 위해서는 우선 사람의 본(bone, 뼈대) 구조를 가진 모델이 필요하다.

 

 

이 예제에서는 애셋 스토어에서 손쉽게 구할 수 있는 유니티 짱을 사용했다. 캐릭터의 기본 자세는 T자 자세를 잡고 있는 것을 사용할 것을 권장한다. 다른 포즈를 취하고 있는 모델의 경우 래그돌을 적용하면 래그돌이 쉽게 무너지는 경향이 있다.

 

 

유니티 짱 모델을 불러왔다면 Hierarchy 뷰에서 우클릭을 한 후에 3D Object>Ragdoll... 항목을 선택한다.

 

 

그러면 Create Ragdoll 창이 뜨는데 창의 각 항목에 대응되는 유니티 짱의 본을 선택해서 넣어주어야 한다. 그리고 Total Mass 값은 래그돌의 무게를 정하는 값이다. 이 값을 정해주면 사람의 평균적인 부위별 무게 비율에 맞춰 각 본들의 무게가 정해진다. 유니티에서 말하는 Mass 값의 기본 단위는 1값이 1kg이라고 하기 때문에 Total Mass 값은 임시로 45kg으로 정해주도록 하자.

 

Strength 값은 래그돌이 모양을 유지하고 붕괴되지 않도록 도와주는 힘에 대한 값이다.

 

 

래그돌이 적용된 게임에서 종종 사망한 캐릭터의 몸이 엿가락처럼 늘어나서 마구 흔들리는 문제는 이 Strength 값이 낮아서 발생하는 문제이다.

 

 

마지막으로 Create 버튼을 클릭하면 모델링의 신체 각 부위에 콜라이더들이 씌워진 것을 볼 수 있다. 이러면 캐릭터에 래그돌이 성공적으로 적용된 것이다.

 

 

플레이 버튼을 눌러보면 유니티 짱이 힘없이 쓰러지는 장면을 볼 수 있다. 머리카락 부위가 뻣뻣한 것이 보이긴 여기에 추가적인 본이 있다면 머리카락 쪽에도 래그돌 기능을 넣어줄 수 있다.

 

 

 

물리적인 힘 가하기

 

게임에서 캐릭터들이 죽은 뒤에 진행 방향이나 공격 받은 방향의 반대로 날아가는 것을 자주 볼 수 있는데, 이 기능은 유니티 상에서 구현하기 어렵지 않다. 래그돌 기능이 적용된 각 신체 부위의 경우, 물리적인 힘을 받을 수 있는 리지드 바디(Rigidbody)를 가지고 있다. 코드 상에서 원하는 신체 부위의 리지드 바디에 AddForce를 가해주면 캐릭터가 날아가는 것을 볼 수 있다.

 

using UnityEngine;

public class RagDollPhysics : MonoBehaviour
{
    [SerializeField]
    Rigidbody spineRigidBody;
   
    // Update is called once per frame
    void Update ()
    {
        if(Input.GetKeyDown(KeyCode.Space))
        {
            spineRigidBody.AddForce(new Vector3(0f, 10000f, 10000f));
        }
    }
}

 

위의 코드는 Space 키를 누르면 캐릭터의 리지드 바디에 특정한 방향으로 힘을 가하는 코드이다.

 

 

작성한 스크립트를 유니티 짱 모델에 넣어주고 래그돌이 적용된 본들 중에 원하는 본을 스크립트에 넣어준다. 예제에서는 신체의 상단 중심이 되는 가슴쪽 척추의 리지드 바디를 선택했다.

 

 

모든 작업이 끝났다면 플레이 버튼을 누르고 Space 키를 눌러보자. 그러면 유니티 짱이 쓰러지려다 앞으로 날아가는 것을 볼 수 있을 것이다.

 


 

래그돌을 이용하는 방법을 추가로 이야기하자면, 이런 래그돌 오브젝트를 만들어둔 다음, 애니메이션이 포함된 일반 캐릭터가 정상적으로 움직이다가 캐릭터가 죽으면 일반 캐릭터 오브젝트의 액티브를 끄고 래그돌 오브젝트의 액티브를 켜서 교체하는 식으로 자주 사용된다.

 

래그돌의 성능은 캐릭터의 사지 전체와 몸통의 관절에 대한 물리를 모두 계산해야하기 때문에 조금은 무거운 편에 속한다. 그렇기 때문에 일반적으로는 캐릭터가 죽고난 이후 몇 초간 물리를 켜두다가 그 이후에 더 이상 움직임이 거의 없는 상태가 되면 물리 계산을 끄거나, 아예 오브젝트를 지우는 방식으로 최적화를 해주어야 한다.

 

 

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

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

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 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

 

반응형

2D 스프라이트 시퀀스 애니메이션

 

애니메이션은 게임에 생동감을 불어넣어 준다. 그런 애니메이션은 2D와 3D 애니메이션으로 나누어 지는데 3D 모델에 본을 심어서 움직이는 3D 애니메이션과 달리 2D 애니메이션은 고전적으로 시퀀스 이미지를 사용해왔다(최근 들어서는 2D 이미지를 부위 별로 나누고 거기에 본을 심어서 움직이는 스파인이나 라이브 2D 같은 방식의 애니메이션도 사용된다).

 

 

시퀀스 이미지란 위의 이미지처럼 진행될 애니메이션을 이미지로 그려서 나열해 놓은 것을 의미한다. 일반적으로는 위의 이미지처럼 하나의 시퀀스 이미지를 뽑아서 가져온 뒤에 오프셋을 이동시키는 방법으로 시퀀스 애니메이션을 사용했지만 유니티에서는 시퀀스 이미지를 각 프레임별로 이미지를 잘라서 사용한다.

 

잘라서 가져온 스프라이트 이미지

 

유니티 엔진에서 스프라이트 시퀀스 애니메이션은 크게 2가지 용도로 사용이 가능하다. 하나는 2D게임을 제작할 때, 2D 오브젝트에 애니메이션을 넣는 것이고, 다른 하나는 UI에서 2D 이펙트를 주거나, 기존의 키 애니메이션이 아닌 방식으로 UI에 애니메이션을 넣고 싶을때 사용하는 것이다.

 

이 2D 시퀀스 애니메이션을 사용하는 방법은 매우 간단하다.

 

 

우선은 간단하게 시퀀스 애니메이션을 적용할 2D 스프라이트 오브젝트를 생성하자.

 

 

그리고 Hierarchy 창에서 생성한 스프라이트 오브젝트를 선택하고 애니메이션 창을 열면 해당 오브젝트에는 아직 애니메이션이 없음을 볼 수 있다. 여기서 Create 버튼을 누르면 새로운 애니메이션을 만들 수 있다.

 

 

새로운 애니메이션을 생성한 이후에 한 애니메이션에 사용될 시퀀스 이미지들을 애니메이션 창에 드래그&드롭하면 그 생성한 애니메이션 클립에 시퀀스 이미지들이 들어가면서 스프라이트 시퀀스 애니메이션이 완성된다. 참고로 1프레임당 시퀀스 이미지 1장이 들어가기 때문에 적당한 속도로 애니메이션을 출력하기 위해서는 애니메이션의 속도 조절을 해야할 것이다. 다음 이미지가 0.5배속으로 만든 스프라이트 애니메이션이 적용된 모습이다.

 

 

2D 스프라이트 시퀀스 애니메이션을 사용할 때,시퀀스 이미지의 프레임이 늘어나면 애니메이션이 부드러워 보이고 퀄리티가 높아지지만 그만큼 더 많은 리소스를 사용하게 된다는 점을 기억해야 한다.

 

또한 시퀀스 애니메이션 작업을 할 때는 애니메이션에 사용되는 시퀀스 이미지들을 한꺼번에 선택해야 하는 경우가 많은데, 만약 시퀀스 이미지들의 해상도가 높거나 이미지들의 개수가 너무 많은 경우, 이미지들을 선택하는 것만으로도 유니티 엔진이 버벅대는 사태가 발생할 수 있다.

 

유니티 엔진의 Project 뷰에서 다량 혹은 고해상도의 이미지를 선택해야하는 작업의 경우에는 Inspector 뷰 우측 상단의 자물쇠 표시를 눌러서 잠궈주고, 하단의 프리뷰 창을 내려주는 것이 많은 도움이 될 것이다.

 

 

 

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

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

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 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

 

반응형

구글 개발자 등록하기

 

구글 애드몹(Admob)이나 구글에서 제공하는 서비스와 API를 이용하여 프로그래밍을 하기 위해서는 구글에 개발자 등록을 해야한다. 구글에 개발자 등록을 하기 위해서는 우선 구글 플레이 콘솔(Google Play Console)에 접속해야 한다.

 

 

구글 플레이 콘솔에 접속하기 위해서는 구글 검색창에서 구글 플레이 콘솔이라고 검색한 뒤 최상단 홈페이지에 접속하면 된다.

 

 

 

개발자 콘솔에 접속했다면 개발자 등록을 하고자하는 구글 계정으로 로그인을 한다.

 

 

구글의 개발자 등록은 위의 그림과 같은 순서로 이루어진다. 로그인 한 이후에는 개발자 계약을 수락해야 하는데, 개발자의 실수로 인해서 개발자 등록이 해지된다거나 구글의 API를 사용하거나 서비스를 이용하여 게시된 상품의 게시가 중지되는 문제가 발생할 수도 있기 때문에 계약서를 꼼꼼히 읽고 주의를 하는 것이 좋다.

 

 

계약을 수락하면 개발자 등록 수수료를 결제해야 하는데 25달러가 든다. 어떤 개발자 등록처럼 연회비 개념으로 내야하는 것이 아니라 등록할 때 최초 1회만 결제하면 되기 때문에 개발자 등록을 함으로서 얻을 이익에 비하면 부담이 적은 편이다.

 

 

구글은 별도의 공인인증서나 키보드 보안 프로그램을 강제하기 않기 때문에, 격렬한 발암 없이도 간단하게 수수료 결제를 끝낼 수 있다.

 

 

마지막으로 세부정보를 간단하게 입력하고 등록 완료를 누르면 구글 개발자 등록을 마치게 된다.

 

 

이제부터 구글에서 제공하는 개발자용 API와 서비스를 이용할 수 있고 구글 플레이 스토어를 통해 앱을 출시할 수도 있게 되었다.

 

 

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

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

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 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

 

반응형

enum class

 

인간은 문자와 기호 그리고 숫자를 이용하고 컴퓨터는 모든 것을 숫자로 받아들인다. 그렇기 때문에 인간이 알아보기 쉽게 문자열로 만들면 프로그램이 느려지고 컴퓨터가 알아보기 쉽게 숫자로 만들면 인간이 알아보기가 어려워진다. 이것을 해결하기 위한 방법의 하나가 바로 enum(열거형)이다.

 

이 enum은 일반적으로 이름을 가지는 정수형의 상수를 정의해서 알아보기 쉽게 해주는데, 이 기존의 enum은 몇가지의 문제점이 존재한다.

 

 

1. 열거형에 존재하는 이름과 같은 이름의 클래스를 선언할 수 없다.

일반적인 enum 내에 선언된 열거자의 이름은 전역적이다. 그렇기 때문에 enum 내부에 선언된 이름과 같은 이름을 가진 클래스를 선언하고 사용하려고 하면 컴파일 에러가 발생한다. 다음의 코드는 이것에 대한 예시이다.

 

#include <iostream>
using namespace std;

enum EColor
{
    Red,
    Green,
    Blue,
};

class Red { };

int main()
{
    Red r;    // 컴파일 에러가 발생한다.
    EColor color = Red;

    return 0;
}

 

위와 같은 일이 발생하는 이유는 MSDN에 다음과 같이 설명되어 있다.

 

enum EColor
{
    Red,
    Green,
    Blue,
};

 

위와 같이 정의된 enum의 의미 체계는 다음과 같다고 한다.

 

static const int Red = 0;
static const int Green = 1;
static const int Blue = 2;

 

다시 말하자면 이미 전역 변수에 같은 이름의 변수가 선언되어 있기 때문에 같은 이름의 클래스를 선언할 수 없는 것이다. 하지만 enum class로 정의된 열거형의 경우에는 위와 같은 문제가 발생하지 않는다.

 

#include <iostream>
using namespace std;

enum class EColor
{
    Red,
    Green,
    Blue,
};

class Red { };

int main()
{
    Red r;    // 컴파일 에러가 발생하지 않는다.
    EColor color = EColor::Red;    // 대신 접근지정자를 이용해 스코프를 지정해주어야 한다.

    return 0;
}

 

열거형을 표준 열거형이 아닌 enum class로 선언하면 열거형 내부에 존재하는 이름으로 클래스를 선언해도 문제가 발생하지 않는다. 하지만 표준 열거형에서는 Red라는 이름만으로 열거형 변수에 값을 넣어줄 수 있었지만 enum class 열거형에서는 열거형 변수에 값을 넣어주기 위해서는 반드시 접근지정자를 이용해서 스코프를 지정해주어야만 컴파일 에러 없이 값을 대입할 수 있게 된다. 이러한 형태의 이유 역시 MSDN에 설명되어 있는데 그것을 보면 왜 이런 형태를 가지는지 충분히 이해할 수 있게 된다.

 

enum class EColor
{
    Red,
    Green,
    Blue,
};

 

enum class로 선언된 EColor의 경우에는 다음과 같은 의미 체계를 가지게 된다.

 

class EColor
{
public:
    static const int Red = 0;
    static const int Green = 1;
    static const int Blue = 2;
};

 

위와 같은 형태를 가지게 된다는 것을 생각해보면 왜 enum class 열거형 변수에 스코프를 지정해 주어야하는지 명확하게 이해할 수 있다.

 

 

 

 

 

2. 표준 열거형은 타입 세이프(Type safe)하지 않다.

일반적으로 프로그래머들은 언어의 동작에서 프로그래머가 무의식적으로 실수를 유도하게 되는 동작을 좋아하지 않는다. 만약 프로그래머가 명시적으로 한 행동에서 문제가 발생하면 명백한 프로그래머의 실수이고 그 문제점을 찾아내기도 쉽지만, 프로그래머가 명시하지 않았는데 언어가 묵시적으로 처리해서 발생하는 문제는 찾아내기 어렵기 때문이다.

 

이러한 측면에서 표준 열거형이 발생시키는 문제가 몇 가지 있다.

 

첫 번째 문제로는 정수형의 변수에 곧바로 대입이 가능하다는 것이다(하지만 정수형에서 열거형으로의 대입은 명시적인 형 변환이 필요하다). 이것으로 인해서 발생하는 문제점에 대해서 경험이 많지 않아서 언급하지는 못하겠지만, 이런 묵시적인 동작으로 인해서 프로그래머가 실수를 할 가능성이 커지는 것은 부인할 수 없는 문제이다.

 

#include <iostream>
using namespace std;

enum EColor
{
    Red,
    Green,
    Blue,
};

int main()
{
    EColor color = Red;
    int i = color;    // 바로 대입이 가능하다.

    return 0;
}

 

하지만 열거형을 enum class로 선언할 경우, 다음과 같이 더 이상 명시적으로 형 변환을 거치지 않는 이상 열거형 변수나 값은 정수형에 대입할 수 없게 된다.

 

#include <iostream>
using namespace std;

enum class EColor
{
    Red,
    Green,
    Blue,
};

int main()
{
    EColor color = EColor::Red;
    int i = static_cast<int>(color);    // 명시적인 형 변환을 거쳐야만 대입이 가능하다.

    return 0;
}

 

두 번째 문제는 명시적인 형 변환 없이도 다른 열거형 간의 비교 연산이 가능하다는 것이다.

 

#include <iostream>
using namespace std;

enum EColor
{
    Red,
    Green,
    Blue,
};

enum EDirection
{
    Forward,
    Backward,
    Right,
    Left,
    Up,
    Down,
};

int main()
{
    EColor color = Red;
    EDirection dir = Up;
   
    if (color == dir)    // 문제없이 비교되고 컴파일 된다.
    {
        cout << "같다" << endl;
    }

    return 0;
}

 

이것이 무슨 문제가 되는지 이해하지 못할 수도 있겠지만, 위의 코드를 살펴보면 EColor 열거형과 EDirection 열거형의 종류와 내용, 그 의미는 명백하게 다르다. 이러한 상황을 프로그래머가 의도한 것이라면 모르겠지만, 이런 상황을 의도하지 않았고 실수로 전혀 다른 열거형을 비교하게 된 것이라면 문제가 될 것이고, 이러한 문제는 컴파일러가 프로그래머에게 알려주지 않기 때문에 찾아내기도 쉽지 않을 것이다.

 

하지만 열거형을 아래와 같이 enum class로 선언하면 명시적인 형 변환을 거치지 않는 이상 다른 열거형에 대한 비교 연산은 불가능해진다.

 

#include <iostream>
using namespace std;

enum class EColor
{
    Red,
    Green,
    Blue,
};

enum class EDirection
{
    Forward,
    Backward,
    Right,
    Left,
    Up,
    Down,
};

int main()
{
    EColor color = EColor::Red;
    EDirection dir = EDirection::Forward;
   
    if (color == (EColor)dir)    // 명시적으로 형 변환을 거친 후에야 비교 연산이 가능해진다.
    {
        cout << "같다" << endl;
    }

    return 0;
}

 

이러한 동작은 프로그래머의 무의식적인 실수로 인한 버그를 막아주는 것이고, 문제를 발생시킬 수 있는 동작의 경우에는 프로그래머가 의도적으로 코드를 작성해야 하고 그로인해 발생할 문제에 대한 대처와 책임을 충분히 해야한다는 것을 의미한다.

 

 

 

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

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

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 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

 

반응형

'C++' 카테고리의 다른 글

[C++ 11] static_assert  (0) 2017.05.23
[C++ 11] Auto Vectorization  (1) 2016.11.01
[C++ 11] Range-Based For  (0) 2016.11.01
[C++ 11] Scoped Lock  (0) 2016.11.01

Programming

-

커스텀 IEnumerator 클래스 만들기(Custon yield instruction)

 

 

코루틴(Coroutine)은 유니티에서 아주 많이 사용되는 기능들 중에 하나다. 코루틴의 대표적인 사용법은 게임의 메인 흐름과 다르게 후방에서 무언가가 돌아가야 하는 경우와 무언가가 완료되기를 기다리는 것이다.

 

이번 섹션에서 이야기할 방법은 주로 후방에서 돌아가는 경우보다는 무언가가 완료되기를 기다리는 경우에 더욱 유용한 것이다. 일반적으로 가장 많이 기다리게 되는 것은 일정한 시간이 지나기를 기다리는 것이다. 그 경우 사용되는 것이 바로 WaitForSeconds 클래스이다. 유니티 개발을 해본 개발자라면 다음과 같은 종류의 코드를 많이 보았을 것이다.

 

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

public class CoroutineExample : MonoBehaviour
{
    private void Start()
    {
        StartCoroutine(WaitForSecondsCoroutine());
    }

    IEnumerator WaitForSecondsCoroutine()
    {
        yield return new WaitForSeconds(5.0f);
        Debug.Log("5초가 지남!");
    }
}

 

5초가 지난 이후에 로그 하나의 띄우는 코드이다. 위와 비슷한 방식으로 WWW 클래스를 이용해서 웹 서버에서 무언가가 전송되기를 기다린다던지, 위의 코드처럼 WaitForSeconds 클래스를 이용해서 얼마간의 시간이 지나기를 기다린다던가 할 수 있고, 이 외에도 여러가지의 것을 기다렸다가 이후의 작업을 진행할 수 있다.

 

유니티에서는 이렇게 원하는 동작을 기다릴 수 있는 IEnumerator 클래스를 제공한다. 하지만 유니티에서 모든 종류의 기능을 제공하는 것은 아니며, 개발자가 새로운 동작을 기다리는 기능을 만들기를 원할 수도 있다.

 

만약 개발자가 코루틴 내에서 Space 키를 입력하기를 기다려야 된다고 가정해보자. 하지만 기본적으로 키 입력을 기다리는 Custom yield Instruction은 존재하지 않는다. 그렇기 때문에 개발자는 이러한 기능을 직접 구현해야하는데 그 방법은 2가지가 있다.

 

 

1. CustomYieldInstruction 상속받기

첫 번째 방법은 CustomYieldInstruction을 상속받는 것이다. 다음은 그 예제이다.

 

using System.Collections;
using UnityEngine;

public class CustomIEnumeratorType1 : CustomYieldInstruction
{
    public override bool keepWaiting
    {
        get
        {
            return !Input.GetKeyDown(KeyCode.Space);
        }
    }
}

 

간단하게 새로운 클래스를 구현하고 CustomYieldInstruction을 상속 받은 뒤에 keepWaiting을 오버로딩해주고 getter에서 원하는 동작을 구현하면 된다. 이 예제에서는 Space 키의 입력을 기다릴 것이기 때문에 Input.GetKeyDown(KeyCode.Space)로 입력했다. Yield instruction의 동작은 "계속 기다릴 것인가?"를 묻고 있기 때문에 계속 기다려야 한다면 true를 반환해야하고 더 이상 기다릴 필요가 없다면 false를 반환해야 한다.

 

 

2. IEnumerator 상속받기

using System.Collections;
using UnityEngine;

public class CustomIEnumeratorType2 : IEnumerator
{
    public object Current
    {
        get
        {
            Debug.Log("대기하는 동안에 처리할 동작");
            return null;
        }
    }

    public bool MoveNext()
    {
        return !Input.GetKeyDown(KeyCode.Space);
    }

    public void Reset()
    {
    }
}

 

두 번째 방법은 새로운 클래스를 구현한 뒤에 IEnumerator를 상속받는 것이다. 이 방법은 CustomYieldInstruction을 상속받는 방법보다는 약간 복잡하지만,

좀 더 많은 기능을 사용할 수 있게 된다. Current를 통해서 코루틴이 대기하는 동안에도 다른 동작을 처리할 수 있고 MoveNext를 통해서 CustomYieldInstruction의 keepWaiting처럼 더 기다려야 하는지에 대한 여부를 대기중인 코루틴에 전달할 수 있다. reset 메서드의 경우는 COM의 상호운용성을 위해 제공되며 반드시 구현해야 하지만 반드시 필요하지는 않다.

 

 

위의 두 가지 방법을 이용하면 코루틴을 수행하는 도중에 원하는 동작을 기다릴 수 있게 된다. 이 기능의 유용한 한 가지 예를 들자면, 동시에 턴이 진행되고 두 사람이 둘 다 완료 버튼을 눌러야 다음 턴으로 진행되는 게임이 있다면, 턴을 넘기는 코루틴을 커스텀으로 제작된 yield 객체를 이용해서 정지시켜두고 두 사람 모두에게서 신호를 받아야 턴 코루틴이 진행되는 방식으로 만들 수 있다.

 

 

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

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

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 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

 

반응형

유니티 개발 중 Access Violation 충돌로 인한 에디터 종료 문제(5.6 Kinect 개발 중에 발생한 문제)

 

5.6.0f3 버전의 유니티 엔진에서 키넥트 V2(Kinect V2 이하 키넥트)를 이용해서 개발하는 도중에 유니티 에디터 상에서 게임 테스트를 하기 위해서 플레이 버튼을 눌렀을 때 유니티 엔진이 Unity Bug Reporter 창을 띄우고 뻗어버리는 일이 발생했다.

 


다음의 내용이 개발하기 위해 세팅되어 있는 것들이었다.

 

Unity 5.6.0f3

Microsoft Kinect SDK 2.0

Visual Studio Community 2017

Kinect Examples with MS-SDK v2

 

버그 발생하기 이전에 수정한 사항은 많지 않았기 때문에 갑자기 발생한 버그라서 버그의 원인을 짐작하기가 쉽지 않았다.

 

 

유니티 엔진은 crash.dmp 파일과 error.log 파일 하나만 남겨놓고 뻗은 상태였고, 로그 내용을 기반으로 구글링도 해보았으나 외국의 개발자들 역시 Access Violation 문제로 고통받고 있을뿐 별다른 해결책은 찾을 수 없었다(그리고 Access Violation 문제라는 것만 같고 개발 세팅이나 문제가 발생하는 시점 역시 달라서 크게 참고가 되지 않았다). 외국 개발자들의 이야기 중에 그나마 도움이 되었던 것은 이 문제가 유니티 에디터에서만 발생하고 빌드한 실행 파일에서는 발생하지 않는다는 것이었다.

 

 

Unity Editor [version: Unity 5.6.0f3_497a0f351392]

mono.dll caused an Access Violation (0xc0000005)
  in module mono.dll at 0033:abc51985.

Error occurred at 2017-06-14_092816.
C:\Program Files\Unity\Editor\Unity.exe, run by PC.
44% memory in use.
8114 MB physical memory [4468 MB free].
14258 MB paging file [9523 MB free].
134217728 MB user address space [134214674 MB free].
Read from location 320f7000 caused an access violation.

Context:
RDI:    0x00000000  RSI: 0x3209d87b  RAX:   0x00000001
RBX:    0x0002cbc2  RCX: 0x00000000  RDX:   0x0392dc0d
RIP:    0xabc51985  RBP: 0x00000000  SegCs: 0x00000033
EFlags: 0x00010202  RSP: 0x005fcb70  SegSs: 0x0000002b
R8:     0x00054d0d  R9:  0x00000000  R10:   0x0002cbc2
R11:    0x00000000  R12: 0x00000000  R13:   0x00000080
R14:    0x000003ff  R15: 0x00002400

Bytes at CS:EIP:
66 46 39 2c 56 73 9f 41 ff c0 ff c3 49 ff c2 eb

Stack:
0x005fcb70: 0000000b 00000000 3989ae80 00000000 ...........9....

.

.

.

0x005feb60: 00000000 ffffffff 00000042 00007fff ........B.......

Module 1
C:\Program Files\Unity\Editor\OpenRL_pthread.dll
Image Base: 0x80000000  Image Size: 0x0000f000
File Size:  50200       File Time:  2017-03-30_143322
Version:
   Company:    Open Source Software community LGPL
   Product:    POSIX Threads for Windows LPGL
   FileDesc:   MS C 32 bit
   FileVer:    2.9.0.0
   ProdVer:    2.9.0.0

Module 2
C:\Program Files\Unity\Editor\OpenRL.dll
Image Base: 0x80000000  Image Size: 0x00c28000
File Size:  12627992    File Time:  2017-03-30_143322
Version:
   Company:    Imagination Technologies, Inc.
   Product:    OpenRL™
   FileDesc:   OpenRL™ Library
   FileVer:    1.5.100.10
   ProdVer:    1.5.100.10

Module 3
C:\WINDOWS\SYSTEM32\MSVCR100.dll
Image Base: 0x53a80000  Image Size: 0x000d2000
File Size:  829264      File Time:  2011-02-19_005232
Version:
   Company:    Microsoft Corporation
   Product:    Microsoft® Visual Studio® 2010
   FileDesc:   Microsoft® C Runtime Library
   FileVer:    10.0.40219.1
   ProdVer:    10.0.40219.1

Module 4
C:\WINDOWS\SYSTEM32\MSVCP100.dll
Image Base: 0x53b60000  Image Size: 0x00098000
File Size:  608080      File Time:  2011-02-19_225156
Version:
   Company:    Microsoft Corporation
   Product:    Microsoft® Visual Studio® 2010
   FileDesc:   Microsoft® C Runtime Library
   FileVer:    10.0.40219.1
   ProdVer:    10.0.40219.1


== [end of error.log] ==

 

에러 로그나 Dump 파일을 봤을 때, 문제는 mono.dll에서 발생하는 것으로 보였다. 하지만 당장 개발이 급했기 때문에 덤프 파일을 분석하지는 못했고 당장의 문제의 원인을 파악하고, 문제를 배제한 뒤에 개발을 다시 시작하기 위해서 프로젝트를 새로 만들어서 리소스와 스크립트를 옮기는 작업을 했다. 하지만 프로젝트를 새로 만들어서 내용물을 옮기는 것만으로는 문제가 해결되지 않았고, 결국 문제가 발생하는 지점을 찾기 위해서 오브젝트에 붙은 컴포넌트를 하나씩 꺼보고 스크립트를 블럭 단위로 주석 처리하는 방식으로 문제 지점을 찾기 위해 작업했다.

 

이 작업을 진행하는 도중의 대부분은 오브젝트에 붙은 컴포넌트를 제거하거나 스크립트를 주석처리하고 플레이해 본뒤에 충돌이 발생하는지 확인하는 것이었다. 그러던 중에 발견한 사항은 다음과 같았다.

 

1. Kinect Examples with MS-SDK v2 에셋에서 제공하는 스크립트를 오브젝트에 붙인 컴포넌트를 게임 씬에서 모두 제거하면 충돌이 발생하지 않는다.

2. Kinect Examples with MS-SDK v2 에셋에서 제공하는 스크립트를 오브젝트에 붙인 컴포넌트를 제거하지 않더라도 내가 작성한 스크립트 중에서 특정 블럭을 주석 처리하면 충돌이 발생하지 않는다.

 

키넥트 개발을 계속해야하기 때문에 1번은 전혀 해결책이 될 수가 없었고 2번의 방법으로 주석 처리했을 때, 충돌이 발생하지 않는 부분을 찾기 위해 해당 코드 블럭을 한줄한줄씩 주석 처리해보면서 플레이 버튼을 눌러보는 수 밖에 없었다.

 

그러던 도중에 단 한 줄을 주석 처리했을 때, 충돌이 발생하지 않는다는 것을 발견할 수 있었다.

 

 

그 문제의 원인은 어이없게도 Debug.Log("업"); 이라는 코드였다. 이 한 줄을 주석 처리하면 더 이상 문제는 발생하지 않았다. 그리고 "업"이 아니라 다른 글자를 사용해도 문제가 해결되었고, 가끔은 다른 로그 내용도 문제를 발생시키기도 했으며, 혹은 Debug.Log("업");이라고 해도 또 다른 특정한 위치에서는 문제가 없이 작동했다.

키넥트가 필요하지 않은 테스트일 때는 Kinect Manager 스크립트를 제외하고, 키넥트가 필요한 시점에는 Log를 주의해서 사용해야 했다.

 

임시방편으로 문제를 우회해서 지나가는 방법은 발견했으나 근본적인 해결책을 찾지 못했다. 추측해보건데 로그를 남기는 작업은 파일에 관여하는데 그 작업 중 어느 부분이 Kinect Examples with MS-SDK가 제공하는 Kinect Manager 스크립트가 처리하는 부분과 충돌이 발생하는 것으로 보인다.


주변 분들이 원인으로 추정되는 몇가지를 이야기 해주었는데, 하나는 키넥트 스레드가 처리하는 부분에서 메인 스레드와 충돌을 일으킨 것이 아닌가 하는 것이고 다른 하나는 특정 문자열에서만 이 현상을 일으키기 때문에 문자열 인코딩 방식이 이런 문제를 발생시킬 수도 있다는 것이었다.

 

 

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

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

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 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)

 

유니티 5에는 고질적인 버그가 하나 있다. 유니티 에디터에서 게임 테스트를 위해서 플레이 버튼을 눌러서 플레이할 때 다른 씬으로 이동하면 라이트가 어둡게 보이는 문제가 바로 그것이다.

 

 

의도한 씬의 밝기는 첫 번째 그림과 같지만 유니티 에디터에서 플레이 버튼을 눌러서 게임을 실행한 뒤에 플레이 도중에 씬을 넘어가면 라이트의 밝기가 두 번째 그림처럼 어두워 진다. 이러한 현상은 게임을 빌드해서 실행했을 경우에는 발생하지 않지만, 라이팅 테스트 하나만을 위해 매번 게임을 새로 빌드해서 실행하는 것은 매우 번거로운 일이다.

 

이 문제를 해결하는 방법은 다음과 같다.

 

 

상단 메뉴에서 Window > Lighting > Setting 을 선택하면 라이팅 세팅을 할 수 있는 창이 열린다.

 

 

열린 Lighting Setting 창의 가장 아래쪽에서 Auto Generate가 체크되어 있는 것을 볼 수 있는데 이 체크를 해제하면 옆의 Generate Lighting 버튼이 활성화된다. 이 버튼을 클릭하면 유니티 에디터에서 테스트를 진행할 때에도 빛이 제대로 들어오는 것을 확인할 수 있다.

 

 

 

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

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

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 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

 

반응형

UnityEditor 네임스페이스를 사용할 때 주의할 점

 

 

 

유니티 엔진에는 유용한 기능이 아주 많지만, 그 모든 기능을 제작자가 필요로 하지는 않는다. 그와 마찬가지로 제작자가 필요로 하는 기능이지만 유니티 엔진에서는 제공하지 않을 수도 있다. 그럴 때에는 원하는 기능을 제작자가 직접 만들어내야 하는데, 그와 관련해서 가장 큰 도움을 주는 것들이 담겨 있는 것이 바로 UnityEditor 네임스페이스(namespace)이다. 여기에는 편리한 기능들이 상당히 많이 담겨 있지만 이 네임스페이스를 사용하기 위해서는 주의할 점들이 몇 가지 존재한다.

 

우선은 이 네임스페이스들의 기능들을 인게임의 기능에서는 사용하면 안된다는 것이다. UnityEditor 네임스페이스에는 찾아보면 쓸만한 기능이 몇 가지 있기 때문에 가끔 이 네임스페이스 안에 존재하는 기능들을 이용해서 인게임의 기능을 구현하려고 하는 사람들이 있다. 하지만 UnityEditor에서 제공하는 기능들은 철저하게 유니티 에디터를 사용자가 원하는 대로 커스터마이즈(Customizie)하는 것을 돕기 위해 지원되는 것으로 인게임에서 동작하는 코드에 집어넣고 게임을 빌드하려고 하면 유니티 에디터는 에러를 출력하고 빌드를 정지할 것이다.

 

두 번째로 주의할 점은, 이 UnityEditor 네임스페이스를 사용하기 위해서 using namespace UnityEditor; 선언을 한 스크립트는 Project 뷰에서 Editor 폴더 내에 모두 넣어두어야 한다는 것이다.

 

 

UnityEditor를 사용하는 cs파일을 Editor 폴더에 넣어주지 않는다면, 만든 에디터 기능을 사용하려고 할 때, 다음과 같은 에러 메시지를 출력하면서 기능이 작동하지 않을 것이다.

 

error CS0246: The type or namespace name `UnityEditor' could not be found. Are you missing a using directive or an assembly reference?


만약에 에디터로서의 기능이 아니라 게임 내에서 디버그 적인 요소로서 UnityEditor의 기능을 사용해야 한다면 그 기능을 사용하는 코드에는 다음 예시와 같이 전처리기 처리를 해주어야 한다.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class UseUnityEditorClass : MonoBehaviour
{
    public void Function()
    {
#if UNITY_EDITOR
        // 유니티 에디터에서 Debug 용으로만 작동해야 하는 코드...
#endif
    }
}

 

 

 

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

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

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 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