Files
Click-PointRPG/Assets/Scripts/SelectionManager.cs

140 lines
3.5 KiB
C#
Raw Permalink Normal View History

2026-02-10 21:27:46 +00:00
using UnityEngine;
using TMPro;
public class SelectionManager : MonoBehaviour
{
public static SelectionManager Instance { get; private set; }
[Header("Nameplate")]
public Canvas worldSpaceCanvas; // a World Space Canvas in scene
public GameObject nameplatePrefab; // prefab containing TextMeshProUGUI
public Vector3 nameplateOffset = new Vector3(0, 2.2f, 0);
[Header("Colors")]
public Color friendlyColor = Color.green;
public Color neutralColor = Color.cyan;
public Color enemyColor = Color.red;
Selectable current;
GameObject activeNameplate;
NameplateController nameplateController;
void Awake()
{
2026-02-11 17:30:49 +00:00
if (Instance != null && Instance != this)
{
Debug.LogWarning("Multiple SelectionManager instances detected. Destroying duplicate.", gameObject);
Destroy(gameObject);
return;
}
2026-02-10 21:27:46 +00:00
Instance = this;
}
2026-02-11 17:30:49 +00:00
void OnDestroy()
{
if (Instance == this) Instance = null;
}
2026-02-10 21:27:46 +00:00
public void Select(Selectable s)
{
2026-02-11 17:30:49 +00:00
if (s == null)
{
ClearSelection();
return;
}
2026-02-10 21:27:46 +00:00
if (current == s) return;
ClearSelection();
current = s;
2026-02-11 17:30:49 +00:00
current.OnSelected();
2026-02-10 21:27:46 +00:00
2026-02-11 17:30:49 +00:00
CreateNameplate(s.displayName, GetColorForAttitude(s.attitude));
}
public void Select(Building b)
{
if (b == null)
2026-02-10 21:27:46 +00:00
{
2026-02-11 17:30:49 +00:00
ClearSelection();
return;
}
ClearSelection();
b.OnSelected();
CreateNameplate(b.displayName, GetColorForAttitude(b.attitude));
}
void CreateNameplate(string displayName, Color color)
{
if (nameplatePrefab == null || worldSpaceCanvas == null) return;
activeNameplate = Instantiate(nameplatePrefab, worldSpaceCanvas.transform, false);
nameplateController = activeNameplate.GetComponent<NameplateController>();
if (nameplateController == null)
{
Debug.LogError("NameplateController not found on nameplate prefab!", nameplatePrefab);
DestroyNameplate();
return;
}
if (current != null)
{
nameplateController.Initialize(current, color, nameplateOffset);
}
else
{
// For buildings, we'll update in LateUpdate with the last known target
nameplateController.SetDisplayName(displayName);
nameplateController.ApplyColor(color);
2026-02-10 21:27:46 +00:00
}
}
public void ClearSelection()
{
2026-02-11 17:30:49 +00:00
if (current != null)
{
current.OnDeselected();
current = null;
}
2026-02-10 21:27:46 +00:00
2026-02-11 17:30:49 +00:00
DestroyNameplate();
}
void DestroyNameplate()
{
2026-02-10 21:27:46 +00:00
if (activeNameplate != null) Destroy(activeNameplate);
activeNameplate = null;
nameplateController = null;
}
Color GetColorForAttitude(Attitude a)
{
2026-02-11 17:30:49 +00:00
return a switch
2026-02-10 21:27:46 +00:00
{
2026-02-11 17:30:49 +00:00
Attitude.Friendly => friendlyColor,
Attitude.Neutral => neutralColor,
Attitude.Enemy => enemyColor,
_ => neutralColor
};
2026-02-10 21:27:46 +00:00
}
2026-02-11 17:30:49 +00:00
void LateUpdate()
2026-02-10 21:27:46 +00:00
{
2026-02-11 17:30:49 +00:00
// Update nameplate position if it exists and has a target
2026-02-10 21:27:46 +00:00
if (nameplateController != null && current != null)
{
nameplateController.FollowTarget(current.transform, nameplateOffset);
}
2026-02-11 17:30:49 +00:00
// Clean up orphaned nameplates if current object was destroyed
2026-02-10 21:27:46 +00:00
if (current == null && activeNameplate != null)
{
2026-02-11 17:30:49 +00:00
DestroyNameplate();
2026-02-10 21:27:46 +00:00
}
}
}