If you would like to apply damage related to distance from explosion and get tool to modify damage multiplier, you should use AnimationCurve.
GrenadeProjectile:
public class GrenadeProjectile : MonoBehaviour
{
[SerializeField, Min(0.1f)] private float _moveSpeed;
[SerializeField, Min(0f)] private float _damage;
[SerializeField, Min(0.1f)] private float _damageRadiusInCells;
[SerializeField] private AnimationCurve _damageMultiplierCurve;
private Vector3 _targetPosition;
private Vector3 _moveDir;
private float _distance;
private Action _onGrenadeExplodes;
private void Update()
{
float translation = _moveSpeed * Time.deltaTime;
transform.position += _moveDir * translation;
_distance -= translation;
if (_distance <= 0)
{
float damageDistance = _damageRadiusInCells * LevelGrid.Instance.CellSize;
Collider[] colliders = Physics.OverlapSphere(_targetPosition, damageDistance);
foreach (Collider collider in colliders)
{
if (collider.TryGetComponent(out Unit targetUnit))
{
var distanceToUnit = Vector3.Distance(targetUnit.GetWorldPosition(), _targetPosition);
if (distanceToUnit < damageDistance)
{
float curveTime = distanceToUnit / damageDistance;
targetUnit.Hit(_damage * _damageMultiplierCurve.Evaluate(curveTime));
}
}
}
Destroy(gameObject);
_onGrenadeExplodes?.Invoke();
}
}
public void Setup(GridPosition gridPosition, Action onGrenadeExplodes)
{
_targetPosition = LevelGrid.Instance.GetWorldPosition(gridPosition);
_moveDir = (_targetPosition - transform.position).normalized;
_distance = Vector3.Distance(_targetPosition, transform.position);
_onGrenadeExplodes = onGrenadeExplodes;
}
}
And add to LevelGrid these properties:
[field: SerializeField, Min(1)] public int Width { get; private set; }
[field: SerializeField, Min(1)] public int Height { get; private set; }
[field: SerializeField, Min(0.1f)] public float CellSize { get; private set; }