using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; public class TurretController : MonoBehaviour, IPooledObject{ [SerializeField] float speed = 1f; [SerializeField] Animator anim = default; [SerializeField] GameObject head = default; [SerializeField] GameObject headObj = default; [Space] [SerializeField, Range(0, 3f)] float firstAttackDelay = 1f; [SerializeField] int numberOfDisks = 10; int currentDisk; [SerializeField] float maxHeigth = 1f; [SerializeField] float minHeigth = 0f; [SerializeField] GameObject turretObject = default; [SerializeField] Transform shootPos = default; [Space] [SerializeField, Range(0, 15)] float shootingDistance = 7f; [SerializeField, Range(0, 5)] float aimingTime = 2f; [SerializeField, Range(0, 1)] float attackDelay = .25f; [SerializeField] LayerMask whatIsPlayer = default; [SerializeField] LayerMask whatIsWall = default; PlayerController player; float rotationVelocity; bool canAttack; bool aiming; bool prepareShooting; bool playerDetected; NavMeshAgent agent; [HideInInspector] public EnemySpawner spawner; [HideInInspector] public RoomTrigger room; // Start is called before the first frame update void Awake(){ agent = FindObjectOfType(); player = FindObjectOfType(); agent.speed = speed; } public void OnObjectSpawn(){ currentDisk = numberOfDisks; turretObject.transform.localPosition = new Vector3(minHeigth + (maxHeigth - minHeigth) / numberOfDisks * currentDisk, 0, 0); playerDetected = aiming = prepareShooting = canAttack = false; agent.Warp(transform.position); agent.isStopped = true; StartCoroutine(FirstAttackDelay()); } IEnumerator FirstAttackDelay(){ yield return new WaitForSeconds(firstAttackDelay); canAttack = true; } void Update(){ if(!playerDetected && Physics.CheckSphere(transform.position, shootingDistance, whatIsPlayer)){ agent.isStopped = false; playerDetected = true; } Vector3 dire = (player.transform.position - (transform.position + Vector3.up * .3f)).normalized; //Ray rayx = new Ray(transform.position + Vector3.up * .3f, dire * Vector3.Distance(transform.position + Vector3.up * .3f, player.transform.position)); //Debug.DrawRay(rayx.origin, rayx.direction * Vector3.Distance(transform.position + Vector3.up, player.transform.position)); if (Physics.CheckSphere(transform.position, shootingDistance, whatIsPlayer) && canAttack && currentDisk > 0){ Ray ray = new Ray(transform.position + Vector3.up * .3f, dire * Vector3.Distance(transform.position + Vector3.up * .3f, player.transform.position)); if (!Physics.Raycast(ray, Vector3.Distance(transform.position + Vector3.up * .3f, player.transform.position), whatIsWall)){ StartCoroutine(Shoot()); canAttack = false; } } if (Physics.CheckSphere(transform.position + Vector3.up, shootingDistance, whatIsPlayer) && canAttack && currentDisk == 0){ Ray ray = new Ray(transform.position + Vector3.up * .3f, dire * Vector3.Distance(transform.position + Vector3.up * .3f, player.transform.position)); if (!Physics.Raycast(ray, Vector3.Distance(transform.position + Vector3.up * .3f, player.transform.position), whatIsWall)){ StartCoroutine(ShootHead()); canAttack = false; } } if (aiming){ if (!prepareShooting){ agent.SetDestination(player.transform.position); }else{ Vector3 pos = player.transform.position - transform.position; float rotY = Mathf.Atan2(-pos.z, pos.x) * Mathf.Rad2Deg; float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, rotY + 90, ref rotationVelocity, .1f); transform.rotation = Quaternion.Euler(0f, angle, 0f); } }else if (playerDetected && !prepareShooting){ agent.SetDestination(player.transform.position); } } IEnumerator ShootHead(){ aiming = true; yield return new WaitForSeconds(aimingTime); agent.isStopped = true; prepareShooting = true; yield return new WaitForSeconds(attackDelay); agent.isStopped = false; aiming = false; prepareShooting = false; anim.SetTrigger("Shoot"); currentDisk--; //turretObject.transform.localPosition = new Vector3(minHeigth + (maxHeigth - minHeigth) / numberOfDisks * currentDisk, 0, 0); headObj.SetActive(false); //FrisbieController frisbie = ObjectPooler.instance.SpawnFromPool("Disk", shootPos.position, transform.rotation).GetComponent(); ObjectPooler.instance.SpawnFromPool("TurretHead", shootPos.position, transform.rotation); canAttack = true; gameObject.SetActive(false); player.percentage += Utils.RAM_cleanseSmall; room.Die(gameObject); } IEnumerator Shoot(){ aiming = true; yield return new WaitForSeconds(aimingTime); agent.isStopped = true; prepareShooting = true; yield return new WaitForSeconds(attackDelay); agent.isStopped = false; aiming = false; prepareShooting = false; anim.SetTrigger("Shoot"); currentDisk--; turretObject.transform.localPosition = new Vector3(minHeigth + (maxHeigth - minHeigth) / numberOfDisks * currentDisk, 0, 0); ObjectPooler.instance.SpawnFromPool("EnemyDisk", shootPos.position, transform.rotation); //FrisbieController frisbie = Instantiate(bullet, transform.position + Vector3.up, transform.rotation).GetComponent(); canAttack = true; } void OnTriggerEnter(Collider col){ if (col.CompareTag("Disk")){ player.percentage += Utils.RAM_cleanseSmall; gameObject.SetActive(false); col.GetComponent().velocity = Vector3.zero; room.Die(gameObject); GameMaster.Instance.Pooler.SpawnFromPool("EnemyExplosion", transform.position); if (Utils.spawnDisk()) GameMaster.Instance.Pooler.SpawnFromPool("DiskPickup", transform.position); StopAllCoroutines(); } } void OnCollisionEnter(Collision col){ if (col.gameObject.CompareTag("Disk")){ player.percentage += Utils.RAM_cleanseSmall; gameObject.SetActive(false); col.gameObject.GetComponent().velocity = Vector3.zero; room.Die(gameObject); GameMaster.Instance.Pooler.SpawnFromPool("EnemyExplosion", transform.position); if (Utils.spawnDisk()) GameMaster.Instance.Pooler.SpawnFromPool("DiskPickup", transform.position); StopAllCoroutines(); } } void OnDrawGizmosSelected(){ Gizmos.DrawWireSphere(transform.position, shootingDistance); } }