36,300원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
Quest Cancel() 메소드
Quest.csComplete() 메소드에서 이벤트들을 초기화(해제)시키는데Cancel() 메소드에서는 이벤트들을 초기화를 안 하는 이유가 있을까요?OnRegister()에서task.onSuccessChanged += OnSuccessChanged;이벤트를 사용해서 Quest를 취소했을 때도 이벤트를 초기화해야 될 것 같다고 생각돼서 질문 남겼습니다!
- 해결됨[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
Task의 IsEqual
Quest System 구현 강의 마지막에 Quest System Test를 실습하던중 제대로 작동하지 않아 문의 드립니다. 디버그를 찍어봤는데 Task Script의 IsTarget() 함수에서 targets.Any(x=>x.IsEqual(target))부분에서 false가 된것이 원인이었습니다. 자세히 보니 QuestSystemTest에서 Target을 TaskTarget형태로 넘겨주고, TaskTarget의 IsEqual에서 TaskTarget형식으로 받아서 문제가 된것이었습니다. 이를 방지하기 위해 아래와 같이 TaskTarget인지를 먼저 검사해야된다고 생각하는데,혹시 제가 놓친부분이 있다면 알려주세요public override bool IsEqual(object target) { if(target.Equals(this))return true; string targetAsString = target as string; if (targetAsString == null) return false; return value == targetAsString; }
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
실전예제 UI 자료
UI 수업자료 다운받아서 사용하려는데 정확하게 방법을 모르겠네요 ㅠ 압축을 해제하면 폴더만 쭉나와서 수업자료를 어떻게 사용해야 하는건가요
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
스크립터블 오브젝트
안녕하세요 수업 도중에 한 가지 질문이 생겨서 글 올립니다.퀘스트를 모듈식으로 조립하기 위해 스크립터블 오브젝트를 많이 사용하던데, 스크립터블 오브젝트는 빌드에 포함되는 에셋 형태이기에, 빌드 용량이 커지게 되고, 사용자가 접근이 가능한 문제가 있다고 알고 있는데, 혹시 제가 이 부분에 대해서 잘못 알고 있는 것일까요?만약 문제가 맞다면, 스크립터블 오브젝트말고 어떤 식으로 구조를 짜는게 좋을까요?
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
Task 예시
테스크에 Count Task와 Set Task를 예로 들어주셨는데 두개의 차이점을 모르겠습니다
- 해결됨[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
퀘스트의 상태인 QuestState를 다른 스크립트에서 받을 수 있나요
이 수업 내용을 토대로 프로젝트에 적용중입니다. 구현중인 내용이 퀘스트의 상태에 따라 대화문이 다르게 출력되도록 하고싶은데 대화문을 출력하는 코드에서 퀘스트의 현재 상태를 가져오지 못합니다. 이렇게 현재 구현했고 SerializeField 를 통해 불러오고 싶은 스크립터블 오브젝트 Quest를 참조했습니다.그런데 QuestGetDialogue()이 코드를 호출했을 때 퀘스트를 받고 난 후에도 Running 상태의 코드를 출력하지 않고 if(quest.State == QuestState.Inactive) { dialogueEvent.dialogues = DataBaseManager.instance.GetDialogue((int)quest.InactiveQuestline.x, (int)quest.InactiveQuestline.y); Debug.Log(quest.State); }여전히 이 코드를 받아옵니다. Debug.Log 를 통해 확인해봤을 때 Quest System에 등록된 퀘스트는 제대로 상태가 변하는데 이 스크립트에서 변한 상태를 못 받아오는거 같아 질문드립니다. ㅠㅠ
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
QuestSystemSaveTest 중 오류가 났습니다
오류 난 콘솔창입니다. 저 콘솔창에서 더블클릭해서 들어가보면 하이라이트한 줄이 문제가 있다고 나오는데 오류 메세지는 Quest.cs의 103번째 줄을 가리켜서 가보니OnRigster 함수 안에 저 줄을 가리키더라고요. 어떤 문제인지 알 수 있을까요 지금까지 그대로 따라왔는데 오류가 떠서 뭔지 모르겠어요 ㅜㅠ
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
IndexoutofRange, Debug.Assert에러 나시는 분들 코드 수정
IndexoutofRange 에러-> QuestSystem Awake의 foreach 부분 주석처리 해주시면 됩니다. achievement 등록이 되어있지 않아서 그런 것 같습니다. Debug.Assert에러 나시는 분들ReceiveReport, CheckIsRunning 함수의 IsRegistered 가 false로 등록되어 있어서 그런 것 같습니다. Debug.Assert(IsRegistered, "This quest has already been registered."); 이 코드 IsRegistered 앞에 " ! "가 붙어 있다면 빼주세요.
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
안녕하세요 질문이 있습니다.
안녕하세요 이 강의로 정말 도움을 많이 본 수강생입니다.Task가 완료된 후 유저가 완료 버튼을 누르면 해당 Task가 지워지면서 보상을 받는 시스템을 만들고 싶어서TaskDescriptor 스크립트에 DestroySelf함수를 만들어 TASK완료시 버튼을 누르면 해당 TASK가 목록에서 지워지면서 보상을 받게끔 했습니다. 하지만 버튼을 누르면 완료된 TASK가 지워지더라도 씬을 이동하거나 앱을 종료하고 다시 실행하면 지워진 TASK가 complete가 된 상태로 다시 생성되어 있습니다. taskDesriptorPrefab이 만들어지는 QuestTracker에서 작업을 해주면 좋을 것 같아 조건도 달고 별 짓을 다해봐도 소용이 없어 질문드립니다.어떻게 하면 좋을까요?
- 해결됨[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
QuestSave & Load 질문
마지막 테스트 부분에서 스페이스를 눌러도 Complete 메시지가 출력되지 않습니다. 콘솔 상에서도 오류가 나지 않아서 뭐가 문제인지 잘 모르겠습니다. 어떤 것을 확인해야 할까요? 그리고 3장의 UI부분에서 creator kit의 버전차이 때문에 Quest Trakcer Prefab이 존재하지 않는 것 같은데Task Descriptor 스크립트를 어떻게 해야 하는건지도 궁금합니다. 버전은 2022.3.8f1 입니다!
- 해결됨[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
This quest has already been registered
안녕하세요 좋은 강의 잘 보고 있습니다!2장의 QuestSystem 부분까지 다 듣고 난 후, 마지막 테스트하는 부분에서 This quest has already been registered. 라는 에러가 나옵니다.강의를 돌려보면서 스크립트를 다르게 작성한 부분이 있나 확인해봤는데도 도저히 해결되지 않아 글을 작성하게 되었습니다. 제가 작성한 스크립트입니다.<Quest>public enum QuestState{ Inactive, Running, Complete, Cancel, WaitingForCompletion}[CreateAssetMenu(menuName = "Quest/Quest", fileName = "Quest_")]public class Quest : ScriptableObject{ #region Event public delegate void TaskSuccessChangedHandler(Quest quest, Task task, int currentSuccess, int prevSuccess); public delegate void CompletedHandler(Quest quest); public delegate void CancelHandler(Quest quest); public delegate void NewTaskGroupHandler(Quest quest, TaskGroup currentTaskGroup, TaskGroup prevTaskGroup); #endregion public event TaskSuccessChangedHandler onTaskSuccessChandged; public event CompletedHandler onCompleted; public event CancelHandler onCanceled; public event NewTaskGroupHandler onNewTaskGroup; public void OnRegister() { // Assert는 인자로 들어온 값이 false면 뒤의 문장을 에러로 띄움.(버그검출용) Debug.Assert(!IsRegistered, "This quest has already been registered."); foreach (var taskGroup in taskGroups) { taskGroup.Setup(this); foreach (var task in taskGroup.Tasks) task.onSuccessChanged += OnSuccessChanged; } State = QuestState.Running; CurrentTaskGroup.Start(); } public Quest Clone() { var clone = Instantiate(this); clone.taskGroups = taskGroups.Select(x => new TaskGroup(x)).ToArray(); return clone; } public void ReceiveReport(string category, object target, int successCount) { Debug.Assert(!IsRegistered, "This quest has already been registered."); Debug.Assert(!IsCancel, "This quest has been canceld"); if (IsComplete) return; if (CurrentTaskGroup.IsAllTaskComplete) { if (currentTaskGroupIndex + 1 == taskGroups.Length) { State = QuestState.WaitingForCompletion; if (useAutoComplete) Complete(); } else { var prevTasKGroup = taskGroups[currentTaskGroupIndex++]; prevTasKGroup.End(); CurrentTaskGroup.Start(); onNewTaskGroup?.Invoke(this, CurrentTaskGroup, prevTasKGroup); } } else State = QuestState.Running; } public void Complete() { CheckIsRunning(); foreach (var taskGroup in taskGroups) taskGroup.Complete(); State = QuestState.Complete; foreach (var reward in rewards) reward.Give(this); onCompleted?.Invoke(this); onTaskSuccessChandged = null; onCompleted = null; onCanceled = null; onNewTaskGroup = null; } public virtual void Cancel() { CheckIsRunning(); Debug.Assert(IsCancelable, "This quest can't be canceled"); State = QuestState.Cancel; onCanceled?.Invoke(this); } private void OnSuccessChanged(Task task, int currentSuccess, int prevSuccess) => onTaskSuccessChandged?.Invoke(this,task,currentSuccess, prevSuccess); [Conditional("UNITY_EDITOR")] private void CheckIsRunning() { Debug.Assert(!IsRegistered, "This quest has already been registered."); Debug.Assert(!IsCancel, "This quest has been canceld"); Debug.Assert(!IsCompleatable, "This quest had already been completed"); }} <QuestSystem>public class QuestSystem : MonoBehaviour{ #region Events public delegate void QuestRegisteredHandler(Quest newQuest); public delegate void QuestCompletedHandler(Quest quest); public delegate void QuestCanceledHandler(Quest quest); #endregion private static QuestSystem instance; private static bool isApplicationQuitting; public static QuestSystem Instance { get { if (!isApplicationQuitting && instance == null) { instance = FindObjectOfType<QuestSystem>(); if (instance == null) { instance = new GameObject("Quest System").AddComponent<QuestSystem>(); DontDestroyOnLoad(instance.gameObject); } } return instance; } } private void Awake() { questDatabase = Resources.Load<QuestDatabase>("QuestDatabase"); achievementDatabase = Resources.Load<QuestDatabase>("AchievementDatabase"); foreach (var achievement in achievementDatabase.Quests) Register(achievement); } public Quest Register(Quest quest) { var newQuest = quest.Clone(); if (newQuest is Achievement) { newQuest.onCompleted += OnAchievementCompleted; activeAchievements.Add(newQuest); newQuest.OnRegister(); onAchievementRegistered?.Invoke(newQuest); } else { newQuest.onCompleted += OnQuestCompleted; newQuest.onCanceled += OnQuestCanceled; activeQuests.Add(newQuest); newQuest.OnRegister(); onQuestRegistered?.Invoke(newQuest); } return newQuest; } public void ReceiveReport(string category, object target, int successCount) { ReceiveReport(activeQuests, category, target, successCount); ReceiveReport(activeAchievements, category, target, successCount); } public void ReceiveReport(Category category, TaskTarget target, int successCount) => ReceiveReport(category.CodeName, target.Value, successCount); public bool CantainsInActiveQuests(Quest quest) => activeQuests.Any(x => x.CodeName == quest.CodeName); public bool CantainsInCompletedQuests(Quest quest) => completedQuests.Any(x => x.CodeName == quest.CodeName); public bool CantainsInActiveAchievements(Quest quest) => activeAchievements.Any(x => x.CodeName == quest.CodeName); public bool CantainsInCompletedAchievements(Quest quest) => completedAchievement.Any(x => x.CodeName == quest.CodeName); private void ReceiveReport(List<Quest> quests, string category, object target, int successCount) { foreach (var quest in quests.ToArray()) quest.ReceiveReport(category, target, successCount); } #region Callback private void OnQuestCompleted(Quest quest) { activeQuests.Remove(quest); completedQuests.Add(quest); onQuestCompleted?.Invoke(quest); } private void OnQuestCanceled(Quest quest) { activeQuests.Remove(quest); onQuestCanceled?.Invoke(quest); Destroy(quest, Time.deltaTime); } private void OnAchievementCompleted(Quest achievement) { activeAchievements.Remove(achievement); completedAchievement.Add(achievement); onAchievementCompleted?.Invoke(achievement); } #endregion} 파일을 따로 올리는 곳이 없어 어쩔 수 없이 스크립트 전체를 올렸고 너무 길어서 변수 부분은 생략했습니다!감사합니다.
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
궁금합니당
현재 2022.3.2f1 버전을 사용하고 있는데 json 패키지가 따로 없어서 에셋스토어에서 다운 할려고 찾아보니 그거 마저도 없는데 어떻게 해야 하는걸까요?
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
궁금한점
MVC, MVP 를 알게됬는데 이 강좌같은 경우는각각 델리게이트 이벤트에 등록하는게 MVP같은데 MVP에 해당하는건가요?관련 예제를 찾아봐도 잘 이해가 안되서여 ㅜ
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
description 생성할때 애니메이션
안녕하세요Quest Tracker 부분에서 새로운 퀘스트가 등록되거나 새로운 task가 등록될때 애니메이션을 주면서 생성하고싶은데 vertical layout group 때문에 UI가 고정되있어서 어떤식으로 해야할지 고민입니다. vertical layout group을 끄고 해볼려고했는데 content size 가 적용이 안되서 이상해보입니다. 혹시 어떤 방법이 있을까요??
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
델리게이트 궁금한점
안녕하세요델리게이트 이해가 조금 안가는게있습니다.A라는 스크립트를 가지고있는 게임오브젝트가 Scene에 여러개가있고 A스크립트에 델리게이트가 있을 경우 A에 델리게이트를 각 게임오브젝트가 공유를 하는건지 , 아니면 개별적으로 따로 등록을해서 움직이는건지 궁금합니다. 예를들어 A 스크립트에 Task 라는 델리게이트가 있고 P 키보드를 누를경우 실행이 될때,Task에 함수를 등록을 하고 한 게임오브젝트에서 Task.Invoke를 할 경우 Scene에 나머지 A스크립트에서도 Task가 실행되는지 궁금합니다. ( 혼자서 만든 델리게이트가 저렇게 공유를 하는데 이게 ScriptableObject가 공유가된건지 아님 원래 그런건지 모르겠지만 한곳에서 델리게이트를 실행하면 같은 스크립트를 가진 곳에서도 같이 실행이되서 각 델리게이트 함수에 조건을 걸어두고 사용했는데 이게 맞나요?)
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
다운캐스팅 에러?
안녕하세요 궁금한게 있습니다. 강의에서 Quest ScriptableObject를 Instantiate()로 복제를 하는데 상속받은 Scriptableobejct에 다운캐스팅을 하면 null이 되는데 왜그러는지 모르겠습니다. 예를들어 A 라는 scriptableobject가 있고 B : A 라는 상속받은 scriptableobject가 있을떄A a = new A(); 를 생성하고a.num = 10;을 한 상태에서 B b = Instantiate(a) as B; b.Id = 2;이렇게하면 b는 null이 됩니다. 제가 원하는건 b.num = 10; 이고 b.id = 2;인 데이터가 생성되는것인데 a는 null이 아닌데 다운캐스팅만 하면 null이 됩니다 ㅜㅜ
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
Npc 퀘스트 탐색
안녕하세요 각 NPC가 퀘스트 목록들이 있는 퀘스트 그룹을 가지고있는데 이 퀘스트가 가능한지 조건 검사를 어떻게 해야할지 고민입니다.제가 생각한건 각 NPC가 퀘스트 목록들이 있는 퀘스트 그룹 변수를 가지고있고 0.2초마다 각 퀘스트 목록에 condition을 체크해서 발생 가능한 퀘스트면 NPC가 퀘스트를 주는거를 생각했는데 문득 이런 방식이 NPC도 많고 검사할 퀘스트도 많다보니까 성능에 영향이 갈거같은 생각이 들어서 혹이 보통 어떤식으로 NPC를 활용해서 퀘스트를 주는지 궁금합니다. ㅜㅜ
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
이벤트를 만들때
퀘스트를 응용해서 이벤트를 만들려고합니다.이벤트는 단순히 퀘스트를 상속받아서 하면될거같은데 문제는 이벤트 발생시 각 발생 프로세스를 어떻게 구현할지가 고민입니다.예를들어 어떤 이벤트는 공간 이동후 적이 몰려오는 이벤트가있고 또 어떤 이벤트는 공간 이동 후 인질을 구출하라는 이벤트가 발생 하는식인데이벤트를 스크립터블 오브젝트로 만들고 거기에 변수로 이벤트 액션이라는 스크립터블오브젝트를 만들어서 해당 이벤트 액션에 각 기능 프로세스를 구현 하려고했는데 변수 세팅하기가 힘들고 먼가 하드 코딩이 될거같아요..혹시 저런식에 이벤트를 어떻게 만드는게 깔끔한가요??
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
QuestSystem_Test 에러 부분 ㅜㅜ
IndexOutOfRangeException: Index was outside the bounds of the array.Quest.get_CurrentTaskGroup () (at Assets/Scripts/Quest/Quest/Quest.cs:60)Quest.OnRegister () (at Assets/Scripts/Quest/Quest/Quest.cs:93)QuestSystem.Register (Quest quest) (at Assets/Scripts/Quest/Quest/QuestSystem.cs:81)QuestSystem.Awake () (at Assets/Scripts/Quest/Quest/QuestSystem.cs:67)이 에러가 생겨요 ㅜㅜ 들어가보면 Quest스크립트에 public TaskGroup CurrentTaskGroup => taskGroups[currentTaskGroupIndex]; 이 줄을 가리키는데 머가문제인지 모르겠어요 ㅜㅜ
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
Save 함수에서 스택오버플로우 발생하는문제가 있습니다
foreach문을 들어가는순간 오류가 터집니다.에디터에서 가리키는 오류구문 80번째 내용은Quest 스크립트의public virtual bool IsSavable => IsSavable; 부분입니다.정말 도저히 이유를 못찾겠습니다..