105 lines
3.8 KiB
C#
105 lines
3.8 KiB
C#
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
namespace Vanguard.UI
|
||
{
|
||
/// <summary>
|
||
/// Фон Lobby: процедурный тёмно-синий градиент с сеткой, центральным
|
||
/// свечением и виньеткой. Кешируется как один спрайт; когда появится
|
||
/// key art, достаточно заменить источник изображения.
|
||
/// </summary>
|
||
public static class LobbyBackdrop
|
||
{
|
||
public const string RootName = "LobbyBackdrop";
|
||
|
||
private static Sprite _sprite;
|
||
|
||
public static RectTransform Create(Transform parent)
|
||
{
|
||
var go = new GameObject(RootName, typeof(RectTransform), typeof(Image));
|
||
var rect = (RectTransform)go.transform;
|
||
rect.SetParent(parent, false);
|
||
UiKit.Stretch(rect);
|
||
rect.SetAsFirstSibling();
|
||
|
||
var image = go.GetComponent<Image>();
|
||
image.sprite = Sprite();
|
||
image.type = Image.Type.Simple;
|
||
image.preserveAspect = false;
|
||
image.raycastTarget = false;
|
||
|
||
return rect;
|
||
}
|
||
|
||
private static Sprite Sprite()
|
||
{
|
||
if (_sprite != null)
|
||
return _sprite;
|
||
|
||
const int width = 512;
|
||
const int height = 288;
|
||
var pixels = new Color32[width * height];
|
||
|
||
var top = new Color(0.010f, 0.026f, 0.070f);
|
||
var middle = new Color(0.017f, 0.055f, 0.135f);
|
||
var bottom = new Color(0.006f, 0.016f, 0.045f);
|
||
var glow = new Color(0.06f, 0.26f, 0.62f);
|
||
var grid = new Color(0.16f, 0.46f, 0.92f);
|
||
|
||
for (var y = 0; y < height; y++)
|
||
{
|
||
var v = y / (float)(height - 1);
|
||
var baseColor = v < 0.55f
|
||
? Color.Lerp(bottom, middle, v / 0.55f)
|
||
: Color.Lerp(middle, top, (v - 0.55f) / 0.45f);
|
||
|
||
for (var x = 0; x < width; x++)
|
||
{
|
||
var u = x / (float)(width - 1);
|
||
var color = baseColor;
|
||
|
||
// Мягкое пятно света над центром сцены.
|
||
var dx = (u - 0.5f) * 2f;
|
||
var dy = (v - 0.62f) * 2.2f;
|
||
var distance = Mathf.Sqrt(dx * dx + dy * dy);
|
||
var light = Mathf.Clamp01(1f - distance / 1.15f);
|
||
color += glow * (light * light * 0.16f);
|
||
|
||
// Сетка с шагом 32 px по текстуре.
|
||
if (x % 32 == 0 || y % 32 == 0)
|
||
color += grid * 0.035f;
|
||
|
||
// Виньетка по краям.
|
||
var vignette = Mathf.Clamp01(
|
||
(Mathf.Abs(dx) * 0.55f + Mathf.Abs(v - 0.5f) * 1.1f - 0.35f) / 0.65f);
|
||
color = Color.Lerp(color, new Color(0f, 0f, 0f), vignette * 0.55f);
|
||
color.a = 1f;
|
||
|
||
pixels[y * width + x] = color;
|
||
}
|
||
}
|
||
|
||
var texture = new Texture2D(width, height, TextureFormat.RGBA32, false)
|
||
{
|
||
hideFlags = HideFlags.DontSave,
|
||
wrapMode = TextureWrapMode.Clamp,
|
||
filterMode = FilterMode.Bilinear,
|
||
name = "LobbyBackdrop",
|
||
};
|
||
texture.SetPixels32(pixels);
|
||
texture.Apply(false, false);
|
||
|
||
_sprite = UnityEngine.Sprite.Create(
|
||
texture,
|
||
new Rect(0f, 0f, width, height),
|
||
new Vector2(0.5f, 0.5f),
|
||
100f,
|
||
0,
|
||
SpriteMeshType.FullRect);
|
||
_sprite.name = "LobbyBackdrop";
|
||
_sprite.hideFlags = HideFlags.DontSave;
|
||
return _sprite;
|
||
}
|
||
}
|
||
}
|