using System; using UnityEngine; using UnityEngine.Serialization; namespace EnergyBarToolkit { [ExecuteInEditMode] public class EnergyBarFollowObject : MonoBehaviour { public GameObject followObject; public Vector3 offset; [FormerlySerializedAs("barRotation")] public Vector3 rotation; public ObjectFinder worldCamera = new ObjectFinder(typeof(Camera), "/Main Camera", "MainCamera", ObjectFinder.Method.ByTag); public bool lookAtCamera = true; public bool updateLookupReference; [SerializeField] [HideInInspector] private Camera renderCamera; private Camera cameraReference; private Canvas canvas; public bool IsPossiblyVisible() { if (followObject != null && cameraReference != null) { Vector3 lhs = followObject.transform.position - cameraReference.transform.position; float num = Vector3.Dot(lhs, cameraReference.transform.forward); return num >= 0f; } Debug.LogError("Cannot determine visibility of this bar.", this); return false; } private void OnEnable() { } private void Start() { } private void Update() { if (!(followObject != null)) { return; } if (!Application.isPlaying || canvas == null) { canvas = GetComponentInParent(); if (canvas == null) { Debug.LogError("This object should be placed under a canvas", this); } } if (!Application.isPlaying || cameraReference == null || updateLookupReference) { cameraReference = worldCamera.Lookup(this); } UpdateFollowObject(); bool flag = IsPossiblyVisible(); EnergyBarBase component = GetComponent(); component.opacity = (flag ? 1 : 0); if (cameraReference != null && canvas != null) { if (canvas.renderMode == RenderMode.WorldSpace && lookAtCamera) { component.transform.rotation = Quaternion.LookRotation(component.transform.position - cameraReference.transform.position); } else { component.transform.rotation = Quaternion.Euler(rotation); } } } private void UpdateFollowObject() { switch (canvas.renderMode) { case RenderMode.ScreenSpaceOverlay: UpdateFollowObjectScreenSpaceOverlay(); break; case RenderMode.ScreenSpaceCamera: UpdateFollowObjectScreenSpaceCamera(); break; case RenderMode.WorldSpace: UpdateFollowObjectWorldSpace(); break; default: throw new ArgumentOutOfRangeException(); } } private void UpdateFollowObjectScreenSpaceOverlay() { UpdateScreenSpace(); } private void UpdateFollowObjectScreenSpaceCamera() { UpdateScreenSpace(); } private void UpdateScreenSpace() { if (cameraReference == null) { Debug.LogError("Render Camera must be set for the follow script to work.", this); return; } Rect pixelRect = canvas.pixelRect; float x = pixelRect.width / 2f; float y = pixelRect.height / 2f; Vector3 vector = cameraReference.WorldToScreenPoint(followObject.transform.position); Vector3 vector2 = vector + offset - new Vector3(x, y); MadTransform.SetLocalPosition(localPosition: new Vector3(vector2.x / canvas.scaleFactor, vector2.y / canvas.scaleFactor), transform: base.transform); } private void UpdateFollowObjectWorldSpace() { MadTransform.SetPosition(base.transform, followObject.transform.position + offset); } } }