Files
jelito/Assets/jelycho/Code/Beacons/BeaconGraphics.cs
2025-08-04 09:33:19 +02:00

128 lines
4.9 KiB
C#

using System;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Events;
namespace RebootReality.jelycho.Beacons {
public class BeaconGraphics : MonoBehaviour {
[SerializeField] BeaconElement[] m_BeaconElements;
[Range(0.0f, 1.0f)] public float growAmount = 0.5f;
[SerializeField] public float growSpeed = 0.5f;
float m_CurrentGrowAmount = 0.0f;
public UnityEvent onGrowCalled = new UnityEvent();
void Update() {
if (m_CurrentGrowAmount >= 1.0f) {
foreach (BeaconElement beaconElement in m_BeaconElements) {
if (!beaconElement.usePulsing) {
continue;
}
float t = (Mathf.Sin(Time.time * beaconElement.pulsingSpeed) + 1.0f) * 0.5f;
float scale = Mathf.Lerp(beaconElement.pulsingMinScale,
beaconElement.pulsingMaxScale,
t);
beaconElement.transform.localScale = Vector3.one * scale;
}
}
if (Mathf.Approximately(m_CurrentGrowAmount, growAmount)) {
return;
}
m_CurrentGrowAmount = Mathf.MoveTowards(m_CurrentGrowAmount,
growAmount,
growSpeed * Time.deltaTime);
UpdateElements(m_CurrentGrowAmount);
}
void UpdateElements(float amount) {
foreach (BeaconElement element in m_BeaconElements) {
if (element.useLocalPosition && element.transform is not null) {
float localPositionT = math.remap(element.startLocalPositionAt,
element.endLocalPositionAt,
0.0f,
1.0f,
amount);
Vector3 localPosition =
Vector3.Lerp(element.minLocalPosition, element.maxLocalPosition, Mathf.Clamp01(localPositionT));
element.transform.localPosition = localPosition;
}
if (element.useScale && element.transform is not null) {
float scaleT = math.remap(element.startScaleAt,
element.endScaleAt,
0.0f,
1.0f,
amount);
Vector3 scale = Vector3.Lerp(element.minScale, element.maxScale, Mathf.Clamp01(scaleT));
element.transform.localScale = scale;
}
if (element.useCutoff && element.meshRenderer is not null) {
float cutoffT = math.remap(element.startCutoffAt,
element.endCutoffAt,
0.0f,
1.0f,
amount);
float cutoff = Mathf.Lerp(0.0f, 1.0f, Mathf.Clamp01(cutoffT));
if (element.flipCutoffDirection) {
cutoff = 1.0f - cutoff;
}
Material material = element.meshRenderer.materials[element.materialIndex];
material.SetFloat("_Cutoff", cutoff);
}
}
}
public void Grow() {
m_CurrentGrowAmount = 0.0f;
UpdateElements(m_CurrentGrowAmount);
growAmount = 1.0f;
onGrowCalled?.Invoke();
}
[Serializable]
struct BeaconElement {
public Transform transform;
public MeshRenderer meshRenderer;
[Header("Local Position(Transform)")]
public bool useLocalPosition;
public Vector3 minLocalPosition;
public Vector3 maxLocalPosition;
public float startLocalPositionAt;
public float endLocalPositionAt;
[Header("Scale (Transform)")]
public bool useScale;
public Vector3 minScale;
public Vector3 maxScale;
public float startScaleAt;
public float endScaleAt;
[Header("Mesh Cutoff (MeshRenderer)")]
public bool useCutoff;
public bool flipCutoffDirection;
public float startCutoffAt;
public float endCutoffAt;
public int materialIndex;
[Header("Pulsing (Transform)")]
public bool usePulsing;
public float pulsingSpeed;
public float pulsingMinScale;
public float pulsingMaxScale;
}
}
}