오늘 학습 키워드
주변 오브젝트 찾기
오늘 학습 한 내용을 나만의 언어로 정리하기
BulletShooter
주변 오브젝트 찾기
- 스킬을 만들다 보면 그 스킬에 영향을 받아야 하는 주변 몬스터를 찾아야 함
- 그걸 어떻게 하나 찾아봤음
Collider[] targets = Physics.OverlapSphere(center, radius, enemyLayer);
- center 를 기준으로 radius만큼 큰 원을 그려서 그 안에 포함되는 Collider를 가짐.
TextRPG
스킬을 다른 플레이어가 못 배워요
- 오류 시나리오
- 스킬 상점 데이터를 JSON으로 저장함
- 플레이어 1이 스킬 1번을 배움
- 저장하고 종료함
- 플레이어 2가 스킬 1을 배우려고 시도함
- 그러나 이미 배운 스킬이라고 뜸
- 오류 해결 아이디어
- 스킬 데이터를 저장하지 말고, 상점에 들어갈 때 스킬 보유목록이랑 체크하기로 함
그럼 어떻게 짤 것인가?
- 스킬 상점 씬을 불러올 때마다 스킬 습득 여부를 체크할거임
- 스킬 상점에 있는 스킬들 중에, 플레이어의 스킬이 있으면 그 스킬은 배운거임
- 처음에 떠오른건, LINQ를 사용하는 방법임
public static void CheckDidYouLearn()
{
SkillManager.skills
.Where(skill => GameManager.player.Skills.Any(ps => ps.Name == skill.Name))
.ToList()
.ForEach(skill => skill.LearnState = LearnState.Learned);
}
- 근데 ChatGPT가 LINQ는 살짝 성능이 떨어진다고 하길래 왜인지 물어봄
- 이게 무슨 소리인가 내 안의 LINQ는 무적이었는데
- 진짜인가 좀 더 찾아봄
- 유의미한 차이는 데이터가 만 개 이상일 때 나타난다고 함
- 지금 당장은 아니지만 그러면 어떻게 해야 하나? 에 대한 ChatGPT의 답변
public static void CheckDidYouLearn()
{
var learnedSkillIds = new HashSet<int>(GameManager.player.Skills.Select(s => s.Id));
foreach (var skill in SkillManager.skills)
{
if (learnedSkillIds.Contains(skill.Id))
{
skill.LearnState = LearnState.Learned;
}
}
}
- 플레이어 스킬 ID를 기반으로 해쉬셋을 만든다
- 스킬 매니저의 스킬을 순회한다
- 해쉬셋에 스킬 아이디가 포함되어있으면 상태를 바꾼다
상점이 이상해요
- 이런 일이 있었다..
- 그래서 확인해봤더니 상점에서 경유하는 ItemSystem이 있는데, 그 안에 인벤토리가 따로 있었다
- 플레이어도 인벤토리를 가지고 있기 때문에, ItemSystem에서는 플레이어 인벤토리를 바로 링크하게 하면 될 듯 하여 수정했더니 해결됨
쿨타임 적용이 안돼요
- 쿨타임을 관리를 어떻게 할 것인가
- Skill - int 딕셔너리로 관리한다. (장점 : Skill 자체를 바꿀 필요는 없음.)
- Skill에 MaxCooldown과 CurrentCooldown으로 관리한다. (굳이?)
- 1안으로 가는게 나을듯.
public void CooldownSetting()
{
foreach(var skill in GameManager.player.Skills)
{
playerCooldowns[skill] = 0;
}
}
public void TickCooldowns()
{
foreach (var skill in playerCooldowns)
{
if (playerCooldowns[skill.Key] > 0)
{
playerCooldowns[skill.Key]--;
}
}
}
- 그리하여 해결됨
이 외에도 나왔던 자잘한 버그들
- 보스 전투 튀면 꺼짐 ⇒ 해결됨.
- 보스 배틀씬은 매번 new로 생성해주다보니 그럼. 강제로 prevScene을 설정해줌
- 판매창에 판매 가격이 없음 ⇒ 해결됨
- 퀘스트출력문 중앙에 옮기기 ⇒
- 스킬트리 이동하면 Console.clear없는거
튜토리얼을 만들고 싶어요
- 기존 함수를 가져다가 오버라이딩하기로 함
// 기존 함수
public static void DrawBox(List<string> contents)
{
int width = GetMaxWidth(contents);
string topBorder = "╔" + new string('═', width) + "╗";
string bottomBorder = "╚" + new string('═', width) + "╝";
Console.WriteLine(topBorder);
Console.WriteLine($"║{new string(' ', width)}║");
foreach (string line in contents)
{
Console.WriteLine($"║{PadCenter(line, width)}║");
}
Console.WriteLine($"║{new string(' ', width)}║");
Console.WriteLine(bottomBorder);
}
// 오버라이딩한 함수.
// 원래는 바로 콘솔에 그려주지만, 그 부분을 가져다가 반환하도록 변경함
public static List<string> DrawBox(List<string> contents, bool retuner)
{
int width = GetMaxWidth(contents);
List<string> strings = new List<string>();
string topBorder = "╔" + new string('═', width) + "╗";
string bottomBorder = "╚" + new string('═', width) + "╝";
strings.Add(topBorder);
strings.Add($"║{new string(' ', width)}║");
foreach (string line in contents)
{
strings.Add($"║{PadCenter(line, width)}║");
}
strings.Add($"║{new string(' ', width)}║");
strings.Add(bottomBorder);
return strings;
}
학습하며 겪었던 문제점 & 에러
문제 1
- 문제&에러에 대한 정의
스킬을 분명 배웠는데 던전 들어가면 스킬 없다고 뜸
- 해결 방법
public class SkillInvenScene : GameScene
{
List<Skill> skills;
public override string SceneName => "스킬트리";
public override GameScene? StartScene()
{
skills = GameManager.player.Skills;
PrintSkills();
return EndScene();
}
public void PrintSkills()
{
List<string> strings = new List<string>();
if (skills != null)
{
for(int i = 0; i < skills.Count; i++)
{
strings.Add($"{i+1} : "+skills[i].ToString());
}
}
else { strings.Add("사용 가능한 스킬이 없습니다."); }
UI.DrawTitledBox(SceneName, strings);
}
}
스킬트리 씬이 시작이 안되면 애초에 skills가 비어있었음…
// 이걸 빼먹어서 ㅡㅡ
skills = GameManager.player.Skills;
- 이 문제&에러를 다시 만나게 되었다면?
초기화 잊지말자
문제 2
- 문제&에러에 대한 정의
레벨이 자꾸 1로 초기화 됨
- 내가 한 시도
레벨 프로퍼티를 확인해봄. private set; 으로 되어있었음
- 해결 방법
set으로 바꿈
- 새롭게 알게 된 점
json 역직렬화 할 때 set 쓰니까 set을 private로 두지 말자