Files
2026-07-21 08:58:18 +05:30

208 lines
6.4 KiB
C#

using UnityEngine;
using UnityEngine.UI;
public class MinimapManager : MonoBehaviour
{
[Header("Camera/RenderTexture Settings")]
[Tooltip("Optional: If set, the minimap camera will render into this RenderTexture.")]
public RenderTexture targetTexture;
[Tooltip("Optional: If set, this RawImage's texture will be assigned to the target RenderTexture.")]
public RawImage targetRawImage;
[Tooltip("Layers rendered by the minimap camera (include 'Minimap' layer here).")]
public LayerMask cullingMask = ~0;
[Header("Follow Settings")]
public Vector3 offset = new Vector3(0f, 50f, 0f);
[Tooltip("GTA V style: map rotates with player heading, player icon stays centered pointing up.")]
public bool rotateWithPlayer = true;
[Tooltip("How fast the minimap rotation follows the player heading. Higher = snappier.")]
public float rotationSmoothSpeed = 10f;
[Header("Zoom Settings")]
public float defaultZoom = 50f;
public float zoomLerpSpeed = 5f;
private Transform player;
private Camera minimapCam;
private float targetZoom;
private bool isCashSystemMode = false;
private float refreshTimer = 0f;
private float refreshInterval = 1f;
/// <summary>
/// The camera's current smoothed Y heading angle.
/// MinimapMarker reads this to match the player chevron rotation exactly.
/// </summary>
public static float SmoothedHeading { get; private set; }
void Awake()
{
minimapCam = GetComponent<Camera>();
if (minimapCam == null)
{
Debug.LogError("MinimapManager must be placed on a Camera object.");
enabled = false;
return;
}
minimapCam.orthographic = true;
minimapCam.orthographicSize = defaultZoom;
minimapCam.nearClipPlane = 0.01f;
minimapCam.farClipPlane = 1000f;
minimapCam.clearFlags = CameraClearFlags.SolidColor;
minimapCam.backgroundColor = new Color(0, 0, 0, 0);
// Ensure Minimap layer is visible
int minimapLayer = LayerMask.NameToLayer("Minimap");
if (minimapLayer >= 0)
{
cullingMask |= (1 << minimapLayer);
Debug.Log($"[MinimapManager] Found Minimap layer: {minimapLayer}");
}
else
{
// FALLBACK: If Minimap layer doesn't exist, use layer 31 (where markers fall back to)
cullingMask |= (1 << 31);
Debug.LogWarning("[MinimapManager] 'Minimap' layer not found! Using layer 31 fallback. " +
"Create 'Minimap' layer in Project Settings for best results.");
}
// Legacy layer support
int iconsLayer = LayerMask.NameToLayer("minimapIcons");
if (iconsLayer >= 0)
{
cullingMask |= (1 << iconsLayer);
}
minimapCam.cullingMask = cullingMask;
if (targetTexture != null)
{
minimapCam.targetTexture = targetTexture;
if (targetRawImage != null)
{
targetRawImage.texture = targetTexture;
}
}
targetZoom = defaultZoom;
}
void Start()
{
// Check game mode
isCashSystemMode = SelectionOptions.Instance != null && SelectionOptions.Instance.isCashSystemSelected;
FindPlayer();
// IMPORTANT: Ensure MinimapMarkerManager exists for markers in ALL modes
MinimapMarkerManager.EnsureExists();
// Create edge indicators for off-screen entities
if (targetRawImage != null)
{
MinimapEdgeIndicator.AttachTo(targetRawImage.rectTransform);
// Add click-to-expand controller
if (targetRawImage.GetComponent<MinimapExpandController>() == null)
targetRawImage.gameObject.AddComponent<MinimapExpandController>();
}
Debug.Log($"[MinimapManager] Initialized - Cash System Mode: {isCashSystemMode}. Using Markers Only.");
Debug.Log("[MinimapManager] IMPORTANT: Main Camera must EXCLUDE 'Minimap' layer from Culling Mask!");
}
void LateUpdate()
{
if (player == null)
{
// Try to find player periodically
FindPlayer();
return;
}
// Periodic check to switch targets if control changed
refreshTimer += Time.deltaTime;
if (refreshTimer >= refreshInterval)
{
refreshTimer = 0f;
FindPlayer();
}
// --- Camera follow ---
transform.position = player.position + offset;
if (rotateWithPlayer)
{
// Smooth rotation for GTA V feel — no jerky snapping
Quaternion targetRotation = Quaternion.Euler(90f, player.eulerAngles.y, 0f);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationSmoothSpeed);
// Expose the ACTUAL smoothed angle so markers can match perfectly
SmoothedHeading = transform.eulerAngles.y;
}
else
{
transform.rotation = Quaternion.Euler(90f, 0f, 0f);
SmoothedHeading = 0f;
}
// Smooth zoom
minimapCam.orthographicSize = Mathf.Lerp(
minimapCam.orthographicSize,
targetZoom,
Time.deltaTime * zoomLerpSpeed
);
}
private void FindPlayer()
{
PlayerControllerNewRohan playerController =
FindObjectOfType<PlayerControllerNewRohan>();
if (playerController != null)
{
player = playerController.transform;
return;
}
GameObject p = GameObject.FindGameObjectWithTag("Player");
if (p != null)
{
player = p.transform;
}
}
// === Public APIs ===
public void SetTarget(Transform newTarget)
{
player = newTarget;
}
public void SetZoom(float zoomSize)
{
targetZoom = Mathf.Max(1f, zoomSize);
}
public void ZoomIn(float amount = 5f)
{
SetZoom(targetZoom - amount);
}
public void ZoomOut(float amount = 5f)
{
SetZoom(targetZoom + amount);
}
// Kept for compatibility, but does nothing now as markers manage themselves
public void ForceRefresh()
{
FindPlayer();
}
public Transform Player => player;
public Camera MinimapCamera => minimapCam;
}