ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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을 초기화 하도록 하였다.

     

    해결~

    댓글

Designed by Tistory.