EscapeShooter/My project/Assets/Project Files/Modules/Floating Text/FloatingTextController.cs

174 lines
8.0 KiB
C#

using System.Collections.Generic;
using UnityEngine;
namespace Watermelon
{
public class FloatingTextController : MonoBehaviour
{
private static FloatingTextController floatingTextController;
[SerializeField] FloatingTextCase[] floatingTextCases;
private Dictionary<int, FloatingTextCase> floatingTextLink;
[Tooltip("Minimal gap between a UI floating text's rendered bounds and the screen edge — spawn positions are snapped inward so the whole text stays visible. In canvas units.")]
[SerializeField] float screenEdgeMargin = 24f;
public void Init()
{
floatingTextController = this;
floatingTextLink = new Dictionary<int, FloatingTextCase>();
for (int i = 0; i < floatingTextCases.Length; i++)
{
FloatingTextCase floatingText = floatingTextCases[i];
if(string.IsNullOrEmpty(floatingText.Name))
{
Debug.LogError("[Floating Text]: Floating Text initialization failed. A unique name (ID) must be provided. Please ensure the 'name' field is not empty before proceeding.", this);
continue;
}
if (floatingText.FloatingTextBehavior == null)
{
Debug.LogError(string.Format("Floating Text ({0}) initialization failed. No Floating Text Behavior linked. Please assign a valid Floating Text Behavior before proceeding.", floatingText.Name), this);
continue;
}
floatingText.Init();
floatingTextLink.Add(floatingText.Name.GetHashCode(), floatingText);
}
}
private void OnDestroy()
{
if(!floatingTextCases.IsNullOrEmpty())
{
for (int i = 0; i < floatingTextCases.Length; i++)
{
PoolManager.DestroyPool(floatingTextCases[i].FloatingTextPool);
}
}
}
public static FloatingTextBaseBehavior SpawnFloatingText(string floatingTextName, Vector3 position)
{
return SpawnFloatingText(floatingTextName.GetHashCode(), string.Empty, position, Quaternion.identity, 1.0f, Color.white);
}
public static FloatingTextBaseBehavior SpawnFloatingText(int floatingTextNameHash, Vector3 position)
{
return SpawnFloatingText(floatingTextNameHash, string.Empty, position, Quaternion.identity, 1.0f, Color.white);
}
public static FloatingTextBaseBehavior SpawnFloatingText(string floatingTextName, string text, Vector3 position)
{
return SpawnFloatingText(floatingTextName.GetHashCode(), text, position, Quaternion.identity, 1.0f, Color.white);
}
public static FloatingTextBaseBehavior SpawnFloatingText(int floatingTextNameHash, string text, Vector3 position)
{
return SpawnFloatingText(floatingTextNameHash, text, position, Quaternion.identity, 1.0f, Color.white);
}
public static FloatingTextBaseBehavior SpawnFloatingText(string floatingTextName, string text, Vector3 position, Quaternion rotation)
{
return SpawnFloatingText(floatingTextName.GetHashCode(), text, position, rotation, 1.0f, Color.white);
}
public static FloatingTextBaseBehavior SpawnFloatingText(int floatingTextNameHash, string text, Vector3 position, Quaternion rotation)
{
return SpawnFloatingText(floatingTextNameHash, text, position, rotation, 1.0f, Color.white);
}
public static FloatingTextBaseBehavior SpawnFloatingText(string floatingTextName, string text, Vector3 position, Quaternion rotation, float scaleMultiplier)
{
return SpawnFloatingText(floatingTextName.GetHashCode(), text, position, rotation, scaleMultiplier, Color.white);
}
public static FloatingTextBaseBehavior SpawnFloatingText(int floatingTextNameHash, string text, Vector3 position, Quaternion rotation, float scaleMultiplier)
{
return SpawnFloatingText(floatingTextNameHash, text, position, rotation, scaleMultiplier, Color.white);
}
public static FloatingTextBaseBehavior SpawnFloatingText(string floatingTextName, string text, Vector3 position, Quaternion rotation, float scaleMultiplier, Color color)
{
return SpawnFloatingText(floatingTextName.GetHashCode(), text, position, rotation, scaleMultiplier, color);
}
public static FloatingTextBaseBehavior SpawnFloatingText(int floatingTextNameHash, string text, Vector3 position, Quaternion rotation, float scaleMultiplier, Color color)
{
if (floatingTextController.floatingTextLink.ContainsKey(floatingTextNameHash))
{
FloatingTextCase floatingTextCase = floatingTextController.floatingTextLink[floatingTextNameHash];
GameObject floatingTextObject = floatingTextCase.FloatingTextPool.GetPooledObject();
FloatingTextBaseBehavior floatingTextBehavior = floatingTextObject.GetComponent<FloatingTextBaseBehavior>();
Vector2 textSize = floatingTextBehavior.GetTextSize(text, scaleMultiplier);
floatingTextObject.transform.position = ClampToScreen(floatingTextCase, position, textSize);
floatingTextObject.transform.rotation = rotation;
floatingTextObject.SetActive(true);
floatingTextBehavior.Activate(text, scaleMultiplier, color);
return floatingTextBehavior;
}
return null;
}
// Snaps a UI floating text's spawn position inside the root canvas rect (== the screen)
// so texts requested near the screen edges don't render partly off-screen. The margin
// accounts for the text's rendered half-size (position is its center) plus the
// configured edge gap. Clamped against the root canvas rather than the pool container —
// containers may be sized differently than the screen. World-space cases (no container)
// pass through unchanged.
private static Vector3 ClampToScreen(FloatingTextCase floatingTextCase, Vector3 position, Vector2 textSize)
{
Transform container = floatingTextCase.ObjectsContainer;
if (container == null) return position;
Canvas canvas = container.GetComponentInParent<Canvas>();
if (canvas == null) return position;
RectTransform canvasRect = (RectTransform)canvas.rootCanvas.transform;
float marginX = floatingTextController.screenEdgeMargin + textSize.x * 0.5f;
float marginY = floatingTextController.screenEdgeMargin + textSize.y * 0.5f;
Rect rect = canvasRect.rect;
Vector3 local = canvasRect.InverseTransformPoint(position);
local.x = Mathf.Clamp(local.x, rect.xMin + marginX, rect.xMax - marginX);
local.y = Mathf.Clamp(local.y, rect.yMin + marginY, rect.yMax - marginY);
return canvasRect.TransformPoint(local);
}
public static FloatingTextBaseBehavior GetFloatingText(string floatingTextName)
{
return GetFloatingText(floatingTextName.GetHashCode());
}
public static FloatingTextBaseBehavior GetFloatingText(int floatingTextNameHash)
{
if (floatingTextController.floatingTextLink.ContainsKey(floatingTextNameHash))
{
FloatingTextCase floatingTextCase = floatingTextController.floatingTextLink[floatingTextNameHash];
GameObject floatingTextObject = floatingTextCase.FloatingTextPool.GetPooledObject();
return floatingTextObject.GetComponent<FloatingTextBaseBehavior>();
}
return null;
}
public static void Unload()
{
FloatingTextCase[] floatingTextCases = floatingTextController.floatingTextCases;
for (int i = 0; i < floatingTextCases.Length; i++)
{
floatingTextCases[i].FloatingTextPool.ReturnToPoolEverything(true);
}
}
}
}