using System; using System.Collections; using UnityEngine; using UnityEngine.Assertions; [RequireComponent(typeof(ProjectileSpawner))] public class ProjectileTower : Tower { [SerializeField, Range(0.01f, 20f)] private float attackSecondsDelay = 1f; [SerializeField] private ProjectilePattern[] projectileSequence; [SerializeField] private GameObject barrel; private ProjectileSpawner projectileSpawner; public Vector3 AimDirection => transform.TransformVector(transform.InverseTransformVector(horizontalArc.ToKnobVector) + transform.InverseTransformVector(verticalArc.ToKnobVector)); protected override void Awake() { base.Awake(); projectileSpawner = GetComponent(); Assert.IsNotNull(projectileSpawner); horizontalArc.Value.AddListener(UpdateBarrelRotation); verticalArc.Value.AddListener(UpdateBarrelRotation); UpdateBarrelRotation(); StartCoroutine(AttackLoop()); } protected override void OnDestroy() { horizontalArc.Value.RemoveListener(UpdateBarrelRotation); verticalArc.Value.RemoveListener(UpdateBarrelRotation); } private IEnumerator AttackLoop() { do { yield return new WaitForSeconds(attackSecondsDelay); UpdateBarrelRotation(); Debug.DrawRay(transform.position, horizontalArc.ToKnobVector, Color.red, attackSecondsDelay); Debug.DrawRay(transform.position, verticalArc.ToKnobVector, Color.green, attackSecondsDelay); Debug.DrawRay(transform.position, AimDirection, Color.yellow, attackSecondsDelay); projectileSpawner.RunBulletSequence(transform.position, transform.up, AimDirection, projectileSequence); } while (true); } private void UpdateBarrelRotation(float unused) => UpdateBarrelRotation(); // Rotate barrel to match rotation private void UpdateBarrelRotation() { barrel.transform.rotation = Quaternion.Euler(verticalArc.Value, horizontalArc.Value, 0f); } }