MMCameraController.cs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. using UnityEngine;
  2. public class MMCameraController : MonoBehaviour
  3. {
  4. [Header("Camera Settings")]
  5. public float moveSpeed = 10f;
  6. public float zoomSpeed = 5f;
  7. public float minZoom = 2f;
  8. public float maxZoom = 200f; // Increased for better map overview
  9. [Header("Team Marker Focus")]
  10. public KeyCode centerOnTeamKey = KeyCode.C;
  11. public KeyCode zoomToFullMapKey = KeyCode.F;
  12. public float focusZoomLevel = 10f;
  13. public float centeringSpeed = 2f;
  14. private Camera cam;
  15. private Vector3 lastMousePosition;
  16. private Vector3 targetPosition;
  17. private float targetZoom;
  18. private bool isMovingToTarget = false;
  19. private SimpleTeamPlacement teamPlacement;
  20. void Start()
  21. {
  22. cam = GetComponent<Camera>();
  23. if (cam == null)
  24. cam = Camera.main;
  25. // Set up camera for top-down view
  26. cam.orthographic = true; // Ensure camera is in orthographic mode for top-down view
  27. // Position camera above the map center, looking down
  28. float mapCenterX = 0f;
  29. float mapCenterZ = 0f;
  30. float cameraHeight = 50f; // High above the map
  31. // Try to get map size from MapMaker2 to center properly
  32. var mapMaker = FindFirstObjectByType<MapMaker2>();
  33. if (mapMaker != null)
  34. {
  35. var mapData = mapMaker.GetMapData();
  36. if (mapData != null)
  37. {
  38. mapCenterX = mapData.Width / 2f;
  39. mapCenterZ = mapData.Height / 2f;
  40. cameraHeight = Mathf.Max(mapData.Width, mapData.Height) * 0.7f; // Scale height with map size
  41. }
  42. }
  43. transform.position = new Vector3(mapCenterX, cameraHeight, mapCenterZ);
  44. // Set camera to look straight down at the map (90 degrees on X-axis)
  45. transform.rotation = Quaternion.Euler(90f, 0f, 0f);
  46. // Set orthographic size to show a good portion of the map
  47. if (cam.orthographic)
  48. {
  49. cam.orthographicSize = Mathf.Max(20f, cameraHeight * 0.3f);
  50. }
  51. // Initialize target values
  52. targetPosition = transform.position;
  53. targetZoom = cam.orthographicSize;
  54. // Find team placement component
  55. teamPlacement = FindFirstObjectByType<SimpleTeamPlacement>();
  56. Debug.Log($"🎥 Camera initialized: Position={transform.position}, Rotation={transform.rotation.eulerAngles}, OrthographicSize={cam.orthographicSize}, Mode={(cam.orthographic ? "Orthographic" : "Perspective")}");
  57. }
  58. void Update()
  59. {
  60. // Handle team marker centering
  61. if (Input.GetKeyDown(centerOnTeamKey))
  62. {
  63. CenterOnTeamMarker();
  64. }
  65. // Handle zoom to full map
  66. if (Input.GetKeyDown(zoomToFullMapKey))
  67. {
  68. ZoomToFullMap();
  69. }
  70. // Handle smooth movement to target
  71. if (isMovingToTarget)
  72. {
  73. transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * centeringSpeed);
  74. cam.orthographicSize = Mathf.Lerp(cam.orthographicSize, targetZoom, Time.deltaTime * centeringSpeed);
  75. // Check if we're close enough to stop moving
  76. if (Vector3.Distance(transform.position, targetPosition) < 0.1f &&
  77. Mathf.Abs(cam.orthographicSize - targetZoom) < 0.1f)
  78. {
  79. isMovingToTarget = false;
  80. }
  81. }
  82. else
  83. {
  84. // Normal camera controls
  85. HandleMovement();
  86. HandleZoom();
  87. HandleMouseDrag();
  88. }
  89. // Help find ForestRiver tiles
  90. if (Input.GetKeyDown(KeyCode.H))
  91. {
  92. Debug.Log("💡 Camera Controls:\n" +
  93. $"- {centerOnTeamKey}: Center on team marker (preserves zoom)\n" +
  94. $"- {zoomToFullMapKey}: Zoom to full map\n" +
  95. "- WASD/Arrows: Move camera\n" +
  96. $"- Mouse wheel: Zoom (range: {minZoom}-{maxZoom})\n" +
  97. "- Middle mouse: Drag\n" +
  98. "- R: Place team randomly (if needed)\n" +
  99. "- F: Look for blue-green ForestRiver tiles");
  100. }
  101. }
  102. /// <summary>
  103. /// Center the camera on the team marker position
  104. /// </summary>
  105. public void CenterOnTeamMarker()
  106. {
  107. if (teamPlacement == null)
  108. {
  109. teamPlacement = FindFirstObjectByType<SimpleTeamPlacement>();
  110. }
  111. if (teamPlacement != null && teamPlacement.IsTeamPlaced())
  112. {
  113. GameObject teamMarker = teamPlacement.GetTeamMarker();
  114. if (teamMarker != null)
  115. {
  116. Vector3 teamPos = teamMarker.transform.position;
  117. // Set target position to center on team marker (keep Y position for camera height)
  118. // For top-down view: X and Z are the map coordinates, Y is camera height
  119. targetPosition = new Vector3(teamPos.x, transform.position.y, teamPos.z);
  120. // Keep current zoom level instead of changing to focusZoomLevel
  121. targetZoom = cam.orthographicSize;
  122. isMovingToTarget = true;
  123. Debug.Log($"🎯 Centering camera on team marker at position: {teamPos}");
  124. }
  125. else
  126. {
  127. Debug.LogWarning("⚠️ Team marker object not found! Team may not be properly placed.");
  128. // Try to find team marker by name as backup
  129. GameObject foundMarker = GameObject.Find("TeamMarker");
  130. if (foundMarker != null)
  131. {
  132. Vector3 teamPos = foundMarker.transform.position;
  133. targetPosition = new Vector3(teamPos.x, transform.position.y, teamPos.z);
  134. targetZoom = cam.orthographicSize;
  135. isMovingToTarget = true;
  136. Debug.Log($"🎯 Found team marker by name, centering at: {teamPos}");
  137. }
  138. else
  139. {
  140. Debug.LogError("❌ Could not find team marker by name either!");
  141. }
  142. }
  143. }
  144. else
  145. {
  146. Debug.LogWarning("⚠️ Team placement not found or team not placed! Try pressing R to place team first.");
  147. }
  148. }
  149. /// <summary>
  150. /// Zoom out to show the entire map
  151. /// </summary>
  152. public void ZoomToFullMap()
  153. {
  154. MapData mapData = null;
  155. float tileSize = 1f;
  156. // Try to find MapMaker2 first
  157. MapMaker2 mapMaker = FindFirstObjectByType<MapMaker2>();
  158. if (mapMaker != null)
  159. {
  160. mapData = mapMaker.GetMapData();
  161. // Get the MapVisualizer to account for tile scaling
  162. MapVisualizer mapVisualizer = FindFirstObjectByType<MapVisualizer>();
  163. tileSize = mapVisualizer != null ? mapVisualizer.tileSize : 1f;
  164. }
  165. if (mapData != null)
  166. {
  167. // Calculate map center accounting for tile size
  168. targetPosition = new Vector3(
  169. (mapData.Width * tileSize) / 2f,
  170. transform.position.y,
  171. (mapData.Height * tileSize) / 2f
  172. );
  173. // Calculate required zoom to fit entire map
  174. float mapHeight = mapData.Height * tileSize;
  175. float mapWidth = mapData.Width * tileSize;
  176. float mapSize = Mathf.Max(mapWidth, mapHeight);
  177. targetZoom = (mapSize / 2f) + 5f; // Add padding for better view
  178. targetZoom = Mathf.Clamp(targetZoom, minZoom, maxZoom);
  179. isMovingToTarget = true;
  180. Debug.Log($"🗺️ Zooming to full map: Size {mapData.Width}x{mapData.Height}, TileSize: {tileSize}, WorldSize: {mapWidth:F1}x{mapHeight:F1}, Zoom: {targetZoom}");
  181. }
  182. else
  183. {
  184. Debug.LogWarning("⚠️ No MapMaker2 component found!");
  185. }
  186. }
  187. private void HandleMovement()
  188. {
  189. float horizontal = Input.GetAxis("Horizontal");
  190. float vertical = Input.GetAxis("Vertical");
  191. if (horizontal != 0 || vertical != 0)
  192. {
  193. // For top-down view: horizontal = X movement, vertical = Z movement
  194. Vector3 movement = new Vector3(horizontal, 0, vertical) * moveSpeed * Time.deltaTime;
  195. transform.Translate(movement, Space.World); // Use world space for consistent movement
  196. // Stop automatic movement to target if user is manually controlling
  197. isMovingToTarget = false;
  198. targetPosition = transform.position;
  199. }
  200. }
  201. private void HandleZoom()
  202. {
  203. float scroll = Input.GetAxis("Mouse ScrollWheel");
  204. if (scroll != 0)
  205. {
  206. float oldSize = cam.orthographicSize;
  207. float newSize = cam.orthographicSize - scroll * zoomSpeed;
  208. newSize = Mathf.Clamp(newSize, minZoom, maxZoom);
  209. cam.orthographicSize = newSize;
  210. // Debug log to check zoom limits
  211. if (newSize >= maxZoom - 0.1f || newSize <= minZoom + 0.1f)
  212. {
  213. Debug.Log($"🔍 Zoom limit reached: {newSize:F1} (min: {minZoom}, max: {maxZoom})");
  214. }
  215. // Update target zoom if we're not moving to a target
  216. if (!isMovingToTarget)
  217. {
  218. targetZoom = newSize;
  219. }
  220. }
  221. }
  222. private void HandleMouseDrag()
  223. {
  224. if (Input.GetMouseButtonDown(2)) // Middle mouse button
  225. {
  226. lastMousePosition = Input.mousePosition;
  227. }
  228. if (Input.GetMouseButton(2))
  229. {
  230. Vector3 delta = Input.mousePosition - lastMousePosition;
  231. Vector3 worldDelta = cam.ScreenToWorldPoint(delta) - cam.ScreenToWorldPoint(Vector3.zero);
  232. transform.position -= worldDelta;
  233. lastMousePosition = Input.mousePosition;
  234. // Stop automatic movement to target if user is manually controlling
  235. isMovingToTarget = false;
  236. targetPosition = transform.position;
  237. }
  238. }
  239. }