ThreeKingdomsSlingshot/Assets/Scripts/Runtime/IbUi.cs

153 lines
5.5 KiB
C#
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
namespace TKS
{
/// <summary>
/// IB(쿠로네코) 슬링샷 UI 이식 값 표(Resources/Skills/ib_ui.csv · C45) + 진행 중 캐릭터 연출(IbUnitMarks)이 쓰는 공용 도우미.
/// </summary>
public static class IbUi
{
public const string TablePath = "Skills/ib_ui";
static Dictionary<string, string> values;
public static void Reload()
{
values = null;
}
static void Ensure()
{
if (values != null) return;
values = new Dictionary<string, string>();
var ta = Resources.Load<TextAsset>(TablePath);
if (ta == null) return;
bool head = true;
foreach (var raw in ta.text.Replace("\r", "").Split('\n'))
{
var line = raw.TrimStart('');
if (line.Trim().Length == 0 || line.TrimStart().StartsWith("#")) continue;
if (head)
{
head = false;
continue;
}
var c = SkillVfx.SplitCsv(line);
if (c.Length >= 2) values[c[0].Trim()] = c[1].Trim();
}
}
public static string Str(string key, string def)
{
Ensure();
string v;
return values.TryGetValue(key, out v) && v.Length > 0 ? v : def;
}
public static float Num(string key, float def)
{
float f;
return float.TryParse(Str(key, ""), NumberStyles.Float, CultureInfo.InvariantCulture, out f) ? f : def;
}
/// <summary>IB 이펙트·UI 배율 = 이 게임 유닛 반지름 / IB 유닛 반지름.</summary>
public static float Scale(Unit u)
{
return u == null ? 1f : u.Radius / Mathf.Max(0.01f, Num("ib_unit_radius", 0.5f));
}
/// <summary>진영 → IB 속성(water · tree · fire · dark · glow).</summary>
public static string Element(Unit u)
{
string camp = u != null && !string.IsNullOrEmpty(u.Camp) ? u.Camp.ToLowerInvariant() : "none";
return Str("element_" + camp, Str("element_none", "dark"));
}
/// <summary>IB 사본 하나 띄우기(유닛에 붙임 · 배율 · 렌더러 정렬).</summary>
public static GameObject Attach(string fxName, Unit u, Vector2 local, float scale, int order)
{
var prefab = SkillVfx.LoadFx(fxName);
if (prefab == null || u == null) return null;
var go = Object.Instantiate(prefab, u.transform);
go.name = fxName;
go.transform.localPosition = new Vector3(local.x, local.y, 0f);
go.transform.localRotation = Quaternion.identity;
var ls = u.transform.lossyScale;
go.transform.localScale = new Vector3(scale / Mathf.Max(0.001f, Mathf.Abs(ls.x)), scale / Mathf.Max(0.001f, Mathf.Abs(ls.y)), 1f);
foreach (var r in go.GetComponentsInChildren<Renderer>(true)) r.sortingOrder = order;
return go;
}
}
/// <summary>
/// 슬링샷 진행 중 캐릭터 연출 — IB 이식(PD 2026-11-10 「선택된 캐릭터 주위 연출이 누락」):
/// 행동할 유닛(선택된 아군 · 행동 가능) = 발밑 도는 원(ef_target_circle · IB BottomPosition) + 몸 둘레 빛(ef_attack_ready_standard · IB CenterPosition) — IB ShowUserTurnMark ·
/// 조준 중(누름 ~ 놓음) = 모든 유닛에 속성 방울(ef_attribute_&lt;속성&gt; · 배율 0.9) — IB SetActiveBarrierVisualEffect.
/// </summary>
public class IbUnitMarks : MonoBehaviour
{
Unit turnUnit;
readonly List<GameObject> turnFx = new List<GameObject>();
readonly List<GameObject> bubbles = new List<GameObject>();
public int BubbleCount
{
get { return bubbles.Count; }
}
public bool TurnMarkVisible
{
get { return turnFx.Count > 0; }
}
public void ShowTurn(Unit u)
{
if (u == turnUnit && turnFx.Count > 0) return;
Clear(turnFx);
turnUnit = u;
if (u == null) return;
float k = IbUi.Scale(u);
int order = Mathf.RoundToInt(IbUi.Num("order_ground", -8f));
Add(turnFx, IbUi.Attach("TKS_Fx_IB_TargetCircle", u, new Vector2(0f, -u.Radius * 0.55f), k, order)); // 발(아트 발 = 원 아래쪽 −0.55 R)
Add(turnFx, IbUi.Attach("TKS_Fx_IB_AttackReady", u, Vector2.zero, k, order));
}
public void ShowBubbles(IEnumerable<Unit> units)
{
Clear(bubbles);
if (units == null) return;
int order = Mathf.RoundToInt(IbUi.Num("order_bubble", 12f));
float bs = IbUi.Num("barrier_scale", 0.9f);
foreach (var u in units)
{
if (u == null || !u.IsAlive) continue;
Add(bubbles, IbUi.Attach("TKS_Fx_IB_Attribute_" + IbUi.Element(u), u, Vector2.zero, IbUi.Scale(u) * bs, order));
}
}
public void HideBubbles()
{
Clear(bubbles);
}
static void Add(List<GameObject> list, GameObject go)
{
if (go != null) list.Add(go);
}
static void Clear(List<GameObject> list)
{
foreach (var g in list)
if (g != null) Destroy(g);
list.Clear();
}
void OnDestroy()
{
Clear(turnFx);
Clear(bubbles);
}
}
}