내용이 아무것도 없는 이유는 중간에 방향을 잃고 이리저리 방황했기 때문입니다.

 

우선 DirectX12의 예시 코드는 C++/CX를 개발이 된 코드입니다.

 

CX를 찾다 보니 UWP가 나오고, UWP를 찾아보다 보니 Windows RT가 나왔습니다.

 

Windows RT는 Windows 8에 추가가 된 것인데, 예시 코드 내부의 것들이 Windows 10에서 Windows RT에 통합이 된 경우가 있었습니다.

 

지금 약간 CX와 UWP, RT의 구분이 잘 되지 않고 있습니다.

 

그래서 몇시간 동안 CX 보다가 UWP 보다가 RT 보다가 왔다갔다 하는 것 같습니다.

 

그러다가 문뜩 "CX고 RT고 지금 게임 쪽에서 이런걸 쓰고는 있나?"라는 의문도 들기 시작했습니다.

 

클라이언트 팁을 조금 찾아보니까 아직까지는 이런 얘기들과는 거리가 조금 먼 상황인 것 같습니다.

 

그래서 다음주에는 DirectX 코드 분석을 하고, 그 뒤에 Windows Desktop Application Template에서 DirectX12 예시 프로그램과 동일한 기능을 구현해보려 합니다.

 

이래저래 Windows Programming을 병행 해야 하지 않을까 싶은데 시간을 더 내기가 힘들어서 고민이 됩니다.

오늘도 이 문제 부분을 고치기 위해 이것저것 시도를 했고, 실패했습니다.

얻은 결과가 몇가지 있다면, MovingDirection이 Climb 상태에서 해제된 이후로도 변하지 않는다는 점.

이 값이 변해야 하는 부분의 다른 함수는 잘 작동하고 있다는 점입니다.

 

다음에는 

1. 프로젝트 rebuilding 해보기

2. 해당 함수가 실행되어야 할 부분에 로그를 찍어서 제대로 동작하는지 확인해보기

 

이정도 먼저 해보려 합니다.

'개발일지 > Treasure Hunter' 카테고리의 다른 글

20.06.08 개발일지  (0) 2020.06.08
20.06.06 개발일지  (0) 2020.06.06
20.06.03 개발일지  (0) 2020.06.03
20.06.01 개발일지  (0) 2020.06.01
20.05.30 개발일지  (0) 2020.05.30

3달정도 자르는 것을 미루던 머리를 깎느라 개발 시간이 조금 줄어들었습니다.

오늘은 Climb의 위와 아래에 다다라서 상태에 벗어난 이후 Animation이 재생되지 않는 문제를 체크해 보았습니다.

 

우선 문제를 조금 더 상세히 분류했습니다.

탈출 시 이동 키를 누르고 있으면 문제가 발생하는데, 그렇지 않으면 정상적으로 작동했습니다.

심지어 애니메이션도 정상 작동했습니다.

문제가 일어날 가능성이 있는 부분이 Overlap 함수에서 Movement 함수까지 넓어졌습니다.

 

Movement 함수를 살펴보니, Climb 상태에서 이동하는 동안에 MovementType이 계속 Climb로 덮어씌워지고 있었습니다.

이 부분을 제거해 보았더니, Climb 상태에서 이동 중 Climb Animation이 재생되지 않았습니다.

그래서 Animatiton에 Stand Idle만 있던 것을 여러 종류의 Idle 값에 따른 Animation을 붙여주었고,

그 결과 함수를 제거해도 Animation이 예전처럼 적용되었습니다.

애니메이션은 여전히 작동하지 않았습니다.

 

슬슬 Anim Instance에서도 문제가 있는건가 의심이 되기 시작했습니다.

갈피가 잘 안잡히는게 이번 달 안에 끝낼 수 있을지 의문이 들기 시작합니다.

'개발일지 > Treasure Hunter' 카테고리의 다른 글

20.06.06 개발일지  (0) 2020.06.06
20.06.04 개발일지  (0) 2020.06.04
20.06.01 개발일지  (0) 2020.06.01
20.05.30 개발일지  (0) 2020.05.30
20.05.28 개발일지  (0) 2020.05.28

https://redchiken.tistory.com/136

 

20.05.26 - 2015 ACM-ICPC 연습

https://www.acmicpc.net/contest/view/116 2015 ACM-ICPC 연습 www.acmicpc.net 오늘 늦잠 잘 정도로 컨디션도 안좋고, 오른쪽 손목이 좋지 않아서 조금만 하려고 했습니다. 하지만 막상 문제를 풀려니까 저번에..

redchiken.tistory.com

저번주에 링크와 더불어 문제 해석을 해놓았기에 이전 글 링크로 대체합니다.

오늘은 Fridge of Your Dream 문제를 풀고, Scortched World 문제를 해결하다가 멈추었습니다.

 

Fridge of Your Dream은 이전에 생각해 놓았던대로 문제를 해결하니까 매우 쉽게 해결이 되었습니다.

그만큼 매우 쉬운 문제였구요.

 

하지만 Scortched World는 생각해 놓은 식대로 풀이가 되지 않았습니다.

적을 맞추는 궤적은 두가지가 있습니다. 종달속도에 도달하기 전에 맞추는 것과, 그 뒤에 맞추는 것.

하지만 막상 발사하기 전에는 이것이 어떻게 될지 모릅니다.

그러다 보니 종달높이를 이용해 식을 분할하는 방식을 채택할 경우, 같은 작업을 반복해야 합니다.

결국 사용할 수 있는 식이 한정되 버리게 되었습니다.

V를 구해야 하는데 그 와중에 도달 시간 T가 필요합니다.

이 과정에서 식이 매우 복잡해집니다.

 

우선은 다음주에는 이 문제를 좀 더 시도 했다가, 아니다 싶으면 다른 문제를 풀어보려 합니다.

'개발일지 > Algorithm' 카테고리의 다른 글

20.06.10 개발일지  (0) 2020.06.10
20.06.09 - 2015 ACM-ICPC 연습  (0) 2020.06.09
20.05.26 - 2015 ACM-ICPC 연습  (0) 2020.05.26
20.05.19 - 2015 ACM-ICPC 연습  (0) 2020.05.19
20.05.12 - 2015 ACM-ICPC 연습  (0) 2020.05.12

늦잠 + 입사지원 겹쳐서 개발을 늦게 시작했지만, 의외로 집중이 잘 되어서 이것저것 잘 한 것 같습니다.

 

오늘은 Climb 중 위아래로 이동 중 갑자기 Climb 상태가 해제되는 현상을 수정했습니다.

정확히는 수정 당했습니다.

문제 상황을 좀 더 명확하게 체크하기 위해 로그를 좀 더 찍어보았습니다.

그 결과 이동 중 갑자기 TriggerEndOverlap 이벤트가 발생하면서 문제가 발생하는 것을 확인했습니다.

이게 조건으로 걸러질수 있는가 하면, Climb의 맨 위와 아래에서 동일한 이벤트로 탈출하기에 불가능합니다.

 

그러다가 Climb의 Component를 Actor 크기와 최대한 비슷하게 맞춰보았더니 문제가 해결되었습니다.

다만 이 상황이 이해가 되지 않는게, 이벤트 발생 조건이 Component가 아니라 Actor입니다.

프로젝트에서 포괄적으로 사용하는 THActorBase에 Component가 있긴 하지만, Climb에는 사용되지 않습니다.

그래서 좀 기묘하고  해결 당했다는 것입니다.

 

이 뒤로는 Climb 위와 아래에 다다라서 상태가 해제된 이후에
Locomotion Animation이 재생되지 않는 현상을 수정해보려 했습니다.

이것도 기묘한 것이, 동일한 함수가 호출되는 Jump나 Re-Interaction에 의한 상태 해제 시에는 정상 작동합니다.

하지만 EndOverlap에 의한 것들만 작동하지 않습니다.

이 함수들을 Enter/ExitClimb로 묶어서 선언해도 마찬가지입니다.

아무래도 뭔가 다른 문제가 있는 것 같습니다.

이 문제가 Client에서만 발생한 것으로 보아 통신 쪽 문제라 생각됩니다.

다음에도 이 부분을 중점적으로 고쳐보고자 합니다.

'개발일지 > Treasure Hunter' 카테고리의 다른 글

20.06.04 개발일지  (0) 2020.06.04
20.06.03 개발일지  (0) 2020.06.03
20.05.30 개발일지  (0) 2020.05.30
20.05.28 개발일지  (0) 2020.05.28
20.05.27 개발일지  (0) 2020.05.27

오늘은 그저께 다시 작성한 Climb 기능의 State Machine을 하나하나 구현을 해보았습니다.

 

우선은 Rope를 먼저 수정하고, Rope에서 문제 없이 잘 작동하면 Wall과 Ladder에도 수정을 할 예정입니다.

 

결론적으로, 반의 반쪽만 완성하였습니다.

 

Climb시 Climb-Idle 상태로는 변합니다.

 

하지만 Enter Climb, Exit Climb와 Climb up, Climb down이 전혀 작동하지 않습니다.

 

또한 Climb move 중 갑자기 MvoementMode가 변하면서 Climb 상태가 해제되는 경우가 있습니다.

 

이 경우, Locomotion Animation도 정상 작동되지 않습니다.

 

간혹 정상적으로 Climb State에서 해제 되어도 Locomotion Animation이 정상 작동하지 않기도 합니다.

 

날이 따뜻해서  노곤노곤해지는 날입니다.

 

월요일에 이 문제를 좀 더 수정해보겠습니다.

'개발일지 > Treasure Hunter' 카테고리의 다른 글

20.06.03 개발일지  (0) 2020.06.03
20.06.01 개발일지  (0) 2020.06.01
20.05.28 개발일지  (0) 2020.05.28
20.05.27 개발일지  (0) 2020.05.27
20.05.25 개발일지  (0) 2020.05.25

이 글은 여러차례 분할하여 작성을 할 예정입니다.

프로젝트를 보면서 전혀 이해하지 못하는 문법들이 있었습니다.

 

UWP와 관련하여 계속해서 검색을 하면서도 답을 찾지 못했는데, 한 PPT에서 답을 찾았습니다.

https://www.slideshare.net/dgtman/f1-c-windows-10-uwp

 

프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~

Windows 10의 UWP 앱을 개발하면 모든 Windows 10 디바이스에서 앱을 작동할 수 있습니다. 이 UWP 앱을 C++로 개발할 수 있습니다. C++로 앱을 개발하면 크로스 플랫폼 지원의 유리함, 기존 코드의 재활용,

www.slideshare.net

이 PPT에 UWP가 무엇이고, 어떤 장단점과 특징이 있는지 잘 설명이 되어 있습니다.

그중에는 제가 그토록 궁금해 하던 C++/CX라는 것에 대해서도 설명이 되어 있습니다.

 

이를 기반으로 다음에 공부를 하고, 코드를 작성한 뒤 설명을 하려 합니다.

코드는 상세히 분석하여, 지울 수 있는 부분은 지운 상태에서 기본 프로젝트를 생성해볼 계획입니다.

https://docs.microsoft.com/ko-kr/visualstudio/ide/how-to-create-project-templates?view=vs-2019

 

프로젝트 템플릿 만들기 - Visual Studio

방법: 프로젝트 템플릿 만들기How to: Create project templates 이 문서의 내용 --> 이 항목에서는 템플릿을 .zip 파일로 패키징하는 템플릿 내보내기 마법사를 사용하여 템플릿을 만드는 방법을 보여줍니

docs.microsoft.com

이렇게 수정하면ㅁ 이후 더 편하게 DirectX12 예시 코드를 작성할 수 있을것이라 생각합니다.

DirectXMath.h 라이브러리에서 4×4 Matrix를 나타내는 데에는 XMMATRIX라는 클래스가 쓰인다.

struct XMMATRIX;

// Fix-up for (1st) XMMATRIX parameter to pass in-register for ARM64 and vector call; by reference otherwise
#if ( defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || _XM_VECTORCALL_ ) && !defined(_XM_NO_INTRINSICS_)
typedef const XMMATRIX FXMMATRIX;
#else
typedef const XMMATRIX& FXMMATRIX;
#endif

// Fix-up for (2nd+) XMMATRIX parameters to pass by reference
typedef const XMMATRIX& CXMMATRIX;

#ifdef _XM_NO_INTRINSICS_
struct XMMATRIX
#else
__declspec(align(16)) struct XMMATRIX
#endif
{
#ifdef _XM_NO_INTRINSICS_
    union
    {
        XMVECTOR r[4];
        struct
        {
            float _11, _12, _13, _14;
            float _21, _22, _23, _24;
            float _31, _32, _33, _34;
            float _41, _42, _43, _44;
        };
        float m[4][4];
    };
#else
    XMVECTOR r[4];
#endif

    XMMATRIX() = default;

    XMMATRIX(const XMMATRIX&) = default;

#if defined(_MSC_VER) && (_MSC_FULL_VER < 191426431)
    XMMATRIX& operator= (const XMMATRIX& M) noexcept { r[0] = M.r[0]; r[1] = M.r[1]; r[2] = M.r[2]; r[3] = M.r[3]; return *this; }
#else
    XMMATRIX& operator=(const XMMATRIX&) = default;

    XMMATRIX(XMMATRIX&&) = default;
    XMMATRIX& operator=(XMMATRIX&&) = default;
#endif

    constexpr XMMATRIX(FXMVECTOR R0, FXMVECTOR R1, FXMVECTOR R2, CXMVECTOR R3) : r{ R0,R1,R2,R3 } {}
    XMMATRIX(float m00, float m01, float m02, float m03,
             float m10, float m11, float m12, float m13,
             float m20, float m21, float m22, float m23,
             float m30, float m31, float m32, float m33);
    explicit XMMATRIX(_In_reads_(16) const float *pArray);

#ifdef _XM_NO_INTRINSICS_
    float       operator() (size_t Row, size_t Column) const { return m[Row][Column]; }
    float&      operator() (size_t Row, size_t Column) { return m[Row][Column]; }
#endif

    XMMATRIX    operator+ () const { return *this; }
    XMMATRIX    operator- () const;

    XMMATRIX&   XM_CALLCONV     operator+= (FXMMATRIX M);
    XMMATRIX&   XM_CALLCONV     operator-= (FXMMATRIX M);
    XMMATRIX&   XM_CALLCONV     operator*= (FXMMATRIX M);
    XMMATRIX&   operator*= (float S);
    XMMATRIX&   operator/= (float S);

    XMMATRIX    XM_CALLCONV     operator+ (FXMMATRIX M) const;
    XMMATRIX    XM_CALLCONV     operator- (FXMMATRIX M) const;
    XMMATRIX    XM_CALLCONV     operator* (FXMMATRIX M) const;
    XMMATRIX    operator* (float S) const;
    XMMATRIX    operator/ (float S) const;

    friend XMMATRIX     XM_CALLCONV     operator* (float S, FXMMATRIX M);
};

XMMATRIX는 SIMD의 장점을 취하기 위해 4개의 XMVECTOR Instance를 사용한다.

또한 Matrix 곱셈을 위한 연산자와 한 성분을 그 Row와 Column의 색인들을 지정해 접근/수정하기 위한 대괄호 연산자를 중복적재하고 있다.

 

또한 XMMATRIX를 이용해 선언된 FXMMATRIX와 CXMMATRIX가 있다.

이 둘의 설명은 주석을 통해 충분히 이해가 가겠지만, 다시 한번 언급을 해두려 한다.

보통 XMMATRIX를 Parameter로 전달 할 때에는 CXMMATRIX를 사용한다.

하지만 특수한 경우에 FXMMATRIX를 사용해야 하기도 하는데

  • 첫번째 XMMATRIX일 것
  • 위 XMMATRIX 변수 앞에 XMVECTOR가 3개 이상 존재하지 않을 것
  • 위 XMMATRIX 변수 뒤에 2개 이상의 float나 double, XMVECTOR가 존재하지 않을 것

 

생성자의 경우에는 항상 CXMMATRIX만 사용하는 것을 권장한다.

 

XMMATRIX에서는 다양한 생성자 외에, XMMatrixSet이라는 함수로도 Instance 생성이 가능하다.

XMMATRIX    XM_CALLCONV     XMMatrixSet(float m00, float m01, float m02, float m03,
                                        float m10, float m11, float m12, float m13,
                                        float m20, float m21, float m22, float m23,
                                        float m30, float m31, float m32, float m33);

Matrix를 클래스 자료 멤버로 저장할 때에는 Vector를 XMFLOAT2나 XMFLOAT3, XMFLOAT4를 사용한 것과 같이 XMFLOAT4X4나 XMFLOAT3X4, XMFLOAT4X3을 사용하는 것이 권장된다.

// 3x3 Matrix: 32 bit floating point components
struct XMFLOAT3X3
{
    union
    {
        struct
        {
            float _11, _12, _13;
            float _21, _22, _23;
            float _31, _32, _33;
        };
        float m[3][3];
    };

    XMFLOAT3X3() = default;

    XMFLOAT3X3(const XMFLOAT3X3&) = default;
    XMFLOAT3X3& operator=(const XMFLOAT3X3&) = default;

    XMFLOAT3X3(XMFLOAT3X3&&) = default;
    XMFLOAT3X3& operator=(XMFLOAT3X3&&) = default;

    XM_CONSTEXPR XMFLOAT3X3(float m00, float m01, float m02,
                            float m10, float m11, float m12,
                            float m20, float m21, float m22)
        : _11(m00), _12(m01), _13(m02),
          _21(m10), _22(m11), _23(m12),
          _31(m20), _32(m21), _33(m22) {}
    explicit XMFLOAT3X3(_In_reads_(9) const float *pArray);

    float       operator() (size_t Row, size_t Column) const { return m[Row][Column]; }
    float&      operator() (size_t Row, size_t Column) { return m[Row][Column]; }
};

//------------------------------------------------------------------------------
// 4x3 Row-major Matrix: 32 bit floating point components
struct XMFLOAT4X3
{
    union
    {
        struct
        {
            float _11, _12, _13;
            float _21, _22, _23;
            float _31, _32, _33;
            float _41, _42, _43;
        };
        float m[4][3];
        float f[12];
    };

    XMFLOAT4X3() = default;

    XMFLOAT4X3(const XMFLOAT4X3&) = default;
    XMFLOAT4X3& operator=(const XMFLOAT4X3&) = default;

    XMFLOAT4X3(XMFLOAT4X3&&) = default;
    XMFLOAT4X3& operator=(XMFLOAT4X3&&) = default;

    XM_CONSTEXPR XMFLOAT4X3(float m00, float m01, float m02,
                            float m10, float m11, float m12,
                            float m20, float m21, float m22,
                            float m30, float m31, float m32)
        : _11(m00), _12(m01), _13(m02),
          _21(m10), _22(m11), _23(m12),
          _31(m20), _32(m21), _33(m22),
          _41(m30), _42(m31), _43(m32) {}
    explicit XMFLOAT4X3(_In_reads_(12) const float *pArray);

    float       operator() (size_t Row, size_t Column) const { return m[Row][Column]; }
    float&      operator() (size_t Row, size_t Column) { return m[Row][Column]; }
};

// 4x3 Row-major Matrix: 32 bit floating point components aligned on a 16 byte boundary
__declspec(align(16)) struct XMFLOAT4X3A : public XMFLOAT4X3
{
    XMFLOAT4X3A() = default;

    XMFLOAT4X3A(const XMFLOAT4X3A&) = default;
    XMFLOAT4X3A& operator=(const XMFLOAT4X3A&) = default;

    XMFLOAT4X3A(XMFLOAT4X3A&&) = default;
    XMFLOAT4X3A& operator=(XMFLOAT4X3A&&) = default;

    XM_CONSTEXPR XMFLOAT4X3A(float m00, float m01, float m02,
                            float m10, float m11, float m12,
                            float m20, float m21, float m22,
                            float m30, float m31, float m32) :
        XMFLOAT4X3(m00,m01,m02,m10,m11,m12,m20,m21,m22,m30,m31,m32) {}
    explicit XMFLOAT4X3A(_In_reads_(12) const float *pArray) : XMFLOAT4X3(pArray) {}
};

//------------------------------------------------------------------------------
// 3x4 Column-major Matrix: 32 bit floating point components
struct XMFLOAT3X4
{
    union
    {
        struct
        {
            float _11, _12, _13, _14;
            float _21, _22, _23, _24;
            float _31, _32, _33, _34;
        };
        float m[3][4];
        float f[12];
    };

    XMFLOAT3X4() = default;

    XMFLOAT3X4(const XMFLOAT3X4&) = default;
    XMFLOAT3X4& operator=(const XMFLOAT3X4&) = default;

    XMFLOAT3X4(XMFLOAT3X4&&) = default;
    XMFLOAT3X4& operator=(XMFLOAT3X4&&) = default;

    XM_CONSTEXPR XMFLOAT3X4(float m00, float m01, float m02, float m03,
                            float m10, float m11, float m12, float m13,
                            float m20, float m21, float m22, float m23)
        : _11(m00), _12(m01), _13(m02), _14(m03),
          _21(m10), _22(m11), _23(m12), _24(m13),
          _31(m20), _32(m21), _33(m22), _34(m23) {}
    explicit XMFLOAT3X4(_In_reads_(12) const float *pArray);

    float       operator() (size_t Row, size_t Column) const { return m[Row][Column]; }
    float&      operator() (size_t Row, size_t Column) { return m[Row][Column]; }
};

// 3x4 Column-major Matrix: 32 bit floating point components aligned on a 16 byte boundary
__declspec(align(16)) struct XMFLOAT3X4A : public XMFLOAT3X4
{
    XMFLOAT3X4A() = default;

    XMFLOAT3X4A(const XMFLOAT3X4A&) = default;
    XMFLOAT3X4A& operator=(const XMFLOAT3X4A&) = default;

    XMFLOAT3X4A(XMFLOAT3X4A&&) = default;
    XMFLOAT3X4A& operator=(XMFLOAT3X4A&&) = default;

    XM_CONSTEXPR XMFLOAT3X4A(float m00, float m01, float m02, float m03,
                             float m10, float m11, float m12, float m13,
                             float m20, float m21, float m22, float m23) :
        XMFLOAT3X4(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23) {}
    explicit XMFLOAT3X4A(_In_reads_(12) const float *pArray) : XMFLOAT3X4(pArray) {}
};

//------------------------------------------------------------------------------
// 4x4 Matrix: 32 bit floating point components
struct XMFLOAT4X4
{
    union
    {
        struct
        {
            float _11, _12, _13, _14;
            float _21, _22, _23, _24;
            float _31, _32, _33, _34;
            float _41, _42, _43, _44;
        };
        float m[4][4];
    };

    XMFLOAT4X4() = default;

    XMFLOAT4X4(const XMFLOAT4X4&) = default;
    XMFLOAT4X4& operator=(const XMFLOAT4X4&) = default;

    XMFLOAT4X4(XMFLOAT4X4&&) = default;
    XMFLOAT4X4& operator=(XMFLOAT4X4&&) = default;

    XM_CONSTEXPR XMFLOAT4X4(float m00, float m01, float m02, float m03,
                            float m10, float m11, float m12, float m13,
                            float m20, float m21, float m22, float m23,
                            float m30, float m31, float m32, float m33)
        : _11(m00), _12(m01), _13(m02), _14(m03),
          _21(m10), _22(m11), _23(m12), _24(m13),
          _31(m20), _32(m21), _33(m22), _34(m23),
          _41(m30), _42(m31), _43(m32), _44(m33) {}
    explicit XMFLOAT4X4(_In_reads_(16) const float *pArray);

    float       operator() (size_t Row, size_t Column) const { return m[Row][Column]; }
    float&      operator() (size_t Row, size_t Column) { return m[Row][Column]; }
};

// 4x4 Matrix: 32 bit floating point components aligned on a 16 byte boundary
__declspec(align(16)) struct XMFLOAT4X4A : public XMFLOAT4X4
{
    XMFLOAT4X4A() = default;

    XMFLOAT4X4A(const XMFLOAT4X4A&) = default;
    XMFLOAT4X4A& operator=(const XMFLOAT4X4A&) = default;

    XMFLOAT4X4A(XMFLOAT4X4A&&) = default;
    XMFLOAT4X4A& operator=(XMFLOAT4X4A&&) = default;

    XM_CONSTEXPR XMFLOAT4X4A(float m00, float m01, float m02, float m03,
                             float m10, float m11, float m12, float m13,
                             float m20, float m21, float m22, float m23,
                             float m30, float m31, float m32, float m33)
        : XMFLOAT4X4(m00,m01,m02,m03,m10,m11,m12,m13,m20,m21,m22,m23,m30,m31,m32,m33) {}
    explicit XMFLOAT4X4A(_In_reads_(16) const float *pArray) : XMFLOAT4X4(pArray) {}
};

 

또한 Matrix와 관련된 여러 기능들에 대한 함수도 지원을 한다.

bool        XM_CALLCONV     XMMatrixIsNaN(FXMMATRIX M);
bool        XM_CALLCONV     XMMatrixIsInfinite(FXMMATRIX M);
bool        XM_CALLCONV     XMMatrixIsIdentity(FXMMATRIX M);

XMMATRIX    XM_CALLCONV     XMMatrixMultiply(FXMMATRIX M1, CXMMATRIX M2);
XMMATRIX    XM_CALLCONV     XMMatrixMultiplyTranspose(FXMMATRIX M1, CXMMATRIX M2);
XMMATRIX    XM_CALLCONV     XMMatrixTranspose(FXMMATRIX M);
XMMATRIX    XM_CALLCONV     XMMatrixInverse(_Out_opt_ XMVECTOR* pDeterminant, _In_ FXMMATRIX M);
XMVECTOR    XM_CALLCONV     XMMatrixDeterminant(FXMMATRIX M);
_Success_(return)
bool        XM_CALLCONV     XMMatrixDecompose(_Out_ XMVECTOR *outScale, _Out_ XMVECTOR *outRotQuat, _Out_ XMVECTOR *outTrans, _In_ FXMMATRIX M);

XMMATRIX    XM_CALLCONV     XMMatrixIdentity();

물론 이런 함수에는 Transformation 함수도 포함되어 있다.

XMMATRIX    XM_CALLCONV     XMMatrixTranslation(float OffsetX, float OffsetY, float OffsetZ);
XMMATRIX    XM_CALLCONV     XMMatrixTranslationFromVector(FXMVECTOR Offset);
XMMATRIX    XM_CALLCONV     XMMatrixScaling(float ScaleX, float ScaleY, float ScaleZ);
XMMATRIX    XM_CALLCONV     XMMatrixScalingFromVector(FXMVECTOR Scale);
XMMATRIX    XM_CALLCONV     XMMatrixRotationX(float Angle);
XMMATRIX    XM_CALLCONV     XMMatrixRotationY(float Angle);
XMMATRIX    XM_CALLCONV     XMMatrixRotationZ(float Angle);
XMMATRIX    XM_CALLCONV     XMMatrixRotationRollPitchYaw(float Pitch, float Yaw, float Roll);
XMMATRIX    XM_CALLCONV     XMMatrixRotationRollPitchYawFromVector(FXMVECTOR Angles);
XMMATRIX    XM_CALLCONV     XMMatrixRotationNormal(FXMVECTOR NormalAxis, float Angle);
XMMATRIX    XM_CALLCONV     XMMatrixRotationAxis(FXMVECTOR Axis, float Angle);
XMMATRIX    XM_CALLCONV     XMMatrixRotationQuaternion(FXMVECTOR Quaternion);
XMMATRIX    XM_CALLCONV     XMMatrixTransformation2D(FXMVECTOR ScalingOrigin, float ScalingOrientation, FXMVECTOR Scaling,
                                                     FXMVECTOR RotationOrigin, float Rotation, GXMVECTOR Translation);
XMMATRIX    XM_CALLCONV     XMMatrixTransformation(FXMVECTOR ScalingOrigin, FXMVECTOR ScalingOrientationQuaternion, FXMVECTOR Scaling,
                                                   GXMVECTOR RotationOrigin, HXMVECTOR RotationQuaternion, HXMVECTOR Translation);
XMMATRIX    XM_CALLCONV     XMMatrixAffineTransformation2D(FXMVECTOR Scaling, FXMVECTOR RotationOrigin, float Rotation, FXMVECTOR Translation);
XMMATRIX    XM_CALLCONV     XMMatrixAffineTransformation(FXMVECTOR Scaling, FXMVECTOR RotationOrigin, FXMVECTOR RotationQuaternion, GXMVECTOR Translation);

 

오늘은 Climb 기능에 대해 적절한 Animation이 재생되도록 개선을 히도했습니다.

 

우선 성과가 있는 점부터 적겠습니다.

 

Climb 시 Animation이 재생되지 않는 이유는 Climb Animation이 속해있는

FullBodyMotion을 관할하는 trigger 값이 적절한 값을 가지지 않았기 때문입니다.

이를 적용하자, Animation이 어느정도 재생이 되기 시작했습니다.

 

이후 Climb를 한번이라도 하면 Climbing 상태로 움직이는 문제가 있었으나,

위와 마찬가지로 Climb 해제 시 FullBodyMotion 값이 적절치 못해서였습니다.

 

남은 시간은 Animation을 기능과 맞추기 위해 시간을 꽤 투자하였으나,

미묘하게 Animation 재생이 어긋나 있었습니다.

일관적이라면 무언가 잘못 입력된 것이겠지만, 규칙성을 찾지 못했습니다.

 

때문에 저는 Animation과 기능의 조건을 잘못 나눈 것이 아닌가 하는 의구심이 들었고,

관련 State Machine을 재정리 하였습니다.

 

이를 기반으로 다시 조건을 부여하여 Animation이 적절히 재생되도록 할 예정입니다.

 

Climb에 필요한 State
Climb Animation State Machine
State별 설명과 트리거 값
Event들의 트리거 변화와 재생되어야 할 Animation

'개발일지 > Treasure Hunter' 카테고리의 다른 글

20.06.01 개발일지  (0) 2020.06.01
20.05.30 개발일지  (0) 2020.05.30
20.05.27 개발일지  (0) 2020.05.27
20.05.25 개발일지  (0) 2020.05.25
20.05.23 개발일지  (2) 2020.05.23

요 며칠 컨디션이 안좋었는데 아무래도 수면 부족이었나봅니다.

아침서부터 편두통과 무력감, 우울감에 찌들어서 개발에 하나도 집중을 하지 못했습니다.

개발을 게을리 하지 않기 위해 낮잠을 자제하는 편인데 너무 힘들고 머리에 뭐가 들어오지 않아

될대로 되라지 싶은 심정으로 그냥 잤습니다.

 

자고 일어나니까 컨디션이 100%까지는 아니더라도 70% 정도까지는 올라온 것 같습니다.

그 덕에 시간은 적었지만, 해결하고자 하는 문제는 해결하였습니다.

오늘 해결한 문제는 Client에서 작업 여부와 관계 없이 MovementMode가 반대로 움직이는 현상을 수정하는 것입니다.

코드가 잘 돌아가는데 값이 반대로 작동하는건 수 개월 전에 기억도 가물가물해지는 시기에 겪고 처음입니다.

그래서 굉장히 오래 걸릴것 같아 오늘 하루 이 문제만 해결하도록 계획을 잡았습니다.

 

그런데 문제가, 문제가 아니었습니다.

우선 어느 시점에서 값이 바뀌는지 알기 위해 MovementMode의 로그를 출력하는 함수를 더 추가했습니다.

원래는 Interaction 작업을 한 직후(B)에만 출력을 하였는데, RPC 함수에서 NetMulticast 함수 내부에 MovementMode 값을 직접 수정하는 코드의 앞, 뒤(A)로도 추가하였습니다.

 

이후 로그를 찍어보니까 생각치도 못하게 나왔습니다.

우선 코드 순서 상 A를 호출하는 함수가 B보다 더 앞입니다. 

Host(Server)에서는 A 다음 B 순서로 잘 찍혔고, 값도 멀쩡했습니다.

하지만 Client에서는 B가 찍힌 후에 A가 찍히고, B 값은 원래 값과 반대로 움직이는 반면
A 값은 정상적으로 변경 전과 변경 후가 의도한대로 변경되었습니다.

 

A 값이 정상적으로 움직인다는 것은 MovementMode의 값은 어느 Client에서도 정상이라고 예상할 수 있습니다.

그렇다면 로그가 찍히는 순서가 다른 것에서 어떤 의미가 있는 것인지를 알아야 했습니다.

이는 조금만 생각해도 금방 알 수 있었습니다.

 

A 코드는 B 코드보다 먼저 실행된다 하더라도 RPC 함수입니다.

때문에 같은 procedure에서 실행되지 않을 것입니다.

Client에서 실행하는 경우, 한번 Host(Server)의 함수를 호출하도록 통신을 하고, 

Host(Server)는 자기 자신을 포함한 모든 Client에서 값을 바꾸도록 다시 한번 함수를 호출할 것입니다.

즉 A는 실행이 될 때까지 두번의 네트워크 통신이 발생합니다.

 

그에 반해 B는 A 부분에서 RPC 함수 통신이 끝나면 그 즉시 바로 호출됩니다.

또한 A와 다른 Procedure 상에서 작동되기 때문에 반드시 A가 B보다 먼저 끝난다는 보장도 없습니다.

때문에 Client에서는 A 호출을 위한 두번의 통신 과정이 B 호출보다 더 늦게 완료 된다고 예상했습니다.

 

그 뒤로는 예상이 맞는지 검증을 하는 과정입니다.

검증은 간단했습니다. Tick에서 값을 로그에 출력해보는 것입니다.

출력 결과, 값 자체는 정상적으로 움직이는 것으로 나왔습니다.

 

결국 이 문제는 기능상, 구현상 문제가 아니라, RPC 함수의 특성에 대한 이해 부족이 문제였습니다.

이를 통해 멀티플레이 게임에서의 디버그 때에는 로그에 지나치게 의존해서는 한된다는 교훈을 얻었습니다.

 

내일에는 Animation 블루프린트의 트리거 값을 조절하여 Climb시 애니메이션이 재생되도록 할 예정입니다.

'개발일지 > Treasure Hunter' 카테고리의 다른 글

20.05.30 개발일지  (0) 2020.05.30
20.05.28 개발일지  (0) 2020.05.28
20.05.25 개발일지  (0) 2020.05.25
20.05.23 개발일지  (2) 2020.05.23
20.05.21 개발일지  (0) 2020.05.21

+ Recent posts