Hi it me again im watching the lesson the granade visual, it a very cool effect and rest , but i was thinkking haw it possible add a proper object or prefab instead of a sphere for the granade because in on my many assets of SyntyStudio i have several prefab of various granade and it a waste dont use it, i think it a nice implemeation
This is the code for the GrenadeProjectile
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GrenadeProjectile : MonoBehaviour
{
public static event EventHandler OnAnyGrenadeExploded;
[SerializeField] private Transform grenadeExplodeVFXPrefab;
[SerializeField] private TrailRenderer trailRenderer;
[SerializeField] private AnimationCurve arcYAnimationCurve;
private Vector3 targetPosition;
private Action onGrenadeBehaviourComplete;
private float totalDistance;
private Vector3 positionXZ;
private void Update()
{
Vector3 moveDir = (targetPosition - positionXZ).normalized;
float moveSpeed = 15f;
positionXZ += moveDir * moveSpeed * Time.deltaTime;
float distance = Vector3.Distance(positionXZ, targetPosition);
float distanceNormalized = 1 - distance / totalDistance;
float maxHeight = totalDistance / 4f;
float positionY = arcYAnimationCurve.Evaluate(distanceNormalized) * maxHeight;
transform.position = new Vector3(positionXZ.x, positionY, positionXZ.z);
float reachedTargetDistance = .2f;
if (Vector3.Distance(positionXZ, targetPosition) < reachedTargetDistance)
{
float damageRadius = 4f;
Collider[] colliderArray = Physics.OverlapSphere(targetPosition, damageRadius);
foreach (Collider collider in colliderArray)
{
if (collider.TryGetComponent<Unit>(out Unit targetUnit))
{
targetUnit.Damage(30);
}
}
OnAnyGrenadeExploded?.Invoke(this, EventArgs.Empty);
trailRenderer.transform.parent = null;
Instantiate(grenadeExplodeVFXPrefab, targetPosition + Vector3.up * 1f, Quaternion.identity);
Destroy(gameObject);
onGrenadeBehaviourComplete();
}
}
public void Setup(GridPosition targetGridPosition, Action onGrenadeBehaviourComplete)
{
this.onGrenadeBehaviourComplete = onGrenadeBehaviourComplete;
targetPosition = LevelGrid.Instance.GetWorldPosition(targetGridPosition);
positionXZ = transform.position;
positionXZ.y = 0;
totalDistance = Vector3.Distance(positionXZ, targetPosition);
}
}
And this one is for the GranadeAction
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GrenadeAction : BaseAction
{
[SerializeField] private Transform grenadeProjectilePrefab;
private int maxThrowDistance = 7;
private void Update()
{
if (!isActive)
{
return;
}
}
public override string GetActionName()
{
return "Grenade";
}
public override EnemyAIAction GetEnemyAIAction(GridPosition gridPosition)
{
return new EnemyAIAction
{
gridPosition = gridPosition,
actionValue = 0,
};
}
public override List<GridPosition> GetValidActionGridPositionList()
{
List<GridPosition> validGridPositionList = new List<GridPosition>();
GridPosition unitGridPosition = unit.GetGridPosition();
for (int x = -maxThrowDistance; x <= maxThrowDistance; x++)
{
for (int z = -maxThrowDistance; z <= maxThrowDistance; z++)
{
GridPosition offsetGridPosition = new GridPosition(x, z);
GridPosition testGridPosition = unitGridPosition + offsetGridPosition;
if (!LevelGrid.Instance.IsValidGridPosition(testGridPosition))
{
continue;
}
int testDistance = Mathf.Abs(x) + Mathf.Abs(z);
if (testDistance > maxThrowDistance)
{
continue;
}
validGridPositionList.Add(testGridPosition);
}
}
return validGridPositionList;
}
public override void TakeAction(GridPosition gridPosition, Action onActionComplete)
{
Transform grenadeProjectileTransform = Instantiate(grenadeProjectilePrefab, unit.GetWorldPosition(), Quaternion.identity);
GrenadeProjectile grenadeProjectile = grenadeProjectileTransform.GetComponent<GrenadeProjectile>();
grenadeProjectile.Setup(gridPosition, OnGrenadeBehaviourComplete);
ActionStart(onActionComplete);
}
private void OnGrenadeBehaviourComplete()
{
ActionComplete();
}
}
I hope this time do the better thing