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.
129 lines
3.5 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|