MMCameraController.cs 10 KB

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