135 lines
3.3 KiB
C#
135 lines
3.3 KiB
C#
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<Canvas>();
|
|
if (canvas == null)
|
|
{
|
|
Debug.LogError("This object should be placed under a canvas", this);
|
|
}
|
|
}
|
|
if (!Application.isPlaying || cameraReference == null || updateLookupReference)
|
|
{
|
|
cameraReference = worldCamera.Lookup<Camera>(this);
|
|
}
|
|
UpdateFollowObject();
|
|
bool flag = IsPossiblyVisible();
|
|
EnergyBarBase component = GetComponent<EnergyBarBase>();
|
|
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);
|
|
}
|
|
}
|
|
}
|