• Home
  • About
    • 게임 개발자 유정룡 photo

      게임 개발자 유정룡

      포트폴리오

    • Learn More
    • Email
    • Github
    • Bitbucket
  • Projects
    • All Projects
    • All Tags

DirectX11 공부 13일차(AnimatorComponent)

14 Jun 2021

Reading time ~1 minute

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에서는 지금까지 프레임 카운터가 얼마나 지났는지 초기화 해준다.

나머지 부분들은 갖고오거나 선언 뿐이라 설명할 것이 없어서 생략한다.



DirectX Share Tweet +1