188 lines
4.5 KiB
C#
188 lines
4.5 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace Cryville.Crtr.Skin.Components {
|
|
public class SpriteInfo {
|
|
string m_frameName;
|
|
public string FrameName {
|
|
get {
|
|
return m_frameName;
|
|
}
|
|
set {
|
|
m_frameName = value;
|
|
Reload();
|
|
}
|
|
}
|
|
public SpriteFrame Frame {
|
|
get;
|
|
private set;
|
|
}
|
|
public Rect Rect {
|
|
get { return Frame.Frame; }
|
|
}
|
|
/// <summary>
|
|
/// The ratio of width divided by height.
|
|
/// </summary>
|
|
public float Ratio {
|
|
get {
|
|
return Rect.width / Rect.height;
|
|
}
|
|
}
|
|
Material _mat;
|
|
public void Bind(Material mat) {
|
|
_mat = mat;
|
|
Reload();
|
|
}
|
|
public void Reload() {
|
|
if (!string.IsNullOrEmpty(FrameName)) {
|
|
if (ChartPlayer.frames.ContainsKey(FrameName)) {
|
|
Frame = ChartPlayer.frames[FrameName];
|
|
}
|
|
else {
|
|
Game.MainLogger.Log(4, "Skin", "Texture {0} not found", FrameName);
|
|
Frame = null;
|
|
}
|
|
}
|
|
else Frame = null;
|
|
if (_mat != null) {
|
|
_mat.mainTexture = Frame?.Texture;
|
|
}
|
|
}
|
|
public static bool IsNullOrEmpty(SpriteInfo sprite) {
|
|
return sprite == null || sprite.Frame == null;
|
|
}
|
|
}
|
|
|
|
public class SpritePlane : SpriteBase {
|
|
public SpritePlane() {
|
|
SubmitProperty("frame", new PropOp.String(v => Frame = v));
|
|
SubmitProperty("frames", new PropOp.StringArray(v => Frames = v));
|
|
SubmitProperty("index", new PropOp.Integer(v => Index = v));
|
|
SubmitProperty("fit", new PropOp.Enum<FitMode>(v => Fit = v, v => (FitMode)v));
|
|
SubmitProperty("shader", new PropOp.String(v => Shader = v));
|
|
}
|
|
|
|
static Vector2[] _origuv;
|
|
protected static Vector2[] OriginalUV {
|
|
get {
|
|
if (_origuv == null) {
|
|
var m = BuiltinResources.Meshes["quad"];
|
|
Vector2[] uv = new Vector2[m.vertices.Length];
|
|
for (int i = 0; i < uv.Length; i++) {
|
|
uv[i] = new Vector2(
|
|
m.vertices[i].x == 0.5 ? 1 : 0,
|
|
m.vertices[i].z == 0.5 ? 1 : 0
|
|
);
|
|
}
|
|
_origuv = uv;
|
|
}
|
|
return _origuv;
|
|
}
|
|
}
|
|
|
|
int m_index;
|
|
public int Index {
|
|
get { return m_index; }
|
|
set {
|
|
m_index = value;
|
|
OnFrameUpdate();
|
|
}
|
|
}
|
|
SpriteInfo[] m_frames = new SpriteInfo[] { new() };
|
|
public string[] Frames {
|
|
set {
|
|
m_frames = new SpriteInfo[value.Length];
|
|
for (int i = 0; i < value.Length; i++) {
|
|
m_frames[i] = new SpriteInfo() { FrameName = value[i] };
|
|
}
|
|
OnFrameUpdate();
|
|
}
|
|
}
|
|
public string Frame {
|
|
set {
|
|
if (value == CurrentFrame.FrameName) return;
|
|
CurrentFrame.FrameName = value;
|
|
OnFrameUpdate();
|
|
}
|
|
}
|
|
protected SpriteInfo CurrentFrame {
|
|
get {
|
|
if (m_frames.Length == 0) return null;
|
|
if (m_index < 0) m_index = 0;
|
|
else if (m_index >= m_frames.Length) m_index = m_frames.Length - 1;
|
|
return m_frames[m_index];
|
|
}
|
|
}
|
|
protected void OnFrameUpdate() {
|
|
if (!mesh.Initialized) return;
|
|
var frame = CurrentFrame;
|
|
if (SpriteInfo.IsNullOrEmpty(frame)) {
|
|
mesh.Renderer.enabled = false;
|
|
return;
|
|
}
|
|
mesh.Renderer.enabled = true;
|
|
mesh.Renderer.sharedMaterial.mainTexture = frame.Frame.Texture;
|
|
UpdateUV();
|
|
UpdateScale();
|
|
}
|
|
Shader m_shader;
|
|
public string Shader {
|
|
set {
|
|
m_shader = BuiltinResources.Shaders[value];
|
|
UpdateShader();
|
|
}
|
|
}
|
|
void UpdateShader() {
|
|
if (!mesh.Initialized) return;
|
|
if (m_shader == null) m_shader = BuiltinResources.Shaders["default"];
|
|
mesh.Renderer.sharedMaterial.shader = m_shader;
|
|
UpdateZIndex();
|
|
}
|
|
readonly Vector2[] _uvs = new Vector2[4];
|
|
protected virtual void UpdateUV() {
|
|
var frame = CurrentFrame;
|
|
if (SpriteInfo.IsNullOrEmpty(frame)) return;
|
|
Vector2[] muv = OriginalUV;
|
|
for (int i = 0; i < _uvs.Length; i++) {
|
|
_uvs[i] = frame.Frame.GetUV(muv[i]);
|
|
}
|
|
mesh.Mesh.uv = _uvs;
|
|
}
|
|
|
|
private FitMode m_fit = FitMode.height;
|
|
public FitMode Fit {
|
|
get { return m_fit; }
|
|
set {
|
|
m_fit = value;
|
|
if (m_fit != FitMode.none && Scale.x != Scale.y) m_fit = FitMode.none;
|
|
}
|
|
}
|
|
public enum FitMode {
|
|
none, width, height
|
|
}
|
|
|
|
protected override void UpdateScale() {
|
|
if (SpriteInfo.IsNullOrEmpty(CurrentFrame)) return;
|
|
base.UpdateScale();
|
|
if (m_fit != FitMode.none && Scale.x != Scale.y) m_fit = FitMode.none;
|
|
}
|
|
|
|
protected override Vector3 BaseScale {
|
|
get {
|
|
return m_fit switch {
|
|
FitMode.none => Vector3.one,
|
|
FitMode.width => new Vector3(1, 1, 1 / CurrentFrame.Ratio),
|
|
FitMode.height => new Vector3(CurrentFrame.Ratio, 1, 1),
|
|
_ => throw new NotSupportedException("Unsupported fit mode"),
|
|
};
|
|
}
|
|
}
|
|
|
|
public override void Init() {
|
|
InternalInit();
|
|
OnFrameUpdate();
|
|
UpdateShader();
|
|
}
|
|
}
|
|
}
|