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 Assets/_ADDONS/MagicArsenal/Effects/Prefabs/Beams/Setup")] [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().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(); _line.useWorldSpace = true; _line.positionCount = 2; _beamStart = beamStartPrefab ? Instantiate(beamStartPrefab, _beam.transform) : null; _beamEnd = beamEndPrefab ? Instantiate(beamEndPrefab, _beam.transform) : null; } } }