92 lines
4.2 KiB
C#
92 lines
4.2 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace TKS.OutGame
|
|
{
|
|
/// <summary>
|
|
/// 펄럭이는 천(로비 깃발 · PD 2026-11-11 「펄럭이는 깃발」) — 스프라이트를 격자로 나눠 줄마다 좌우로 민다(위 = 고정 · 아래로 갈수록 크게 · 물결이 아래로 흐름).
|
|
/// 배경 그림의 원래 깃발 위에 같은 자리로 덮어 그리므로, 줄마다 폭을 미는 양 이상 넓혀(flare) 원래 깃발이 옆으로 드러나지 않게 한다(배경 다시 그리기 없음).
|
|
/// 매 프레임 메시를 다시 만들므로 Frame 캔버스 안에 둔다(UiLayer.Isolate).
|
|
/// </summary>
|
|
[RequireComponent(typeof(CanvasRenderer))]
|
|
public class UiWaveImage : MaskableGraphic
|
|
{
|
|
public Sprite sprite;
|
|
public int cols = 4;
|
|
public int rows = 14;
|
|
/// <summary>아래끝 좌우 흔들림(스프라이트 px).</summary>
|
|
public float amp;
|
|
public float period = 2f;
|
|
/// <summary>위 → 아래 물결 수.</summary>
|
|
public float waves = 1f;
|
|
public float phase;
|
|
/// <summary>물결 골의 어두움(0 = 없음).</summary>
|
|
public float shade = 0.1f;
|
|
/// <summary>천이 바람을 받아 부푸는 폭(스프라이트 px · 넓어지는 쪽으로만 · 아래로 갈수록 크게) — 좁아지면 원래 깃발이 드러나므로 0 이상만.</summary>
|
|
public float billow;
|
|
/// <summary>true = 아래끝 고정 · 위로 갈수록 크게 흔들림(풀·꽃 덤불 · PD 2026-11-12 「훈련장 주변 꽃이나 풀이 하늘거리는」) · 기본 false = 깃발(위 고정).</summary>
|
|
public bool fromBottom;
|
|
|
|
public override Texture mainTexture
|
|
{
|
|
get { return sprite != null ? sprite.texture : s_WhiteTexture; }
|
|
}
|
|
|
|
protected override void Awake()
|
|
{
|
|
base.Awake();
|
|
if (Application.isPlaying) UiLayer.Isolate(gameObject);
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (amp > 0f && period > 0f) SetVerticesDirty();
|
|
}
|
|
|
|
protected override void OnPopulateMesh(VertexHelper vh)
|
|
{
|
|
vh.Clear();
|
|
if (sprite == null || cols < 1 || rows < 1) return;
|
|
var r = GetPixelAdjustedRect();
|
|
var uv = UnityEngine.Sprites.DataUtility.GetOuterUV(sprite);
|
|
float unit = r.width / Mathf.Max(1f, sprite.rect.width); // 스프라이트 px → 이 그래픽 단위
|
|
float half = Mathf.Max(1f, sprite.rect.width * 0.5f);
|
|
float t = Application.isPlaying ? Time.unscaledTime : 0f;
|
|
float cx = r.center.x;
|
|
const float Tau = Mathf.PI * 2f;
|
|
for (int j = 0; j <= rows; j++)
|
|
{
|
|
float v = j / (float)rows; // 0 = 위 · 1 = 아래
|
|
float s = fromBottom ? 1f - v : v; // 고정 끝에서 잰 거리(0 = 고정)
|
|
float env = s * s;
|
|
float ph = (t / period - s * waves + phase) * Tau;
|
|
float dx = amp * env * Mathf.Sin(ph);
|
|
float puff = billow * env * (0.5f + 0.5f * Mathf.Sin(ph * 0.5f + 1.3f)); // 0 ~ billow(넓어지기만)
|
|
float flare = (amp * env + env + puff) / half; // 미는 양 + 1 px(원래 깃발 가림) + 부풂
|
|
float dark = shade * env * (0.5f + 0.5f * Mathf.Cos(ph));
|
|
var c = color;
|
|
c.r *= 1f - dark;
|
|
c.g *= 1f - dark;
|
|
c.b *= 1f - dark;
|
|
float y = r.yMax - v * r.height;
|
|
float uy = Mathf.Lerp(uv.w, uv.y, v);
|
|
for (int i = 0; i <= cols; i++)
|
|
{
|
|
float u = i / (float)cols;
|
|
float x = r.xMin + u * r.width;
|
|
x = cx + (x - cx) * (1f + flare) + dx * unit;
|
|
vh.AddVert(new Vector3(x, y), c, new Vector2(Mathf.Lerp(uv.x, uv.z, u), uy));
|
|
}
|
|
}
|
|
int w = cols + 1;
|
|
for (int j = 0; j < rows; j++)
|
|
for (int i = 0; i < cols; i++)
|
|
{
|
|
int a = j * w + i;
|
|
vh.AddTriangle(a, a + 1, a + w + 1);
|
|
vh.AddTriangle(a, a + w + 1, a + w);
|
|
}
|
|
}
|
|
}
|
|
}
|