131 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			131 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|   | using System.Collections; | |||
|  | using System.Collections.Generic; | |||
|  | using UnityEngine; | |||
|  | using UnityEngine.UI; | |||
|  | using RPGCreationKit; | |||
|  | 
 | |||
|  | namespace RPGCreationKit | |||
|  | { | |||
|  |     /// <summary> | |||
|  |     /// Manages the whole logic behind the Compass | |||
|  |     /// </summary> | |||
|  |     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(); | |||
|  |         } | |||
|  | 
 | |||
|  |         /// <summary> | |||
|  |         /// Calculate and rotate the Compass to north | |||
|  |         /// </summary> | |||
|  |         private void CalculateNorth() | |||
|  |         { | |||
|  |             northDir.z = cameraT.eulerAngles.y; | |||
|  |             transform.localEulerAngles = northDir; | |||
|  |             northPointer.eulerAngles = northDir; | |||
|  |         } | |||
|  | 
 | |||
|  |         /// <summary> | |||
|  |         /// Calculate the direction of the object (from the UI pointer to the world) and rotate the pointer toward it | |||
|  |         /// </summary> | |||
|  |         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; | |||
|  |         } | |||
|  | 
 | |||
|  |         /// <summary> | |||
|  |         /// Calculate the direction of the object (from the UI pointer to the world) and rotate the pointer toward it | |||
|  |         /// </summary> | |||
|  |         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); | |||
|  |         } | |||
|  | 
 | |||
|  |         /// <summary> | |||
|  |         /// Called when a Quest or a QuestObjective updates. | |||
|  |         /// </summary> | |||
|  |         public void OnQuestUpdate() | |||
|  |         { | |||
|  |             currentObjective = null; | |||
|  |             CheckActiveObjectives(); | |||
|  |         } | |||
|  | 
 | |||
|  |         /// <summary> | |||
|  |         /// Called when a new Quest Objective is active | |||
|  |         /// </summary> | |||
|  |         /// <param name="t">The transform to point to</param> | |||
|  |         public void ChangeQuestObjective(Transform t) | |||
|  |         { | |||
|  |             currentObjective = t; | |||
|  |             CheckActiveObjectives(); | |||
|  |         } | |||
|  | 
 | |||
|  |         /// <summary> | |||
|  |         /// Enable/Disable the Red Pointer when it is the case. | |||
|  |         /// </summary> | |||
|  |         public void CheckActiveObjectives() | |||
|  |         { | |||
|  |             // Disable the Red Pointer if no marked quest objective is active | |||
|  |             curObjPointer.gameObject.SetActive(currentObjective != null ? true : false); | |||
|  |         } | |||
|  |     } | |||
|  | } |