36,300원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
Save 함수에서 스택오버플로우 발생하는문제가 있습니다
foreach문을 들어가는순간 오류가 터집니다.에디터에서 가리키는 오류구문 80번째 내용은Quest 스크립트의public virtual bool IsSavable => IsSavable; 부분입니다.정말 도저히 이유를 못찾겠습니다..
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
Category 스크립트 작성할때 Equals에 대해 궁금한게 있습니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. public override bool Equals(object other) => base.Equals(other);이 부분이 왜 추가가 되는건지 궁금합니다. 어짜피 Category 파라미터가 아닌 object형 파라미터는 재정의 안하면 자동으로 base의 Equals를 호출하는게 아닌가요? 이 부분이 헷갈려서... 질문드립니다
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
ShowDetail 질문
선생님 안녕하세요. QuestView 부분에서 질문이 있습니다.처음에 QuestListView에서 elementTextPrefab의 토글 이벤트로 QuestView의 ShowDetail 메서드를 등록해서실제로 elementTextPrefab의 토글이 바뀔때마다 ShowDetail의 isOn부분을 제어하게되는데, 토글이 바뀔때 quest의 내용까지 바뀌는 것은 처음에 이벤트를 등록할 때 quest 파라미터의 정보까지 한꺼번에 등록되어서 그런것인가요?
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
스크립터블 오브젝트 질문
안녕하세요 복습하다가 질문드리게되었습니다. 스크립터블 오브젝트는 클라이언트 내에서 에셋으로 생성된 형태이기 때문에 되도록이면 컨텐츠 보안에 민감하지 않은 정보를 담고 있어야 할까요? 예를 들어 무기 아이템의 공격력 정보를 스크립터블 오브젝트에 그대로 담아 놓고 쓰면 보안에 취약한가요?
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
onSuccessChanged? 의 의미가 어떤것인가요?
Task.cs를 보면아래와 같은 코드가 있던데 혹시 onSuccessChanged에 ?가 붙은 것은 어떤 의미인가요? if (currentSuccess != prevSuccess) { State = currentSuccess == needSuccessToComplete ? TaskState.Complete : TaskState.Running; onSuccessChanged?.Invoke(this, currentSuccess, prevSuccess); }
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
게임 시작 시 Quest Target Marker 오브젝트 비활성화
안녕하세요. 강의 완강 후 해결되지 않은 점이 있어 올립니다..! 퀘스트를 등록하고 업데이트나 데이터를 저장하고 가져오는 등의 기능들은 정상적으로 작동하나 게임 시작 시 Quest Target Marker 게임 오브젝트가 비활성화되어 작동하지 않습니다..!! 강의를 여러 번 돌려봤지만 어디서 잘못된 건지 찾기가 힘들어서요..! 다시 살펴보아야 할 부분이 어딜까요..?ㅜㅠ
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
QuestView 테스트시 착선이 그어지지 않는 현상
안녕하세요 선생님 QuestView.cs 작성을 완료하고 UI에 전부 부착하고 테스트를 하는도중,완료된 task의 description에 착선이 그어지지 않는 현상이 있어서요..isComplete가 true인 조건문이 발동되지 않아 착선이 그어지지 않는것 같은데제가 실력이 부족해 왜 발동이 안되는지 인지가 되지 않아 질문 남깁니다강의에서는 착선이 그어졌는지 확인하는 장면은 없는것같아원래 안그어지는 버그인지, 제 코드의 문제인지 확인이 어렵네요 ㅜ.ㅜ무엇이 원인인지 답변 주시면 감사하겠습니다! 완료된 퀘스트가 ??로 보이는 모습 // QuestDetailView.cs -> Show 메서드 중.. foreach (var taskGroup in quest.TaskGroups) { foreach (var task in taskGroup.Tasks) { var poolObject = taskDescriptorPool[taskIndex++]; poolObject.gameObject.SetActive(true); // 실행 안되는 부분 if (taskGroup.IsComplete) poolObject.UpdateTextUsingStrikeThrough(task); // else if (taskGroup == quest.CurrentTaskGroup) poolObject.UpdateText(task); else poolObject.UpdateText("● ??????????"); } }
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
QuestSystemSaveTest 수강 후 오류
안녕하세요 선생님강의를 열심히 따라 듣고있던 중 세이브 & 로드 구현하고 테스트하는 와중 에러메세지 때문에 몇일 고민하다가 도저히 안되겠어서 글 남깁니다어딘가 오타가있는건 아닌지 꼼꼼히 확인해봤는데 제눈엔 도저히 찾질 못하겠습니다 ㅜㅜ우선 에러메세지는 다음과 같습니다세이브 테스트 오브젝트에 스크립트도 잘 부착하였구요스크립터블 오브젝트도 강의와 똑같이 만들고 부착하였습니다어느 스크립트가 문제인지 몰라 Quest, QuestSystem, QuestSystemSaveTest세가지 스크립트 작성하여 등록하겠습니다Quest.csusing System.Collections; using System.Collections.Generic; using UnityEngine; using System.Linq; using System.Diagnostics; using Debug = UnityEngine.Debug; public enum QuestState { Inactive, Running, Complete, Cancel, WaitingForCompletion // 퀘스트 완료시 자동으로 완료되는게 아닌, 사용자가 퀘스트 완료를 눌러야 완료되는 상태 } [CreateAssetMenu(menuName = "Quest/Quest", fileName ="Quest_")] public class Quest : ScriptableObject { #region Event public delegate void TaskSuccessChangeHandler(Quest quest, Task task, int currentSuccess, int prevSuccess); public delegate void CompleteHandler(Quest quest); public delegate void CancelHandler(Quest quest); public delegate void NewTaskGroupHandler(Quest quest, TaskGroup currentTaskGroup, TaskGroup prevTaskGroup); #endregion [SerializeField] private Category category; [SerializeField] private Sprite icon; [Header("Text")] [SerializeField] private string codeName; [SerializeField] private string displayName; [SerializeField, TextArea] private string description; [Header("Task")] [SerializeField] private TaskGroup[] taskGroups; [Header("Reward")] [SerializeField] private Reward[] rewards; [Header("Condition")] [SerializeField] private Condition[] acceptionConditions; [SerializeField] private Condition[] cancelConditions; [Header("Option")] [SerializeField] private bool useAutoComplete; [SerializeField] private bool isCancelable; // 캔슬 불가능한 퀘스트를 위한 변수 [SerializeField] private bool isSaveable; private int currentTaskGroupIndex; #region 프로퍼티들 public Category Category => category; public Sprite Icon => icon; public string CodeName => codeName; public string DisplayName => displayName; public string Description => description; public QuestState State { get; private set; } public TaskGroup CurrentTaskGroup => taskGroups[currentTaskGroupIndex]; public IReadOnlyList<TaskGroup> TaskGroups => taskGroups; public IReadOnlyList<Reward> Rewards => rewards; public bool IsRegistered => State != QuestState.Inactive; public bool IsCompletable => State == QuestState.WaitingForCompletion; public bool IsComplete => State == QuestState.Complete; public bool IsCancel => State == QuestState.Cancel; public virtual bool IsCancelable => isCancelable && cancelConditions.All(x=>x.IsPass(this)); public bool IsAcceptable => acceptionConditions.All(x => x.IsPass(this)); public virtual bool IsSaveable => isSaveable; #endregion public event TaskSuccessChangeHandler onTaskSuccessChanged; public event CompleteHandler onCompleted; public event CancelHandler onCanceled; public event NewTaskGroupHandler onNewTaskGroup; // Awake 역할의 함수로 Quest가 System에 등록되면 실행될 함수 public void OnRegister() { // 퀘스트를 중복 등록했을경우 에러 발생 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 void ReceiveReport(string category, object target, int successCount) { Debug.Assert(IsRegistered, "This quest has already been registered."); Debug.Assert(!IsCancel, "this quest has been canceled"); if (IsComplete) return; CurrentTaskGroup.ReceiveReport(category, target, successCount); if (CurrentTaskGroup.IsAllTaskComplete) { if (currentTaskGroupIndex + 1 == taskGroups.Length) // 다음 taskGroup이 없다면 { 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); onTaskSuccessChanged = 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); } public Quest Clone() { var clone = Instantiate(this); clone.taskGroups = taskGroups.Select(x => new TaskGroup(x)).ToArray(); return clone; } public QuestSaveData ToSaveData() { return new QuestSaveData { codeName = codeName, state = State, taskGroupIndex = currentTaskGroupIndex, taskSuccessCounts = CurrentTaskGroup.Tasks.Select(x => x.CurrentSuccess).ToArray() }; } public void LoadFrom(QuestSaveData saveData) { State = saveData.state; currentTaskGroupIndex = saveData.taskGroupIndex; for (int i = 0; i < currentTaskGroupIndex; i++) { var taskGroup = taskGroups[i]; taskGroup.Start(); taskGroup.Complete(); } for (int i = 0; i < saveData.taskSuccessCounts.Length; i++) { CurrentTaskGroup.Start(); CurrentTaskGroup.Tasks[i].CurrentSuccess = saveData.taskSuccessCounts[i]; } } private void OnSuccessChanged(Task task, int currentSuccess, int prevSuccess) => onTaskSuccessChanged?.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 canceled"); Debug.Assert(!IsComplete, "this quest has already been completed"); } } QuestSystem.csusing System.Collections; using System.Collections.Generic; using UnityEngine; using System.Linq; using Newtonsoft.Json.Linq; public class QuestSystem : MonoBehaviour { #region Save Path private const string kSaveRootPath = "questSystem"; private const string kActiveQuestsSavePath = "activeQuests"; private const string kCompletedQuestsSavePath = "completedQuests"; private const string kActiveAchievementsSavePath = "activeAchievements"; private const string kCompletedAchievementsSavePath = "completedAchievements"; #endregion #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 List<Quest> activeQuests = new List<Quest>(); private List<Quest> completedQuests = new List<Quest>(); private List<Quest> activeAchievements = new List<Quest>(); private List<Quest> completedAchievements = new List<Quest>(); private QuestDatabase questDatabase; private QuestDatabase achievementDatabase; public event QuestRegisteredHandler onQuestRegistered; public event QuestCompletedHandler onQuestCompleted; public event QuestCanceledHandler onQuestCanceled; public event QuestRegisteredHandler onAchievementRegistered; public event QuestCompletedHandler onAchievementCompleted; public IReadOnlyList<Quest> ActiveQuests => activeQuests; public IReadOnlyList<Quest> CompletedQuests => completedQuests; public IReadOnlyList<Quest> ActiveAchievements => activeAchievements; public IReadOnlyList<Quest> CompletedAchievements => completedAchievements; private void Awake() { questDatabase = Resources.Load<QuestDatabase>("QuestDatabase"); achievementDatabase = Resources.Load<QuestDatabase>("AchievementDatabase"); if(!Load()) // 저장된 데이터가 없다면 업적에 등록 { foreach (var achievement in achievementDatabase.Quests) Register(achievement); } } private void OnApplicationQuit() { isApplicationQuitting = true; Save(); } 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; } // 내부용 private void ReceiveReport(List<Quest> quests, string category, object target, int successCount) { foreach (var quest in quests.ToArray()) quest.ReceiveReport(category, target, successCount); } //외부용 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 void CompleteWaitingQuests() { foreach (var quest in activeQuests.ToList()) { if (quest.IsCompletable) quest.Complete(); } } public bool ContainsInActiveQuests(Quest quest) => activeQuests.Any(x => x.CodeName == quest.CodeName); public bool ContainsInCompletedQuests(Quest quest) => completedQuests.Any(x => x.CodeName == quest.CodeName); public bool ContainsInActiveAchievements(Quest quest) => activeAchievements.Any(x => x.CodeName == quest.CodeName); public bool ContainsInCompletedAchievements(Quest quest) => completedAchievements.Any(x => x.CodeName == quest.CodeName); private void Save() { var root = new JObject(); root.Add(kActiveQuestsSavePath, CreateSaveDatas(activeQuests)); root.Add(kCompletedQuestsSavePath, CreateSaveDatas(completedQuests)); root.Add(kActiveAchievementsSavePath, CreateSaveDatas(activeAchievements)); root.Add(kCompletedAchievementsSavePath, CreateSaveDatas(completedAchievements)); PlayerPrefs.SetString(kSaveRootPath, root.ToString()); PlayerPrefs.Save(); } private bool Load() { if (PlayerPrefs.HasKey(kSaveRootPath)) { var root = JObject.Parse(PlayerPrefs.GetString(kSaveRootPath)); LoadSaveDatas(root[kActiveQuestsSavePath], questDatabase, LoadActiveQuest); LoadSaveDatas(root[kCompletedQuestsSavePath], questDatabase, LoadCompletedQuest); LoadSaveDatas(root[kActiveAchievementsSavePath], achievementDatabase, LoadActiveQuest); LoadSaveDatas(root[kCompletedAchievementsSavePath], achievementDatabase, LoadCompletedQuest); return true; } else return false; } private JArray CreateSaveDatas(IReadOnlyList<Quest> quests) { var saveDatas = new JArray(); foreach (var quest in quests) { if(quest.IsSaveable) saveDatas.Add(JObject.FromObject(quest.ToSaveData())); // SaveData를 Json형태로 변환하여 JsonArray에 넣어줌 } return saveDatas; } private void LoadSaveDatas(JToken datasToken, QuestDatabase database, System.Action<QuestSaveData, Quest> OnSuccess) { var datas = datasToken as JArray; foreach (var data in datas) { var saveData = data.ToObject<QuestSaveData>(); var quest = database.FindQuestBy(saveData.codeName); OnSuccess.Invoke(saveData, quest); } } private void LoadActiveQuest(QuestSaveData saveData, Quest quest) { var newQuest = Register(quest); newQuest.LoadFrom(saveData); } private void LoadCompletedQuest(QuestSaveData saveData, Quest quest) { var newQuest = quest.Clone(); newQuest.LoadFrom(saveData); if (newQuest is Achievement) completedAchievements.Add(newQuest); else completedQuests.Add(newQuest); } #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); completedAchievements.Add(achievement); onAchievementCompleted?.Invoke(achievement); } #endregion } QuestSystemSaveTest.csusing System.Collections; using System.Collections.Generic; using UnityEngine; public class QuestSystemSaveTest : MonoBehaviour { [SerializeField] private Quest quest; [SerializeField] private Category category; [SerializeField] private TaskTarget target; private void Start() { var questSystem = QuestSystem.Instance; if(questSystem.ActiveQuests.Count == 0) { Debug.Log("Register"); var newQuest = questSystem.Register(quest); } else { questSystem.onQuestCompleted += (quest) => { Debug.Log("Complete"); PlayerPrefs.DeleteAll(); PlayerPrefs.Save(); }; } } private void Update() { if (Input.GetKeyDown(KeyCode.Space)) QuestSystem.Instance.ReceiveReport(category, target, 1); } } 이상입니다..
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
퀘스트를 만들다보니 궁금한점이 생겨 질문합니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 좋은 강의 감사합니다.퀘스트를 제가 생각한 방식에 맞게 만들다보니 궁금한 점이 생겨서 질문드립니다.만약에 예를 들어 몬스터 5마리를 잡고 해당 몬스터가 드랍하는 아이템을 얻어야한다. 라는 퀘스트가 있다면 해당 몬스터에 두개의 QuestReport를 달아줘야 하는건가요?
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
Quest 스크립트에서 Complete
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. Quest 스크립트의 Complete에서 질문사항이 있습니다.Complete함수에서 맨 처음부터 CheakIsRunning을 실행 해준다면 무조건 IsComplete는 false이기 때문에 오류가 실행되지 않나요?? (따로 디버그를 찍어보았지만 두번 실행되는건 아닙니다.)테스트 해본결과 계속 오류가 실행되어서 CheakIsRunning을 맨 밑으로 내려줬더니 정상 실행이 되는데 이렇게 해도 문제가 없나요? 변경 전변경 후
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
새로운 강의 일정이 궁금합니다
이번 강의가 너무 도움이 되고 좋았어서 다음 강의가 많이 기대가 되는데 언제쯤 수강할 수 있을까요?
- 해결됨[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
퀘스트 시스템 관련 NullReferenceException 오류에 대해 질문드립니다.
유익한 강의 올려주셔서 감사합니다 :) 유니티 관련 모듈화 프로그래밍 강의 중 가장 퀄리티가 좋아 매우 만족하며 수강하고있습니다 :)질문드리고 싶은 부분은 QuestSystem 기능 입니다. QustSystem.cs 의 instance 에서 NullReferenceException 오류가 발생하고 있습니다.(퀘스트 Save & Load (with JSON) 구현 부분까지 수강, 실습 다 완료한 상태라 관련 스크립트까지 오류목록에 떳지만, Save & Load 수강 전에도 NullReferenceException오류가 있었습니다!) 아래캡처는 오류 부분 더블클릭시 이동되어진 코드부분입니다. (QuestSystem.cs) 의심되는 코드부분 몇개 더 첨부해봅니다..instance에 Null이 들어가서 그러는걸까요..? 원본 코드랑 비교도 해보고 이것저것 찾아봣지만 해결이 안되서 3일째 되는날 주섬주섬 질문해봅니다.😥
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
QuestTrackerView.cs 의 foreach 부분을 지울 경우, QuestTrackerUI 가 업데이트 되지 않는 이유는 무엇인가요?
먼저, 좋은 강의 정말 감사드립니다. 모듈화를 처음 접해보아서 조금 어렵긴 하지만, 큰 도움이 되는 강의라고 생각합니다. 강의를 듣고, 다시 코드를 이해하던 중 QuestTrackerView.cs 에서 이벤트에 등록하는 부분이 존재할 경우, foreach 부분이 없어도 자동으로 QuestSystem.cs 에서 onQuestResgistered.Invoke() 에서 등록이 될 것이라고 생각해서 foreach 부분을 주석처리 해도 된다고 생각했는데, 실제로 주석처리를 할 경우 QuestTrackerUI 가 업데이트 되지 않아서 코드 동작 방식이 궁금하여 질문드립니다. (그림 1: 강의를 따라한 경우 정상적으로 작동하는 모습)제가 이해한 내용은 다음과 같습니다. 먼저 QuestTrackerView.cs 에서 QuestSystem.Instance.onQuestRegistered += CreateQuestTracker;를 통해 이벤트에 등록합니다. 그 후 QuestSystem.cs 의 onQuestRegistered?.Invoke(newQuest);부분에서 QuestGiver 에 의해 받은 퀘스트가 등록되므로, QuestTrackerView.cs 의 CreateQuestTracker 가 실행될 것이라고 생각했습니다. 즉, foreach (var quest in QuestSystem.Instance.ActiveQuests) { CreateQuestTracker(quest); }부분은 필요 없을 것이라고 생각했습니다. 그러나 이 부분을 주석처리하고 실행하니 (즉 아래 코드와 같이 돌리니) UI 가 없데이트 되지 않았습니다. //QuestTrackerView.cs private void Start() { QuestSystem.Instance.onQuestRegistered += CreateQuestTracker; //foreach (var quest in QuestSystem.Instance.ActiveQuests) //{ // CreateQuestTracker(quest); //} }(그림 2 - 주석처리를 하고 게임을 실행한 경우 QuestTrackerUI 가 생기지 않는 모습 )QuestSystem.cs 의 Register 메소드도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(); Debug.Log($"is on quest registered true? {onQuestRegistered == null}"); onQuestRegistered?.Invoke(newQuest); } return newQuest; }와 같이, activeQuest.Add(newQuest) 를 통해 activeQuest를 업데이트하고, onQuestRegistered?.Invoke(newQuest)를 합니다. 그렇다면 왜 똑같은 code block 에서 업데이트 되는 activeQuest 를 foreach 로 돌면서 UI 업데이트를 하는 것은 제대로 동작하는데, onQuestRegisterd?.Invoke(newQuest) 에서 UI 업데이트를 하는 것은 정상적으로 작동하지 않는 것인가요? 감사합니다.
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
퀘스트 시스템에 관련된 질문입니다.
선생님. 강의 잘 듣고 있습니다. 강의를 듣던 중에 궁금증이 생겨 질문 드립니다.만약 특정 시간 이후에 리셋 되는 일일,주간, 월간 퀘스트 등의 반복 퀘스트 와 같은 경우에는기존에 작성된 Task , Quest 클래스 에서 변수들을 모두 protected 로 변경하여 상속을 통해 새로운 클래스에 추가하는 것이 좋을까요? 아니면 기존에 작성된 Task , Quest 클래스에서 직접 코드를 수정하여 추가하는 것이 좋을까요?
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
새로운 강의 일정 질문입니다.
안녕하세요 이전에 드렸던 질문이긴 하지만, 새로운 강의(스킬 시스템)은 10월 경에 정확히 수강 할 수 있는지 알 수 있나요?
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
퀘스트 시스템 작성 이후 테스트 과정에서 오류가 납니다.
NullReferenceException: Object reference not set to an instance of an objectQuestSystemTest.Start () (at Assets/WJ/Ouest/QuestTest/QuestSystemTest.cs:18)퀘스트 시스템 작성 후 퀘스트 시스템 테스트 스크립트를 만들어 실행했는데 위와 같은 오류가 나오면서 제대로 테스트할 수 없습니다.questSystem.onQuestRegistered += (quest) => { print($"New Quest:{quest.CodeName} Registered"); print($"Active Quests Count:{questSystem.ActiveQuests.Count}"); };18번 라인은 다음과 같은데 어디서 문제가 생긴걸까요?더하여 혹시 가능하다면 델리게이트, 이벤트 사용법과 람다식응용에 대한 설명도 들을 수 있을지 질문드리고싶습니다. 감사합니다.
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
갑자기 OutOfRange가 떠요ㅠㅠ
왜이럴까요..
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
Json 질문입니다
선생님 조금 불필요한 질문일수도 있지만ㅠ 현업에서 JObject, JArray를 활용하는 Newtonsoft.Json.Linq와 JsonUtility.ToJson, FromJson<T> + Unity JsonUtility 중에서 어떤 것을 더 많이 활용하나요? 아니면 서로 활용하는 용도가 다를 수 있는건가요?
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
Conditions Linq 질문입니다.
선생님! Condition에서 IsQuestComplete의 IsPass를 재정의하기전에 Quest 스크립트의 public bool IsAcceptable => acceptionConditions.All(x => x.IsPass(this)) 함수에서 아직 재정의한 함수가 없음에도 리턴 값이 true가 나오는 이유에 대해 궁금합니다. Any로 바꿨을 땐 false리턴하는 것을 보고 헷려서 질문을 드리게 되었습니다 ㅠㅠ
- 미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
Quest Tracker 질문입니다.
선생님 영상 12분까지 따라했는데 Kill Normal Gem Slim5에 대한 Quest Tracker UI가 그대로 남아있습니다. 게임 Points는 30점으로 제대로 저장이 되어있고, 게임 시작시 Quest Giver로 인해 Active Quests로 2개의 퀘스트가 Add 되어서 UI로 다시 출력이 되는데 원인을 잘 모르겠습니다. (Completed Quest로 Kill Normal Gem Slim5이 Add 된 것은 확인했습니다)