게시글
질문&답변
2024.04.27
instantiate에 대해서 질문입니다.
수강해주셔서 감사합니다. Instantiate는 Serialize 할 수 있는 변수들만 복사됩니다. 다시 말해 Serialize 가능한 public 변수와 [SerializeField]가 붙은 private 변수만 복사되며, 일반 private 변수는 복사되지 않습니다. 감사합니다.
- 0
- 1
- 42
질문&답변
2024.04.26
SkillSystemWindow 스크립트 drawDatabase함수에서 null참조발생
보내주신 프로젝트를 확인해보았습니다. 직접 만드신 Category class가 IdentifiedObject를 상속 받지 않아서 생긴 문제입니다. (사진) IODatabase에서 관리되는 모든 객체들은 IdentifiedObject를 상속 받아야합니다. (사진) 해당 부분을 다음과 같이 수정하시고, Resources 폴더를 비우신 뒤 다시 Window를 열면 정상적으로 작동합니다. 감사합니다.
- 0
- 3
- 94
질문&답변
2024.04.26
SkillSystemWindow 스크립트 drawDatabase함수에서 null참조발생
수강해주셔서 감사합니다. 혹시 이전에 Code를 직접 작성하신 부분이 있으실까요? dataType.BaseType이 null이라는 소리는 dataType이 IdentifiedObject를 상속 받고 있지 않고 있을 가능성이 높습니다.
- 0
- 3
- 94
질문&답변
2024.04.18
Quest Cancel() 메소드
수강해주셔서 감사합니다. 이후에 보실 QuestSystem Script에서 Quest가 Cancel이되면 Destroy 함수로 Quest를 파괴합니다. 그래서 굳이 event를 초기화해주지 않은 것입니다. 참고로 Quest 완료 시에 event를 초기화시키는건 Quest 완료시엔 Quest가 QuestSystem의 Completed List에 보관되기 때문에 불필요하게 메모리를 차지하고 있지 않게 하기 위해서입니다. 다만, 강의의 코드는 하나의 가이드일 뿐, Complete와 Cancel 함수에 통일성을 주고 싶다고 생각이 드시면 Cancel 함수에도 event 초기화 Code를 넣으셔도 됩니다. 감사합니다.
- 0
- 2
- 79
질문&답변
2024.04.17
Task의 IsEqual
수강해주셔서 감사합니다. QuestSystemTest Script의 Update 함수를 보시면 다음과 같은데요, void Update() { if (Input.GetKeyDown(KeyCode.Space)) QuestSystem.Instance.ReceiveReport(category, target, 1); } 실행되는 QuestSystem Script 114번 줄, TaskTarget을 인자로 받는 ReceiveReort 함수를 보시면 다음과 같습니다. // 114번 줄 public void ReceiveReport(Category category, TaskTarget target, int successCount) => ReceiveReport(category.CodeName, target.Value, successCount); 위 함수에서 TaskTarget의 Value를 인자로 108번 줄의 ReceiveReport 함수를 호출하게 되므로, // 108번 줄 public void ReceiveReport(string category, object target, int successCount) { ReceiveReport(activeQuests, category, target, successCount); ReceiveReport(activeAchievements, category, target, successCount); } Task에게 TaskTarget 자체가 보고 되는 일은 없습니다. 제가 말씀드린 Code들을 확인해보시면 될 것 같습니다. 감사합니다.
- 0
- 1
- 48
질문&답변
2024.04.16
실전예제 UI 자료
수강해주셔서 감사합니다. 수업 자료로 업로드 되어있던 파일은 .unitypackage 파일이였는데요, 인프런측 오류인지 .gz 확장자로 다운로드 되는 것을 확인하였습니다. package 파일을 zip 형태로 압축해서 다시 업로드하였구요, zip을 푸셔서 나온 .unitypackage 파일을 프로젝트에 풀어주시면 됩니다. 다른 방법으로는 다운로드 받으신 수압 자료의 .gz 확장자를 .unitypackage 확장자로 바꿔주시면 됩니다. 불편을 드려 죄송합니다. 감사합니다.
- 0
- 1
- 54
질문&답변
2024.04.14
2강 Database에 리플렉션에 대해 질문입니다.
수강해주셔서 감사합니다. 맞습니다. C++ 같은 언어에서는 friend Keyword를 통해서 private 변수에 접근이 가능하지만 C#에서는 그 방법이 없으므로 보통 Reflection을 통해 은닉성을 지키면서 수정을 가합니다. 다만 이는 IODatabase가 IO 객체를 관리한다는 명확한 상하관계에 놓여있기 때문에 택한 방식으로 Reflection의 무분별한 남용은 또 다른 은닉성의 파괴로 이어지게 됩니다. 감사합니다.
- 0
- 1
- 92
질문&답변
2024.04.14
스크립터블 오브젝트
수강해주셔서 감사합니다. ScriptableObject는 Asset이기 때문에 빌드 용량이 커지는 것 자체는 맞으나 Data 객체이기 때문에 유의미한 정도로 늘어나는건 아닙니다. 프로젝트 폴더에서 ScriptableObject Asset의 용량을 확인해보시면 1~2kb 정도 밖에 안하구요, 나중에 Skill처럼 훨씬 많은 Data를 담는 ScriptableObject를 만든다고해도 10kb 내외의 용량을 가지게 됩니다. ScriptableObject를 수 십만개 만드실게 아니시라면 용량은 신경 쓸 부분이 아닙니다. 사용자가 접근이 가능한 문제라는건 아마 언패킹해서 데이터 변조 후 리패킹 하는 것을 얘기하시는 것 같은데요, 데이터 변조는 보안이 뚫린 이상 코드부터 시작해서 각종 에셋들까지 모두 변조가 가능하기 때문에 ScriptableObject만의 문제가 아닙니다. 보안상 가장 좋은 구조는 Database를 구축해서 Quest Table을 만들고, 서버에서 Database와 통신하여 실시간으로 Quest를 조립하고, Quest에 관한 모든 처리를 서버에서 진행, 클라이언트는 Update된 Quest의 정보만 받아오는 구조입니다. 로컬에서 DB와 통신해도 되긴하지만 그렇게되면 DB 수정을 통해 실시간 패치가 가능하다는 것과 ScriptableObject처럼 언패킹을 통한 직접적인 변조가 불가능하기 때문에 우회 변조를 해야한다는 점 정도를 빼면 보안상 큰 이점은 없다고 생각하시면 됩니다. 다만, 아무래도 인디 혹은 개인 개발자가 Database와 서버를 운용하기에는 비용 문제와 기술 난이도 문제가 있기 때문에 싱글 게임이나 인디쪽에선 ScriptableObject 기반 구조나 엑셀 기반 구조로 많이 만듭니다. 감사합니다.
- 0
- 1
- 72
질문&답변
2024.04.12
Task 예시
수강해주셔서 감사합니다. 단순히 Task의 성공 횟수를 결정하는 공식의 차이입니다. Count는 공식으로 나타내면 (현재 성공 횟수 + 보고 받은 성공 횟수 = 최종 성공 횟수) 입니다. '슬라임을 100마리 잡아라'라는 Task가 있을 때, (=슬라임 토벌 0/100) 슬라임을 1마리 잡게되면 위 공식에 대입해서 (현재 성공 횟수( 0 ) + 슬라임을 잡은 횟수( 1 ) = 최종 성공 횟수( 1 ))로 Task의 현재 성공 횟수는 1이 됩니다. (=슬라임 토벌 1/100) 여기서 다시 슬라임을 한마리 잡으면 (1 + 1 = 2)가 되겠죠. (=슬라임 토벌 2/100) 결론적으로 슬라임을 100마리 잡게되면 Task가 완료됩니다. (=슬라임 토벌 100/100) Set은 공식으로 나타내면 (보고 받은 성공 횟수 = 최종 성공 횟수) 입니다. 강의 영상의 내용처럼 '레벨 47을 달성해라'라는 Task가 있을 때, (=레벨 달성 0/47) 현재 레벨(45)을 Task에 보고하게 되면 (현재 레벨( 45 ) = (최종 성공 횟수( 45 ))로 Task의 성공 횟수는 45가 됩니다. (=레벨 달성 45/47) 여기서 레벨 업을 하게되어 레벨(46)을 Task에게 다시 보고하게 되면 Task의 성공 횟수는 46이 되게 됩니다. (=레벨 달성 46/47) 반대로 레벨이 떨어져서 44가 되면 마찬가지로 Task의 성공 횟수는 44가 되게 됩니다. (=레벨 달성 44/47) 결론적으로 레벨이 47 이상이 되면 Task가 완료됩니다. (=레벨 달성 47/47) 만들기에 따라서는 레벨 달성 Task도 Count 공식으로 설정하고 레벨 업을 할 때마다 몇 렙이 올랐는지 보고해서 계산해도 됩니다. Count 방식 현재 레벨(45) + 보고 받은 성공 횟수(1) = 최종 성공 횟수(46) (=레벨 달성 44/47) 현재 레벨(46) + 보고 받은 성공 횟수(1) = 최종 성공 횟수(47) (=레벨 달성 47/47) 다만 경험상 '특정 수치보다 큰 지' 확인해야하는 경우 Set 방식으로 계산하는게 여러 상황에 대응할 수 있기 때문에 Set으로 예시를 들어드린겁니다. 해당 내용은 Task Script 작성 강의에서 보실 수 있습니다. 감사합니다.
- 0
- 1
- 45
질문&답변
2024.04.07
퀘스트의 상태인 QuestState를 다른 스크립트에서 받을 수 있나요
수강해주셔서 감사합니다. 먼저 기억하셔야할건 SerializeField로 받아오는건 Quest의 원본이며, QuestSystem에 등록되는건 Quest의 사본입니다. //QuestSystem.cs 81번줄 public Quest Register(Quest quest) { var newQuest = quest.Clone(); // Quest의 사본 ... } 즉, 등록된 Quest의 상태를 찾아오려면 먼저 QuestSystem에 등록된 Quest를 찾아와야합니다. 지금은 그냥 SerializeField로 받은 원본 Quest의 상태를 확인하고 계신데, 원본 Quest는 QuestSystem에 등록되지 않으므로 상태가 계속 Inactive 상태입니다. 함수의 첫 줄에 var registeredQuest = QuestSystem.Instance.ActiveQuests.FirstOrDefault(x => x.CodeName == quest.CodeName); 를 추가하시고, registeredQuest의 상태를 확인하시면 정상 작동할 것으로 보입니다. 감사합니다.
- 1
- 2
- 129