using AllyAIMachineTools; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.AI; public class AIAllyMachine : MonoBehaviour { [HideInInspector] public GameManager gameManager; [HideInInspector] public DisplayLog logD; [HideInInspector] public AllyBotStateMachine botMachine; [HideInInspector] public NavMeshAgent thisAgent; [HideInInspector] public LineRenderer laserLine; [HideInInspector] public AudioSource audioS; [HideInInspector] public Health enemyHealth; [HideInInspector] public Animator animator; [HideInInspector] public SoundManager soundMgr; public string displayName = "Ally Bot"; public int attackDistance; public int hitChance; public int critChance; public int searchRadius; public int stopDistance; public int turretRotateSpeed; public int barrelMoveSpeed; public int bodyRotateSpeed; public int retreatRadius; public int reinforcementRadius; public float fireRate; public GameObject enemyObject; public GameObject playerObject; public GameObject impactObject; public Transform lineOrigin; public Transform barrelEnd; public Transform turretPos; public Transform barrelPos; public Vector3 contactPoint; public Vector3 regroupPos; public bool canSeeEnemy; public bool disabled; public bool onTarget = false; public bool removingEnemy = false; public bool supportBuff = false; public ParticleSystem laserParticles; public Light barrelLight; public List<GameObject> friendlyBots; public List<GameObject> additionalEnemies = new List<GameObject>(); public List<GameObject> nearbyFriendlies = new List<GameObject>(); public List<Material> lasers = new List<Material>(); private float timeToScan = 0; private void Start() { transform.parent = null; botMachine = GetComponent<AllyBotStateMachine>(); foreach (GameObject bot in GameObject.FindGameObjectsWithTag("Target")) { if (bot.GetComponent<Health>() && bot.GetComponent<AIAllyMachine>()) friendlyBots.Add(bot); } friendlyBots.Remove(this.gameObject); friendlyBots.Remove(GameObject.Find("PlayerSphere")); thisAgent = GetComponent<NavMeshAgent>(); soundMgr = GameObject.Find("Persistent Object").GetComponent<SoundManager>(); gameManager = GameObject.Find("Persistent Object").GetComponent<GameManager>(); logD = GameObject.Find("RunningUI/Text Log/Log Panel/Content").GetComponent<DisplayLog>(); playerObject = GameObject.Find("PlayerSphere"); laserLine = GetComponent<LineRenderer>(); audioS = GetComponent<AudioSource>(); regroupPos = GameObject.Find("AllyBotRegroupPoint").transform.position; barrelLight = barrelEnd.gameObject.GetComponent<Light>(); animator = GetComponent<Animator>(); barrelLight.enabled = false; } void Update() { timeToScan += Time.deltaTime; if (timeToScan >= 1.0f) { DrawSearchRays(); DrawBarrelRay(); timeToScan = 0.0f; } } private void DrawSearchRays() { Quaternion startingAngle = Quaternion.AngleAxis(-60, Vector3.up); Quaternion stepAngle = Quaternion.AngleAxis(5, Vector3.up); RaycastHit hit; var angle = transform.rotation * startingAngle; var direction = angle * Vector3.forward; for (var i = 0; i < 72; i++) //creates the draw rays that the bot uses to detect enemies { if (Physics.Raycast(lineOrigin.transform.position, direction, out hit, searchRadius)) { if (hit.collider.gameObject.CompareTag("Enemy")) { Debug.DrawRay(lineOrigin.transform.position, direction * hit.distance, Color.red); canSeeEnemy = true; additionalEnemies.Add(hit.collider.gameObject); additionalEnemies = additionalEnemies.Distinct().ToList(); SetTarget(); break; } else if (hit.collider.gameObject.CompareTag("EnemyStructure")) { Debug.DrawRay(lineOrigin.transform.position, direction * hit.distance, Color.green); canSeeEnemy = true; additionalEnemies.Add(hit.collider.gameObject); additionalEnemies = additionalEnemies.Distinct().ToList(); SetTarget(); break; } else if (hit.collider.gameObject.CompareTag("Target")) { Debug.DrawRay(lineOrigin.transform.position, direction * hit.distance, Color.blue); nearbyFriendlies.Add(hit.collider.gameObject); nearbyFriendlies = nearbyFriendlies.Distinct().ToList(); } else { Debug.DrawRay(lineOrigin.transform.position, direction * hit.distance, Color.yellow); canSeeEnemy = false; } } else { Debug.DrawRay(lineOrigin.transform.position, direction * searchRadius, Color.white); canSeeEnemy = false; } direction = stepAngle * direction; } for (int i = 0; i < additionalEnemies.Count; i++) { if (Vector3.Distance(transform.position, additionalEnemies[i].transform.position) > searchRadius || additionalEnemies[i].activeSelf == false) additionalEnemies.RemoveAt(i); } for (int i = 0; i < nearbyFriendlies.Count; i++) { if (Vector3.Distance(transform.position, nearbyFriendlies[i].transform.position) > searchRadius || nearbyFriendlies[i].activeSelf == false) nearbyFriendlies.RemoveAt(i); } } public void SetTarget() //after enemies are found this method will decide which enemy is the current target { float minDistance = float.MaxValue; GameObject targetBot = null; if (additionalEnemies.Count > 0) //if the list is not empty { if (additionalEnemies.Count == 1) //if theres only one enemy { enemyObject = additionalEnemies[0]; enemyHealth = enemyObject.GetComponent<Health>(); } else if (additionalEnemies.Count > 1) //if there is more than 1 enemy { for (int i = 0; i < additionalEnemies.Count; i++)// for each enemy in the list get the distance between this bot and the enemy and then decide if that distance is the shortest one { float thisDistance = Vector3.Distance(transform.position, additionalEnemies[i].transform.position); if (thisDistance < minDistance) { minDistance = thisDistance; targetBot = additionalEnemies[i]; } } //after the loop is complete set the enemyobject to the target that is closest enemyObject = targetBot; enemyHealth = enemyObject.GetComponent<Health>(); } } } public void DrawBarrelRay() { RaycastHit hit; if (Physics.Raycast(barrelEnd.transform.position, barrelEnd.forward, out hit, attackDistance + 10)) { if (hit.collider.gameObject.CompareTag("Enemy")) { Debug.DrawRay(barrelEnd.transform.position, barrelEnd.forward * hit.distance, Color.red); contactPoint = hit.point; onTarget = true; } else if (hit.collider.gameObject.CompareTag("Target")) { Debug.DrawRay(barrelEnd.transform.position, barrelEnd.forward * hit.distance, Color.blue); contactPoint = hit.point; onTarget = true; } else { Debug.DrawRay(barrelEnd.transform.position, barrelEnd.forward * hit.distance, Color.yellow); onTarget = false; } } else { Debug.DrawRay(barrelEnd.transform.position, barrelEnd.forward * attackDistance); onTarget = false; } } public void CreateImpactParticles() { Instantiate(impactObject, contactPoint, Quaternion.identity, gameObject.transform.parent); } }