조기 수료하는 인원들이 발표되었다.
아쉽게도 그 안에 들지 못했지만.. 그만큼 더 공부할 시간이 많이 남았다는 것에 더 의미를 두기로 했다.
특히나 알고리즘 보다도 유니티의 기능들을 적용하는 것에 좀 부족하다고 생각해서 이번 주부터는 2주 정도마다 조그만 토이 프로젝트를 스스로 해보기로 했다.
이번 프로젝트는 저번에 다 완성하지 못한 닷지 게임으로 결정했다.
닷지 게임을 완성하고, 더 나아가서 '뱀파이어 서바이벌' 게임을 오마주 하기로 했다.
이번 회고록에서는 수업과 개인 프로젝트 위주로 내용을 작성하고, 개인적인 리뷰를 해보려고 한다.
Starters 10주차 수업 - 'ProBuilder'
Probuilder
유니티를 통해서 게임을 만들면서 가장 힘든 것이 무엇인가 하면.. 사실 개발적인 것보다도 원하는 에셋을 구하거나 직접 만드는 것이었다.
하지만, 놀랍게도 'ProBuilder'라는 패키지를 사용하면 유니티 내에서 어느 정도 디자인이 가능하다는 사실을 알게 되었다.
'PorBuilder'와 'ProGrid'를 import하면 처음 보이는 모습이다.
격자가 생기는데, 오브젝트를 이동하거나 할 때에 격자에 맞추어서 움직여지기도 한다.
(사실, 기존에도 할 수 있지만.. 그냥 그런 설정 없이 바로 되는 게 편리하다.)
또한, tools라는 탭이 새로 생기는데, 이 탭을 통해서 바로 'ProBuilder'를 만져볼 수가 있다.
new shape로 여러가지 기본 도형들을 만들어볼 수 있고, 만들어진 도형을 만질 수 있다.
위의 이미지는 arch 도형을 새로 만들어본 모습이다.
사실 여러 가지 만져보면서 다른 도형도 만들어보고, 만져보기는 했지만 똥 손이라 그런지 멋진 것을 만들지는 못했다.
texture를 이용해서 만든 내 첫 ProBuilder 역작이 위에 있다.
정말 아직은 형편없지만.. 그래도 조금 더 만들어보면 더 멋진 지형지물 등을 만들 수 있을 것이라는 생각이 들어 좋았다.
Starters 10주차 토이 프로젝트 - '닷지 + 뱀파이어 서바이벌'
닷지 - '캐릭터 이동, 탄환 이동, 점수 표시 등'
KeyController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class KeyController : MonoBehaviour
{
void Awake()
{
}
void Update()
{
if (Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Vertical") != 0)
{
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
GameManager.Instance.JoystickM.OnKeyAxis(x, y);
}
else if (Input.GetAxis("Horizontal") == 0 && Input.GetAxis("Vertical") == 0)
{
GameManager.Instance.JoystickM.OnKeyExit();
}
if (Input.GetKey(KeyCode.Z))
{
SkillManager.Instance.ShotAttack();
}
if (Input.GetKey(KeyCode.X))
{
SkillManager.Instance.ShotSkill();
}
}
void FixedUpdate()
{
}
}
먼저 PC 유저를 위해서 'keyController'라는 새로운 함수를 통해 키보드 입력을 받아 이동할 수 있게 하였다.
Bullet.cs
if (Vector2.Distance(playerPos, this.transform.localPosition) < 0.1f)
{
playerPos += playerDir * 2;
}
if (playerDir != null)
this.transform.localPosition = Vector2.MoveTowards(this.transform.position, playerPos, Time.deltaTime * speed * 3f);
그리고, 적 탄환 프리팹에 있는 'Bullet'의 코드를 조금 수정했다.
기존에는 플레이어를 계속적으로 따라오도록 했으나 이제는 직선으로 탄환이 나아가도록 했다.
.moveToward 함수에서 플레이어 위치를 계속 업데이트에서 받지 않고, 탄환이 생겼을 때에만 받은 뒤에 그 방향으로 쭉 나아가게 하였다.
그리고, 해당 위치에 다다르면, 그 방향으로 위치 값을 계속 늘려서 정해진 거리까지 계속 직선으로 탄환이 나아가도록 했다.
UIManager.cs
expUI.text = $"LV {lvSetting.curLv:##0} \nEXP : {lvSetting.curEXP:##0} / {lvSetting.maxEXP}";
scoreUI.text = $"Score : {GameManager.Instance.score:#00}";
'GameManager'라는 싱글톤 클래스에서 레벨, 경험치, 스코어 등의 값들을 저장하였다.
그리고 캔버스에 UI를 추가해서 각 텍스트에 맞는 값들을 각각 집어넣었다.
뱀파이어 서바이벌 - '레벨업 시스템, 스킬 등'
뱀파이어 서바이벌이라는 게임에서 가장 중요한 점이라고 하면, 레벨업 시에 스킬이나 스탯 업그레이드를 선택하는 요소일 것이다.
UPgradeList.cs 일부
public enum UpgradeType
{
upgrade = 0,
attack,
skill,
CountIndex
}
public enum UpgradeStates
{
damage = 0,
speed,
shotSpeed,
bulletScale,
bulletRange,
curHP,
maxHP,
CountIndex
}
'upgradeList'라는 클래스 바깥에 업그레이드 타입과 'upgrade'(스탯 업그레이드) 일 경우에 올릴 스탯 타입을 저장하는 업그레이드 스탯 enum을 생성하였다.
UpgradeList - OnEnable()
private void OnEnable()
{
selectedIdx = 0;
int[] idx = new int[3] { -1, -1, -1 };
for (int i = 0; i < 3; i++)
{
int n = -1;
while (idx.Contains(n))
{
n = Random.Range(0, upgradeList.Length);
if (upgradeList[n].upgradeType == UpgradeType.attack)
{
if (SkillManager.Instance.attackType.ToString() == upgradeList[n].name)
{
n = -1;
}
else
{
int skillN = (int)System.Enum.Parse(typeof(SkillManager.AttackType), upgradeList[n].name);
UIManager.Instance.MakedUpgradeBtn(btns[i].gameObject, upgradeList[n], skillN, SkillManager.Instance.attackPrefabs[skillN].GetComponent<SpriteRenderer>().sprite);
}
}
else if (upgradeList[n].upgradeType == UpgradeType.skill)
{
if (SkillManager.Instance.skillType.ToString() == upgradeList[n].name)
{
n = -1;
}
else
{
int skillN = (int)System.Enum.Parse(typeof(SkillManager.SkillType), upgradeList[n].name);
UIManager.Instance.MakedUpgradeBtn(btns[i].gameObject, upgradeList[n], skillN, SkillManager.Instance.skillPrefabs[skillN].GetComponent<SpriteRenderer>().sprite);
}
}
else if (upgradeList[n].upgradeType == UpgradeType.upgrade && upgradeList[n].upgradeStates == UpgradeStates.curHP)
{
if (GameManager.Instance.playerHP >= GameManager.Instance.playerMaxHP)
{
n = -1;
}
else
{
UIManager.Instance.MakedUpgradeBtn(btns[i].gameObject, upgradeList[n]);
}
}
else if (upgradeList[n].upgradeType == UpgradeType.upgrade && upgradeList[n].upgradeStates == UpgradeStates.maxHP)
{
if (GameManager.Instance.playerMaxHP >= GameManager.Instance.fullMaxHP)
{
n = -1;
}
else
{
UIManager.Instance.MakedUpgradeBtn(btns[i].gameObject, upgradeList[n]);
}
}
else if (upgradeList[n].upgradeType == UpgradeType.upgrade && upgradeList[n].upgradeStates == UpgradeStates.damage)
{
if (GameManager.Instance.playerDmg >= GameManager.Instance.fullPlayerDmg)
{
n = -1;
}
else
{
UIManager.Instance.MakedUpgradeBtn(btns[i].gameObject, upgradeList[n]);
}
}
else if (upgradeList[n].upgradeType == UpgradeType.upgrade && upgradeList[n].upgradeStates == UpgradeStates.speed)
{
if (GameManager.Instance.playerSpeed >= GameManager.Instance.fullPlayerSpeed)
{
n = -1;
}
else
{
UIManager.Instance.MakedUpgradeBtn(btns[i].gameObject, upgradeList[n]);
}
}
else
{
UIManager.Instance.MakedUpgradeBtn(btns[i].gameObject, upgradeList[n]);
}
}
idx[i] = n;
}
selected = idx;
}
조금 길어졌지만, 위의 코드는 레벨업 할 때마다 새로운 업그레이드 3개를 뽑는 코드이다.
만약 현재 기본 공격 그리고, 현재 스킬이 새로 뽑은 기본 공격, 스킬과 같다면 다시 뽑도록 만들었고, HP의 경우에도 데미지를 입지 않은 경우에는 현재 체력을 올리는 선택지가 뽑혔을 때에 다시 뽑도록 하였다.
UpgradeStat 함수
public void UpgradeStat(UpgradeStates stat, float value)
{
switch (stat)
{
case UpgradeStates.damage:
GameManager.Instance.playerDmg += (int)value;
break;
case UpgradeStates.speed:
GameManager.Instance.playerSpeed += value;
break;
case UpgradeStates.shotSpeed:
GameManager.Instance.playerShotSpeed += value;
break;
case UpgradeStates.bulletScale:
GameManager.Instance.playerBulletScale += value;
break;
case UpgradeStates.bulletRange:
GameManager.Instance.playerBulletRange += value;
break;
case UpgradeStates.curHP:
if (GameManager.Instance.playerHP + (int)value > GameManager.Instance.playerMaxHP)
UIManager.Instance.HPUP(GameManager.Instance.playerMaxHP - GameManager.Instance.playerHP);
UIManager.Instance.HPUP((int)value);
break;
case UpgradeStates.maxHP:
UIManager.Instance.MaxHPUP((int)value);
break;
default:
break;
}
}
스탯 업그레이드를 선택한 경우에 각 업그레이드 스탯 타입에 따라서 해당하는 스탯 변수의 값을 정해진 값만큼 올리도록 하였다.
ChangeAttack, ChangeSkill() 함수
public void ChangeAttack(string name)
{
if (!System.Enum.IsDefined(typeof(SkillManager.AttackType), name))
return;
SkillManager.AttackType atkType = (SkillManager.AttackType)System.Enum.Parse(typeof(SkillManager.AttackType), name);
SkillManager.Instance.ChangeAtk((int)atkType);
}
public void ChangeSkill(string name)
{
if (!System.Enum.IsDefined(typeof(SkillManager.SkillType), name))
return;
SkillManager.SkillType sklType = (SkillManager.SkillType)System.Enum.Parse(typeof(SkillManager.SkillType), name);
SkillManager.Instance.ChangeSkill((int)sklType);
}
기본 공격과 스킬 선택지는 위의 함수를 실행하도록 하였다.
SkillManager라는 싱글톤 클래스에 저장되어 있는 현재 기본 공격과 스킬의 타입을 변경시켜준다.
이렇게 해서 일주일 정도 만든 결과물은 아래와 같다.
아직 부족한 부분이 많지만, 그래도 나 스스로는 일주일 동안 나름 많이 만든 것 같아서 뿌듯하다.
유데미 코리아 바로가기 :
Udemy Korea - 실용적인 온라인 강의, 글로벌 전문가에게 배워보세요. | Udemy Korea
유데미코리아 AI, 파이썬, 리엑트, 자바, 노션, 디자인, UI, UIX, 기획 등 전문가의 온라인 강의를 제공하고 있습니다.
www.udemykorea.com
💡 본 포스팅은 유데미-웅진씽크빅 취업 부트캠프 유니티 1기 과정 후기로 작성되었습니다.
'Starters 부트캠프 > B - log' 카테고리의 다른 글
유데미 스타터스 유니티 개발자 취업 부트캠프 1기 - 12주차 학습 일지 (7) | 2022.09.11 |
---|---|
유데미 스타터스 유니티 개발자 취업 부트캠프 1기 - 11주차 학습 일지 (0) | 2022.09.04 |
유데미 스타터스 유니티 개발자 취업 부트캠프 1기 - 9주차 학습 일지 (0) | 2022.08.21 |
유데미 스타터스 유니티 개발자 취업 부트캠프 1기 - 8주차 학습 일지 (0) | 2022.08.14 |
유데미 스타터스 유니티 개발자 취업 부트캠프 1기 - 7주차 학습 일지 (0) | 2022.08.07 |