using System; using UnityEngine; using Logger = Cryville.Common.Logger; namespace Cryville.Crtr.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; } } /// /// The ratio of width divided by height. /// public float Ratio { get { return Rect.width / Rect.height; } } bool _loaded; Material _mat; public void Bind(Material mat) { _loaded = true; _mat = mat; Reload(); } public void Load() { _loaded = true; Reload(); } public void Reload() { if (!_loaded) return; if (!string.IsNullOrEmpty(FrameName)) { if (ChartPlayer.frames.ContainsKey(FrameName)) { Frame = ChartPlayer.frames[FrameName]; } else { Logger.Log("main", 4, "Skin", "Texture {0} not found", FrameName); Frame = null; } } else Frame = null; if (_mat != null) { _mat.mainTexture = Frame == null ? null : Frame.Texture; } } } public class SpritePlane : SpriteBase { public SpritePlane() { SubmitProperty("frame", new PropOp.String(v => Frame = v), 2); SubmitProperty("fit", new PropOp.Enum(v => Fit = v)); SubmitProperty("opacity", new PropOp.Float(v => Opacity = v)); } static Vector2[] _origuv; protected static Vector2[] OriginalUV { get { if (_origuv == null) { var m = GenericResources.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; } } protected SpriteInfo frameInfo = new SpriteInfo(); public string Frame { get { return frameInfo.FrameName; } set { frameInfo.FrameName = value; OnFrameUpdate(); } } protected void OnFrameUpdate() { if (!mesh.Initialized) return; if (frameInfo.Frame == null) { mesh.Renderer.enabled = false; return; } mesh.Renderer.enabled = true; UpdateUV(); UpdateScale(); UpdateZIndex(); } protected virtual void UpdateUV() { if (frameInfo.Frame == null) { Logger.Log("main", 4, "Skin", "Unable to load texture {0}", frameInfo.FrameName); return; } Vector2[] muv = OriginalUV; Vector2[] uv = new Vector2[muv.Length]; for (int i = 0; i < uv.Length; i++) { uv[i] = frameInfo.Frame.GetUV(muv[i]); } mesh.Mesh.uv = uv; } float _opacity = 1; public float Opacity { get { return _opacity; } set { _opacity = value; UpdateOpacity(); } } void UpdateOpacity() { if (!mesh.Initialized) return; var c = mesh.Renderer.material.color; c.a = _opacity; mesh.Renderer.material.color = c; } 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 (frameInfo.Frame == null) return; base.UpdateScale(); if (m_fit != FitMode.none && Scale.x != Scale.y) m_fit = FitMode.none; } protected override Vector3 BaseScale { get { switch (m_fit) { case FitMode.none: return Vector3.one; case FitMode.width: return new Vector3(1, 1, 1 / frameInfo.Ratio); case FitMode.height: return new Vector3(frameInfo.Ratio, 1, 1); default: throw new NotSupportedException("Unsupported fit mode"); } } } public override void Init() { InternalInit(); frameInfo.Bind(mesh.Renderer.material); OnFrameUpdate(); UpdateOpacity(); } } }