// Checks if there are any hostiles within a 25f sphere radius. Then gets the closest one within line of sight. // Line of sight here means not obstructed by buildings/terrain/other units/ etc // Returns null if no such hostile is found. // This is currently being called in several Update methods, need an optimization to drastically reduce calls // Do not make this a command, there will be too much traffic and its needless public GameObject AcquireTarget() { Collider[] colls = Physics.OverlapSphere(transform.position, 55f); GameObject targetLocal = null; float distanceLocal = float.MaxValue; foreach (Collider coll in colls) { if (coll.transform.gameObject.tag == attackTag) { TroopClass enemyTC = coll.transform.gameObject.GetComponent <TroopClass>(); if (enemyTC != null) { enemyTC.visible = true; } float newDistance = Vector3.Distance(coll.transform.position, this.gameObject.transform.position); if (targetLocal == null || newDistance < distanceLocal) { if (coll.gameObject == targetLocal) { } targetLocal = coll.gameObject; distanceLocal = newDistance; } } } if (targetLocal != null && ProgUtils.InLineOfSight(gameObject, targetLocal) && targetLocal.GetComponent <TroopClass>().isHidden == false) { return(targetLocal); } return(null); }
void Update() { // Can only attack when the timer is greater than attack speed, hence; // Greater attack speed value actually means more time between attacks attackTimer += 0.5f * Time.deltaTime; // If there is no target to attack, then find a target in range if (target == null) { SetTarget(tc.AcquireTarget()); // Else if there is a target, attack if in range or move to it if not in range } else { if (ProgUtils.InRange(gameObject, target, attackRange)) { if (ProgUtils.InLineOfSight(gameObject, target)) { tc.Stop(); Attack(); } else if (tc.IsStopped()) { tc.Move(target.transform.position); } } else { tc.Move(ProgUtils.GetNearestWithinRange(gameObject, target, attackRange - 2f)); } } }
public static bool InCover(GameObject attacker, GameObject target) { foreach (GameObject cov in cover) { if (ProgUtils.InRange(attacker, target, cov)) { Vector3 vec1 = attacker.transform.position; Vector3 vec2 = target.transform.position; RaycastHit hit; if (Physics.Raycast(vec1, vec2 - vec1, out hit, Vector3.Distance(vec1, vec2))) { if (hit.collider.gameObject.tag == "Cover") { float attackDistance = Mathf.Abs(Vector3.Distance(attacker.transform.position, cov.transform.position)); float targetDistance = Mathf.Abs(Vector3.Distance(cov.transform.position, target.transform.position)); if (attackDistance > targetDistance) { return(true); } } } } } return(false); }
//Delegated helper function for SelectTroops static void SelectTroop(TroopClass troop, Vector3 corner1, Vector3 corner2) { if (troop != null && ProgUtils.InSelectWindow(corner1, corner2, troop.transform.position)) { troop.MarkSelected(); selectedTroops.Push(troop); } }
void EndSelect() { GameObject target = null; //Get click point will set target equal to whatever the player clicked on selectedEndPoint = ProgUtils.GetClickPoint(cam, out target); if (target != null && target.tag == "Friendly") { commandManager.AddTroop(target.GetComponent <TroopClass>()); } commandManager.SelectTroops(); }
// Like Warcraft/AoE/DotA the camera pans if the mouse moves to an edge // Not a command because only this client needs to be aware of its camera position void CameraMovement() { float horizontal, vertical; float screenLow = .05f; float screenHigh = .95f; float invertControls = 1f; if (gameObject.name == "Red_Player") { invertControls = -1f; } if (ProgUtils.InRange(Screen.width * screenLow, Screen.width * screenHigh, Input.mousePosition.x)) { horizontal = 0f; } else { horizontal = mouseSensitivity * ProgUtils.GetSign(Input.mousePosition.x - Screen.width / 2) * invertControls; } if (ProgUtils.InRange(Screen.height * screenLow, Screen.height * screenHigh, Input.mousePosition.y)) { vertical = 0f; } else { vertical = mouseSensitivity * ProgUtils.GetSign(Input.mousePosition.y - Screen.height / 2) * invertControls; } Vector3 camPos = gameObject.transform.position; if (camPos.x >= xBound) { horizontal = Mathf.Clamp(horizontal, -1f, 0f); } if (camPos.x <= -15) { horizontal = Mathf.Clamp(horizontal, 0f, 1f); } if (camPos.z >= yBound) { vertical = Mathf.Clamp(vertical, -1f, 0f); } if (camPos.z <= -15) { vertical = Mathf.Clamp(vertical, 0f, 1f); } transform.Translate(horizontal, 0, vertical, Space.World); }
void EndSelect() { selectedEndPoint = ProgUtils.GetClickPoint(); RaycastHit hit; Vector3 pos = gameObject.transform.position; if (Physics.Raycast(pos, selectedEndPoint - pos, out hit, Mathf.Infinity)) { if (hit.collider.gameObject.tag == "Friendly") { CommandManagement.AddTroop(hit.collider.gameObject.GetComponent <TroopClass>()); } } CommandManagement.SelectTroops(); }
void SetTarget() { CommandManagement.target = null; CommandManagement.pointSelected = ProgUtils.GetClickPoint(); //Get Click Point also sets CommandManagement.target to //what it clicked on, if it clicked on an enemy if (CommandManagement.target != null) { //if the target is not null, it means GetClickPoint found an enemy so attack it //the Combat class handles movement towards enemies so it isn't done here CommandManagement.SetAttackTargets(); } else { //There was no enemy so just move to the pointSelected as usual CommandManagement.MoveTroops(); } }
// Like Warcraft/AoE/DotA the camera pans if the mouse moves to an edge void CameraMovement() { float horizontal; float vertical; if (ProgUtils.InRange(Screen.width * .05f, Screen.width * .95f, Input.mousePosition.x)) { horizontal = 0f; } else { horizontal = mouseSensitivity * ProgUtils.GetSign(Input.mousePosition.x - Screen.width / 2); } if (ProgUtils.InRange(Screen.height * .05f, Screen.height * .95f, Input.mousePosition.y)) { vertical = 0f; } else { vertical = mouseSensitivity * ProgUtils.GetSign(Input.mousePosition.y - Screen.height / 2); } Vector3 camPos = gameObject.transform.position; if (camPos.x >= xBound) { Mathf.Clamp(horizontal, -1f, 0f); } if (camPos.x <= 0) { Mathf.Clamp(horizontal, 0f, 1f); } if (camPos.y >= yBound) { Mathf.Clamp(vertical, -1f, 0f); } if (camPos.y <= 0) { Mathf.Clamp(vertical, 0f, 1f); } transform.Translate(horizontal, 0, vertical, Space.World); }
void SetTarget() { GameObject newTarget = null; //Have to reset commandManager's current target to null so right clicks disengage by default commandManager.target = null; //get click point will set newTarget to whatever the player clicked on commandManager.pointSelected = ProgUtils.GetClickPoint(cam, out newTarget); if (newTarget != null && newTarget.tag == commandManager.GetEnemySide()) { //the Combat class handles movement towards enemies so it isn't done here commandManager.SetManagerTarget(newTarget); commandManager.SetAttackTargets(); } else { //There was no enemy so just move to the pointSelected as usual commandManager.MoveTroops(); } }
public static void SetAttackTargets() { ProgUtils.IterateAll(selectedTroops, SetAttackTarget); attacking = false; }
void Death() { gameObject.GetComponent <TroopClass> ().UnmarkSelected(); ProgUtils.RecursiveDestruction(gameObject); Destroy(this); }
public static void ClearSelection() { ProgUtils.IterateAll(selectedTroops, UnmarkTroop); selectedTroops.Clear(); }
public static void MoveTroops() { ProgUtils.IterateAll(selectedTroops, MoveTroop); }
// Selection works by creating two Vector3's on the surface of the map. Any selectable in between // these Vector3 corners are considered selected and added to the selection stack. // Also not a command because only determines where this client began selecting void BeginSelect() { selectedStartPoint = ProgUtils.GetClickPoint(cam); dragOrigin = new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y); }
public static void SelectTroops() { ProgUtils.IterateAll(troops, SelectTroop, Camera.main.gameObject); }
public void SelectTroops() { ProgUtils.IterateAll(troops, SelectTroop, camScript); }