AnimatorComponent
갖고있는 Animation들을 관리해주는 컴포넌트이다.
AnimatorComponent.h
#pragma once
#include "IComponent.h"
enum class AnimationMode : uint
{
Play,
Stop,
Pause
};
class AnimatorComponent final : public IComponent
{
public:
AnimatorComponent(class Context* const context, class Actor* const actor, class Transform* const transform);
~AnimatorComponent() = default;
void Initialize() override;
void Update() override;
void Destroy() override;
const AnimationMode& GetAnimationMode() const { return animation_mode; }
void SetAnimationMode(const AnimationMode& mode) { this->animation_mode = mode; }
const uint& GetCurrentFrameNumber() const { return current_frame_number; }
void SetCurrentFrameNumber(const uint& number) { this->current_frame_number = number; }
const std::shared_ptr<class Animation> GetCurrentAnimation();
void SetCurrentAnimation(const std::string& animation_name);
const std::map<std::string, std::shared_ptr<class Animation>>& GetAnimations() const { return animations; }
const Keyframe* GetCurrentKeyframe() const;
void AddAniamtion(const std::string& animation_name, const std::shared_ptr<class Animation>& animation);
void Play();
void Stop();
void Pause();
bool IsPlaying() const { return animation_mode == AnimationMode::Play; }
private:
class Timer* timer = nullptr;
AnimationMode animation_mode = AnimationMode::Play;
uint current_frame_number = 0;
float frame_counter = 0.0f;
std::weak_ptr<class Animation> current_animation;
std::map<std::string, std::shared_ptr<class Animation>> animations;
};
애니메이션 모드는 지금 현재 애니메이션을 멈출지 플레이할지 정해준다.
AnimatorComponent.cpp
void AnimatorComponent::Update()
{
if (current_animation.expired() || !IsPlaying())
{
return;
}
frame_counter += timer->GetDeltaTimeMS();
if (frame_counter > GetCurrentKeyframe()->time)
{
current_frame_number++;
switch (current_animation.lock()->GetRepeatType())
{
case RepeatType::Once:
if (current_frame_number >= current_animation.lock()->GetKeyframeCount())
{
current_frame_number = current_animation.lock()->GetKeyframeCount() - 1;
Pause();
}
break;
case RepeatType::Loop:
current_frame_number %= current_animation.lock()->GetKeyframeCount();
break;
}
frame_counter = 0.0f;
}
}
가장 중요한 Update부분이다.
현재 플레이중이거나 현재 매니메이션이 없으면 돌지 않고,
frame_counter에서 현재까지 얼마나 시간이 흘렀는지 확이한 뒤, 원하는 시간이 지났으면 current_frame_number를 하나씩 증가시켜준다.
그리고 그 값에 따라서 현재 애니메이션의 프레임 카운터를 갖고와 반복시킬지 한번 플레이할지 결정한다.
void AnimatorComponent::Play()
{
animation_mode = AnimationMode::Play;
frame_counter = 0.0f;
}
void AnimatorComponent::Stop()
{
animation_mode = AnimationMode::Stop;
current_frame_number = 0;
frame_counter = 0.0f;
}
void AnimatorComponent::Pause()
{
animation_mode = AnimationMode::Pause;
}
Play와 Stop에서는 지금까지 프레임 카운터가 얼마나 지났는지 초기화 해준다.
나머지 부분들은 갖고오거나 선언 뿐이라 설명할 것이 없어서 생략한다.