using UnityEngine;
///
/// Universal camera controller for focusing on team marker and managing map overview.
/// Can be attached to any camera to provide team marker centering functionality.
///
public class TeamMarkerCameraController : MonoBehaviour
{
[Header("Team Marker Focus Settings")]
[Tooltip("Key to center camera on team marker")]
public KeyCode centerOnTeamKey = KeyCode.C;
[Tooltip("Key to zoom out to show full map")]
public KeyCode zoomToFullMapKey = KeyCode.F;
[Tooltip("Key to show help information")]
public KeyCode showHelpKey = KeyCode.H;
[Header("Movement Settings")]
[Tooltip("Speed of camera movement when centering")]
[Range(0.5f, 5f)]
public float centeringSpeed = 2f;
[Tooltip("Zoom level when focusing on team marker")]
[Range(5f, 50f)]
public float focusZoomLevel = 15f;
[Tooltip("Maximum zoom out level for full map view")]
[Range(50f, 300f)]
public float maxZoomOut = 200f;
[Header("Auto-Center Settings")]
[Tooltip("Automatically center on team marker when it's first placed")]
public bool autoCenterOnTeamPlacement = true;
[Tooltip("Delay before auto-centering (allows map to generate first)")]
[Range(0f, 5f)]
public float autoCenterDelay = 2f;
// Private variables
private Camera cam;
private Vector3 targetPosition;
private float targetZoom;
private bool isMovingToTarget = false;
private SimpleTeamPlacement teamPlacement;
private bool hasAutocentered = false;
void Start()
{
cam = GetComponent();
if (cam == null)
cam = Camera.main;
// Initialize target values
targetPosition = transform.position;
targetZoom = cam.orthographicSize;
// Find team placement component
teamPlacement = FindFirstObjectByType();
// Auto-center on team marker after delay if enabled
if (autoCenterOnTeamPlacement)
{
Invoke(nameof(AutoCenterOnTeamMarker), autoCenterDelay);
}
}
void Update()
{
// Handle input
HandleInput();
// Handle smooth movement to target
if (isMovingToTarget)
{
HandleSmoothMovement();
}
}
private void HandleInput()
{
// Center on team marker
if (Input.GetKeyDown(centerOnTeamKey))
{
CenterOnTeamMarker();
}
// Zoom to full map
if (Input.GetKeyDown(zoomToFullMapKey))
{
ZoomToFullMap();
}
// Show help
if (Input.GetKeyDown(showHelpKey))
{
ShowHelp();
}
}
private void HandleSmoothMovement()
{
// Smoothly move camera to target position and zoom
transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * centeringSpeed);
cam.orthographicSize = Mathf.Lerp(cam.orthographicSize, targetZoom, Time.deltaTime * centeringSpeed);
// Check if we're close enough to stop moving
float positionDistance = Vector3.Distance(transform.position, targetPosition);
float zoomDistance = Mathf.Abs(cam.orthographicSize - targetZoom);
if (positionDistance < 0.5f && zoomDistance < 0.5f)
{
isMovingToTarget = false;
Debug.Log("🎯 Camera movement complete");
}
}
///
/// Center the camera on the team marker position
///
public void CenterOnTeamMarker()
{
if (teamPlacement == null)
{
teamPlacement = FindFirstObjectByType();
}
if (teamPlacement != null && teamPlacement.IsTeamPlaced())
{
GameObject teamMarker = teamPlacement.GetTeamMarker();
if (teamMarker != null)
{
Vector3 teamPos = teamMarker.transform.position;
// Set target position to center on team marker (preserve camera height)
targetPosition = new Vector3(teamPos.x, transform.position.y, teamPos.z);
targetZoom = focusZoomLevel;
isMovingToTarget = true;
Debug.Log($"🎯 Centering camera on team marker at position: {teamPos}");
}
else
{
Debug.LogWarning("⚠️ Team marker object not found!");
}
}
else
{
Debug.LogWarning("⚠️ Team placement not found or team not placed!");
}
}
///
/// Zoom out to show the entire map
///
public void ZoomToFullMap()
{
// Try to find MapMaker2 first
MapMaker2 mapMaker = FindFirstObjectByType();
if (mapMaker != null)
{
var mapData = mapMaker.GetMapData();
if (mapData != null)
{
SetFullMapView(mapData.Width, mapData.Height);
return;
}
}
// Last resort: Use a reasonable default size
Debug.LogWarning("⚠️ Could not find map data, using default map size for full view");
SetFullMapView(100, 100);
}
private void SetFullMapView(int mapWidth, int mapHeight)
{
// Calculate map center
targetPosition = new Vector3(
mapWidth / 2f,
transform.position.y,
mapHeight / 2f
);
// Calculate required zoom to fit entire map with some padding
float mapSize = Mathf.Max(mapWidth, mapHeight);
targetZoom = Mathf.Min(mapSize * 0.8f, maxZoomOut);
isMovingToTarget = true;
Debug.Log($"🗺️ Zooming to full map: Size {mapWidth}x{mapHeight}, Zoom: {targetZoom}");
}
///
/// Auto-center on team marker (called after delay)
///
private void AutoCenterOnTeamMarker()
{
if (!hasAutocentered && autoCenterOnTeamPlacement)
{
hasAutocentered = true;
CenterOnTeamMarker();
}
}
///
/// Show help information in console
///
private void ShowHelp()
{
Debug.Log("🎮 Team Marker Camera Controls:\n" +
$"- {centerOnTeamKey}: Center camera on team marker\n" +
$"- {zoomToFullMapKey}: Zoom out to show full map\n" +
$"- {showHelpKey}: Show this help\n" +
"- Mouse wheel: Zoom in/out\n" +
"- WASD/Arrow keys: Move camera (if supported by main controller)\n" +
"- Middle mouse: Drag camera (if supported by main controller)");
}
///
/// Stop any automatic camera movement (useful when user wants manual control)
///
public void StopAutoMovement()
{
isMovingToTarget = false;
targetPosition = transform.position;
targetZoom = cam.orthographicSize;
}
///
/// Force update team placement reference (useful if team placement changes)
///
public void RefreshTeamPlacement()
{
teamPlacement = FindFirstObjectByType();
}
void OnEnable()
{
// Show brief help when component is enabled
Invoke(nameof(ShowBriefHelp), 1f);
}
private void ShowBriefHelp()
{
Debug.Log($"🎯 Team Marker Camera Controller enabled! Press {showHelpKey} for help.");
}
}