Thanks for the responses!
I can’t seem to uploaded the scripts as attachments, so hopefully it’s OK to just paste them in here…
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletProjectile : MonoBehaviour
{
[SerializeField] private TrailRenderer trailRenderer;
[SerializeField] private Transform bulletHitVFXPrefab;
[SerializeField] private Vector3 targetPosition;
[SerializeField] private Vector3 targetPosition2;
public void Setup(Vector3 _targetPosition)
{
//Debug.Log("target position parameter is " + _targetPosition);
targetPosition2 = _targetPosition;
this.targetPosition = _targetPosition;
//Debug.Log("Target position is " + this.targetPosition);
}
private void Update()
{
targetPosition = targetPosition2;
//Debug.Log(targetPosition);
Vector3 moveDir = (targetPosition - transform.position).normalized;
float distanceBeforeMoving = Vector3.Distance(transform.position, targetPosition);
float moveSpeed = 200f;
transform.position += moveDir * moveSpeed * Time.deltaTime;
float distanceAfterMoving = Vector3.Distance(transform.position, targetPosition);
//distanceBeforeMoving < distanceAfterMoving
if (distanceBeforeMoving < distanceAfterMoving)
{
transform.position = targetPosition;
trailRenderer.transform.parent = null;
Destroy(gameObject);
Instantiate(bulletHitVFXPrefab, targetPosition, Quaternion.identity);
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class ShootAction : BaseAction
{
public event EventHandler<OnShootEventArgs> OnShoot;
public class OnShootEventArgs : EventArgs
{
public Unit targetUnit;
public Unit shootingUnit;
}
private enum State
{
Aiming,
Shooting,
Cooloff,
}
private State state;
private int maxShootDistance = 7;
private float stateTimer;
private Unit targetUnit;
private bool canShootBullet;
private void Update()
{
if (!isActive)
{
return;
}
stateTimer -= Time.deltaTime;
switch (state)
{
case State.Aiming:
Vector3 aimDirection = (targetUnit.GetWorldPosition() - unit.GetWorldPosition()).normalized;
float rotateSpeed = 10f;
transform.forward = Vector3.Lerp(transform.forward, aimDirection, rotateSpeed * Time.deltaTime);
break;
case State.Shooting:
if (canShootBullet)
{
Shoot();
canShootBullet = false;
}
break;
case State.Cooloff:
break;
}
if (stateTimer < 0)
{
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;
}
// Debug.Log(state);
}
private void Shoot()
{
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;
}
validGridPositionList.Add(testGridPosition);
}
}
return validGridPositionList;
}
public override void TakeAction(GridPosition gridPosition, Action onActionComplete)
{
targetUnit = LevelGrid.Instance.GetUnitAtGridPosition(gridPosition);
//Debug.Log(targetUnit.name);
// Debug.Log("Aiming");
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 GetBestEnemyAIAction(GridPosition gridPosition)
{
Unit targetUnit = LevelGrid.Instance.GetUnitAtGridPosition(gridPosition);
return new EnemyAIAction
{
gridPosition = gridPosition,
actionValue = 100 + (int)MathF.Round((1- targetUnit.GetHealthNormalized()) * 100f),
};
}
public int GetTargetCountAtPosition(GridPosition gridPosition)
{
return GetValidActionGridPositionList(gridPosition).Count;
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UnitAnimator : MonoBehaviour
{
[SerializeField] Animator animator;
[SerializeField] Transform bulletProjectilePrefab;
[SerializeField] Transform shootPointTransform;
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_OnStartShooting;
}
}
private void MoveAction_OnStartMoving(object sender, EventArgs e)
{
animator.SetBool("isWalking", true);
}
private void MoveAction_OnStopMoving(object sender, EventArgs e)
{
animator.SetBool("isWalking", false);
}
private void ShootAction_OnStartShooting(object sender, ShootAction.OnShootEventArgs e)
{
animator.SetTrigger("Shoot");
Transform bulletProjectileTransform = Instantiate(bulletProjectilePrefab, shootPointTransform.position, Quaternion.identity);
BulletProjectile bulletProjectile = bulletProjectilePrefab.GetComponent< BulletProjectile>();
Vector3 targetShootAtPosition = e.targetUnit.GetWorldPosition();
targetShootAtPosition.y = shootPointTransform.position.y;
bulletProjectile.Setup(targetShootAtPosition);
}
}