-
231002 Batch파일 경로 문제 오류 , Animation의 Start Event Function기록 2023. 10. 2. 14:31
1. 배치파일 오류
용량이 큰 파일들이 많아 Github에 올리기 어렵기 때문에 압축해서 올린 후 batch파일을 통해 한번에 풀어 사용하고 있다.
문제상황)
언제부터인가 배치파일에 빨간글씨가..
원인파악)
내용을 파악해보니 해당 경로에 Cube14.fbx와 Map_Offce.fbx가 이미 존재하기 때문에 덮어쓴다는 오류였다.
파일 존재 여부를 체크하는 함수를 사용했는데 왜?? 싶었다.
내용을 확인해 보니
IF NOT EXIST "%~dp0%ContentResources\Mesh\Map\UIBackGroundMap.fbx" ( powershell expand-archive ContentResources\Zip\UIBackGroundMap.zip ContentResources\Mesh\Map\Office ) IF NOT EXIST "%~dp0%ContentResources\Mesh\Map\Cube14.fbx" ( powershell expand-archive ContentResources\Zip\Cube14.zip ContentResources\Mesh\Map\Office ) IF NOT EXIST "%~dp0%ContentResources\Mesh\Map\Map_Office.fbx" ( powershell expand-archive ContentResources\Zip\Map_Office.zip ContentResources\Mesh\Map\Office )
"ContentResources\Mesh\Map\Office"경로에 생성을 하지만 "ContentResources\Mesh\Map" 경로에서 파일 존재여부를 체크해서 발생하는 문제였다.
문제해결)
IF NOT EXIST "%~dp0%ContentResources\Mesh\Map\Office\UIBackGroundMap.fbx" ( powershell expand-archive ContentResources\Zip\UIBackGroundMap.zip ContentResources\Mesh\Map\Office ) IF NOT EXIST "%~dp0%ContentResources\Mesh\Map\Office\Cube14.fbx" ( powershell expand-archive ContentResources\Zip\Cube14.zip ContentResources\Mesh\Map\Office ) IF NOT EXIST "%~dp0%ContentResources\Mesh\Map\Office\Map_Office.fbx" ( powershell expand-archive ContentResources\Zip\Map_Office.zip ContentResources\Mesh\Map\Office )
확인 경로를 변경하여 문제 해결~
++++++++) 오류 내용을 확인하고 싶은데 스크립트가 사라진다면
"Pause"를 마지막줄에 추가하여 내용을 확인할 수 있다.
2. Animation의 StartEvent Function
애니메이션 중 원하는 인덱스프레임에 함수를 실행하는 기능
하나의 애니메이션을 가지고 있는 GameEngineFBXAnimationInfo 클래스에
std::map<UINT, AnimStartFunc> StartFunc;
이를 추가한다.
AnimStartFunc의 내용은 다음과 같다.
struct AnimStartFunc { bool bStart = false; \\ 실행했는지 체크 std::function<void()> pFunc = nullptr; \\ functional 함수 };
StartFunction을 설정하는 함수를 추가한다
void GameEngineFBXRenderer::SetAnimationStartFunc(const std::string_view& _Name, UINT _Index, std::function<void()> _Func) { std::string sUpperName = GameEngineString::ToUpper(_Name); \\지정한 애니메이션 이름 if (Animations.end() == Animations.find(sUpperName)) { MsgAssert("해당 이름의 애니메이션이 없습니다." + sUpperName); return; } std::shared_ptr< GameEngineFBXAnimationInfo> Info = Animations[sUpperName]; //std::weak_ptr<GameEngineFBXAnimationInfo> AnimInfo = Animations[sUpperName]; if ((Info->Start > _Index) || (_Index >= Info->End)) { MsgAssert("설정하려는 인덱스가 " + sUpperName + "의 최대 프레임인 " + std::to_string(Info->Start)+","+ std::to_string(Info->End) + " 을(를) 넘었습니다"); return; } Info->StartFunc[_Index].pFunc = _Func; Info->StartFunc[_Index].bStart = false; }
AnimationInfo가 업데이트할 때 마다 이를 실행할 수 있도록 한다.
void GameEngineFBXAnimationInfo::Update(float _DeltaTime) { if (true == ParentRenderer->Pause) \\ 퍼즈상태이면 애니메이션을 돌리지 않는다. { return; } CurFrameTime += _DeltaTime; PlayTime += _DeltaTime; float CurInter = Inter; \\ 프레임마다 다른 inter을 둘 수 있기 때문에 if (FrameTime.size() > CurFrame) { CurInter = FrameTime[CurFrame]; } while (CurFrameTime >= CurInter) { CurFrameTime -= CurInter; ++CurFrame; if (CurFrame >= End) \\ 마지막 프레임 경우 { if (true == Loop) { CurFrame = Start; } else { CurFrame = End - 1; EndValue = true; } for (std::pair<const UINT, AnimStartFunc>& PairStartFunc : StartFunc) \\ startfunction 실행여부 초기화 { PairStartFunc.second.bStart = false; } } } if (StartFunc.end() != StartFunc.find(CurFrame)) \\ 현재 애니메이션 프레임에서 startfunction이 존재하고 실행하지 않았다면? { if (StartFunc[CurFrame].bStart == false && StartFunc[CurFrame].pFunc != nullptr) { StartFunc[CurFrame].pFunc(); StartFunc[CurFrame].bStart = true; } } }
여기서 문제가 발생하는데!!
문제 상황)
프레임이 겁나 낮은 경우 해당 프레임이 씹혀서 넘어가는 상황이 발생하고 그 때 startfunction이 실행되지 않는 문제가 발생한다는 점!
원인파악)
while (CurFrameTime >= CurInter) { CurFrameTime -= CurInter; ++CurFrame; if (CurFrame >= End) \\ 마지막 프레임 경우 { if (true == Loop) { CurFrame = Start; } else { CurFrame = End - 1; EndValue = true; } for (std::pair<const UINT, AnimStartFunc>& PairStartFunc : StartFunc) \\ startfunction 실행여부 초기화 { PairStartFunc.second.bStart = false; } } }
이 부분에서 밀린 프레임을 모두 처리하고 startfunction을 체크하기 때문이다.
문제 해결)
void GameEngineFBXAnimationInfo::Update(float _DeltaTime) { if (true == ParentRenderer->Pause) \\ 퍼즈상태이면 애니메이션을 돌리지 않는다. { return; } CurFrameTime += _DeltaTime; PlayTime += _DeltaTime; float CurInter = Inter; \\ 프레임마다 다른 inter을 둘 수 있기 때문에 if (FrameTime.size() > CurFrame) { CurInter = FrameTime[CurFrame]; } while (CurFrameTime >= CurInter) { CurFrameTime -= CurInter; ++CurFrame; if (StartFunc.end() != StartFunc.find(CurFrame)) \\ 현재 애니메이션 프레임에서 startfunction이 존재하고 실행하지 않았다면? { if (StartFunc[CurFrame].bStart == false && StartFunc[CurFrame].pFunc != nullptr) { StartFunc[CurFrame].pFunc(); StartFunc[CurFrame].bStart = true; } } if (CurFrame >= End) \\ 마지막 프레임 경우 { if (true == Loop) { CurFrame = Start; for (std::pair<const UINT, AnimStartFunc>& PairStartFunc : StartFunc) \\ startfunction 실행여부 초기화 { PairStartFunc.second.bStart = false; } } else { CurFrame = End - 1; EndValue = true; } } } }
CurFrame을 바꿀 때 StartFunction을 실행하도록 하였고
애니메이션 설정이 Loop로 실행하는 경우만 StartFucntion을 초기화 하도록 하였다.
해결~
'기록' 카테고리의 다른 글
231005 Attack 원거리 공격 (1) 2023.10.05 231003 PhysX Collision Checking (1) 2023.10.03 20231001 PhysX Component를 가지는 액터 Position체크 (0) 2023.10.01 20230928 플레이어 버그와 최적화 (0) 2023.09.28 20230927 PhysX RayCast와 DirectX Indersects (0) 2023.09.27