|
@@ -17,9 +17,17 @@ public class SelectionManager : MonoBehaviour
|
|
|
private GameObject dragGhost;
|
|
private GameObject dragGhost;
|
|
|
private Vector3 dragStartPosition;
|
|
private Vector3 dragStartPosition;
|
|
|
|
|
|
|
|
|
|
+ // Box Selection
|
|
|
|
|
+ private bool isBoxSelecting = false;
|
|
|
|
|
+ private Vector2 boxSelectionStart;
|
|
|
|
|
+
|
|
|
public Villager SelectedVillager => selectedVillager;
|
|
public Villager SelectedVillager => selectedVillager;
|
|
|
public GameObject SelectedObject => selectedObject;
|
|
public GameObject SelectedObject => selectedObject;
|
|
|
|
|
|
|
|
|
|
+ // Event for selection changes
|
|
|
|
|
+ public delegate void SelectionChangedHandler();
|
|
|
|
|
+ public static event SelectionChangedHandler OnSelectionChanged;
|
|
|
|
|
+
|
|
|
void Start()
|
|
void Start()
|
|
|
{
|
|
{
|
|
|
playerCamera = Camera.main;
|
|
playerCamera = Camera.main;
|
|
@@ -35,11 +43,40 @@ public class SelectionManager : MonoBehaviour
|
|
|
|
|
|
|
|
void HandleInput()
|
|
void HandleInput()
|
|
|
{
|
|
{
|
|
|
- // Left click - selection
|
|
|
|
|
|
|
+ // Left click - selection or box selection start
|
|
|
var mouse = Mouse.current;
|
|
var mouse = Mouse.current;
|
|
|
if (mouse.leftButton.wasPressedThisFrame)
|
|
if (mouse.leftButton.wasPressedThisFrame)
|
|
|
{
|
|
{
|
|
|
- HandleSelection();
|
|
|
|
|
|
|
+ // Start potential box selection
|
|
|
|
|
+ boxSelectionStart = mouse.position.ReadValue();
|
|
|
|
|
+ isBoxSelecting = false; // Not yet, wait for drag
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Check if dragging for box selection (only when no villager is selected)
|
|
|
|
|
+ if (mouse.leftButton.isPressed && !isDragging && selectedVillager == null)
|
|
|
|
|
+ {
|
|
|
|
|
+ Vector2 currentMousePos = mouse.position.ReadValue();
|
|
|
|
|
+ float dragDistance = Vector2.Distance(boxSelectionStart, currentMousePos);
|
|
|
|
|
+
|
|
|
|
|
+ // Start box selection if dragged more than 10 pixels
|
|
|
|
|
+ if (dragDistance > 10f && !isBoxSelecting)
|
|
|
|
|
+ {
|
|
|
|
|
+ isBoxSelecting = true;
|
|
|
|
|
+ Debug.Log("Started box selection");
|
|
|
|
|
+ }
|
|
|
|
|
+ } // Complete box selection on release
|
|
|
|
|
+ if (mouse.leftButton.wasReleasedThisFrame)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (isBoxSelecting)
|
|
|
|
|
+ {
|
|
|
|
|
+ CompleteBoxSelection();
|
|
|
|
|
+ isBoxSelecting = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (!isDragging)
|
|
|
|
|
+ {
|
|
|
|
|
+ // Single click selection (only if not dragging)
|
|
|
|
|
+ HandleSelection();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Right click - cancel/deselect
|
|
// Right click - cancel/deselect
|
|
@@ -108,6 +145,9 @@ public class SelectionManager : MonoBehaviour
|
|
|
|
|
|
|
|
var mouse = Mouse.current;
|
|
var mouse = Mouse.current;
|
|
|
|
|
|
|
|
|
|
+ // Don't start dragging if box selecting
|
|
|
|
|
+ if (isBoxSelecting) return;
|
|
|
|
|
+
|
|
|
// Start dragging
|
|
// Start dragging
|
|
|
if (selectedVillager != null && mouse.leftButton.wasPressedThisFrame && !isDragging)
|
|
if (selectedVillager != null && mouse.leftButton.wasPressedThisFrame && !isDragging)
|
|
|
{
|
|
{
|
|
@@ -226,6 +266,17 @@ public class SelectionManager : MonoBehaviour
|
|
|
_ => selectedVillager.currentJob // Keep current job if dropped on something else
|
|
_ => selectedVillager.currentJob // Keep current job if dropped on something else
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ // Special check for Builder job - requires workshop
|
|
|
|
|
+ if (newJob == JobType.Builder)
|
|
|
|
|
+ {
|
|
|
|
|
+ GameObject[] workshops = GameObject.FindGameObjectsWithTag("BuildingWorkshop");
|
|
|
|
|
+ if (workshops == null || workshops.Length == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ Debug.LogWarning("⚠️ Cannot assign Builder job - No Builder's Workshop found! Build one first.");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (newJob != selectedVillager.currentJob || (newJob != JobType.None && selectedVillager.targetWorkplace != dropTarget))
|
|
if (newJob != selectedVillager.currentJob || (newJob != JobType.None && selectedVillager.targetWorkplace != dropTarget))
|
|
|
{
|
|
{
|
|
|
// Assign job and specific workplace
|
|
// Assign job and specific workplace
|
|
@@ -245,6 +296,9 @@ public class SelectionManager : MonoBehaviour
|
|
|
|
|
|
|
|
Debug.Log($"SelectionManager: Selected villager: {villager.villagerName}");
|
|
Debug.Log($"SelectionManager: Selected villager: {villager.villagerName}");
|
|
|
Debug.Log($"SelectionManager: OnVillagerSelected event triggered");
|
|
Debug.Log($"SelectionManager: OnVillagerSelected event triggered");
|
|
|
|
|
+
|
|
|
|
|
+ // Notify UI of selection change
|
|
|
|
|
+ OnSelectionChanged?.Invoke();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void SelectObject(GameObject obj)
|
|
public void SelectObject(GameObject obj)
|
|
@@ -258,6 +312,9 @@ public class SelectionManager : MonoBehaviour
|
|
|
selectable?.OnSelected();
|
|
selectable?.OnSelected();
|
|
|
|
|
|
|
|
Debug.Log($"Selected object: {obj.name}");
|
|
Debug.Log($"Selected object: {obj.name}");
|
|
|
|
|
+
|
|
|
|
|
+ // Notify UI of selection change
|
|
|
|
|
+ OnSelectionChanged?.Invoke();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void DeselectAll()
|
|
public void DeselectAll()
|
|
@@ -281,6 +338,80 @@ public class SelectionManager : MonoBehaviour
|
|
|
isDragging = false;
|
|
isDragging = false;
|
|
|
DestroyDragGhost();
|
|
DestroyDragGhost();
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ Debug.Log("SelectionManager: Deselected all");
|
|
|
|
|
+
|
|
|
|
|
+ // Notify UI of selection change
|
|
|
|
|
+ OnSelectionChanged?.Invoke();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ void OnGUI()
|
|
|
|
|
+ {
|
|
|
|
|
+ if (isBoxSelecting && Mouse.current != null)
|
|
|
|
|
+ {
|
|
|
|
|
+ Vector2 mouseStart = boxSelectionStart;
|
|
|
|
|
+ Vector2 mouseEnd = Mouse.current.position.ReadValue();
|
|
|
|
|
+
|
|
|
|
|
+ // Convert to GUI coordinates (Y is flipped)
|
|
|
|
|
+ mouseStart.y = Screen.height - mouseStart.y;
|
|
|
|
|
+ mouseEnd.y = Screen.height - mouseEnd.y;
|
|
|
|
|
+
|
|
|
|
|
+ Rect selectionRect = new Rect(
|
|
|
|
|
+ Mathf.Min(mouseStart.x, mouseEnd.x),
|
|
|
|
|
+ Mathf.Min(mouseStart.y, mouseEnd.y),
|
|
|
|
|
+ Mathf.Abs(mouseStart.x - mouseEnd.x),
|
|
|
|
|
+ Mathf.Abs(mouseStart.y - mouseEnd.y)
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ // Draw selection box
|
|
|
|
|
+ GUI.color = new Color(0.8f, 0.8f, 0.95f, 0.25f);
|
|
|
|
|
+ GUI.DrawTexture(selectionRect, Texture2D.whiteTexture);
|
|
|
|
|
+ GUI.color = new Color(0.8f, 0.8f, 0.95f, 1f);
|
|
|
|
|
+ GUI.Box(selectionRect, "");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ void CompleteBoxSelection()
|
|
|
|
|
+ {
|
|
|
|
|
+ Vector2 mouseStart = boxSelectionStart;
|
|
|
|
|
+ Vector2 mouseEnd = Mouse.current.position.ReadValue();
|
|
|
|
|
+
|
|
|
|
|
+ // Create screen space rectangle
|
|
|
|
|
+ Rect selectionRect = new Rect(
|
|
|
|
|
+ Mathf.Min(mouseStart.x, mouseEnd.x),
|
|
|
|
|
+ Mathf.Min(mouseStart.y, mouseEnd.y),
|
|
|
|
|
+ Mathf.Abs(mouseStart.x - mouseEnd.x),
|
|
|
|
|
+ Mathf.Abs(mouseStart.y - mouseEnd.y)
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ // Find all villagers
|
|
|
|
|
+ Villager[] allVillagers = FindObjectsOfType<Villager>();
|
|
|
|
|
+ Villager firstVillager = null;
|
|
|
|
|
+
|
|
|
|
|
+ foreach (Villager villager in allVillagers)
|
|
|
|
|
+ {
|
|
|
|
|
+ Vector3 screenPos = playerCamera.WorldToScreenPoint(villager.transform.position);
|
|
|
|
|
+
|
|
|
|
|
+ // Check if villager is in selection box and in front of camera
|
|
|
|
|
+ if (screenPos.z > 0 && selectionRect.Contains(new Vector2(screenPos.x, screenPos.y)))
|
|
|
|
|
+ {
|
|
|
|
|
+ if (firstVillager == null)
|
|
|
|
|
+ {
|
|
|
|
|
+ firstVillager = villager;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Select the first villager found
|
|
|
|
|
+ if (firstVillager != null)
|
|
|
|
|
+ {
|
|
|
|
|
+ SelectVillager(firstVillager);
|
|
|
|
|
+ Debug.Log($"Box selection completed: selected {firstVillager.villagerName}");
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ Debug.Log("Box selection completed: no villagers found");
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CancelCurrentAction()
|
|
void CancelCurrentAction()
|
|
@@ -290,6 +421,10 @@ public class SelectionManager : MonoBehaviour
|
|
|
isDragging = false;
|
|
isDragging = false;
|
|
|
DestroyDragGhost();
|
|
DestroyDragGhost();
|
|
|
}
|
|
}
|
|
|
|
|
+ else if (isBoxSelecting)
|
|
|
|
|
+ {
|
|
|
|
|
+ isBoxSelecting = false;
|
|
|
|
|
+ }
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
DeselectAll();
|
|
DeselectAll();
|