finnaly both are working i will paste immediatly look
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ReloadAction : BaseAction
{
[SerializeField] private AudioClip reloadSoundClip;
private AudioSource reloadSound;
public event EventHandler OnReloadActionStarted;
public event EventHandler OnReloadActionCompleted;
private float reloadTime = 0.6f;
private float stateTimer;
private void Start()
{
reloadSound = gameObject.AddComponent<AudioSource>();
if (reloadSoundClip != null)
{
reloadSound.clip = reloadSoundClip;
reloadSound.playOnAwake = false;
}
}
private void Update()
{
if (!isActive) return;
stateTimer -= Time.deltaTime;
if (stateTimer <= 0f)
{
Reload();
OnReloadActionCompleted?.Invoke(this, EventArgs.Empty);
ActionComplete();
}
}
public override string GetActionName()
{
return "Reload";
}
public override void TakeAction(GridPosition gridPosition, Action onActionComplete)
{
if (!unit.IsEnemy())
{
stateTimer = reloadTime;
OnReloadActionStarted?.Invoke(this, EventArgs.Empty);
ActionStart(onActionComplete);
}
else
{
// Non fare nulla se è un'IA nemica
Debug.Log("IA nemica tentata di ricaricare");
onActionComplete();
}
}
public override List<GridPosition> GetValidActionGridPositionList()
{
return new List<GridPosition> { unit.GetGridPosition() };
}
public override int GetActionPointCost()
{
return 1; // Puoi cambiare questo valore in base alle tue esigenze
}
private void Reload()
{
// Aggiungi la logica di ricarica qui
if (reloadSoundClip != null)
{
reloadSound.Play();
}
}
public override EnemyAIAction GetEnemyAIAction(GridPosition gridPosition)
{
return null; // Non fornire un'azione per l'IA nemica
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UnitAnimator : MonoBehaviour
{
[SerializeField] private Animator animator;
[SerializeField] private Transform bulletProjectilePrefab;
[SerializeField] private Transform Muzzle;
[SerializeField] private Transform gunTransform;
[SerializeField] private Transform swordTransform;
private void Awake()
{
if (TryGetComponent<MoveAction>(out MoveAction moveAction))
{
moveAction.OnStartMoving += MoveAction_OnStartMoving;
moveAction.OnStopMoving += MoveAction_OnStopMoving;
}
if (TryGetComponent<ShootAction>(out ShootAction shootAction))
{
shootAction.OnShoot += ShootAction_OnShoot;
}
if (TryGetComponent<SwordAction>(out SwordAction swordAction))
{
swordAction.OnSwordActionStarted += SwordAction_OnSwordActionStarted;
swordAction.OnSwordActionCompleted += SwordAction_OnSwordActionCompleted;
}
if (TryGetComponent<GrenadeAction>(out GrenadeAction grenadeAction))
{
grenadeAction.OnGrenadeActionStarted += GrenadeAction_GrenadeActionStarted;
grenadeAction.OnGrenadeActionCompleted += GrenadeAction_GrenadeActionCompleted;
}
// Gestione eventi di ricarica con riferimento a un'istanza specifica
if (TryGetComponent<ReloadAction>(out ReloadAction reloadAction))
{
reloadAction.OnReloadActionStarted += ReloadAction_OnReloadActionStarted;
reloadAction.OnReloadActionCompleted += ReloadAction_OnReloadActionCompleted;
}
}
// Eventi Azione Granata
private void GrenadeAction_GrenadeActionStarted(object sender, EventArgs e)
{
animator.SetTrigger("Grenade");
}
private void GrenadeAction_GrenadeActionCompleted(object sender, EventArgs e)
{
EquipGun();
}
// Eventi Ricarica Arma
private void ReloadAction_OnReloadActionStarted(object sender, EventArgs e)
{
animator.SetTrigger("ReloadStart");
}
private void ReloadAction_OnReloadActionCompleted(object sender, EventArgs e)
{
animator.SetTrigger("ReloadEnd");
EquipGun(); // Equip gun after reload is completed
}
// Eventi azione Spada
private void Start()
{
EquipGun();
}
private void SwordAction_OnSwordActionStarted(object sender, EventArgs e)
{
EquipSword();
animator.SetTrigger("SwordSlash");
}
private void SwordAction_OnSwordActionCompleted(object sender, EventArgs e)
{
EquipGun();
}
// Eventi Azione Movimento
private void MoveAction_OnStartMoving(object sender, EventArgs e)
{
animator.SetBool("IsSprint", true);
}
private void MoveAction_OnStopMoving(object sender, EventArgs e)
{
animator.SetBool("IsSprint", false);
}
private void ShootAction_OnShoot(object sender, ShootAction.OnShootEventArgs e)
{
animator.SetTrigger("Shoot");
Transform bulletProjectileTransform = Instantiate(bulletProjectilePrefab, Muzzle.position, Quaternion.identity);
BulletProjectile bulletProjectile = bulletProjectileTransform.GetComponent<BulletProjectile>();
Vector3 targetUnitShootAtPosition = e.targetUnit.GetWorldPosition();
targetUnitShootAtPosition.y = Muzzle.position.y;
bulletProjectile.Setup(targetUnitShootAtPosition);
}
private void EquipSword()
{
swordTransform.gameObject.SetActive(true);
gunTransform.gameObject.SetActive(false);
}
private void EquipGun()
{
swordTransform.gameObject.SetActive(false);
gunTransform.gameObject.SetActive(true);
}
}
Finally its work sorry Bixarro for the disturb but im too happy, if needed can use and i give you thi one
public class ShootAction : BaseAction
{
[SerializeField] private AudioClip shootSoundClip;
private AudioSource HandGunShootSound;
public static event EventHandler<OnShootEventArgs> OnAnyShoot;
public event EventHandler<OnShootEventArgs> OnShoot;
public class OnShootEventArgs : EventArgs
{
public Unit targetUnit;
public Unit shootingUnit;
}
private enum State
{
Aiming,
Shooting,
Cooloff,
}
[SerializeField] private LayerMask obstaclesLayerMask;
private State state;
private int maxShootDistance = 7;
private float stateTimer;
private Unit targetUnit;
private bool canShootBullet;
// Gestione componente AudioSource a questo oggetto per la riproduzione dell'AudioClip
private void Start()
{
HandGunShootSound = gameObject.AddComponent<AudioSource>();
HandGunShootSound.playOnAwake = false; // Assicurati che l'AudioClip non venga riprodotto automaticamente all'avvio
HandGunShootSound.clip = shootSoundClip; // Assegna l'AudioClip all'AudioSource
}
private void Update()
{
if (!isActive)
{
return;
}
stateTimer -= Time.deltaTime;
switch (state)
{
case State.Aiming:
Vector3 aimDir = (targetUnit.GetWorldPosition() - unit.GetWorldPosition()).normalized;
float rotateSpeed = 10f;
transform.forward = Vector3.Lerp(transform.forward, aimDir, Time.deltaTime * rotateSpeed);
break;
case State.Shooting:
if (canShootBullet)
{
Shoot();
canShootBullet = false;
}
break;
case State.Cooloff:
break;
}
if (stateTimer <= 0f)
{
NextState();
}
}
private void NextState()
{
switch (state)
{
case State.Aiming:
state = State.Shooting;
float shootingStateTime = 0.1f;
stateTimer = shootingStateTime;
break;
case State.Shooting:
state = State.Cooloff;
float coolOffStateTime = 0.5f;
stateTimer = coolOffStateTime;
break;
case State.Cooloff:
ActionComplete();
break;
}
}
private void Shoot()
{
if (shootSoundClip != null)
{
HandGunShootSound.Play(); // Riproduci l'AudioClip
}
OnAnyShoot?.Invoke(this, new OnShootEventArgs
{
targetUnit = targetUnit,
shootingUnit = unit
});
OnShoot?.Invoke(this, new OnShootEventArgs
{
targetUnit = targetUnit,
shootingUnit = unit
});
targetUnit.Damage(40);
}
public override string GetActionName()
{
return "Shoot";
}
public override List<GridPosition> GetValidActionGridPositionList()
{
GridPosition unitGridPosition = unit.GetGridPosition();
return GetValidActionGridPositionList(unitGridPosition);
}
public List<GridPosition> GetValidActionGridPositionList(GridPosition unitGridPosition)
{
List<GridPosition> validGridPositionList = new List<GridPosition>();
for (int x = -maxShootDistance; x <= maxShootDistance; x++)
{
for (int z = -maxShootDistance; z <= maxShootDistance; 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 > maxShootDistance)
{
continue;
}
if (!LevelGrid.Instance.HasAnyUnitOnGridPosition(testGridPosition))
{
// Grid Position is empty, no Unit
continue;
}
Unit targetUnit = LevelGrid.Instance.GetUnitAtGridPosition(testGridPosition);
if (targetUnit.IsEnemy() == unit.IsEnemy())
{
// Both Units on same 'team'
continue;
}
Vector3 unitWorldPosition = LevelGrid.Instance.GetWorldPosition(unitGridPosition);
Vector3 shootDir = (targetUnit.GetWorldPosition() - unitWorldPosition).normalized;
float unitShoulderHeight = 1.7f;
if (Physics.Raycast(
unitWorldPosition + Vector3.up * unitShoulderHeight,
shootDir,
Vector3.Distance(unitWorldPosition, targetUnit.GetWorldPosition()),
obstaclesLayerMask))
{
// Blocked by an Obstacle
continue;
}
validGridPositionList.Add(testGridPosition);
}
}
return validGridPositionList;
}
public override void TakeAction(GridPosition gridPosition, Action onActionComplete)
{
targetUnit = LevelGrid.Instance.GetUnitAtGridPosition(gridPosition);
state = State.Aiming;
float aimingStateTime = 1f;
stateTimer = aimingStateTime;
canShootBullet = true;
ActionStart(onActionComplete);
}
public Unit GetTargetUnit()
{
return targetUnit;
}
public int GetMaxShootDistance()
{
return maxShootDistance;
}
public override EnemyAIAction GetEnemyAIAction(GridPosition gridPosition)
{
Unit targetUnit = LevelGrid.Instance.GetUnitAtGridPosition(gridPosition);
return new EnemyAIAction
{
gridPosition = gridPosition,
actionValue = 100 + Mathf.RoundToInt((1 - targetUnit.GetHealthNormalized()) * 100f),
};
}
public int GetTargetCountAtPosition(GridPosition gridPosition)
{
return GetValidActionGridPositionList(gridPosition).Count;
}
}
its the my Version of ShootAction Scpit with the adding of sound maybe its a little improvement but very pleasant