hyrule 2022. 5. 23. 16:18

http://hyrule.tistory.com/111 

 

*** 공부 방법 ***

1. 코딩을 해야 하는 부분은 첫 부분에 변수나 함수, 메소드에 대한 선언이 코드블럭으로 표시되어 있다. //ex) MakeFunction(); 2. 코드블럭 하단에는 해당 선언에 대한 구현 로직이 작성되어 있다. 처

hyrule.tistory.com

 


- 사실 스킬 쿨타임은 개별적으로 구현해도 전혀 상관없지만,

통일성과 편의성을 위해 구조체와 열거체, vector 자료구조를 사용하여 구현해 보자.

 

- 스킬 쿨타임 정보를 담은 구조체를, 배열 vector 안에 넣어서 관리하고,

- 스킬을 사용하는 각 클래스는 열거체에 각 스킬의 순서를 정해놓고 , vector 자료구조에 해당 번호로 저장해준 뒤, 필요할 때마다 꺼내서 사용한다.

- 스킬 쿨타임은 Update() 함수에서 vector 순회를 통해 일괄적으로 관리해준다.

 

struct SkillCoolTimeSet
{};

- 현재 구현한 클래스인 CPlayer, CMonster 두 캐릭터는 총알을 발사한다.

 

- 두 클래스에 공통적으로 쿨타임 시스템을 적용할 수 있으므로 해당 클래스의 공통 부모 클래스에 구현하는 것이 적합하다.

 

- 해당 구조체에는

-- 스킬 쿨타임을 몇 초로 설정할 지,

-- 스킬 쿨타임이 몇 초 남았는지,

-- 현재 스킬 쿨타임인지

에 대한 변수가 들어가야 한다.

 

- 만약 생성자에서 스킬 쿨타임을 따로 입력받으면, 해당 스킬 쿨타임으로 설정되게 만들어 주자.

더보기
Character.h

//스킬 쿨타임 체크용 구조체. 각각 스킬은 해당 객체에서 열거체를 통해 관리할것.
struct SkillCoolTimeSet
{
	float CoolTime;
	float CoolTimeLeft;
	bool isCoolTime;

	SkillCoolTimeSet(float cooltime = 5.f) :
		CoolTime(cooltime),
		CoolTimeLeft(0.f),
		isCoolTime(false)
	{
	}
};

- 이제 쿨타임을 배열 벡터에 넣어 관리할 것이다. 클래스 안에 선언해준다.

더보기
//Character.h

protected:
	std::vector<SkillCoolTimeSet> m_SkillCoolTimeSet;

CheckSkillCoolTime();

- 편의성을 위한 해당 메소드를 구현한다.

 

- CheckSkillCoolTime() 메소드는 Character을 상속받는 객체들의 Update()메소드에서 사용한다.

-- 인자로 스킬의 최대 갯수(열거체로부터 얻어올 수 있다)와 DeltaTime을 받아온다.

--- 열거체로부터 Vector()의 최대 사이즈를 받아서 순회를 돌며,

--- 스킬 쿨타임에 진입한 스킬들에 대한 남은 쿨타임을 계산하고,

--- 쿨타임이 끝나면 다시 사용이 가능하도록 바꿔주는 메소드이다.

더보기
//Character.cpp

void CCharacter::CheckSkillCoolTime(int SkillEnumEnd, float DeltaTime)
{
	//등록된 스킬의 수만큼 순회를 돈다.
	for (size_t i = 0; i < SkillEnumEnd; ++i)
	{
		//만약 스킬의 쿨타임이면,
		if (m_SkillCoolTimeSet[i].isCoolTime)
		{
			//스킬의 쿨타임의 남은 시간을 DeltaTime만큼 감소시킨다.
			m_SkillCoolTimeSet[i].CoolTimeLeft -= DeltaTime;

			//만약 스킬 쿨타임이 다 돌았으면
			if (m_SkillCoolTimeSet[i].CoolTimeLeft <= 0.f)
			{
				//스킬을 다시 사용 가능하도록 활성화시킨다.
				m_SkillCoolTimeSet[i].isCoolTime = false;
			}
		}
	}
}

EnterSkillCoolTIme();

- 각 스킬 메소드에서 호출할 메소드이다.

-- 해당 스킬을 사용했을 경우, 스킬 사용 여부를 true로 바꾸고, 

-- 스킬의 남은 쿨타임 시간을 설정해준다.

더보기
//Character.cpp

//스킬 사용시 이 함수에 스킬의 Enum을 넣으면 편하게 처리 가능
void CCharacter::EnterSkillCoolTIme(int SkillEnum)
{
	//스킬이 쿨타임에 진입했다고 바꾸고
	m_SkillCoolTimeSet[SkillEnum].isCoolTime = true;

	//스킬의 쿨타임 남은 시간을 초기화한다.
	m_SkillCoolTimeSet[SkillEnum].CoolTimeLeft = m_SkillCoolTimeSet[SkillEnum].CoolTime;
}

- 설정이 완료되었으면 플레이어의 총알 발사 로직에 쿨타임을 적용해 보자.


- 플레이어의 스킬 목록을 열거체로 만들어주어야 한다.

- 아직은 스킬이 평타밖에 없으므로, 평타만 등록해 준다.

더보기
//Player.h

enum class EPlayerSkill
{
	BasicAttack,
	End
};

- CPlayer 초기화 시 배열 벡터를 스킬 갯수만큼 미리 리사이즈해놓고, 스킬 쿨타임을 설정해준다.

더보기
bool CPlayer::Init(CGameObject* Obj)
{
	
    //...이외의 코드들...//

	
	//스킬 설정
	m_SkillCoolTimeSet.resize((size_t)EPlayerSkill::End);
	m_SkillCoolTimeSet[(int)EPlayerSkill::BasicAttack].CoolTime = 0.5f;

	//...이외의 코드들...//

	return true;
}

- 아직은 평타밖에 구현되어있지 않으므로, 해당 평타 로직에 스킬 쿨타임 관련 로직을 추가하면 끝.

더보기
void CPlayer::GunFire()
{
	//쿨타임이면 그냥 return
	if (m_SkillCoolTimeSet[(int)EPlayerSkill::BasicAttack].isCoolTime)
		return;
	
    //쿨타임이 아니면 쿨타임으로 바꾸는 메소드를 호출하고
	EnterSkillCoolTIme((int)EPlayerSkill::BasicAttack);
    
    //스킬 로직 진행
	CBullet* Bullet = m_OwnerScene->CreateObject<CBullet>("PlayerBullet", this);
	Bullet->SetSpeedDir(1000.f, m_Dir);
	Bullet->SetPos(m_GunTipPos);
}

- 스킬 쿨타임을 0.5초로 설정했으므로, 평타 버튼을 광클릭해도 평타가 0.5초마다 발사되는지 확인해 보자.

 

 

GameFrameworkStepbyStep_27_SkillCoolTime.zip
0.04MB