작성
·
356
0
안녕하세요. 강의 완강 후 해결되지 않은 점이 있어 올립니다..!
퀘스트를 등록하고 업데이트나 데이터를 저장하고 가져오는 등의 기능들은 정상적으로 작동하나 게임 시작 시
Quest Target Marker 게임 오브젝트가 비활성화되어 작동하지 않습니다..!!
강의를 여러 번 돌려봤지만 어디서 잘못된 건지 찾기가 힘들어서요..! 다시 살펴보아야 할 부분이 어딜까요..?ㅜㅠ
답변 1
0
수강해주셔서 감사합니다.
QuestTargetMarker의 활성화, 비활성화를 담당하는건 QuestTargetMarker Script의 UpdateRunningTargetTaskCount 함수인데요, 이 함수가 작성한 의도대로 작동하고 있는지부터 확인하셔야합니다. 작성하신 QuestTargetMarker Code 전체를 올려주시면 빠르게 문제를 확인해드리겠습니다.
확인해보니 똑같이 잘 따라오셔서 해당 Script에서 문제가 발견되지 않았습니다. 이렇게되면 좀 복잡해지는데요,
1. Quest나 Task의 Event가 제대로 호출이 되지 않고 있거나,
2. currentTaskGroup.FindTaskByTarget(target); 이 Code가 제대로 작동하지 않고 있거나,
3. Task의 State가 제대로 Update되지 않고 있을 수 있습니다.
그래서 전체 Code를 확인해봐야 문제를 잡을 수 있을 것 같습니다. Script를 압축해서 muramasa666@naver.com으로 보내주시면 확인해드리겠습니다.
보내주신 파일을 통해 문제를 확인했습니다.
Task Script의 129번 줄 ContainsTarget 함수의 내용을 아래와 같이 수정해주시면 됩니다.
targets.Any(x => x.Equals(target));
=> targets.Any(x => x.IsEquals(target));
target 비교를 만든 TaskTarget의 IsEquals 함수가 아닌 C# 기본 Equals 함수로 비교하여 생기는 문제였습니다.
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;
}
}