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

140 lines
3.5 KiB
C#

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()
{
if (Instance != null && Instance != this)
{
Debug.LogWarning("Multiple SelectionManager instances detected. Destroying duplicate.", gameObject);
Destroy(gameObject);
return;
}
Instance = this;
}
void OnDestroy()
{
if (Instance == this) Instance = null;
}
public void Select(Selectable s)
{
if (s == null)
{
ClearSelection();
return;
}
if (current == s) return;
ClearSelection();
current = s;
current.OnSelected();
CreateNameplate(s.displayName, GetColorForAttitude(s.attitude));
}
public void Select(Building b)
{
if (b == null)
{
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);
}
}
public void ClearSelection()
{
if (current != null)
{
current.OnDeselected();
current = null;
}
DestroyNameplate();
}
void DestroyNameplate()
{
if (activeNameplate != null) Destroy(activeNameplate);
activeNameplate = null;
nameplateController = null;
}
Color GetColorForAttitude(Attitude a)
{
return a switch
{
Attitude.Friendly => friendlyColor,
Attitude.Neutral => neutralColor,
Attitude.Enemy => enemyColor,
_ => neutralColor
};
}
void LateUpdate()
{
// Update nameplate position if it exists and has a target
if (nameplateController != null && current != null)
{
nameplateController.FollowTarget(current.transform, nameplateOffset);
}
// Clean up orphaned nameplates if current object was destroyed
if (current == null && activeNameplate != null)
{
DestroyNameplate();
}
}
}