-
[졸업작품] 턴제 게임을 만들자 #2.5 코딩노트(1)유니티3D/졸업작품 2023. 5. 2. 16:19
이번 글에는 지난 개발일지 #2를 작성하면서 공부가 되었던 부분들을 정리해보려 한다.
아마 이제 앞으로도 #3, #4, …를 작성하면서 #n.5 넘버링으로 코딩노트를 작성하게 될 것 같다.
물론 공부가 된 코딩스킬을 곧이곧대로 적어놓진 않을거고, 내가 공부하여 깨달은 방식 그대로 적어놓을 것이기 때문에, 이 글 또한 튜토리얼로 써먹기엔 문제가 있을 것이다. 혹시 내가 잘못 공부했거나, 추가하고픈 내용이 있으면 댓글로 알려주길 바란다.
1. System.Serializable, SerializeField
아직은 개발을 이제 막 시작한 단계이고, 내 코딩 스킬도 아직 굉장히 어린 수준이어서, 조금 남발한 감이 있나 싶은 요소다. 하지만 그렇다고 안 쓸 수 없는 게, 이걸 쓰면 private 선언(기본적으로 유니티 C# 클래스 안에 있는 요소는 맨 앞에 어떤 범위지정자도 없으면 private로 자동으로 범위가 지정된다.)된 멤버변수라도, 인스펙터로 꺼내올 수 있다!
인스펙터에 나타난 private 맴버변수들. 인스펙터에 올라왔으니, private 맴버변수라도 인스펙터에서 값을 수정할 수 있다! 원래 인스펙터에 어떤 맴버변수를 띄우려면, 그 멤버변수가 public으로 선언되어야 한다.
하지만 public으로 선언하면, 다른 클래스에서도 함부로 꺼내 쓸 수 있게 되어, 자칫 잘못하면 예상 못한 부분에서 값이 이상하게 바뀔 수 있다. 이럴 때 해당 멤버변수 바로 윗줄에 [SerializeField]를 선언하면, 해당 멤버변수를 private로 선언하면서 인스펙터에 띄울 수 있게 된다. [System.Serializable]는 이것의 클래스 버전이고.
주의할 점은 [SerializeField] 바로 아랫줄에 있는 멤버변수만 인스펙터에 노출시킬 수 있다는 거다.
위쪽 사진에서 한 줄에 연달아 선언된 hp, mp, def, atk, comp는 인스펙터에 노출되었지만, 그 아래 선언된 crit은 노출되지 않았다. 2. Header, Range
SerializeField로 온갖 것을 인스펙터로 노출시키다 보니, 인스펙터가 너무 길어지고, 좀 정리가 필요해졌다. 그래서 간단하게나마 인스펙터를 커스터마이징 하는 법을 구글링 하고, 이 두 가지를 써먹기로 했다.
2.1. [Header()]
인스펙터에 제목을 달아주는 요소다. 원하는 위치에 [Header("아무말")]를 넣어주면, 인스펙터에서 Bold체로 "아무말"이 출력된다.
2.2. [Range(n, N)]
멤버변수 선언 전에 집어넣는 요소다.
n~N까지의 범위를 가진 슬라이더를 인스펙터에 표시한다.
3. error CS0051
Skill 클래스를 멤버 클래스로 갓 선언했을 때, 콘솔에 이런 에러들이 떴었다.
구글링을 해보니 접근범위와 관련된 오류였다.
여기까지 보았을 땐, 솔직히 잘 이해가 되지 않았다.
아니, private 선언이 된 클래스를 가지고, 같은 private 멤버변수로 선언하는 건데, 왜 문제가 생기는 거지?
하지만 콘솔은 자세히 읽어봐야 한다고. 영어가 싫고, 가독성이 절망적이어도 꼭 읽어보아야 한다고.
자세히 읽어보니 문제는 이 부분이 아니었다. 콘솔에서 Assets\Script\CharacterBehavor.cs(141, 16)이라 적힌 부분이 보이는가? 이 부분이 에러가 난 부분이 어디인지 가리켜주는 것이다. 이를 해석해 보면, 141번 줄과 155, 163번 줄의 16번째 글자에서 에러가 났다는 뜻이란 걸 알 수 있다.
문제의 141번, 155, 163번 줄 알았다. Skill 클래스는 private 멤버 클래스다.
외부 클래스가 아니고, CharacterBehavor클래스에 속해있는 맴버 클래스다.
CharacterBehavor 클래스가 없으면 바깥에 따로 존재할 수 없는 클래스다. 게다가 private 맴버 클래스로 선언되었으니, 다른 CharacerBehavor 인스턴스에서 이 Skill 클래스에 접근할 수도 없는 것이다.
그런데 그걸 외부에서 쓰라고 만들어놓은 메서드에 인수로 요구하고 있으니, 외부에서 볼 땐 없는 것이나 마찬가지인 것을 내놓으라고 왈가왈부 하는 꼴인 것이었다. 그러니 에러가 날 수밖에.
이 에러를 해결하는 방법은 쉽다. 이 모든 문제의 중심인 Skill 클래스의 접근제한을 public으로 선언하면 된다.
문 제 해 결 너무 쉽게 public으로 접근제한을 바꿔버리는 거 아니냐 할 수 있겠지만, Skill 클래스 자체가 외부로 불려 갈 일이 많은 클래스다.(UI만 생각하더라도, 스킬 목록을 만들기 위해 UI에서 주구장창 불러와 표시해야 한다.)
그럼 멤버 클래스로 만들지 않고, 따로 다른 클래스로 빼라! 아예 Skill을 인수로 받지 않는 메서드를 새로 만들라! 할 수도 있다. 하지만 그런건 지금 내 실력이 아직 이수준이라는 핑계를 대고 넘어가도록 하겠다. 나중에 코딩 스킬이 더 늘면 스태틱 클래스로 만들든, 아예 다른 클래스로 빼든 후속 조치를 취할지도 모르지.
4. 맴버 클래스 배열 선언하기
나는 궁극기와 방어, 회피, 반격을 제외한 나머지 스킬은 배열로 묶어 관리하겠다고 했었다.
마지막 노트는 이 배열을 만들며 겪은 시행착오다.
C#의 배열은 C++의 배열과는 사뭇 다르다.
크기 3의 int형 배열을 만든다면, int[] a = new int[3]; 으로 선언해야 한다.
그래서 Skill 클래스의 배열을 위와 같이 Skill[] skills = new Skill[skillCNT];로 선언했다. (skillCNT는 int로, 위쪽에 선언)
그랬더니..
에러가 떴다.
알아보니 배열의 크기를 상수가 아닌 변수로 설정했기 때문이었다.
SkillCNT에 const를 붙여 상수취급 하게 하고, Awake에서 배열 속 각 원소에 새로운 Skill 클래스 공간을 할당해준다.
이로써 인스펙터에서 문제 없이 스킬의 가짓수를 정하고, 스킬을 만들어낼 수 있게 되었다.
'유니티3D > 졸업작품' 카테고리의 다른 글
[졸업작품] 턴제 게임을 만들자 #4 1 : 1 합 (0) 2023.07.11 [졸업작품] 턴제 게임을 만들자 #3 합 매니저 만들기(1) (0) 2023.05.17 [졸업작품] 턴제 게임을 만들자 #2 플레이어 설계 (0) 2023.04.27 [졸업작품] 턴제 게임을 만들자 #1 구상 (0) 2023.04.14