397 lines
17 KiB
C#
397 lines
17 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using UnityEngine;
|
|||
|
|
using UnityEngine.EventSystems;
|
|||
|
|
using UnityEngine.UI;
|
|||
|
|
|
|||
|
|
namespace TKS.OutGame
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 아웃게임 와이어프레임 UI 도우미 — uGUI + Malgun Gothic(TextUtil) · 아트 없음 = 도형 + 글자 · 기준 1080×1920 · 색 = 목업 img03·06·08·11.
|
|||
|
|
/// 위치 인자는 전부 「부모 안 기준점(anchor) · 피벗 · 기준점에서의 거리 · 크기」(UI px).
|
|||
|
|
/// </summary>
|
|||
|
|
public static class UiKit
|
|||
|
|
{
|
|||
|
|
public static readonly Color Bg = new Color(0.95f, 0.92f, 0.85f);
|
|||
|
|
public static readonly Color Paper = new Color(0.99f, 0.97f, 0.92f);
|
|||
|
|
public static readonly Color Header = new Color(0.92f, 0.87f, 0.78f);
|
|||
|
|
public static readonly Color Ink = new Color(0.17f, 0.12f, 0.10f);
|
|||
|
|
public static readonly Color InkSoft = new Color(0.45f, 0.39f, 0.34f);
|
|||
|
|
public static readonly Color Dark = new Color(0.21f, 0.16f, 0.14f);
|
|||
|
|
public static readonly Color Red = new Color(0.74f, 0.26f, 0.19f);
|
|||
|
|
public static readonly Color Line = new Color(0.33f, 0.26f, 0.22f);
|
|||
|
|
public static readonly Color Slot = new Color(0.80f, 0.76f, 0.70f);
|
|||
|
|
public static readonly Color Coin = new Color(0.88f, 0.67f, 0.20f);
|
|||
|
|
public static readonly Color Jade = new Color(0.27f, 0.60f, 0.52f);
|
|||
|
|
public static readonly Color Grain = new Color(0.76f, 0.58f, 0.38f);
|
|||
|
|
public static readonly Color Ok = new Color(0.36f, 0.62f, 0.31f);
|
|||
|
|
public static readonly Color Star = new Color(0.93f, 0.68f, 0.13f);
|
|||
|
|
public static readonly Color Disabled = new Color(0.66f, 0.62f, 0.58f);
|
|||
|
|
public static readonly Color Purple = new Color(0.58f, 0.36f, 0.70f);
|
|||
|
|
public static readonly Color White = Color.white;
|
|||
|
|
|
|||
|
|
static Sprite round;
|
|||
|
|
|
|||
|
|
/// <summary>둥근 모서리 9-slice(모서리 22 px).</summary>
|
|||
|
|
public static Sprite Round
|
|||
|
|
{
|
|||
|
|
get
|
|||
|
|
{
|
|||
|
|
if (round == null) round = MakeRound(64, 22);
|
|||
|
|
return round;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static Sprite Circle
|
|||
|
|
{
|
|||
|
|
get { return ProceduralSprites.Circle; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static Sprite MakeRound(int size, int radius)
|
|||
|
|
{
|
|||
|
|
var tex = new Texture2D(size, size, TextureFormat.RGBA32, false);
|
|||
|
|
tex.wrapMode = TextureWrapMode.Clamp;
|
|||
|
|
tex.hideFlags = HideFlags.DontSave;
|
|||
|
|
var px = new Color[size * size];
|
|||
|
|
for (int y = 0; y < size; y++)
|
|||
|
|
for (int x = 0; x < size; x++)
|
|||
|
|
{
|
|||
|
|
float cx = Mathf.Clamp(x + 0.5f, radius, size - radius);
|
|||
|
|
float cy = Mathf.Clamp(y + 0.5f, radius, size - radius);
|
|||
|
|
float d = Vector2.Distance(new Vector2(x + 0.5f, y + 0.5f), new Vector2(cx, cy));
|
|||
|
|
px[y * size + x] = new Color(1f, 1f, 1f, Mathf.Clamp01(radius - d + 0.5f));
|
|||
|
|
}
|
|||
|
|
tex.SetPixels(px);
|
|||
|
|
tex.Apply();
|
|||
|
|
float b = radius + 2;
|
|||
|
|
var sp = Sprite.Create(tex, new Rect(0, 0, size, size), new Vector2(0.5f, 0.5f), 100f, 0, SpriteMeshType.FullRect, new Vector4(b, b, b, b));
|
|||
|
|
sp.hideFlags = HideFlags.DontSave;
|
|||
|
|
return sp;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ---------- 기본 ----------
|
|||
|
|
|
|||
|
|
public static RectTransform Rect(string name, Transform parent, Vector2 anchor, Vector2 pivot, Vector2 pos, Vector2 size)
|
|||
|
|
{
|
|||
|
|
var go = new GameObject(name, typeof(RectTransform));
|
|||
|
|
go.transform.SetParent(parent, false);
|
|||
|
|
var rt = (RectTransform)go.transform;
|
|||
|
|
rt.anchorMin = rt.anchorMax = anchor;
|
|||
|
|
rt.pivot = pivot;
|
|||
|
|
rt.anchoredPosition = pos;
|
|||
|
|
rt.sizeDelta = size;
|
|||
|
|
return rt;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>부모 전체에서 안쪽 여백(왼·오·위·아래)만 뺀 영역.</summary>
|
|||
|
|
public static RectTransform Fill(string name, Transform parent, float l = 0f, float r = 0f, float t = 0f, float b = 0f)
|
|||
|
|
{
|
|||
|
|
var go = new GameObject(name, typeof(RectTransform));
|
|||
|
|
go.transform.SetParent(parent, false);
|
|||
|
|
var rt = (RectTransform)go.transform;
|
|||
|
|
rt.anchorMin = Vector2.zero;
|
|||
|
|
rt.anchorMax = Vector2.one;
|
|||
|
|
rt.pivot = new Vector2(0.5f, 0.5f);
|
|||
|
|
rt.offsetMin = new Vector2(l, b);
|
|||
|
|
rt.offsetMax = new Vector2(-r, -t);
|
|||
|
|
return rt;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>위쪽 띠(부모 가로 전체 · 위에서 top 아래 · 높이 h).</summary>
|
|||
|
|
public static RectTransform TopBand(string name, Transform parent, float top, float h, float l = 0f, float r = 0f)
|
|||
|
|
{
|
|||
|
|
var go = new GameObject(name, typeof(RectTransform));
|
|||
|
|
go.transform.SetParent(parent, false);
|
|||
|
|
var rt = (RectTransform)go.transform;
|
|||
|
|
rt.anchorMin = new Vector2(0f, 1f);
|
|||
|
|
rt.anchorMax = new Vector2(1f, 1f);
|
|||
|
|
rt.pivot = new Vector2(0.5f, 1f);
|
|||
|
|
rt.offsetMin = new Vector2(l, -top - h);
|
|||
|
|
rt.offsetMax = new Vector2(-r, -top);
|
|||
|
|
return rt;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static Image Paint(RectTransform rt, Color c, bool rounded = true, bool raycast = false)
|
|||
|
|
{
|
|||
|
|
var img = rt.gameObject.AddComponent<Image>();
|
|||
|
|
img.color = c;
|
|||
|
|
if (rounded)
|
|||
|
|
{
|
|||
|
|
img.sprite = Round;
|
|||
|
|
img.type = Image.Type.Sliced;
|
|||
|
|
}
|
|||
|
|
img.raycastTarget = raycast;
|
|||
|
|
return img;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static Image Box(string name, Transform parent, Vector2 anchor, Vector2 pivot, Vector2 pos, Vector2 size, Color c, bool rounded = true)
|
|||
|
|
{
|
|||
|
|
return Paint(Rect(name, parent, anchor, pivot, pos, size), c, rounded);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static Image Dot(string name, Transform parent, Vector2 anchor, Vector2 pivot, Vector2 pos, float d, Color c)
|
|||
|
|
{
|
|||
|
|
var img = Rect(name, parent, anchor, pivot, pos, new Vector2(d, d)).gameObject.AddComponent<Image>();
|
|||
|
|
img.sprite = Circle;
|
|||
|
|
img.color = c;
|
|||
|
|
img.raycastTarget = false;
|
|||
|
|
return img;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>테두리(외곽선 효과 · 둥근 상자에 굵은 선처럼 보임).</summary>
|
|||
|
|
public static void Border(Graphic g, Color c, float w = 4f)
|
|||
|
|
{
|
|||
|
|
var o = g.gameObject.AddComponent<Outline>();
|
|||
|
|
o.effectColor = c;
|
|||
|
|
o.effectDistance = new Vector2(w, -w);
|
|||
|
|
o.useGraphicAlpha = false;
|
|||
|
|
var o2 = g.gameObject.AddComponent<Outline>();
|
|||
|
|
o2.effectColor = c;
|
|||
|
|
o2.effectDistance = new Vector2(-w, w);
|
|||
|
|
o2.useGraphicAlpha = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static Text Label(Transform parent, string s, int size, Color c, TextAnchor align, Vector2 anchor, Vector2 pivot, Vector2 pos, Vector2 box, bool bold = true)
|
|||
|
|
{
|
|||
|
|
var rt = Rect("Text", parent, anchor, pivot, pos, box);
|
|||
|
|
return Style(rt.gameObject.AddComponent<Text>(), s, size, c, align, bold);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>부모 전체에 꽉 찬 글자(가운데 정렬 기본).</summary>
|
|||
|
|
public static Text FillLabel(Transform parent, string s, int size, Color c, TextAnchor align = TextAnchor.MiddleCenter, bool bold = true, float pad = 0f)
|
|||
|
|
{
|
|||
|
|
var rt = Fill("Text", parent, pad, pad, 0f, 0f);
|
|||
|
|
return Style(rt.gameObject.AddComponent<Text>(), s, size, c, align, bold);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static Text Style(Text t, string s, int size, Color c, TextAnchor align, bool bold)
|
|||
|
|
{
|
|||
|
|
t.font = TextUtil.Font;
|
|||
|
|
t.fontSize = size;
|
|||
|
|
t.fontStyle = bold ? FontStyle.Bold : FontStyle.Normal;
|
|||
|
|
t.alignment = align;
|
|||
|
|
t.color = c;
|
|||
|
|
t.horizontalOverflow = HorizontalWrapMode.Wrap;
|
|||
|
|
t.verticalOverflow = VerticalWrapMode.Overflow;
|
|||
|
|
t.supportRichText = true;
|
|||
|
|
t.raycastTarget = false;
|
|||
|
|
t.text = s;
|
|||
|
|
return t;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static Button Btn(string name, Transform parent, string label, int fontSize, Color bg, Color fg, Vector2 anchor, Vector2 pivot, Vector2 pos, Vector2 size, Action onClick)
|
|||
|
|
{
|
|||
|
|
var img = Box(name, parent, anchor, pivot, pos, size, bg);
|
|||
|
|
img.raycastTarget = true;
|
|||
|
|
var b = img.gameObject.AddComponent<Button>();
|
|||
|
|
var cb = b.colors;
|
|||
|
|
cb.disabledColor = new Color(0.75f, 0.75f, 0.75f, 0.85f);
|
|||
|
|
b.colors = cb;
|
|||
|
|
if (onClick != null) b.onClick.AddListener(() => onClick());
|
|||
|
|
FillLabel(img.transform, label, fontSize, fg, TextAnchor.MiddleCenter, true, 6f);
|
|||
|
|
return b;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static Text LabelOf(Button b)
|
|||
|
|
{
|
|||
|
|
return b.GetComponentInChildren<Text>(true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>둥근 막대 게이지 · 반환 = 채움(SetBar 로 0~1).</summary>
|
|||
|
|
public static RectTransform Bar(string name, Transform parent, Vector2 anchor, Vector2 pivot, Vector2 pos, Vector2 size, Color bg, Color fg)
|
|||
|
|
{
|
|||
|
|
var back = Box(name, parent, anchor, pivot, pos, size, bg);
|
|||
|
|
var fill = Fill("Fill", back.transform);
|
|||
|
|
fill.anchorMax = new Vector2(0f, 1f);
|
|||
|
|
Paint(fill, fg);
|
|||
|
|
return fill;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static void SetBar(RectTransform fill, float v)
|
|||
|
|
{
|
|||
|
|
v = Mathf.Clamp01(v);
|
|||
|
|
fill.anchorMax = new Vector2(v, 1f);
|
|||
|
|
fill.gameObject.SetActive(v > 0.001f);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>세로 스크롤 격자 목록(칸 크기 cell · 열 columns) · 반환 = 내용(자식 = 칸).</summary>
|
|||
|
|
public static RectTransform ScrollGrid(string name, Transform parent, float l, float r, float t, float b, Vector2 cell, Vector2 spacing, int columns, out ScrollRect scroll)
|
|||
|
|
{
|
|||
|
|
var vp = Fill(name, parent, l, r, t, b);
|
|||
|
|
var vimg = vp.gameObject.AddComponent<Image>();
|
|||
|
|
vimg.color = new Color(1f, 1f, 1f, 0f);
|
|||
|
|
vimg.raycastTarget = true;
|
|||
|
|
vp.gameObject.AddComponent<RectMask2D>();
|
|||
|
|
var content = new GameObject("Content", typeof(RectTransform)).GetComponent<RectTransform>();
|
|||
|
|
content.SetParent(vp, false);
|
|||
|
|
content.anchorMin = new Vector2(0f, 1f);
|
|||
|
|
content.anchorMax = new Vector2(1f, 1f);
|
|||
|
|
content.pivot = new Vector2(0.5f, 1f);
|
|||
|
|
content.offsetMin = content.offsetMax = Vector2.zero;
|
|||
|
|
var grid = content.gameObject.AddComponent<GridLayoutGroup>();
|
|||
|
|
grid.cellSize = cell;
|
|||
|
|
grid.spacing = spacing;
|
|||
|
|
grid.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
|
|||
|
|
grid.constraintCount = columns;
|
|||
|
|
grid.childAlignment = TextAnchor.UpperCenter;
|
|||
|
|
grid.padding = new RectOffset(0, 0, 6, 12);
|
|||
|
|
var fit = content.gameObject.AddComponent<ContentSizeFitter>();
|
|||
|
|
fit.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
|||
|
|
scroll = vp.gameObject.AddComponent<ScrollRect>();
|
|||
|
|
scroll.viewport = vp;
|
|||
|
|
scroll.content = content;
|
|||
|
|
scroll.horizontal = false;
|
|||
|
|
scroll.vertical = true;
|
|||
|
|
scroll.movementType = ScrollRect.MovementType.Clamped;
|
|||
|
|
scroll.scrollSensitivity = 60f;
|
|||
|
|
return content;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static void Clear(Transform t)
|
|||
|
|
{
|
|||
|
|
for (int i = t.childCount - 1; i >= 0; i--)
|
|||
|
|
{
|
|||
|
|
var c = t.GetChild(i).gameObject;
|
|||
|
|
c.SetActive(false);
|
|||
|
|
UnityEngine.Object.Destroy(c);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>목록 칸(격자 자식) — 둥근 카드 + 클릭.</summary>
|
|||
|
|
public static Image Cell(Transform content, string name, Color fill, Action onClick)
|
|||
|
|
{
|
|||
|
|
var go = new GameObject(name, typeof(RectTransform));
|
|||
|
|
go.transform.SetParent(content, false);
|
|||
|
|
var img = Paint((RectTransform)go.transform, fill);
|
|||
|
|
img.raycastTarget = true;
|
|||
|
|
if (onClick != null)
|
|||
|
|
{
|
|||
|
|
var b = go.AddComponent<Button>();
|
|||
|
|
b.onClick.AddListener(() => onClick());
|
|||
|
|
}
|
|||
|
|
return img;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ---------- 영웅 표시 ----------
|
|||
|
|
|
|||
|
|
public static Color TypeColor(UnitType t)
|
|||
|
|
{
|
|||
|
|
switch (t)
|
|||
|
|
{
|
|||
|
|
case UnitType.Infantry: return new Color(0.62f, 0.33f, 0.22f);
|
|||
|
|
case UnitType.Spear: return new Color(0.30f, 0.50f, 0.30f);
|
|||
|
|
case UnitType.Cavalry: return new Color(0.28f, 0.32f, 0.45f);
|
|||
|
|
case UnitType.Archer: return new Color(0.70f, 0.52f, 0.20f);
|
|||
|
|
case UnitType.Strategist: return Purple;
|
|||
|
|
}
|
|||
|
|
return Dark;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>등급(승급 green… · 장비 white…) 표시 이름.</summary>
|
|||
|
|
public static string GradeKo(string g)
|
|||
|
|
{
|
|||
|
|
switch (g)
|
|||
|
|
{
|
|||
|
|
case "white": return "흰";
|
|||
|
|
case "green": return "녹";
|
|||
|
|
case "blue": return "청";
|
|||
|
|
case "purple": return "자";
|
|||
|
|
case "orange": return "주";
|
|||
|
|
case "gold": return "금";
|
|||
|
|
}
|
|||
|
|
return g;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static Color GradeColor(string g)
|
|||
|
|
{
|
|||
|
|
switch (g)
|
|||
|
|
{
|
|||
|
|
case "white": return new Color(0.80f, 0.79f, 0.76f);
|
|||
|
|
case "green": return new Color(0.38f, 0.64f, 0.33f);
|
|||
|
|
case "blue": return new Color(0.29f, 0.48f, 0.78f);
|
|||
|
|
case "purple": return Purple;
|
|||
|
|
case "orange": return new Color(0.90f, 0.50f, 0.18f);
|
|||
|
|
case "gold": return new Color(0.92f, 0.74f, 0.16f);
|
|||
|
|
}
|
|||
|
|
return Slot;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static string Stars(int n, int max)
|
|||
|
|
{
|
|||
|
|
var sb = new System.Text.StringBuilder();
|
|||
|
|
for (int i = 0; i < max; i++) sb.Append(i < n ? "★" : "☆");
|
|||
|
|
return sb.ToString();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static readonly Dictionary<string, Sprite> artCache = new Dictionary<string, Sprite>();
|
|||
|
|
|
|||
|
|
/// <summary>일러 = Resources/Units/<art> front_idle 첫 프레임(없으면 다른 클립 첫 프레임 · 없으면 null = 도형).</summary>
|
|||
|
|
public static Sprite ArtSprite(string art)
|
|||
|
|
{
|
|||
|
|
if (string.IsNullOrEmpty(art)) return null;
|
|||
|
|
Sprite sp;
|
|||
|
|
if (artCache.TryGetValue(art, out sp)) return sp;
|
|||
|
|
var a = UnitArt.Load(art);
|
|||
|
|
Sprite[] frames = null;
|
|||
|
|
if (a != null && !a.Clips.TryGetValue("front_idle", out frames))
|
|||
|
|
foreach (var kv in a.Clips)
|
|||
|
|
{
|
|||
|
|
frames = kv.Value;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
sp = frames != null && frames.Length > 0 ? frames[0] : null;
|
|||
|
|
artCache[art] = sp;
|
|||
|
|
return sp;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 초상(틀 안을 마스크) — 일러가 있으면 그 그림(zoom > 1 = 위쪽 얼굴 부분 확대) · 없으면 병종 색 원 + 병종 글자.
|
|||
|
|
/// circle = 원형 틀(편성 자리) · false = 둥근 사각.
|
|||
|
|
/// </summary>
|
|||
|
|
public static RectTransform Portrait(string name, Transform parent, HeroDb.Hero h, Vector2 anchor, Vector2 pivot, Vector2 pos, Vector2 size, bool circle, float zoom, Color frame)
|
|||
|
|
{
|
|||
|
|
var rt = Rect(name, parent, anchor, pivot, pos, size);
|
|||
|
|
var bg = rt.gameObject.AddComponent<Image>();
|
|||
|
|
bg.color = frame;
|
|||
|
|
bg.raycastTarget = false;
|
|||
|
|
if (circle) bg.sprite = Circle;
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
bg.sprite = Round;
|
|||
|
|
bg.type = Image.Type.Sliced;
|
|||
|
|
}
|
|||
|
|
var mask = rt.gameObject.AddComponent<Mask>();
|
|||
|
|
mask.showMaskGraphic = frame.a > 0.01f;
|
|||
|
|
if (frame.a <= 0.01f) bg.color = Color.white; // 투명 틀: 알파 0 그래픽은 스텐실을 안 써서 자식이 안 보임 → 불투명 + 그리지 않음
|
|||
|
|
var sp = h != null ? ArtSprite(h.art) : null;
|
|||
|
|
if (sp != null)
|
|||
|
|
{
|
|||
|
|
// zoom ≤ 1 = 전신 가운데 · zoom > 1 = 위쪽(얼굴) 확대
|
|||
|
|
bool bust = zoom > 1f;
|
|||
|
|
var a = bust
|
|||
|
|
? Rect("Art", rt, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, size.y * 0.06f * zoom), size * zoom)
|
|||
|
|
: Rect("Art", rt, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, size * zoom);
|
|||
|
|
var img = a.gameObject.AddComponent<Image>();
|
|||
|
|
img.sprite = sp;
|
|||
|
|
img.preserveAspect = true;
|
|||
|
|
img.raycastTarget = false;
|
|||
|
|
}
|
|||
|
|
else if (h != null)
|
|||
|
|
{
|
|||
|
|
float d = Mathf.Min(size.x, size.y) * 0.72f;
|
|||
|
|
var dot = Dot("Shape", rt, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, d, TypeColor(h.type));
|
|||
|
|
FillLabel(dot.transform, UnitTypeInfo.Mark(h.type), Mathf.RoundToInt(d * 0.5f), White);
|
|||
|
|
}
|
|||
|
|
return rt;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>병종 배지(어두운 둥근 칸 + 글자).</summary>
|
|||
|
|
public static Image TypeBadge(Transform parent, UnitType t, Vector2 anchor, Vector2 pivot, Vector2 pos, float h)
|
|||
|
|
{
|
|||
|
|
var b = Box("Type", parent, anchor, pivot, pos, new Vector2(h * 1.3f, h), Dark);
|
|||
|
|
FillLabel(b.transform, UnitTypeInfo.Mark(t), Mathf.RoundToInt(h * 0.62f), White);
|
|||
|
|
return b;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|