캐릭터에 무기를 추가할것 이다.
캐릭터에 무기를 추가하는 방법은 두가지정도 사용할 수 있는데,
사용하는 무기를 그때그떄 넣어주어서 동적으로 부여하는 방법 과
모든 무기를 캐릭터에 집어넣어 두고 사용할 경우에만 해당 무기를 활성화시키는 방법
이 두가지를 사용할 수 있다.
우리는 모든 무기를 캐릭터에 넣어두고 사용하게 할것이다.
#pragma once
class Weapon
{
public:
Weapon(SkillData data, Transform* player) : data(data), player(player)
{}
virtual ~Weapon() = default;
virtual void Update() = 0;
virtual void Render() = 0;
virtual void GUIRender() {}
void LevelUp();
protected:
SkillData data;
Transform* player;
};
우선 무기에 대한 헤더를 생성한다.
모든 무기는 위 헤더를 상속받아 사용하며, 무기의 데이터와 플레이어의 위치정보를 받아와 활용한다.
#pragma once
#pragma once
struct SkillData
{
int key;
string name;
int level;
string icon;
float power;
float speed;
float interval;
int count;
float lifeTime;
bool through;
float knockback;
};
class SurvivalDataManager : public Singleton<SurvivalDataManager>
{
private:
friend class Singleton;
SurvivalDataManager();
~SurvivalDataManager();
public:
void LoadTable();
SkillData GetSkillData(int key) { return skillDatas[key]; }
int GetSkillSize() { return skillDatas.size(); }
private:
map<int, SkillData> skillDatas;
};
SkillData는 위와같다. 데이터는 csv로 불러와 사용하게 되며, 각각 의미있는 정보를 부여받아 저장한다.
무기의 키값, 이름, 무기의 래벨, 아이콘, 힘, 속도, 공격속도, 최대개수, 생존시간, 관통여부, 넉백여부 를 관여한다.
우선 구현해볼 무기는, 칼과 파이어볼이다.
파이어볼은 투사체로 플레이어->몬스터 위치로 발사되며, 항상 가장 가까운 몬스터의 위치로 발사된다.
칼은, 회전체로 플레이어를 중심으로 회전하며, 주변의 몬스터를 공격한다. 맞은 몬스터는 넉벡된다.
이러한 기초를 가지고 설계해보자.
칼
#pragma once
class WeaponSword : public Weapon
{
private:
const UINT MAX_COUNT = 6;
const float RANGE = 5.0f;
public:
WeaponSword(SkillData data, Transform* player);
~WeaponSword();
void Update() override;
void Render() override;
void GUIRender() override;
private:
vector<Sword*> swords;
float angle = 0.0f;
};
무기정보를 상속받아 사용한다.
플레이어 주변을 회전하며 공격하는 성질을 가진다.
Weapon을 상속받아 사용함으로, 무기데이터를 활용한다.
#include "Framework.h"
WeaponSword::WeaponSword(SkillData data, Transform* player)
: Weapon(data, player)
{
swords.resize(MAX_COUNT);
FOR(MAX_COUNT)
{
swords[i] = new Sword();
swords[i]->SetActive(i < data.count);
}
}
WeaponSword::~WeaponSword()
{
for (Sword*& sword : swords)
delete sword;
}
void WeaponSword::Update()
{
angle += data.speed * DELTA;
float step = XM_2PI / data.count;
Vector3 pos = player->GetLocalPosition();
FOR(data.count)
{
angle += step * i;
pos.x += cos(angle) * RANGE;
pos.z += sin(angle) * RANGE;
swords[i]->SetLocalPosition(pos);
swords[i]->SetLocalRotation({ XM_PIDIV2, -angle + XM_PIDIV2, 0.0f });
swords[i]->Update();
}
}
void WeaponSword::Render()
{
for (Sword*& sword : swords)
sword->Render();
}
void WeaponSword::GUIRender()
{
for (Sword*& sword : swords)
sword->GetCollider()->GUIRender();
}
무기의 업데이트정보 이다.
업데이트시, 무기의 최대개수에 따라 360도를 개수로 나누어 위치한다.
또한, 플레이어를 중심으로 회전하여 칼날부분이 항상 바깥쪽을 향하게 한다.
파이어볼
#pragma once
class WeaponFireball : public Weapon
{
public:
WeaponFireball(SkillData data, Transform* player);
~WeaponFireball();
void Update() override;
void Render() override;
private:
float time = 0.0f;
};
파이어볼은 무기와 비슷하게 생성되나, 생존시간만 관여한다.
FireBallManager에서 데이터를 확인하여, 생존시간이 초과하였을 경우 삭제하기 위함이다.
#include "Framework.h"
WeaponFireball::WeaponFireball(SkillData data, Transform* player)
: Weapon(data, player)
{
FireBallManager::Get();
}
WeaponFireball::~WeaponFireball()
{
FireBallManager::Delete();
}
void WeaponFireball::Update()
{
time += DELTA;
if (time > data.interval)
{
time -= data.interval;
Transform* monster = MonsterManager::Get()->GetClosestMonster(player->GetLocalPosition());
if (monster)
{
Vector3 direction = (monster->GetLocalPosition() - player->GetLocalPosition()).GetNormalized();
FireBallManager::Get()->Fire(player->GetLocalPosition(), direction, data);
}
}
FireBallManager::Get()->Update();
}
void WeaponFireball::Render()
{
FireBallManager::Get()->Render();
}
시간에 따라 속도값으로 타겟을 중심으로 목표방향으로 날아간다.
목표방향은 가장 가까운 몬스터를 MonsterManager에서 받아와서 사용하게 되낟.
direction으로 해당 방향을 정규화하고.
그 방향대로 이동한다.
만약 몬스터가 존재하지 않는다면 생성되지 않는다.
'서울게임아카데미 교육과정 6개월 국비과정' 카테고리의 다른 글
20231211 48일차 AnimationInstancing응용7 (0) | 2023.12.11 |
---|---|
20231208 47일차 AnimationInstancing응용6 (0) | 2023.12.09 |
20231206 45일차 클래스 개요도, AnimationInstancing응용4 (1) | 2023.12.06 |
20231205 44일차 AnimationInstancing응용3 (0) | 2023.12.05 |
20231204 43일차 중간점검 (0) | 2023.12.04 |