You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
RizzeProjectile/Assets/Scripts/Projectiles/Hitscan/InstantHitscanProjectile.cs

129 lines
3.5 KiB
C#

using UnityEngine;
namespace Projectiles
{
/// <summary>
/// Hitscan projectile with immediate effect and optional trail path.
/// </summary>
public class InstantHitscanProjectile : HitscanProjectile
{
// PRIVATE MEMBERS
[SerializeField]
private float _visibleTime = 2f;
[Header("Trail")]
[SerializeField]
private LineRenderer _trail;
[SerializeField]
private Gradient _fadeoutTrailGradient;
[SerializeField]
private float _fadeoutTrailWidthMultiplier = 1f;
private Gradient _startTrailGradient;
private float _startTrailWidthMultiplier;
private Gradient _trailGradient;
private float _time;
// HitscanProjectile INTERFACE
public override void Activate(ref HitscanData data)
{
base.Activate(ref data);
var startPosition = Context.BarrelTransforms[data.BarrelIndex].position;
transform.position = startPosition;
transform.rotation = Quaternion.LookRotation(data.FireDirection);
SpawnImpactVisual(data.ImpactPosition, data.ImpactNormal);
if (_trail != null)
{
_trail.SetPosition(0, startPosition);
_trail.SetPosition(1, (Vector3)data.ImpactPosition != Vector3.zero ? data.ImpactPosition : startPosition + (Vector3)data.FireDirection * _maxDistance);
}
_time = 0f;
}
public override void Render(ref HitscanData data, ref HitscanData fromData, float alpha)
{
base.Render(ref data, ref fromData, alpha);
_time += Time.deltaTime;
IsFinished = _time >= _visibleTime;
if (_trail != null)
{
float progress = _time / _visibleTime;
_trail.colorGradient = LerpGradient(_startTrailGradient, _fadeoutTrailGradient, _trailGradient, progress);
_trail.widthMultiplier = Mathf.Lerp(_startTrailWidthMultiplier, _fadeoutTrailWidthMultiplier, progress);
}
}
// MONOBEHAVIOUR
protected override void Awake()
{
base.Awake();
if (_trail != null)
{
_startTrailGradient = _trail.colorGradient;
_startTrailWidthMultiplier = _trail.widthMultiplier;
_trailGradient = new Gradient();
_trailGradient.SetKeys(new GradientColorKey[_startTrailGradient.colorKeys.Length], new GradientAlphaKey[_startTrailGradient.alphaKeys.Length]);
if (_trailGradient.colorKeys.Length != _fadeoutTrailGradient.colorKeys.Length || _trailGradient.alphaKeys.Length != _fadeoutTrailGradient.alphaKeys.Length)
{
Debug.LogError($"{gameObject.name} - Trail gradient and fadeout gradient must have identical number of color and alpha keys");
}
}
}
// PRIVATE METHODS
private Gradient LerpGradient(Gradient from, Gradient to, Gradient result, float alpha)
{
// TODO: This allocates a lot (array copies)
var fromColorKeys = from.colorKeys;
var toColorKeys = to.colorKeys;
var resultColorKeys = result.colorKeys;
for (int i = 0; i < resultColorKeys.Length; i++)
{
GradientColorKey key = default;
key.color = Color.Lerp(fromColorKeys[i].color, toColorKeys[i].color, alpha);
key.time = Mathf.Lerp(fromColorKeys[i].time, toColorKeys[i].time, alpha);
resultColorKeys[i] = key;
}
var fromAlphaKeys = from.alphaKeys;
var toAlphaKeys = to.alphaKeys;
var resultAlphaKeys = result.alphaKeys;
for (int i = 0; i < resultAlphaKeys.Length; i++)
{
GradientAlphaKey key = default;
key.alpha = Mathf.Lerp(fromAlphaKeys[i].alpha, toAlphaKeys[i].alpha, alpha);
key.time = Mathf.Lerp(fromAlphaKeys[i].time, toColorKeys[i].time, alpha);
resultAlphaKeys[i] = key;
}
result.SetKeys(resultColorKeys, resultAlphaKeys);
return result;
}
}
}