using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using RPGCreationKit; namespace RPGCreationKit { /// /// Manages the whole logic behind the Compass /// public class Compass : MonoBehaviour { #region Singleton public static Compass instance; private void Awake() { if (instance == null) instance = this; else { Debug.LogError("Anomaly detected with the Singleton Pattern of 'Compass', are you using multple Compass?"); Destroy(this); } } #endregion // Transform of the camera [SerializeField] private Transform cameraT; // References to the compass UI [SerializeField] private RectTransform northPointer; [SerializeField] private RectTransform curObjPointer; // The current objective to point private Transform currentObjective; private Vector3 lastKnownPos; // The north direction private Vector3 northDir; // currentObjective private Vector3 objDir; private float angle; private void Start() { // At the start we look if the compass pointer (red one) should be active or not CheckActiveObjectives(); } // Update is called once per frame private void Update() { // In each frame we calcualte and update the North and the Direction of the CurrentObjective CalculateNorth(); if (currentObjective != null) CalculateObjDir(); else CalculateObjDirLastPos(); } /// /// Calculate and rotate the Compass to north /// private void CalculateNorth() { northDir.z = cameraT.eulerAngles.y; transform.localEulerAngles = northDir; northPointer.eulerAngles = northDir; } /// /// Calculate the direction of the object (from the UI pointer to the world) and rotate the pointer toward it /// private void CalculateObjDir() { // Calculate the direction objDir = cameraT.InverseTransformDirection(currentObjective.position - cameraT.position); // Calculate the angle angle = Mathf.Atan2(-objDir.x, objDir.z) * Mathf.Rad2Deg; // Rotate the pointer curObjPointer.eulerAngles = new Vector3(0, 0, angle); lastKnownPos = currentObjective.position; } /// /// Calculate the direction of the object (from the UI pointer to the world) and rotate the pointer toward it /// private void CalculateObjDirLastPos() { // Calculate the direction objDir = cameraT.InverseTransformDirection(lastKnownPos - cameraT.position); // Calculate the angle angle = Mathf.Atan2(-objDir.x, objDir.z) * Mathf.Rad2Deg; // Rotate the pointer curObjPointer.eulerAngles = new Vector3(0, 0, angle); } /// /// Called when a Quest or a QuestObjective updates. /// public void OnQuestUpdate() { currentObjective = null; CheckActiveObjectives(); } /// /// Called when a new Quest Objective is active /// /// The transform to point to public void ChangeQuestObjective(Transform t) { currentObjective = t; CheckActiveObjectives(); } /// /// Enable/Disable the Red Pointer when it is the case. /// public void CheckActiveObjectives() { // Disable the Red Pointer if no marked quest objective is active curObjPointer.gameObject.SetActive(currentObjective != null ? true : false); } } }