[WinApi] 엔진 애니메이션 추가

라멘커비·2024년 2월 1일
0

WinApi

목록 보기
9/32

엔진

🍎복습

  • 원점은 왼쪽 위

  • FTransform을 가지면 화면에 나오기 위해 만들어진 애들

  • AActor와 USceneComponent는 FTransform을 가진다. 이 두 클래스를 상속받는 클래스들은 다 화면에 나오기 위해 존재하는 애들

  • 이 코드때문에 렌더러는 액터 위치에 상대적으로 위치함.

  • Actor는 Scale 의미 없다. Renderer크기로 됨.

  • Renderer Position의 중앙부터 이미지가 그려지는 것이 아니라 왼쪽위부터 그리게 만들어놨음. X값을 ImageLeft로 넣어주기 때문이다.

  • 멤버 함수 포인터로 안 하고 static으로 전역 함수 포인터 사용하는 이유?
    멤버함수 포인터는 thiscall
//A클래스의 멤버함수 포인터
void(A::*Ptr)() = A::Function;

//A클래스의 멤버함수 포인터를 사용하려면 사용법이 편하지도 않다.
A NewA;
(NewA.*Ptr0)();

멤버 함수 포인터는 사용법이 편하지 않기 때문에 엔진에서 static 붙여서 전역 함수 포인터로 사용한것임. 멤버 함수 포인터의 특별한 이점이 없음.

🍎프레임 애니메이션 원리

액터의 Tick에서 이미지를 계속 다음 이미지 위치로 자르면서 보여줌(움짤처럼)

1초에 한 번 X축 방향으로 이동하면서 다음 이미지 보여주는 코드.
(여기서는 이미지가 가로로 32)

근데 이걸 하나씩 코드로 쳐야할 게 아니라 인터페이스화 시켜야 한다.

// 0번부터 12번까지 애니메이션해라 0.1초 간격으로
Renderer->CreateAnimation("Idle", "TestFolderAnimation", 0, 12, 0.1f);
Renderer->ChangeAnimation("Idle");

이런 인터페이스.

in "ImagaRenderer.cpp"

void UImageRenderer::CreateAnimation(
	std::string_view _AnimationName,
	std::string_view _ImageName,
	int _Start,
	int _End,
	float _Inter,
	bool _Loop /*= true*/
)
{
	UWindowImage* FindImage = UEngineResourcesManager::GetInst().FindImg(_ImageName);

	if (nullptr == FindImage)
	{
		MsgBoxAssert(std::string(_ImageName) + "이미지가 존재하지 않습니다.");
		return;
	}

	std::string UpperAniName = UEngineString::ToUpper(_AnimationName);

	if (true == AnimationInfos.contains(UpperAniName))
	{
		MsgBoxAssert(std::string(UpperAniName) + "라는 이름의 애니메이션이 이미 존재합니다.");
		return;
	}

	UAnimationInfo& Info = AnimationInfos[UpperAniName];
	Info.Image = FindImage;
	Info.CurFrame = 0;
	Info.Start = _Start;
	Info.End = _End;
	Info.CurTime = 0.0f;
	Info.Loop = _Loop;

	int Size = Info.End - Info.Start;
	Info.Times.reserve(Size);
	Info.Indexs.reserve(Size);
	for (int i = _Start; i <= _End; i++)
	{
		Info.Times.push_back(_Inter);
	}

	for (int i = _Start; i <= _End; i++)
	{
		Info.Indexs.push_back(i);
	}
}

void UImageRenderer::ChangeAnimation(std::string_view _AnimationName)
{
	std::string UpperAniName = UEngineString::ToUpper(_AnimationName);

	if (false == AnimationInfos.contains(UpperAniName))
	{
		MsgBoxAssert(std::string(UpperAniName) + "라는 이름의 애니메이션이 존재하지 않습니다.");
		return;
	}

	UAnimationInfo& Info = AnimationInfos[UpperAniName];
	CurAnimation = &Info;
	CurAnimation->CurFrame = 0;
	CurAnimation->CurTime = CurAnimation->Times[0];
}

생각 정리


profile
일단 시작해보자

0개의 댓글