Files
2026-07-09 21:33:33 +02:00

114 lines
4.1 KiB
C#

using Sirenix.OdinInspector;
using UnityEngine;
namespace VOID.Generic.Projectile.Drawers
{
public class BeamProjectileDrawer : MonoBehaviour
{
[Title("Positions")]
[SerializeField] private bool autoPositions;
[HideIf(nameof(autoPositions))] [SerializeField] [Required] private Transform from;
[HideIf(nameof(autoPositions))] [SerializeField] [Required] private Transform to;
[Title("Prefabs")]
[InfoBox("Those prefabs are from addon MagicArsenal located in <b>Assets/_ADDONS/MagicArsenal/Effects/Prefabs/Beams/Setup</b>")]
[SerializeField] [Required] private GameObject beamLineRendererPrefab;
[SerializeField] [Required] private GameObject beamStartPrefab;
[SerializeField] [Required] private GameObject beamEndPrefab;
[Title("Beam Options")]
[SerializeField] private float textureScrollSpeed = 5f;
[SerializeField] private float textureLengthScale = 5f;
[Title("Width Pulse Options")]
[SerializeField] private float startScale = 1.0f;
[SerializeField] private float endScale = 1.0f;
[SerializeField] private float pulseSpeed = 1.0f;
private GameObject _beamStart;
private GameObject _beamEnd;
private GameObject _beam;
private LineRenderer _line;
private float _lerpValue;
private bool _pulseExpanding;
public void Awake()
{
if (autoPositions)
{
GetComponent<ProjectileObject>().onStart.AddListener(SetPositions);
}
}
private void Start()
{
SpawnBeam();
}
private void SetPositions(ProjectileObject projectile)
{
from = projectile.caster.unitData.castPosition;
to = projectile.gameObject.transform;
}
private void FixedUpdate()
{
if (_beam)
{
var fromPosition = from.position;
var toPosition = to.position;
_line.SetPosition(0, fromPosition);
_line.SetPosition(1, toPosition);
_beamStart.transform.position = fromPosition;
_beamStart.transform.LookAt(toPosition);
_beamEnd.transform.position = toPosition;
_beamEnd.transform.LookAt(fromPosition);
var distance = Vector3.Distance(fromPosition, toPosition);
//This sets the scale of the texture so it doesn't look stretched
_line.material.mainTextureScale = new Vector2(distance / textureLengthScale, 1);
//This scrolls the texture along the beam if not set to 0
_line.material.mainTextureOffset -= new Vector2(Time.deltaTime * textureScrollSpeed, 0);
}
_lerpValue += (_pulseExpanding ? 1 : -1) * Time.deltaTime * pulseSpeed;
if (_lerpValue >= 1.0f)
{
_pulseExpanding = false;
_lerpValue = 1.0f;
}
else if (_lerpValue <= 0.0f)
{
_pulseExpanding = true;
_lerpValue = 0.0f;
}
var currentWidth = Mathf.Lerp(startScale, endScale, Mathf.Sin(_lerpValue * Mathf.PI));
_line.startWidth = currentWidth;
_line.endWidth = currentWidth;
}
private void SpawnBeam()
{
if (!beamLineRendererPrefab) return;
_beam = Instantiate(beamLineRendererPrefab);
_beam.transform.position = transform.position;
_beam.transform.parent = transform;
_beam.transform.rotation = transform.rotation;
_line = _beam.GetComponent<LineRenderer>();
_line.useWorldSpace = true;
_line.positionCount = 2;
_beamStart = beamStartPrefab ? Instantiate(beamStartPrefab, _beam.transform) : null;
_beamEnd = beamEndPrefab ? Instantiate(beamEndPrefab, _beam.transform) : null;
}
}
}