SelectionManager.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. using UnityEngine;
  2. using UnityEngine.InputSystem;
  3. using System.Collections.Generic;
  4. public class SelectionManager : MonoBehaviour
  5. {
  6. [Header("Selection Settings")]
  7. public LayerMask selectableLayerMask = -1;
  8. public Material ghostMaterial;
  9. private Villager selectedVillager;
  10. private GameObject selectedObject;
  11. private Camera playerCamera;
  12. // Drag and Drop
  13. private bool isDragging = false;
  14. private GameObject dragGhost;
  15. private Vector3 dragStartPosition;
  16. public Villager SelectedVillager => selectedVillager;
  17. public GameObject SelectedObject => selectedObject;
  18. void Start()
  19. {
  20. playerCamera = Camera.main;
  21. if (playerCamera == null)
  22. playerCamera = FindObjectOfType<Camera>();
  23. }
  24. void Update()
  25. {
  26. HandleInput();
  27. HandleDragAndDrop();
  28. }
  29. void HandleInput()
  30. {
  31. // Left click - selection
  32. var mouse = Mouse.current;
  33. if (mouse.leftButton.wasPressedThisFrame)
  34. {
  35. HandleSelection();
  36. }
  37. // Right click - cancel/deselect
  38. if (mouse.rightButton.wasPressedThisFrame)
  39. {
  40. CancelCurrentAction();
  41. }
  42. }
  43. void HandleSelection()
  44. {
  45. if (Mouse.current == null || playerCamera == null) return;
  46. Ray ray = playerCamera.ScreenPointToRay(Mouse.current.position.ReadValue());
  47. RaycastHit hit;
  48. if (Physics.Raycast(ray, out hit, Mathf.Infinity, selectableLayerMask))
  49. {
  50. GameObject hitObject = hit.collider.gameObject;
  51. // Check if we hit a villager
  52. Villager villager = hitObject.GetComponent<Villager>();
  53. if (villager != null)
  54. {
  55. SelectVillager(villager);
  56. return;
  57. }
  58. // Check for other selectable objects
  59. ISelectable selectable = hitObject.GetComponent<ISelectable>();
  60. if (selectable != null)
  61. {
  62. SelectObject(hitObject);
  63. return;
  64. }
  65. // If we hit something else, check parent objects
  66. Transform parent = hitObject.transform.parent;
  67. while (parent != null)
  68. {
  69. villager = parent.GetComponent<Villager>();
  70. if (villager != null)
  71. {
  72. SelectVillager(villager);
  73. return;
  74. }
  75. selectable = parent.GetComponent<ISelectable>();
  76. if (selectable != null)
  77. {
  78. SelectObject(parent.gameObject);
  79. return;
  80. }
  81. parent = parent.parent;
  82. }
  83. }
  84. // If we didn't hit anything selectable, deselect
  85. DeselectAll();
  86. }
  87. void HandleDragAndDrop()
  88. {
  89. if (Mouse.current == null) return;
  90. var mouse = Mouse.current;
  91. // Start dragging
  92. if (selectedVillager != null && mouse.leftButton.wasPressedThisFrame && !isDragging)
  93. {
  94. StartDrag();
  95. }
  96. // Update drag
  97. if (isDragging)
  98. {
  99. UpdateDrag();
  100. }
  101. // End dragging
  102. if (isDragging && mouse.leftButton.wasReleasedThisFrame)
  103. {
  104. EndDrag();
  105. }
  106. }
  107. void StartDrag()
  108. {
  109. isDragging = true;
  110. dragStartPosition = selectedVillager.transform.position;
  111. // Create ghost object
  112. CreateDragGhost();
  113. }
  114. void UpdateDrag()
  115. {
  116. if (dragGhost != null)
  117. {
  118. // Move ghost to mouse position
  119. Ray ray = playerCamera.ScreenPointToRay(Mouse.current.position.ReadValue());
  120. if (Physics.Raycast(ray, out RaycastHit hit))
  121. {
  122. dragGhost.transform.position = hit.point + Vector3.up * 0.1f;
  123. }
  124. }
  125. }
  126. void EndDrag()
  127. {
  128. isDragging = false;
  129. if (dragGhost != null)
  130. {
  131. Vector3 dropPosition = dragGhost.transform.position;
  132. // Check what we're dropping on
  133. Ray ray = playerCamera.ScreenPointToRay(Mouse.current.position.ReadValue());
  134. if (Physics.Raycast(ray, out RaycastHit hit))
  135. {
  136. HandleDrop(hit.collider.gameObject, dropPosition);
  137. }
  138. DestroyDragGhost();
  139. }
  140. }
  141. void CreateDragGhost()
  142. {
  143. if (selectedVillager != null)
  144. {
  145. dragGhost = Instantiate(selectedVillager.gameObject);
  146. // Make it a ghost (semi-transparent, no collisions)
  147. Collider ghostCollider = dragGhost.GetComponent<Collider>();
  148. if (ghostCollider != null)
  149. ghostCollider.enabled = false;
  150. // Remove any scripts that might interfere
  151. Villager ghostVillager = dragGhost.GetComponent<Villager>();
  152. if (ghostVillager != null)
  153. Destroy(ghostVillager);
  154. // Apply ghost material
  155. Renderer ghostRenderer = dragGhost.GetComponent<Renderer>();
  156. if (ghostRenderer != null && ghostMaterial != null)
  157. {
  158. ghostRenderer.material = ghostMaterial;
  159. }
  160. else if (ghostRenderer != null)
  161. {
  162. Color ghostColor = ghostRenderer.material.color;
  163. ghostColor.a = 0.5f;
  164. ghostRenderer.material.color = ghostColor;
  165. }
  166. }
  167. }
  168. void DestroyDragGhost()
  169. {
  170. if (dragGhost != null)
  171. {
  172. Destroy(dragGhost);
  173. dragGhost = null;
  174. }
  175. }
  176. void HandleDrop(GameObject dropTarget, Vector3 dropPosition)
  177. {
  178. if (selectedVillager == null) return;
  179. VillagerManager villagerManager = GameManager.Instance.villagerManager;
  180. // Determine what to do based on drop target
  181. string targetTag = dropTarget.tag;
  182. JobType newJob = targetTag switch
  183. {
  184. "Tree" => JobType.Woodcutter,
  185. "Stone" => JobType.Stonecutter,
  186. "Farm" => JobType.Farmer,
  187. "TownHall" => JobType.None, // Unemployed - return to town hall
  188. _ => selectedVillager.currentJob // Keep current job if dropped on something else
  189. };
  190. if (newJob != selectedVillager.currentJob || (newJob != JobType.None && selectedVillager.targetWorkplace != dropTarget))
  191. {
  192. // Assign job and specific workplace
  193. villagerManager.AssignVillagerToSpecificWorkplace(selectedVillager, newJob, dropTarget);
  194. Debug.Log($"Assigned {selectedVillager.villagerName} to {newJob} at specific {dropTarget.name}");
  195. }
  196. }
  197. public void SelectVillager(Villager villager)
  198. {
  199. // Deselect previous
  200. DeselectAll();
  201. selectedVillager = villager;
  202. selectedObject = villager.gameObject;
  203. villager.SetSelected(true);
  204. Debug.Log($"SelectionManager: Selected villager: {villager.villagerName}");
  205. Debug.Log($"SelectionManager: OnVillagerSelected event triggered");
  206. }
  207. public void SelectObject(GameObject obj)
  208. {
  209. // Deselect previous
  210. DeselectAll();
  211. selectedObject = obj;
  212. ISelectable selectable = obj.GetComponent<ISelectable>();
  213. selectable?.OnSelected();
  214. Debug.Log($"Selected object: {obj.name}");
  215. }
  216. public void DeselectAll()
  217. {
  218. if (selectedVillager != null)
  219. {
  220. selectedVillager.SetSelected(false);
  221. selectedVillager = null;
  222. }
  223. if (selectedObject != null)
  224. {
  225. ISelectable selectable = selectedObject.GetComponent<ISelectable>();
  226. selectable?.OnDeselected();
  227. selectedObject = null;
  228. }
  229. // Cancel any ongoing drag
  230. if (isDragging)
  231. {
  232. isDragging = false;
  233. DestroyDragGhost();
  234. }
  235. }
  236. void CancelCurrentAction()
  237. {
  238. if (isDragging)
  239. {
  240. isDragging = false;
  241. DestroyDragGhost();
  242. }
  243. else
  244. {
  245. DeselectAll();
  246. }
  247. Debug.Log("Cancelled current action");
  248. }
  249. }
  250. // Interface for selectable objects
  251. public interface ISelectable
  252. {
  253. void OnSelected();
  254. void OnDeselected();
  255. }