summaryrefslogtreecommitdiff
path: root/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/ExampleScenes/Scenes/OldExamples/Example18_RTS/RTSUI.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/ExampleScenes/Scenes/OldExamples/Example18_RTS/RTSUI.cs')
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/ExampleScenes/Scenes/OldExamples/Example18_RTS/RTSUI.cs249
1 files changed, 249 insertions, 0 deletions
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/ExampleScenes/Scenes/OldExamples/Example18_RTS/RTSUI.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/ExampleScenes/Scenes/OldExamples/Example18_RTS/RTSUI.cs
new file mode 100644
index 0000000..bb436fb
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/ExampleScenes/Scenes/OldExamples/Example18_RTS/RTSUI.cs
@@ -0,0 +1,249 @@
+using UnityEngine;
+using UnityEngine.UI;
+using System.Collections;
+using Pathfinding;
+using System.Linq;
+
+namespace Pathfinding.Examples.RTS {
+ [HelpURL("https://arongranberg.com/astar/documentation/stable/rtsui.html")]
+ public class RTSUI : MonoBehaviour {
+ public static RTSUI active;
+ public RectTransform selectionBox;
+ public GameObject menuRoot;
+ public GameObject menuItemPrefab;
+ public State state;
+ public Button clickFallback;
+ public GameObject buildingPreview;
+ public LayerMask groundMask;
+
+ public AudioClip click;
+ public AudioClip notEnoughResources;
+
+ public RTSWorldSpaceUI worldSpaceUI;
+
+ RTSUnitBuilder.BuildingItem buildingInfo;
+ int ignoreFrame = -1;
+
+ Menu activeMenu;
+
+ public enum State {
+ Normal,
+ PlacingBuilding,
+ Dragging
+ }
+
+ [System.Serializable]
+ public class MenuItem {
+ public Sprite icon;
+ public string label;
+ public string description;
+ }
+
+ // Use this for initialization
+ void Awake () {
+ active = this;
+
+ /*foreach (var btn in buildingMenuRoot.GetComponentsInChildren<RTSBuildingButton>()) {
+ btn.gameObject.GetComponent<Button>().onClick.AddListener(() => {
+ StartBuildingPlacement(btn);
+ });
+ }*/
+ }
+
+ public class Menu {
+ GameObject root;
+ GameObject itemPrefab;
+
+ public Menu (GameObject root, GameObject itemPrefab) {
+ this.root = root;
+ this.itemPrefab = itemPrefab;
+ }
+
+ public void Hide () {
+ if (root != null) {
+ for (int i = 0; i < root.transform.childCount; i++) {
+ GameObject.Destroy(root.transform.GetChild(i).gameObject);
+ }
+ root = null;
+ }
+ }
+
+ public void AddItem (MenuItem item, System.Action callback) {
+ var go = GameObject.Instantiate(itemPrefab) as GameObject;
+
+ go.transform.SetParent(root.transform);
+ go.GetComponent<Button>().onClick.AddListener(() => callback());
+ go.transform.Find("Image/Icon").GetComponent<Image>().sprite = item.icon;
+ go.transform.Find("Label").GetComponent<Text>().text = item.label;
+ go.transform.Find("Description").GetComponent<Text>().text = item.description;
+ }
+ }
+
+ public Menu ShowMenu () {
+ if (activeMenu != null) {
+ activeMenu.Hide();
+ }
+
+ activeMenu = new Menu(menuRoot, menuItemPrefab);
+ return activeMenu;
+ }
+
+ Vector2 dragStart;
+ bool hasSelected = false;
+
+ // Update is called once per frame
+ void Update () {
+ HandleSelection();
+ HandleMovement();
+ HandleBuildingPlacement();
+ }
+
+ void HandleBuildingPlacement () {
+ var overUI = UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject();
+
+ if (state == State.PlacingBuilding) {
+ if (Input.GetKeyDown(KeyCode.Mouse1) || Input.GetKeyDown(KeyCode.Escape)) {
+ RTSManager.instance.audioManager.Play(notEnoughResources);
+ AbortBuildingPlacement();
+ }
+
+ buildingPreview.transform.position = RaycastScreenPoint(Input.mousePosition, groundMask).point;
+
+ // Ignore the first frame as that will also be a key down event
+ if (!overUI && Input.GetKeyDown(KeyCode.Mouse0) && Time.frameCount != ignoreFrame) {
+ if (RTSBuildingManager.IsValidBuildingPlacement(buildingPreview)) {
+ if (RTSManager.instance.GetPlayer(1).resources.GetResource(RTSUnit.Type.ResourceCrystal) < buildingInfo.cost) {
+ RTSManager.instance.audioManager.Play(notEnoughResources);
+ Debug.LogError("Not enouch resources");
+ } else {
+ RTSManager.instance.audioManager.Play(click);
+ RTSManager.instance.GetPlayer(1).resources.AddResource(RTSUnit.Type.ResourceCrystal, -buildingInfo.cost);
+ GameObject.Instantiate(buildingInfo.prefab, buildingPreview.transform.position, buildingPreview.transform.rotation);
+ }
+ GameObject.Destroy(buildingPreview);
+ state = State.Normal;
+ } else {
+ // Building placement failed
+ }
+ }
+ }
+ }
+
+ public void StartBuildingPlacement (RTSUnitBuilder.BuildingItem buildingInfo) {
+ if (state == State.PlacingBuilding) {
+ GameObject.Destroy(buildingPreview);
+ state = State.Normal;
+ }
+
+ if (RTSManager.instance.GetPlayer(1).resources.GetResource(RTSUnit.Type.ResourceCrystal) < buildingInfo.cost) {
+ Debug.LogError("Not enouch resources");
+ RTSManager.instance.audioManager.Play(notEnoughResources);
+ return;
+ }
+
+ this.buildingInfo = buildingInfo;
+ buildingPreview = GameObject.Instantiate(buildingInfo.prefab) as GameObject;
+ ignoreFrame = Time.frameCount;
+ state = State.PlacingBuilding;
+
+ // Disable all navmesh cuts and colliders on the preview
+ foreach (var cut in buildingPreview.GetComponentsInChildren<NavmeshCut>()) {
+ cut.enabled = false;
+ }
+ foreach (var coll in buildingPreview.GetComponentsInChildren<Collider>()) {
+ coll.enabled = false;
+ }
+ }
+
+ void AbortBuildingPlacement () {
+ if (buildingPreview != null) {
+ GameObject.Destroy(buildingPreview);
+ state = State.Normal;
+ }
+ }
+
+ void HandleMovement () {
+ if (state == State.Normal && Input.GetKeyDown(KeyCode.Mouse1)) {
+ RTSManager.instance.audioManager.Play(click);
+ RTSManager.instance.units.MoveGroupTo(RTSManager.instance.units.selectedUnits, RaycastScreenPoint(Input.mousePosition, groundMask).point, true, Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.A) ? MovementMode.AttackMove : MovementMode.Move);
+ }
+ }
+
+ void HandleSelection () {
+ var overUI = UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject();
+
+ if (state != State.Normal && state != State.Dragging) return;
+
+ if (!overUI && Input.GetKeyDown(KeyCode.Mouse0)) {
+ dragStart = Input.mousePosition;
+ state = State.Dragging;
+ hasSelected = false;
+ }
+
+ if (state == State.Dragging) {
+ Vector2 dragEnd = Input.mousePosition;
+ var mn = Vector2.Min(dragStart, dragEnd);
+ var mx = Vector2.Max(dragStart, dragEnd);
+ var rect = Rect.MinMaxRect(mn.x, mn.y, mx.x, mx.y);
+
+ bool isSelecting = (dragEnd - dragStart).magnitude > 5;
+ hasSelected |= isSelecting;
+ selectionBox.gameObject.SetActive(isSelecting);
+
+ if (isSelecting) {
+ selectionBox.offsetMin = Vector2.Min(dragStart, dragEnd);
+ selectionBox.offsetMax = Vector2.Max(dragStart, dragEnd);
+ }
+
+ if (!Input.GetKey(KeyCode.Mouse0)) {
+ state = State.Normal;
+ selectionBox.gameObject.SetActive(false);
+
+ if (isSelecting) {
+ RTSManager.instance.units.SetSelection(unit => {
+ var screenPos = RTSManager.instance.units.cam.WorldToScreenPoint(unit.transform.position);
+ return rect.Contains(screenPos);
+ });
+ } else {
+ // Clicking
+ var hit = RaycastScreenPoint(dragEnd, -1);
+ var p = hit.point;
+ float clickFuzzDistance = 0.1f;
+ float minDist = 0;
+ RTSUnit minUnit = hit.collider != null? hit.collider.gameObject.GetComponentInParent<RTSUnit>() : null;
+ if (minUnit == null) {
+ foreach (var unit in RTSManager.instance.units.units) {
+ var dir = unit.transform.position - p;
+ dir.y = 0;
+ var dist = dir.magnitude - unit.radius - clickFuzzDistance;
+ if (dist < minDist) {
+ minDist = dist;
+ minUnit = unit;
+ }
+ }
+ }
+
+ RTSManager.instance.units.SetSelection(u => u == minUnit);
+ }
+ } else if (hasSelected) {
+ foreach (var unit in RTSManager.instance.units.units) {
+ var screenPos = RTSManager.instance.units.cam.WorldToScreenPoint(unit.transform.position);
+ unit.selectionIndicatorEnabled = rect.Contains(screenPos);
+ }
+ }
+ }
+ }
+
+ RaycastHit RaycastScreenPoint (Vector2 mousePosition, LayerMask mask) {
+ var ray = RTSManager.instance.units.cam.ScreenPointToRay(mousePosition);
+ RaycastHit hit;
+
+ if (Physics.Raycast(ray, out hit, float.PositiveInfinity, mask)) {
+ Debug.DrawRay(hit.point, Vector3.up, Color.red, 2);
+ return hit;
+ } else {
+ throw new System.Exception("Mouse raycast did not hit anything");
+ }
+ }
+ }
+}