Code structure cleanup.
This commit is contained in:
66
Assets/Cryville/Crtr/Skin/Components/MeshBase.cs
Normal file
66
Assets/Cryville/Crtr/Skin/Components/MeshBase.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Skin.Components {
|
||||
[DisallowMultipleComponent]
|
||||
public abstract class MeshBase : SkinComponent {
|
||||
public MeshBase() {
|
||||
SubmitProperty("color", new PropOp.Color(v => Color = v));
|
||||
SubmitProperty("opacity", new PropOp.Float(v => {
|
||||
var c = Color;
|
||||
c.a *= v;
|
||||
Color = c;
|
||||
}));
|
||||
SubmitProperty("zindex", new PropOp.Integer(v => ZIndex = (short)v));
|
||||
}
|
||||
|
||||
protected MeshWrapper mesh = new MeshWrapper();
|
||||
protected Material[] materials;
|
||||
|
||||
short _zindex;
|
||||
public short ZIndex {
|
||||
get {
|
||||
return _zindex;
|
||||
}
|
||||
set {
|
||||
if (value < 0 || value > 5000)
|
||||
throw new ArgumentOutOfRangeException("value", "Z-index must be in [0..5000]");
|
||||
_zindex = value;
|
||||
UpdateZIndex();
|
||||
}
|
||||
}
|
||||
protected void UpdateZIndex() {
|
||||
if (!mesh.Initialized) return;
|
||||
foreach (var mat in materials) {
|
||||
mat.renderQueue = _zindex;
|
||||
}
|
||||
}
|
||||
|
||||
Color _color = Color.white;
|
||||
public Color Color {
|
||||
get { return _color; }
|
||||
set {
|
||||
_color = value;
|
||||
UpdateColor();
|
||||
}
|
||||
}
|
||||
protected virtual void UpdateColor() {
|
||||
if (!mesh.Initialized) return;
|
||||
foreach (var mat in materials) {
|
||||
mat.color = _color;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDestroy() {
|
||||
DestroyMaterials();
|
||||
mesh.Destroy();
|
||||
}
|
||||
|
||||
protected void DestroyMaterials() {
|
||||
if (materials == null) return;
|
||||
foreach (var mat in materials) {
|
||||
Material.Destroy(mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Cryville/Crtr/Skin/Components/MeshBase.cs.meta
Normal file
11
Assets/Cryville/Crtr/Skin/Components/MeshBase.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75daba44e5811b943a08e6f137cc2b0c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
51
Assets/Cryville/Crtr/Skin/Components/MeshWrapper.cs
Normal file
51
Assets/Cryville/Crtr/Skin/Components/MeshWrapper.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Skin.Components {
|
||||
public class MeshWrapper {
|
||||
public GameObject MeshObject {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public MeshFilter MeshFilter {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
Mesh m_mesh;
|
||||
public Mesh Mesh {
|
||||
get { return m_mesh; }
|
||||
set { MeshFilter.sharedMesh = m_mesh = value; }
|
||||
}
|
||||
public Transform MeshTransform {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public Renderer Renderer {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public bool Initialized {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public static Material NewMaterial() {
|
||||
return Material.Instantiate(BuiltinResources.Materials["-SpriteMat"]);
|
||||
}
|
||||
public void Init(Transform parent) {
|
||||
MeshObject = new GameObject("__mesh__");
|
||||
MeshTransform = MeshObject.transform;
|
||||
MeshTransform.SetParent(parent, false);
|
||||
if (MeshObject.GetComponent<MeshFilter>() == null)
|
||||
MeshObject.AddComponent<MeshFilter>();
|
||||
if (MeshObject.GetComponent<MeshRenderer>() == null)
|
||||
MeshObject.AddComponent<MeshRenderer>();
|
||||
MeshFilter = MeshObject.GetComponent<MeshFilter>();
|
||||
Renderer = MeshObject.GetComponent<Renderer>();
|
||||
Initialized = true;
|
||||
}
|
||||
public void Destroy() {
|
||||
Mesh.Destroy(m_mesh);
|
||||
m_mesh = null;
|
||||
GameObject.Destroy(MeshObject);
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Cryville/Crtr/Skin/Components/MeshWrapper.cs.meta
Normal file
12
Assets/Cryville/Crtr/Skin/Components/MeshWrapper.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39e842e4379944f46ae46577bd5f51d4
|
||||
timeCreated: 1636616568
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
227
Assets/Cryville/Crtr/Skin/Components/PolygonSGO.cs
Normal file
227
Assets/Cryville/Crtr/Skin/Components/PolygonSGO.cs
Normal file
@@ -0,0 +1,227 @@
|
||||
using Cryville.Common.Buffers;
|
||||
using Cryville.Common.Pdt;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Skin.Components {
|
||||
public class PolygonSGO : SectionalGameObject {
|
||||
static readonly SimpleObjectPool<List<Vector3>> _ptPool = new SimpleObjectPool<List<Vector3>>(1024);
|
||||
static readonly SimpleObjectPool<List<float>> _lPool = new SimpleObjectPool<List<float>>(1024);
|
||||
|
||||
static readonly ListPool<int> _indexPool = new ListPool<int>();
|
||||
static readonly ListPool<Vector3> _vertPool = new ListPool<Vector3>();
|
||||
static readonly ListPool<Vector2> _uvPool = new ListPool<Vector2>();
|
||||
static readonly ArrayPool<Vector2> _shapePool = new ArrayPool<Vector2>(0x100, 0x10000);
|
||||
|
||||
public PolygonSGO() {
|
||||
SubmitProperty("head", new PropOp.String(v => head.FrameName = v));
|
||||
SubmitProperty("body", new PropOp.String(v => body.FrameName = v));
|
||||
SubmitProperty("tail", new PropOp.String(v => tail.FrameName = v));
|
||||
SubmitProperty("shape", new op_set_shape(this), 2);
|
||||
}
|
||||
|
||||
#pragma warning disable IDE1006
|
||||
public class op_set_shape : PdtOperator {
|
||||
readonly PolygonSGO _self;
|
||||
public op_set_shape(PolygonSGO self) : base(1) {
|
||||
_self = self;
|
||||
}
|
||||
protected override unsafe void Execute() {
|
||||
var o = GetOperand(0);
|
||||
if (o.Type != PdtInternalType.Vector) throw new ArgumentException("Not a vector");
|
||||
_self._shapeLength = (o.Length - sizeof(int)) / sizeof(Vector2);
|
||||
if (_self._shape != null) _shapePool.Return(_self._shape);
|
||||
_self._shape = _shapePool.Rent(_self._shapeLength);
|
||||
for (int i = 0; i < _self._shapeLength; i++) {
|
||||
_self._shape[i] = o.As<Vector2>(i * sizeof(Vector2));
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE1006
|
||||
|
||||
int _shapeLength = 0;
|
||||
Vector2[] _shape = null;
|
||||
float GetWidth() {
|
||||
float r = 0;
|
||||
for (int i = 1; i < _shapeLength; i++) {
|
||||
r += (_shape[i] - _shape[i-1]).magnitude;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public SpriteInfo head = new SpriteInfo();
|
||||
public SpriteInfo body = new SpriteInfo();
|
||||
public SpriteInfo tail = new SpriteInfo();
|
||||
|
||||
List<Vector3> vertices;
|
||||
List<float> lengths;
|
||||
float sumLength = 0;
|
||||
|
||||
public override void Init() {
|
||||
mesh.Init(transform);
|
||||
mesh.Mesh = new Mesh();
|
||||
|
||||
mesh.Renderer.sharedMaterials = materials = new Material[] {
|
||||
MeshWrapper.NewMaterial(),
|
||||
MeshWrapper.NewMaterial(),
|
||||
MeshWrapper.NewMaterial(),
|
||||
};
|
||||
head.Bind(materials[0]);
|
||||
body.Bind(materials[1]);
|
||||
tail.Bind(materials[2]);
|
||||
|
||||
base.Init();
|
||||
}
|
||||
|
||||
protected override void OnDestroy() {
|
||||
if (_shape != null) _shapePool.Return(_shape);
|
||||
if (vertices != null) {
|
||||
_ptPool.Return(vertices);
|
||||
_lPool.Return(lengths);
|
||||
}
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
protected override void AppendPointInternal(Vector3 p, Quaternion r) {
|
||||
if (vertices == null) {
|
||||
vertices = _ptPool.Rent();
|
||||
lengths = _lPool.Rent();
|
||||
}
|
||||
|
||||
for (int i = 0; i < _shapeLength; i++) {
|
||||
Vector2 sp = r * _shape[i];
|
||||
vertices.Add(p + (Vector3)sp);
|
||||
}
|
||||
|
||||
if (prevpt != null) {
|
||||
float len = (p - prevpt.Value).magnitude;
|
||||
lengths.Add(len);
|
||||
sumLength += len;
|
||||
}
|
||||
}
|
||||
|
||||
List<Vector3> verts;
|
||||
List<Vector2> uvs;
|
||||
List<int> trih = null, trib = null, trit = null;
|
||||
static readonly List<int> _emptyTris = new List<int>();
|
||||
|
||||
public override void Seal() {
|
||||
if (vertCount <= 1 || sumLength == 0) return;
|
||||
int vcpsec = _shapeLength; // Vertex Count Per Section
|
||||
float width = GetWidth();
|
||||
float headLength = 0;
|
||||
if (head.Frame != null) headLength = width / head.Ratio;
|
||||
float tailLength = 0;
|
||||
if (tail.Frame != null) tailLength = width / tail.Ratio;
|
||||
float endLength = headLength + tailLength;
|
||||
if (sumLength <= endLength) {
|
||||
// The total length of the two ends is longer than the whole mesh, squeeze the two ends
|
||||
float ratio = sumLength / endLength;
|
||||
headLength *= ratio;
|
||||
tailLength *= ratio;
|
||||
}
|
||||
|
||||
// Find the vertex counts needed for the three parts from the head
|
||||
float l0 = 0;
|
||||
int hvc = 0;
|
||||
for (; l0 < headLength && hvc < lengths.Count; hvc++)
|
||||
l0 += lengths[hvc];
|
||||
int bvc = 0;
|
||||
for (; l0 < sumLength - tailLength && hvc + bvc < lengths.Count; bvc++)
|
||||
l0 += lengths[hvc + bvc];
|
||||
int tvc = lengths.Count - hvc - bvc + 1;
|
||||
if (hvc > 0) {
|
||||
hvc++;
|
||||
bvc++;
|
||||
}
|
||||
bvc++;
|
||||
int vc = hvc + bvc + tvc;
|
||||
|
||||
verts = _vertPool.Rent(vc * vcpsec);
|
||||
uvs = _uvPool.Rent(vc * vcpsec);
|
||||
int i = 0; int t = 0; float l = 0;
|
||||
if (head.Frame != null) { GenerateMeshTo(verts, uvs, out trih, head, ref i, ref t, ref l, 0, headLength, vcpsec, hvc); }
|
||||
GenerateMeshTo(verts, uvs, out trib, body, ref i, ref t, ref l, headLength, sumLength - tailLength, vcpsec, hvc + bvc);
|
||||
if (tail.Frame != null) { GenerateMeshTo(verts, uvs, out trit, tail, ref i, ref t, ref l, sumLength - tailLength, sumLength, vcpsec, vc); }
|
||||
|
||||
mesh.Mesh.subMeshCount = 3;
|
||||
int m = 0;
|
||||
mesh.Mesh.SetVertices(verts);
|
||||
mesh.Mesh.SetUVs(0, uvs);
|
||||
mesh.Mesh.SetTriangles(head.Frame == null ? _emptyTris : trih, m++);
|
||||
mesh.Mesh.SetTriangles(trib, m++);
|
||||
mesh.Mesh.SetTriangles(tail.Frame == null ? _emptyTris : trit, m++);
|
||||
mesh.Mesh.RecalculateNormals();
|
||||
|
||||
_vertPool.Return(verts); verts = null;
|
||||
_uvPool.Return(uvs); uvs = null;
|
||||
if (trih != null) { _indexPool.Return(trih); trih = null; }
|
||||
if (trib != null) { _indexPool.Return(trib); trib = null; }
|
||||
if (trit != null) { _indexPool.Return(trit); trit = null; }
|
||||
}
|
||||
|
||||
void GenerateMeshTo(List<Vector3> verts, List<Vector2> uvs, out List<int> tris, SpriteInfo info, ref int i, ref int t, ref float l, float startl, float endl, int vcpsec, int vend) {
|
||||
if (i > lengths.Count) {
|
||||
tris = _indexPool.Rent(0);
|
||||
return;
|
||||
}
|
||||
|
||||
int t0 = t;
|
||||
var frame = info.Frame;
|
||||
|
||||
if (startl != 0) {
|
||||
float pl2 = l - lengths[i - 1];
|
||||
float fr2 = (startl - pl2) / (l - pl2);
|
||||
for (int j = 0; j < vcpsec; j++, t++) {
|
||||
verts[t] =
|
||||
vertices[vcpsec*(i-1)+j] * (1-fr2)
|
||||
+ vertices[vcpsec*i+j] * fr2;
|
||||
var u = j / (vcpsec - 1);
|
||||
if (frame != null) uvs[t] = frame.GetUV(u, 0);
|
||||
}
|
||||
}
|
||||
for (; t / vcpsec < vend - 1; i++) {
|
||||
var v = (l - startl) / (endl - startl);
|
||||
for (int j = 0; j < vcpsec; j++, t++) {
|
||||
verts[t] = vertices[vcpsec*i+j];
|
||||
var u = j / (vcpsec - 1);
|
||||
if (frame != null) uvs[t] = frame.GetUV(u, v);
|
||||
}
|
||||
l += lengths[i];
|
||||
}
|
||||
float pl = l - lengths[i - 1];
|
||||
float fr = (endl - pl) / (l - pl);
|
||||
for (int j = 0; j < vcpsec; j++, t++) {
|
||||
verts[t] =
|
||||
vertices[vcpsec*(i-1)+j] * (1-fr)
|
||||
+ vertices[vcpsec*i+j] * fr;
|
||||
var u = j / (vcpsec - 1);
|
||||
if (frame != null) uvs[t] = frame.GetUV(u, 1);
|
||||
}
|
||||
|
||||
tris = _indexPool.Rent((vend - t0 / vcpsec - 1) * (vcpsec - 1) * 6);
|
||||
int i3 = 0;
|
||||
for (int i1 = t0 + vcpsec + 1; i1 < t; i1++) {
|
||||
if (i1 % vcpsec == 0) continue;
|
||||
int i2 = i1 - vcpsec;
|
||||
tris[i3++] = i1 - 1;
|
||||
tris[i3++] = i2;
|
||||
tris[i3++] = i2 - 1;
|
||||
tris[i3++] = i1 - 1;
|
||||
tris[i3++] = i1;
|
||||
tris[i3++] = i2;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Reset() {
|
||||
base.Reset();
|
||||
if (mesh.Initialized) mesh.Mesh.Clear();
|
||||
if (vertices != null) {
|
||||
vertices.Clear();
|
||||
lengths.Clear();
|
||||
}
|
||||
sumLength = 0;
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Cryville/Crtr/Skin/Components/PolygonSGO.cs.meta
Normal file
11
Assets/Cryville/Crtr/Skin/Components/PolygonSGO.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed3932875286a2947b9c600ba47f1066
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
50
Assets/Cryville/Crtr/Skin/Components/SectionalGameObject.cs
Normal file
50
Assets/Cryville/Crtr/Skin/Components/SectionalGameObject.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Skin.Components {
|
||||
public abstract class SectionalGameObject : MeshBase {
|
||||
protected Vector3? prevpt;
|
||||
protected Quaternion? prevrot;
|
||||
protected int vertCount = 0;
|
||||
Part part = Part.whole;
|
||||
enum Part {
|
||||
whole = 0,
|
||||
idle = 1,
|
||||
start = 2,
|
||||
end = 3,
|
||||
}
|
||||
|
||||
public SectionalGameObject() {
|
||||
SubmitProperty("partial", new PropOp.Boolean(v => part = Part.idle));
|
||||
SubmitProperty("part", new PropOp.Enum<Part>(v => part = v, v => (Part)v), 2);
|
||||
}
|
||||
|
||||
public override void Init() {
|
||||
UpdateZIndex();
|
||||
UpdateColor();
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void AppendPoint(Vector3 p) {
|
||||
AppendPoint(p, Quaternion.identity);
|
||||
}
|
||||
|
||||
public void AppendPoint(Vector3 p, Quaternion r) {
|
||||
if (prevpt == p && prevrot == r || ((int)part & 1) == 1) return;
|
||||
AppendPointInternal(p, r);
|
||||
// if (!headGenerated) Logger.Log("main", 0, "Skin/Polysec", "{0}", r);
|
||||
prevpt = p;
|
||||
prevrot = r;
|
||||
vertCount++;
|
||||
}
|
||||
|
||||
protected abstract void AppendPointInternal(Vector3 wp, Quaternion r);
|
||||
|
||||
public abstract void Seal();
|
||||
|
||||
public virtual void Reset() {
|
||||
vertCount = 0;
|
||||
prevpt = null;
|
||||
prevrot = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f2666d577419bd43aec55ad614a43f4
|
||||
timeCreated: 1596633346
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
89
Assets/Cryville/Crtr/Skin/Components/SkinAnimation.cs
Normal file
89
Assets/Cryville/Crtr/Skin/Components/SkinAnimation.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using Cryville.Common;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Logger = Cryville.Common.Logging.Logger;
|
||||
|
||||
namespace Cryville.Crtr.Skin.Components {
|
||||
public class SkinAnimation : SkinComponent {
|
||||
public SkinAnimation() {
|
||||
SubmitProperty("name", new PropOp.Identifier(v => Name = v));
|
||||
SubmitProperty("duration", new PropOp.Float(v => Duration = v));
|
||||
SubmitProperty("iteration", new PropOp.Float(v => Iteration = v));
|
||||
SubmitProperty("direction", new PropOp.Enum<AnimationDirection>(v => Direction = v, v => (AnimationDirection)v));
|
||||
SubmitProperty("delay", new PropOp.Float(v => Delay = v));
|
||||
Iteration = 1;
|
||||
}
|
||||
|
||||
SkinContext _skinContext;
|
||||
Transform _writeTransform;
|
||||
|
||||
AnimationSpan _anim;
|
||||
int _name;
|
||||
public int Name {
|
||||
set {
|
||||
if (_name == value) return;
|
||||
_name = value;
|
||||
if (value == 0) {
|
||||
_anim = null;
|
||||
}
|
||||
else {
|
||||
var id = new Identifier(value);
|
||||
AnimationSpan anim;
|
||||
if (!ChartPlayer.pskin.animations.TryGetValue(id, out anim)) {
|
||||
Logger.Log("main", 4, "Skin", "Animation {0} not found", id.Name);
|
||||
_anim = null;
|
||||
return;
|
||||
}
|
||||
_anim = anim;
|
||||
}
|
||||
}
|
||||
}
|
||||
public float Duration { get; private set; }
|
||||
public float Iteration { get; private set; }
|
||||
public AnimationDirection Direction { get; private set; }
|
||||
public float Delay { get; private set; }
|
||||
|
||||
double _startTime;
|
||||
|
||||
public override void Init() {
|
||||
_skinContext = new SkinContext(transform);
|
||||
}
|
||||
public override void Rewind(double time, Transform target) {
|
||||
_startTime = time;
|
||||
if (target == null) target = transform;
|
||||
_writeTransform = target;
|
||||
}
|
||||
public override void Tick(SkinContainer c, double time) {
|
||||
float _rtime = (float)(time - _startTime - Delay) / Duration;
|
||||
if (_rtime < 0) _rtime = 0;
|
||||
else if (_rtime > Iteration) {
|
||||
if (Direction.HasFlag(AnimationDirection.alternate)) {
|
||||
_rtime = Iteration % 2;
|
||||
if (_rtime > 1) _rtime = 2 - _rtime;
|
||||
}
|
||||
else {
|
||||
_rtime = Iteration % 1;
|
||||
if (_rtime == 0) _rtime = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (Direction.HasFlag(AnimationDirection.alternate)) {
|
||||
_rtime %= 2;
|
||||
if (_rtime > 1) _rtime = 2 - _rtime;
|
||||
}
|
||||
else {
|
||||
_rtime %= 1;
|
||||
}
|
||||
}
|
||||
if (Direction.HasFlag(AnimationDirection.reverse)) _rtime = 1 - _rtime;
|
||||
if (_anim != null) c.MatchAnimation(_anim, _rtime, new RuntimeSkinContext(_skinContext, _writeTransform));
|
||||
}
|
||||
protected override void OnDestroy() { }
|
||||
}
|
||||
[Flags]
|
||||
public enum AnimationDirection {
|
||||
normal = 0,
|
||||
reverse = 1,
|
||||
alternate = 2,
|
||||
}
|
||||
}
|
11
Assets/Cryville/Crtr/Skin/Components/SkinAnimation.cs.meta
Normal file
11
Assets/Cryville/Crtr/Skin/Components/SkinAnimation.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80318e36af5412345871bdbf80d49ef2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
41
Assets/Cryville/Crtr/Skin/Components/SkinComponent.cs
Normal file
41
Assets/Cryville/Crtr/Skin/Components/SkinComponent.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Collections.Specialized;
|
||||
using Cryville.Common.Pdt;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Skin.Components {
|
||||
public abstract class SkinComponent : MonoBehaviour {
|
||||
/// <summary>
|
||||
/// The property operators of the component.
|
||||
/// </summary>
|
||||
public IntKeyedDictionary<SkinProperty> Properties { get; private set; }
|
||||
/// <summary>
|
||||
/// Submits a property.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the property.</param>
|
||||
/// <param name="property">The property.</param>
|
||||
protected void SubmitProperty(string name, PdtOperator property, int udl = 1) {
|
||||
Properties.Add(IdentifierManager.Shared.Request(name), new SkinProperty(property, udl));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a skin component.
|
||||
/// </summary>
|
||||
protected SkinComponent() {
|
||||
Properties = new IntKeyedDictionary<SkinProperty>();
|
||||
}
|
||||
|
||||
public virtual void Init() { }
|
||||
public virtual void Rewind(double time, Transform target) { }
|
||||
public virtual void Tick(SkinContainer c, double time) { }
|
||||
protected abstract void OnDestroy();
|
||||
}
|
||||
public struct SkinProperty {
|
||||
public PdtOperator Operator { get; set; }
|
||||
public int UpdateDynamicLevel { get; set; }
|
||||
public SkinProperty(PdtOperator op, int udl = 0) {
|
||||
Operator = op;
|
||||
UpdateDynamicLevel = udl;
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Cryville/Crtr/Skin/Components/SkinComponent.cs.meta
Normal file
12
Assets/Cryville/Crtr/Skin/Components/SkinComponent.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a54d8e3558a89f8499fc049afd84e959
|
||||
timeCreated: 1623576806
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
98
Assets/Cryville/Crtr/Skin/Components/SpriteBase.cs
Normal file
98
Assets/Cryville/Crtr/Skin/Components/SpriteBase.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using Cryville.Common.Pdt;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Skin.Components {
|
||||
public abstract class SpriteBase : MeshBase {
|
||||
public SpriteBase() {
|
||||
SubmitProperty("bound", new op_set_bound(this));
|
||||
SubmitProperty("pivot", new PropOp.Vector2(v => Pivot = v));
|
||||
SubmitProperty("scale", new PropOp.Vector2(v => Scale = v));
|
||||
SubmitProperty("ui", new PropOp.Boolean(v => UI = v));
|
||||
}
|
||||
|
||||
#pragma warning disable IDE1006
|
||||
class op_set_bound : PdtOperator {
|
||||
readonly SpriteBase _self;
|
||||
public op_set_bound(SpriteBase self) : base(2) {
|
||||
_self = self;
|
||||
}
|
||||
protected override void Execute() {
|
||||
_self.SetBound(
|
||||
GetOperand(0).As<Vector2>(),
|
||||
GetOperand(1).As<Vector3>()
|
||||
);
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE1006
|
||||
|
||||
Vector2 _scale = Vector2.one;
|
||||
public Vector2 Scale {
|
||||
get { return _scale; }
|
||||
set {
|
||||
_scale = value;
|
||||
UpdateScale();
|
||||
}
|
||||
}
|
||||
protected virtual void UpdateScale() {
|
||||
if (!mesh.Initialized) return;
|
||||
var s = BaseScale;
|
||||
var ss = new Vector3(_scale.x, 1, _scale.y);
|
||||
s.Scale(ss);
|
||||
mesh.MeshTransform.localScale = s;
|
||||
OnPivotUpdate();
|
||||
}
|
||||
protected abstract Vector3 BaseScale {
|
||||
get;
|
||||
}
|
||||
protected virtual Vector3 BaseSize {
|
||||
get { return Vector3.one; }
|
||||
}
|
||||
|
||||
Vector2 _pivot;
|
||||
public Vector2 Pivot {
|
||||
get { return _pivot; }
|
||||
set {
|
||||
_pivot = value;
|
||||
OnPivotUpdate();
|
||||
}
|
||||
}
|
||||
protected void OnPivotUpdate() {
|
||||
if (!mesh.Initialized) return;
|
||||
var r = new Vector3(_pivot.x - BasePivot.x, 0, _pivot.y - BasePivot.y);
|
||||
r.Scale(mesh.MeshTransform.localScale);
|
||||
r.Scale(BaseSize);
|
||||
mesh.MeshTransform.localPosition = -r;
|
||||
}
|
||||
protected virtual Vector2 BasePivot {
|
||||
get { return Vector2.zero; }
|
||||
}
|
||||
|
||||
public void SetBound(Vector2 piv, Vector3 pos) {
|
||||
var r = Quaternion.Inverse(transform.rotation);
|
||||
var da = piv - Pivot;
|
||||
var dp = r * (pos - transform.localPosition);
|
||||
if (da.x != 0) _scale.x = dp.x / da.x;
|
||||
if (da.y != 0) _scale.y = dp.z / da.y;
|
||||
}
|
||||
|
||||
static readonly Quaternion uirot
|
||||
= Quaternion.Euler(new Vector3(-90, 0, 0));
|
||||
bool _ui;
|
||||
public bool UI {
|
||||
get { return _ui; }
|
||||
set {
|
||||
_ui = value;
|
||||
if (_ui) transform.localRotation = uirot;
|
||||
}
|
||||
}
|
||||
|
||||
protected void InternalInit(string meshName = "quad") {
|
||||
mesh.Init(transform);
|
||||
mesh.Renderer.sharedMaterials = materials = new Material[] { MeshWrapper.NewMaterial() };
|
||||
mesh.Mesh = Mesh.Instantiate(BuiltinResources.Meshes[meshName]);
|
||||
UpdateColor();
|
||||
UpdateScale();
|
||||
UpdateZIndex();
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Cryville/Crtr/Skin/Components/SpriteBase.cs.meta
Normal file
12
Assets/Cryville/Crtr/Skin/Components/SpriteBase.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 248ab93b20a0ac9439afaee32357ed5c
|
||||
timeCreated: 1614907140
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
188
Assets/Cryville/Crtr/Skin/Components/SpritePlane.cs
Normal file
188
Assets/Cryville/Crtr/Skin/Components/SpritePlane.cs
Normal file
@@ -0,0 +1,188 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Logger = Cryville.Common.Logging.Logger;
|
||||
|
||||
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 {
|
||||
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 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 SpriteInfo() };
|
||||
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 {
|
||||
switch (m_fit) {
|
||||
case FitMode.none: return Vector3.one;
|
||||
case FitMode.width: return new Vector3(1, 1, 1 / CurrentFrame.Ratio);
|
||||
case FitMode.height: return new Vector3(CurrentFrame.Ratio, 1, 1);
|
||||
default: throw new NotSupportedException("Unsupported fit mode");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Init() {
|
||||
InternalInit();
|
||||
OnFrameUpdate();
|
||||
UpdateShader();
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Cryville/Crtr/Skin/Components/SpritePlane.cs.meta
Normal file
12
Assets/Cryville/Crtr/Skin/Components/SpritePlane.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76053cf6896b7304fb0ec26546de1ace
|
||||
timeCreated: 1609142271
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
15
Assets/Cryville/Crtr/Skin/Components/SpriteRect.cs
Normal file
15
Assets/Cryville/Crtr/Skin/Components/SpriteRect.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Skin.Components {
|
||||
public class SpriteRect : SpriteBase {
|
||||
public SpriteRect() { }
|
||||
|
||||
protected override Vector3 BaseScale {
|
||||
get { return Vector3.one; }
|
||||
}
|
||||
|
||||
public override void Init() {
|
||||
InternalInit();
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Cryville/Crtr/Skin/Components/SpriteRect.cs.meta
Normal file
12
Assets/Cryville/Crtr/Skin/Components/SpriteRect.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a902fb77646e6eb4eb96d8ac86b3ee0e
|
||||
timeCreated: 1614821846
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
89
Assets/Cryville/Crtr/Skin/Components/SpriteScale3.cs
Normal file
89
Assets/Cryville/Crtr/Skin/Components/SpriteScale3.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Skin.Components {
|
||||
public class SpriteScale3 : SpritePlane {
|
||||
public SpriteScale3() {
|
||||
SubmitProperty("border", new PropOp.Vector2(v => Border = v));
|
||||
}
|
||||
|
||||
static readonly Dictionary<float, int> uvrefl
|
||||
= new Dictionary<float, int>() {
|
||||
{-0.5f, 0}, {-0.4f, 1}, {0.4f, 2}, {0.5f, 3},
|
||||
};
|
||||
static Vector2[] _origuv;
|
||||
protected static new Vector2[] OriginalUV {
|
||||
get {
|
||||
if (_origuv == null) {
|
||||
var m = BuiltinResources.Meshes["quad_scale3h"];
|
||||
Vector2[] uv = new Vector2[m.vertices.Length];
|
||||
for (int i = 0; i < uv.Length; i++) {
|
||||
uv[i] = new Vector2(
|
||||
uvrefl[m.vertices[i].x],
|
||||
uvrefl[m.vertices[i].z]
|
||||
);
|
||||
}
|
||||
_origuv = uv;
|
||||
}
|
||||
return _origuv;
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 _border = new Vector2(0, 1);
|
||||
public Vector2 Border {
|
||||
get { return _border; }
|
||||
set {
|
||||
_border = value;
|
||||
UpdateScale();
|
||||
}
|
||||
}
|
||||
protected override void UpdateScale() {
|
||||
base.UpdateScale();
|
||||
if (!mesh.Initialized) return;
|
||||
UpdateUV();
|
||||
}
|
||||
|
||||
readonly Vector2[] _uvs = new Vector2[8];
|
||||
readonly Vector3[] _verts = new Vector3[8];
|
||||
protected override void UpdateUV() {
|
||||
var frame = CurrentFrame;
|
||||
if (SpriteInfo.IsNullOrEmpty(frame)) return;
|
||||
|
||||
Vector2[] muv = OriginalUV;
|
||||
|
||||
var or = frame.Ratio;
|
||||
var sr = Scale.x / Scale.y;
|
||||
var rr = or / sr;
|
||||
var b1 = rr * _border.x;
|
||||
var b2 = 1 - rr * (1 - _border.y);
|
||||
|
||||
for (int i = 0; i < muv.Length; i++) {
|
||||
float x; float bx;
|
||||
switch ((int)muv[i].x) {
|
||||
case 0: x = 0; bx = 0; break;
|
||||
case 1: x = _border.x; bx = b1; break;
|
||||
case 2: x = _border.y; bx = b2; break;
|
||||
case 3: x = 1; bx = 1; break;
|
||||
default: throw new NotSupportedException("Built-in resource corrupted");
|
||||
}
|
||||
float y;
|
||||
switch ((int)muv[i].y) {
|
||||
case 0: y = 0; break;
|
||||
case 3: y = 1; break;
|
||||
default: throw new NotSupportedException("Built-in resource corrupted");
|
||||
}
|
||||
_uvs[i] = frame.Frame.GetUV(x, y);
|
||||
bx -= 0.5f; y -= 0.5f;
|
||||
_verts[i] = new Vector3(bx, 0, y);
|
||||
}
|
||||
mesh.Mesh.uv = _uvs;
|
||||
mesh.Mesh.vertices = _verts;
|
||||
}
|
||||
|
||||
public override void Init() {
|
||||
InternalInit("quad_scale3h");
|
||||
OnFrameUpdate();
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Cryville/Crtr/Skin/Components/SpriteScale3.cs.meta
Normal file
12
Assets/Cryville/Crtr/Skin/Components/SpriteScale3.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31dc4a947b5c7c645aa8fc2b82b4fba7
|
||||
timeCreated: 1615333501
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
175
Assets/Cryville/Crtr/Skin/Components/SpriteText.cs
Normal file
175
Assets/Cryville/Crtr/Skin/Components/SpriteText.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
using Cryville.Common.Buffers;
|
||||
using Cryville.Common.Pdt;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Skin.Components {
|
||||
public class SpriteText : SpriteBase {
|
||||
public SpriteText() {
|
||||
SubmitProperty("frames", new op_set_frames(this));
|
||||
SubmitProperty("value", new PropOp.TargetString(() => Value));
|
||||
SubmitProperty("size", new PropOp.Float(v => Size = v));
|
||||
SubmitProperty("spacing", new PropOp.Float(v => Spacing = v));
|
||||
}
|
||||
|
||||
#pragma warning disable IDE1006
|
||||
class op_set_frames : PdtOperator {
|
||||
readonly SpriteText _self;
|
||||
public op_set_frames(SpriteText self) : base(2) {
|
||||
_self = self;
|
||||
}
|
||||
protected override unsafe void Execute() {
|
||||
var keys = GetOperand(0).AsString();
|
||||
var values = GetOperand(1);
|
||||
int arrtype; int len;
|
||||
values.GetArraySuffix(out arrtype, out len);
|
||||
if (arrtype != PdtInternalType.String) throw new InvalidCastException("Not an array of strings");
|
||||
if (len != keys.Length) throw new ArgumentException("Length of key not equal to frame count");
|
||||
var result = new Dictionary<char, SpriteInfo>(len);
|
||||
int o = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
string v = values.AsString(o);
|
||||
o += v.Length * sizeof(char) + sizeof(int);
|
||||
result.Add(keys[i], new SpriteInfo { FrameName = v });
|
||||
}
|
||||
_self.Frames = result;
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE1006
|
||||
|
||||
protected override void OnDestroy() {
|
||||
base.OnDestroy();
|
||||
foreach (var m in meshes) m.Value.Destroy();
|
||||
}
|
||||
|
||||
Dictionary<char, SpriteInfo> m_frames;
|
||||
public Dictionary<char, SpriteInfo> Frames {
|
||||
get { return m_frames; }
|
||||
set { m_frames = value; UpdateFrames(); }
|
||||
}
|
||||
|
||||
readonly TargetString m_value = new TargetString();
|
||||
public TargetString Value { get { return m_value; } }
|
||||
|
||||
public float m_size;
|
||||
public float Size {
|
||||
get { return m_size; }
|
||||
set { m_size = value; UpdateScale(); }
|
||||
}
|
||||
|
||||
public float m_spacing;
|
||||
public float Spacing {
|
||||
get { return m_spacing; }
|
||||
set { m_spacing = value; UpdateScale(); }
|
||||
}
|
||||
|
||||
protected override void UpdateScale() {
|
||||
if (!mesh.Initialized) return;
|
||||
UpdateMeshes();
|
||||
base.UpdateScale();
|
||||
}
|
||||
|
||||
void UpdateFrames() {
|
||||
if (!mesh.Initialized) return;
|
||||
float frameHeight = 0;
|
||||
foreach (var m in meshes) m.Value.Destroy();
|
||||
meshes.Clear();
|
||||
verts.Clear();
|
||||
uvs.Clear();
|
||||
DestroyMaterials();
|
||||
materials = new Material[m_frames.Count];
|
||||
int i = 0;
|
||||
foreach (var f in m_frames) {
|
||||
if (SpriteInfo.IsNullOrEmpty(f.Value)) continue;
|
||||
if (frameHeight == 0) frameHeight = f.Value.Rect.height;
|
||||
else if (frameHeight != f.Value.Rect.height) throw new Exception("Inconsistent frame height for text component");
|
||||
var tex = f.Value.Frame.Texture;
|
||||
if (!meshes.ContainsKey(tex)) {
|
||||
var m = new MeshWrapper();
|
||||
m.Init(mesh.MeshTransform);
|
||||
m.Mesh = new Mesh();
|
||||
var mat = MeshWrapper.NewMaterial();
|
||||
mat.mainTexture = tex;
|
||||
m.Renderer.sharedMaterial = materials[i++] = mat;
|
||||
meshes.Add(tex, m);
|
||||
verts.Add(tex, new List<Vector3>());
|
||||
uvs.Add(tex, new List<Vector2>());
|
||||
tris.Add(tex, new List<int>());
|
||||
}
|
||||
}
|
||||
UpdateColor();
|
||||
UpdateScale();
|
||||
}
|
||||
|
||||
float sum_x;
|
||||
readonly Dictionary<Texture2D, MeshWrapper> meshes = new Dictionary<Texture2D, MeshWrapper>();
|
||||
readonly Dictionary<Texture2D, List<Vector3>> verts = new Dictionary<Texture2D, List<Vector3>>();
|
||||
readonly Dictionary<Texture2D, List<Vector2>> uvs = new Dictionary<Texture2D, List<Vector2>>();
|
||||
readonly Dictionary<Texture2D, List<int>> tris = new Dictionary<Texture2D, List<int>>();
|
||||
void UpdateMeshes() {
|
||||
if (meshes.Count == 0) return;
|
||||
sum_x = 0;
|
||||
foreach (var t in meshes) {
|
||||
var key = t.Key;
|
||||
verts[key].Clear();
|
||||
uvs[key].Clear();
|
||||
tris[key].Clear();
|
||||
}
|
||||
foreach (var c in m_value) {
|
||||
var f = m_frames[c];
|
||||
var t = f.Frame.Texture;
|
||||
float w = f.Ratio * m_size;
|
||||
verts[t].Add(new Vector3(sum_x , 0, 0));
|
||||
verts[t].Add(new Vector3(sum_x + w, 0, 0));
|
||||
verts[t].Add(new Vector3(sum_x + w, 0, m_size));
|
||||
verts[t].Add(new Vector3(sum_x , 0, m_size));
|
||||
uvs[t].Add(f.Frame.GetUV(new Vector2(0, 0)));
|
||||
uvs[t].Add(f.Frame.GetUV(new Vector2(1, 0)));
|
||||
uvs[t].Add(f.Frame.GetUV(new Vector2(1, 1)));
|
||||
uvs[t].Add(f.Frame.GetUV(new Vector2(0, 1)));
|
||||
sum_x += w + m_spacing;
|
||||
}
|
||||
foreach (var t in meshes) {
|
||||
var key = t.Key;
|
||||
var m = meshes[key].Mesh;
|
||||
m.Clear();
|
||||
int cc = verts[key].Count / 4;
|
||||
var _tris = tris[key];
|
||||
for (int i = 0; i < cc; i++) {
|
||||
_tris.Add(i * 4);
|
||||
_tris.Add(i * 4 + 3);
|
||||
_tris.Add(i * 4 + 1);
|
||||
_tris.Add(i * 4 + 1);
|
||||
_tris.Add(i * 4 + 3);
|
||||
_tris.Add(i * 4 + 2);
|
||||
}
|
||||
m.SetVertices(verts[key]);
|
||||
m.SetUVs(0, uvs[key]);
|
||||
m.SetTriangles(tris[key], 0);
|
||||
m.RecalculateNormals();
|
||||
}
|
||||
sum_x -= m_spacing;
|
||||
}
|
||||
|
||||
protected override Vector3 BaseSize {
|
||||
get { return new Vector3(sum_x, 1, m_size); }
|
||||
}
|
||||
protected override Vector3 BaseScale {
|
||||
get {
|
||||
return Vector3.one;
|
||||
}
|
||||
}
|
||||
protected override Vector2 BasePivot {
|
||||
get { return new Vector2(-0.5f, -0.5f); }
|
||||
}
|
||||
|
||||
public override void Init() {
|
||||
InternalInit();
|
||||
UpdateFrames();
|
||||
mesh.Mesh.Clear();
|
||||
UpdateScale();
|
||||
Value.OnUpdate += UpdateScale;
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Cryville/Crtr/Skin/Components/SpriteText.cs.meta
Normal file
12
Assets/Cryville/Crtr/Skin/Components/SpriteText.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c3781c012a298849b9276df00b6f59c
|
||||
timeCreated: 1636509150
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
59
Assets/Cryville/Crtr/Skin/Components/TrackLine.cs
Normal file
59
Assets/Cryville/Crtr/Skin/Components/TrackLine.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Skin.Components {
|
||||
public class TrackLine : SectionalGameObject {
|
||||
readonly List<Vector3> vertices = new List<Vector3>();
|
||||
|
||||
LineRenderer lineRenderer;
|
||||
|
||||
public TrackLine() {
|
||||
SubmitProperty("width", new PropOp.Float(v => Width = v));
|
||||
}
|
||||
|
||||
private float m_width;
|
||||
public float Width {
|
||||
get { return m_width; }
|
||||
set {
|
||||
m_width = value;
|
||||
if (lineRenderer != null) {
|
||||
lineRenderer.startWidth = value;
|
||||
lineRenderer.endWidth = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Init() {
|
||||
lineRenderer = gameObject.AddComponent<LineRenderer>();
|
||||
lineRenderer.materials = materials = new Material[] { MeshWrapper.NewMaterial() };
|
||||
Width = Width;
|
||||
base.Init();
|
||||
}
|
||||
|
||||
protected override void UpdateColor() {
|
||||
base.UpdateColor();
|
||||
if (lineRenderer != null) {
|
||||
lineRenderer.startColor = Color;
|
||||
lineRenderer.endColor = Color;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void AppendPointInternal(Vector3 p, Quaternion r) {
|
||||
vertices.Add(p);
|
||||
}
|
||||
|
||||
public override void Seal() {
|
||||
#if UNITY_5_6_OR_NEWER
|
||||
lineRenderer.positionCount = vertices.Count;
|
||||
#else
|
||||
lineRenderer.SetVertexCount(vertices.Count);
|
||||
#endif
|
||||
for (int i = 0; i < vertices.Count; i++) lineRenderer.SetPosition(i, vertices[i]);
|
||||
}
|
||||
|
||||
public override void Reset() {
|
||||
base.Reset();
|
||||
vertices.Clear();
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Cryville/Crtr/Skin/Components/TrackLine.cs.meta
Normal file
12
Assets/Cryville/Crtr/Skin/Components/TrackLine.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7806feaea6d6c2540b2cb950286d379c
|
||||
timeCreated: 1596635435
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
12
Assets/Cryville/Crtr/Skin/Components/TransformInterface.cs
Normal file
12
Assets/Cryville/Crtr/Skin/Components/TransformInterface.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Skin.Components {
|
||||
public class TransformInterface : SkinComponent {
|
||||
public TransformInterface() {
|
||||
SubmitProperty("pos", new PropOp.Vector3(v => transform.localPosition = v));
|
||||
SubmitProperty("rot", new PropOp.Vector3(v => transform.localRotation = Quaternion.Euler(v)));
|
||||
SubmitProperty("scale", new PropOp.Vector3(v => transform.localScale = v));
|
||||
}
|
||||
protected override void OnDestroy() { }
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a8a184616fd97d4a877c59c2ff76ba3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user