231002 Batch파일 경로 문제 오류 , Animation의 Start Event Function
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을 초기화 하도록 하였다.
해결~