인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

강아지호빵찐빵님의 프로필 이미지
강아지호빵찐빵

작성한 질문수

[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템

Task 목표 표시를 위한 Quest Target Marker 제작

게임 시작 시 Quest Target Marker 오브젝트 비활성화

작성

·

356

0

안녕하세요. 강의 완강 후 해결되지 않은 점이 있어 올립니다..!

퀘스트를 등록하고 업데이트나 데이터를 저장하고 가져오는 등의 기능들은 정상적으로 작동하나 게임 시작 시

Quest Target Marker 게임 오브젝트가 비활성화되어 작동하지 않습니다..!!

강의를 여러 번 돌려봤지만 어디서 잘못된 건지 찾기가 힘들어서요..! 다시 살펴보아야 할 부분이 어딜까요..?ㅜㅠ

 

답변 1

0

Developer G님의 프로필 이미지
Developer G
지식공유자

수강해주셔서 감사합니다.

QuestTargetMarker의 활성화, 비활성화를 담당하는건 QuestTargetMarker Script의 UpdateRunningTargetTaskCount 함수인데요, 이 함수가 작성한 의도대로 작동하고 있는지부터 확인하셔야합니다. 작성하신 QuestTargetMarker Code 전체를 올려주시면 빠르게 문제를 확인해드리겠습니다.

 

using System.Collections;

using System.Collections.Generic;

using System.Linq;

using UnityEngine;

public class QuestTargetMarker : MonoBehaviour

{

//해당 Target을 가진 Task을 찾아온다

[SerializeField]

private TaskTarget target;

[SerializeField]

private MarkerMaterialData[] markerMaterialDatas;

//Marker를 표시해야 할 Quest와 Task를 저장

private Dictionary<Quest, Task> targetTasksByQuest = new Dictionary<Quest, Task>();

private Transform cameraTransform;

private Renderer renderer;

private int currentRunningTargetTaskCount;

private void Awake()

{

cameraTransform = Camera.main.transform;

renderer = GetComponent<Renderer>();

}

private void Start()

{

gameObject.SetActive(false);

QuestSystem.Instance.onQuestRegistered += TryAddTargetQuest;

foreach (var quest in QuestSystem.Instance.ActiveQuests)

TryAddTargetQuest(quest);

}

private void Update()

{

var rotation = Quaternion.LookRotation((cameraTransform.position - transform.position).normalized);

transform.rotation = Quaternion.Euler(0f, rotation.eulerAngles.y + 180f, 0);

}

//이벤트 해제

private void OnDestroy()

{

QuestSystem.Instance.onQuestRegistered -= TryAddTargetQuest;

foreach ((Quest quest, Task task) in targetTasksByQuest)

{

quest.onNewTaskGroup -= UpdateTargetTask;

quest.onCompleted -= RemoveTargetQuest;

task.onStateChanged -= UpdateRunningTargetTaskCount;

}

}

private void TryAddTargetQuest(Quest quest)

{

if(target != null && quest.ContainsTarget(target))

{

quest.onNewTaskGroup += UpdateTargetTask;

quest.onCompleted += RemoveTargetQuest;

UpdateTargetTask(quest, quest.CurrentTaskGroup);

}

}

private void UpdateTargetTask(Quest quest, TaskGroup currentTaskGroup, TaskGroup prevTaskGroup = null)

{

targetTasksByQuest.Remove(quest);

var task = currentTaskGroup.FindTaskByTarget(target);

if(task != null)

{

targetTasksByQuest[quest] = task;

task.onStateChanged += UpdateRunningTargetTaskCount;

UpdateRunningTargetTaskCount(task, task.State);

}

}

//Quest 완료시에 Target에서 지워주는 함수

private void RemoveTargetQuest(Quest quest) => targetTasksByQuest.Remove(quest);

private void UpdateRunningTargetTaskCount(Task task, TaskState currentState, TaskState prevState = TaskState.Inactive)

{

if (currentState == TaskState.Running)

{

renderer.material = markerMaterialDatas.First(x => x.category == task.Category).markerMaterial;

currentRunningTargetTaskCount++;

}

else

currentRunningTargetTaskCount--;

gameObject.SetActive(currentRunningTargetTaskCount != 0);

}

[System.Serializable]

private struct MarkerMaterialData

{

public Category category;

public Material markerMaterial;

}

}

 

Developer G님의 프로필 이미지
Developer G
지식공유자

확인해보니 똑같이 잘 따라오셔서 해당 Script에서 문제가 발견되지 않았습니다. 이렇게되면 좀 복잡해지는데요,

1. Quest나 Task의 Event가 제대로 호출이 되지 않고 있거나,
2. currentTaskGroup.FindTaskByTarget(target); 이 Code가 제대로 작동하지 않고 있거나,
3. Task의 State가 제대로 Update되지 않고 있을 수 있습니다.

그래서 전체 Code를 확인해봐야 문제를 잡을 수 있을 것 같습니다. Script를 압축해서 muramasa666@naver.com으로 보내주시면 확인해드리겠습니다.

보냈습니다 :P

Developer G님의 프로필 이미지
Developer G
지식공유자

보내주신 파일을 통해 문제를 확인했습니다.

Task Script의 129번 줄 ContainsTarget 함수의 내용을 아래와 같이 수정해주시면 됩니다.
targets.Any(x => x.Equals(target));
=> targets.Any(x => x.IsEquals(target));
target 비교를 만든 TaskTarget의 IsEquals 함수가 아닌 C# 기본 Equals 함수로 비교하여 생기는 문제였습니다.

확인했습니다. 이런 단순한 실수를..ㅠㅠㅠㅠㅠ 감사합니다!

강아지호빵찐빵님의 프로필 이미지
강아지호빵찐빵

작성한 질문수

질문하기