void LateUpdate() { if (!marqueeActive) { // No raycasting when over a GUI widget. if (GUIUtility.hotControl != 0) { disabledBecauseGUI = true; } // Wait for mouse0 to go up, then wait a frame. if (disabledBecauseGUI) { if (Input.GetMouseButtonUp(0)) { disabledBecauseGUI = false; } return; } } if (activeGhost != null) { TryToPlaceThing(); return; } if (selectedUnits != null) { selectedUnits.RemoveAll(e => e == null); } bool addToSelection = ModifierActive("left shift") || ModifierActive("right shift"); if (Input.GetButtonUp("Select")) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (!addToSelection) { ClearSelected(); } // Selectable units only. RaycastHit hit; if (Physics.Raycast(ray, out hit, Mathf.Infinity, 1 << selectableThingLayer)) { var unit = hit.transform.gameObject; if (!selectedUnits.Contains(unit)) { SelectUnit(unit); } else if (addToSelection) { DeselectUnit(unit); } } } if (Input.GetButtonUp("Action")) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // Shoot for units first. RaycastHit hit; if (Physics.Raycast(ray, out hit, Mathf.Infinity, 1 << selectableThingLayer)) { Entity target = hit.transform.gameObject.GetComponent <Entity>(); foreach (var unit in selectedUnits) { if (unit == null) { continue; } ComSat.IssueAttack(unit.GetComponent <Entity>(), new[] { target }); } // Otherwise, do a move. } else if (Physics.Raycast(ray, out hit, Mathf.Infinity, 1 << terrainLayer)) { DVector2 point = new DVector2((DReal)hit.point.z, (DReal)hit.point.x); foreach (var unit in selectedUnits) { if (unit == null) { continue; } ComSat.IssueMove(unit.GetComponent <Entity>(), point); } } } if (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1)) { marqueeMode = Input.GetMouseButtonDown(0) ? MarqueeMode.Select : MarqueeMode.Target; marqueeActive = true; marqueeOrigin = MousePosition(); } if (Input.GetMouseButtonUp(0) || Input.GetMouseButtonUp(1)) { if (marqueeRect.width != 0 && marqueeRect.height != 0) { var selection = new List <Entity>(); if (!addToSelection && Input.GetMouseButtonUp(0)) { ClearSelected(); } var selectableUnits = GameObject.FindGameObjectsWithTag("MultiSelectableUnit"); foreach (GameObject unit in selectableUnits) { Entity e = unit.GetComponent <Entity>(); if (e == null) { Debug.LogWarning("No entity in unit " + unit); continue; } if (marqueeMode == MarqueeMode.Select && e.team != ComSat.localTeam) { continue; } if (marqueeMode == MarqueeMode.Target && e.team == ComSat.localTeam) { continue; } // Convert the world position of the unit to a screen position and then to a GUI point. Vector3 screenPos = Camera.main.WorldToScreenPoint(unit.transform.position); Vector2 screenPoint = new Vector2(screenPos.x, Screen.height - screenPos.y); if (marqueeRect.Contains(screenPoint)) { selection.Add(e); } } if (marqueeMode == MarqueeMode.Select) { foreach (var u in selection) { SelectUnit(u.gameObject); } } else { var a = selection.ToArray(); foreach (var attacker in selectedUnits) { if (attacker == null) { continue; } ComSat.IssueAttack(attacker.GetComponent <Entity>(), a); } } } // Reset the marquee so it no longer appears on the screen. marqueeRect.width = 0; marqueeRect.height = 0; marqueeActive = false; } if (Input.GetMouseButton(0) || Input.GetMouseButton(1)) { Vector2 mouse = MousePosition(); // Compute a new marquee rectangle. marqueeRect.x = marqueeOrigin.x; marqueeRect.y = marqueeOrigin.y; marqueeRect.width = mouse.x - marqueeOrigin.x; marqueeRect.height = mouse.y - marqueeOrigin.y; // Prevent negative widths/heights. if (marqueeRect.width < 0) { marqueeRect.x += marqueeRect.width; marqueeRect.width = -marqueeRect.width; } if (marqueeRect.height < 0) { marqueeRect.y += marqueeRect.height; marqueeRect.height = -marqueeRect.height; } } GroupStuff(); }