Add project files.
This commit is contained in:
15
Assets/Cryville/Crtr/Anchor.cs
Normal file
15
Assets/Cryville/Crtr/Anchor.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class Anchor {
|
||||
bool _opened;
|
||||
public bool Opened { get { return _opened; } }
|
||||
public Transform Transform { get; set; }
|
||||
public void Open() {
|
||||
_opened = true;
|
||||
}
|
||||
public void Close() {
|
||||
_opened = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Anchor.cs.meta
Normal file
12
Assets/Cryville/Crtr/Anchor.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe131992309d7034a89259ab7191200a
|
||||
timeCreated: 1636290820
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Cryville/Crtr/Browsing.meta
Normal file
9
Assets/Cryville/Crtr/Browsing.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf6d413b13da4fe4eab20a567d8ee795
|
||||
folderAsset: yes
|
||||
timeCreated: 1638415418
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
21
Assets/Cryville/Crtr/Browsing/BrowserItem.cs
Normal file
21
Assets/Cryville/Crtr/Browsing/BrowserItem.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Cryville.Common;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Browsing {
|
||||
internal abstract class BrowserItem : MonoBehaviour {
|
||||
public int? Id { get; private set; }
|
||||
protected ResourceItemMeta meta;
|
||||
internal virtual void Load(int id, ResourceItemMeta item) {
|
||||
Id = id;
|
||||
meta = item;
|
||||
}
|
||||
}
|
||||
|
||||
public struct ResourceItemMeta {
|
||||
public bool IsDirectory { get; set; }
|
||||
public AsyncDelivery<Texture2D> Icon { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string DescriptionMain { get; set; }
|
||||
public string DescriptionSub { get; set; }
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Browsing/BrowserItem.cs.meta
Normal file
12
Assets/Cryville/Crtr/Browsing/BrowserItem.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfa7de3f6f944914d9999fcfda245f97
|
||||
timeCreated: 1637552994
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
52
Assets/Cryville/Crtr/Browsing/BrowserItemTile.cs
Normal file
52
Assets/Cryville/Crtr/Browsing/BrowserItemTile.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Crtr.Browsing {
|
||||
internal class BrowserItemTile : BrowserItem {
|
||||
#pragma warning disable IDE0044
|
||||
[SerializeField]
|
||||
private Sprite m_iconPlaceholder;
|
||||
#pragma warning restore IDE0044
|
||||
|
||||
private bool _dir;
|
||||
private Image _icon;
|
||||
private Text _title;
|
||||
private Text _desc;
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
void Awake() {
|
||||
_icon = transform.Find("__content__/Icon").GetComponent<Image>();
|
||||
_title = transform.Find("__content__/Texts/Title/__text__").GetComponent<Text>();
|
||||
_desc = transform.Find("__content__/Texts/Description/__text__").GetComponent<Text>();
|
||||
}
|
||||
void OnDestroy() {
|
||||
if (meta.Icon != null) meta.Icon.Cancel();
|
||||
if (_icon.sprite != null && _icon.sprite != m_iconPlaceholder) {
|
||||
Texture2D.Destroy(_icon.sprite.texture);
|
||||
Sprite.Destroy(_icon.sprite);
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
internal override void Load(int id, ResourceItemMeta item) {
|
||||
OnDestroy();
|
||||
base.Load(id, item);
|
||||
_dir = meta.IsDirectory;
|
||||
_icon.sprite = m_iconPlaceholder;
|
||||
if (meta.Icon != null) meta.Icon.Destination = DisplayCover;
|
||||
_title.text = meta.Name;
|
||||
_desc.text = string.Format("{0}\n{1}", meta.DescriptionMain, meta.DescriptionSub);
|
||||
}
|
||||
private void DisplayCover(bool succeeded, Texture2D tex) {
|
||||
if (succeeded) {
|
||||
_icon.sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero);
|
||||
}
|
||||
}
|
||||
public void OnClick() {
|
||||
if (Id == null) return;
|
||||
ResourceBrowser resourceBrowser = GetComponentInParent<ResourceBrowser>();
|
||||
if (_dir) resourceBrowser.OnDirectoryItemClicked(Id.Value);
|
||||
else resourceBrowser.OnObjectItemClicked(Id.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Browsing/BrowserItemTile.cs.meta
Normal file
12
Assets/Cryville/Crtr/Browsing/BrowserItemTile.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b38d66b3e6e5d94438c72f855c4efff9
|
||||
timeCreated: 1637554149
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
71
Assets/Cryville/Crtr/Browsing/DetailPanel.cs
Normal file
71
Assets/Cryville/Crtr/Browsing/DetailPanel.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Unity.UI;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Crtr.Browsing {
|
||||
public class DetailPanel : ResourceBrowserUnit {
|
||||
#pragma warning disable IDE0044
|
||||
[SerializeField]
|
||||
private Sprite m_coverPlaceholder;
|
||||
#pragma warning restore IDE0044
|
||||
|
||||
int _id;
|
||||
ChartDetail _data;
|
||||
GameObject _placeholder;
|
||||
GameObject _outerContent;
|
||||
DockOccupiedRatioLayoutGroup _outerContentGroup;
|
||||
Transform _content;
|
||||
Image _cover;
|
||||
Text _title;
|
||||
Text _desc;
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
protected override void Awake() {
|
||||
base.Awake();
|
||||
_placeholder = transform.Find("__placeholder__").gameObject;
|
||||
_outerContent = transform.Find("__content__").gameObject;
|
||||
_outerContentGroup = _outerContent.GetComponent<DockOccupiedRatioLayoutGroup>();
|
||||
_content = _outerContent.transform.Find("__content__");
|
||||
_cover = _content.Find("Cover").GetComponent<Image>();
|
||||
_title = _content.Find("Texts/Title").GetComponent<Text>();
|
||||
_desc = _content.Find("Texts/Description").GetComponent<Text>();
|
||||
}
|
||||
void OnDestroy() {
|
||||
if (_data.Cover != null) _data.Cover.Cancel();
|
||||
if (_cover.sprite != null && _cover.sprite != m_coverPlaceholder) {
|
||||
Texture2D.Destroy(_cover.sprite.texture);
|
||||
Sprite.Destroy(_cover.sprite);
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
public void Load(int id, ChartDetail data) {
|
||||
_id = id;
|
||||
_placeholder.SetActive(false);
|
||||
_outerContent.SetActive(true);
|
||||
OnDestroy();
|
||||
_data = data;
|
||||
_cover.sprite = m_coverPlaceholder;
|
||||
if (data.Cover != null) data.Cover.Destination = DisplayCover;
|
||||
var meta = data.Meta;
|
||||
_title.text = string.Format("{0}\n{1}", meta.song.name, meta.chart.name);
|
||||
_desc.text = string.Format(
|
||||
"Music artist: {0}\nCharter: {1}\nLength: {2}\nNote Count: {3}",
|
||||
meta.song.author, meta.chart.author,
|
||||
TimeSpan.FromSeconds(meta.chart.length).ToString(3), meta.note_count
|
||||
);
|
||||
}
|
||||
private void DisplayCover(bool succeeded, Texture2D tex) {
|
||||
if (succeeded) {
|
||||
_cover.sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero);
|
||||
}
|
||||
}
|
||||
public void OnPlay() {
|
||||
Master.Open(_id);
|
||||
}
|
||||
public void OnConfig() {
|
||||
Master.OpenConfig(_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Browsing/DetailPanel.cs.meta
Normal file
12
Assets/Cryville/Crtr/Browsing/DetailPanel.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 477e04b1ed5b60e48886fb76081245c5
|
||||
timeCreated: 1637722157
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
14
Assets/Cryville/Crtr/Browsing/IResourceManager.cs
Normal file
14
Assets/Cryville/Crtr/Browsing/IResourceManager.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace Cryville.Crtr.Browsing {
|
||||
public interface IResourceManager<T> {
|
||||
string[] CurrentDirectory { get; }
|
||||
int ChangeDirectory(string[] dir);
|
||||
int OpenDirectory(int id);
|
||||
int ReturnToDirectory(int id);
|
||||
ResourceItemMeta GetItemMeta(int id);
|
||||
T GetItemDetail(int id);
|
||||
string GetItemPath(int id);
|
||||
|
||||
bool ImportItemFrom(string path);
|
||||
string[] GetSupportedFormats();
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Browsing/IResourceManager.cs.meta
Normal file
12
Assets/Cryville/Crtr/Browsing/IResourceManager.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 453013bb1af4e344198e688c515d0e13
|
||||
timeCreated: 1637234367
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
155
Assets/Cryville/Crtr/Browsing/LegacyResourceManager.cs
Normal file
155
Assets/Cryville/Crtr/Browsing/LegacyResourceManager.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Unity;
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Cryville.Crtr.Browsing {
|
||||
internal class LegacyResourceManager : IResourceManager<ChartDetail> {
|
||||
private readonly string _rootPath;
|
||||
private DirectoryInfo cd;
|
||||
private DirectoryInfo[] items = new DirectoryInfo[0];
|
||||
public string[] CurrentDirectory { get; private set; }
|
||||
|
||||
static readonly Dictionary<string, List<ResourceConverter>> converters
|
||||
= new Dictionary<string, List<ResourceConverter>>();
|
||||
|
||||
public LegacyResourceManager(string rootPath) {
|
||||
_rootPath = rootPath;
|
||||
}
|
||||
|
||||
static LegacyResourceManager() {
|
||||
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) {
|
||||
foreach (var type in asm.GetTypes()) {
|
||||
if (type.IsSubclassOf(typeof(ResourceConverter))) {
|
||||
var converter = (ResourceConverter)Activator.CreateInstance(type);
|
||||
foreach (var f in converter.GetSupportedFormats()) {
|
||||
if (!converters.ContainsKey(f))
|
||||
converters.Add(f, new List<ResourceConverter> { converter });
|
||||
else converters[f].Add(converter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int ChangeDirectory(string[] dir) {
|
||||
CurrentDirectory = dir;
|
||||
cd = new DirectoryInfo(_rootPath + "/charts/" + string.Join("/", dir));
|
||||
items = cd.GetDirectories();
|
||||
return items.Length;
|
||||
}
|
||||
|
||||
public int OpenDirectory(int id) {
|
||||
string[] nd = new string[CurrentDirectory.Length + 1];
|
||||
Array.Copy(CurrentDirectory, nd, CurrentDirectory.Length);
|
||||
nd[CurrentDirectory.Length] = items[id].Name;
|
||||
return ChangeDirectory(nd);
|
||||
}
|
||||
|
||||
public int ReturnToDirectory(int id) {
|
||||
string[] nd = new string[id + 1];
|
||||
Array.Copy(CurrentDirectory, nd, id + 1);
|
||||
return ChangeDirectory(nd);
|
||||
}
|
||||
|
||||
public ResourceItemMeta GetItemMeta(int id) {
|
||||
var item = items[id];
|
||||
AsyncDelivery<Texture2D> cover = null;
|
||||
var coverFile = item.GetFiles("cover.*");
|
||||
if (coverFile.Length > 0) {
|
||||
cover = new AsyncDelivery<Texture2D>();
|
||||
var task = new LoadTextureTask(Game.FileProtocolPrefix + coverFile[0].FullName, cover.Deliver);
|
||||
cover.CancelSource = task.Cancel;
|
||||
Game.NetworkTaskWorker.SubmitNetworkTask(task);
|
||||
}
|
||||
string name = item.Name;
|
||||
string desc = "(Unknown)";
|
||||
var metaFile = new FileInfo(item.FullName + "/meta.json");
|
||||
if (metaFile.Exists) {
|
||||
using (var reader = new StreamReader(metaFile.FullName)) {
|
||||
var meta = JsonConvert.DeserializeObject<ChartMeta>(reader.ReadToEnd());
|
||||
name = meta.song.name;
|
||||
desc = meta.chart.name;
|
||||
}
|
||||
}
|
||||
return new ResourceItemMeta {
|
||||
IsDirectory = false,
|
||||
Icon = cover,
|
||||
Name = name,
|
||||
DescriptionMain = desc,
|
||||
};
|
||||
}
|
||||
|
||||
public ChartDetail GetItemDetail(int id) {
|
||||
var item = items[id];
|
||||
AsyncDelivery<Texture2D> cover = null;
|
||||
var coverFile = item.GetFiles("cover.*");
|
||||
if (coverFile.Length > 0) {
|
||||
cover = new AsyncDelivery<Texture2D>();
|
||||
var task = new LoadTextureTask(Game.FileProtocolPrefix + coverFile[0].FullName, cover.Deliver);
|
||||
cover.CancelSource = task.Cancel;
|
||||
Game.NetworkTaskWorker.SubmitNetworkTask(task);
|
||||
}
|
||||
ChartMeta meta = new ChartMeta();
|
||||
var metaFile = new FileInfo(item.FullName + "/meta.json");
|
||||
if (metaFile.Exists) {
|
||||
using (var reader = new StreamReader(metaFile.FullName)) {
|
||||
meta = JsonConvert.DeserializeObject<ChartMeta>(reader.ReadToEnd());
|
||||
}
|
||||
}
|
||||
return new ChartDetail {
|
||||
Cover = cover,
|
||||
Meta = meta,
|
||||
};
|
||||
}
|
||||
|
||||
public string GetItemPath(int id) {
|
||||
return items[id].Name + "/.umgc";
|
||||
}
|
||||
|
||||
public bool ImportItemFrom(string path) {
|
||||
var file = new FileInfo(path);
|
||||
if (!converters.ContainsKey(file.Extension)) return false;
|
||||
foreach (var converter in converters[file.Extension]) {
|
||||
var resources = converter.ConvertFrom(file);
|
||||
foreach (var res in resources) {
|
||||
if (res is ChartResource) {
|
||||
var tres = (ChartResource)res;
|
||||
var dir = new DirectoryInfo(_rootPath + "/charts/" + res.Name);
|
||||
if (!dir.Exists) dir.Create();
|
||||
using (var writer = new StreamWriter(dir.FullName + "/.umgc")) {
|
||||
writer.Write(JsonConvert.SerializeObject(tres.Main, Game.GlobalJsonSerializerSettings));
|
||||
}
|
||||
using (var writer = new StreamWriter(dir.FullName + "/meta.json")) {
|
||||
writer.Write(JsonConvert.SerializeObject(tres.Meta, Game.GlobalJsonSerializerSettings));
|
||||
}
|
||||
}
|
||||
else if (res is CoverResource) {
|
||||
var tres = (CoverResource)res;
|
||||
var dir = new DirectoryInfo(_rootPath + "/charts/" + res.Name);
|
||||
if (!dir.Exists) dir.Create();
|
||||
var dest = new FileInfo(_rootPath + "/charts/" + res.Name + "/cover" + tres.Source.Extension);
|
||||
if (!dest.Exists) tres.Source.CopyTo(dest.FullName);
|
||||
}
|
||||
else if (res is SongResource) {
|
||||
var tres = (SongResource)res;
|
||||
var dir = new DirectoryInfo(_rootPath + "/songs/" + res.Name);
|
||||
if (!dir.Exists) dir.Create();
|
||||
var dest = new FileInfo(_rootPath + "/songs/" + res.Name + "/.ogg");
|
||||
if (!dest.Exists) tres.Source.CopyTo(dest.FullName);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public string[] GetSupportedFormats() {
|
||||
return converters.Keys.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Browsing/LegacyResourceManager.cs.meta
Normal file
12
Assets/Cryville/Crtr/Browsing/LegacyResourceManager.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aac40491bc6619e47a5b81e6d9f1a5d3
|
||||
timeCreated: 1637975898
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
55
Assets/Cryville/Crtr/Browsing/PVPBool.cs
Normal file
55
Assets/Cryville/Crtr/Browsing/PVPBool.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace Cryville.Crtr.Browsing {
|
||||
public class PVPBool : PropertyValuePanel, IPointerClickHandler {
|
||||
bool _value;
|
||||
public override object Value {
|
||||
get { return _value; }
|
||||
set { _value = (bool)value; }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
RectTransform m_on;
|
||||
[SerializeField]
|
||||
RectTransform m_handleArea;
|
||||
[SerializeField]
|
||||
RectTransform m_handle;
|
||||
|
||||
public void Toggle() {
|
||||
_value = !_value;
|
||||
Callback(Value);
|
||||
}
|
||||
|
||||
const float SPEED = 8;
|
||||
float _ratio;
|
||||
#pragma warning disable IDE0051
|
||||
void Start() {
|
||||
m_handleArea.sizeDelta = new Vector2(m_handle.rect.height - m_handle.rect.width, 0);
|
||||
}
|
||||
|
||||
void Update() {
|
||||
if (_value && _ratio != 1) {
|
||||
_ratio += SPEED * Time.deltaTime;
|
||||
if (_ratio > 1) _ratio = 1;
|
||||
UpdateGraphics();
|
||||
}
|
||||
else if (!_value && _ratio != 0) {
|
||||
_ratio -= SPEED * Time.deltaTime;
|
||||
if (_ratio < 0) _ratio = 0;
|
||||
UpdateGraphics();
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
void UpdateGraphics() {
|
||||
m_on.anchorMax = new Vector2(_ratio, m_on.anchorMax.y);
|
||||
m_handle.anchorMin = new Vector2(_ratio, m_handle.anchorMin.y);
|
||||
m_handle.anchorMax = new Vector2(_ratio, m_handle.anchorMax.y);
|
||||
}
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData) {
|
||||
Toggle();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Cryville/Crtr/Browsing/PVPBool.cs.meta
Normal file
11
Assets/Cryville/Crtr/Browsing/PVPBool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b281561aca5d19f43ba8af035de8ec98
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
147
Assets/Cryville/Crtr/Browsing/PVPNumber.cs
Normal file
147
Assets/Cryville/Crtr/Browsing/PVPNumber.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Crtr.Browsing {
|
||||
public class PVPNumber : PropertyValuePanel {
|
||||
double m_value;
|
||||
public override object Value {
|
||||
get {
|
||||
float s_value = GetDisplayValue();
|
||||
return IntegerMode ? (object)(int)s_value : (object)s_value;
|
||||
}
|
||||
set {
|
||||
if (value is double) m_value = (double)value;
|
||||
else m_value = IntegerMode ? (double)(int)value : (double)(float)value;
|
||||
float s_value = GetDisplayValue();
|
||||
m_text.text = s_value.ToString();
|
||||
if (Range != null && MaxStep == 0) {
|
||||
SetRatio((float)(m_value - Range.Value.x) / (Range.Value.y - Range.Value.x));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float GetDisplayValue() {
|
||||
double s_value = m_value;
|
||||
if (Precision > 0)
|
||||
s_value = Math.Round(s_value / Precision) * Precision;
|
||||
if (IntegerMode)
|
||||
s_value = Math.Round(s_value);
|
||||
return (float)s_value;
|
||||
}
|
||||
|
||||
public bool IntegerMode { get; set; }
|
||||
public bool LogarithmicMode { get; set; }
|
||||
public float MaxStep { get; set; }
|
||||
public double Precision { get; set; }
|
||||
public Vector2? Range { get; set; }
|
||||
|
||||
[SerializeField]
|
||||
EventTrigger m_ctn;
|
||||
[SerializeField]
|
||||
RectTransform m_handleArea;
|
||||
[SerializeField]
|
||||
RectTransform m_handle;
|
||||
[SerializeField]
|
||||
Text m_text;
|
||||
#pragma warning disable IDE0051
|
||||
void Start() {
|
||||
var ev = new EventTrigger.Entry { eventID = EventTriggerType.InitializePotentialDrag };
|
||||
ev.callback.AddListener(e => OnInitializePotentialDrag((PointerEventData)e));
|
||||
m_ctn.triggers.Add(ev);
|
||||
ev = new EventTrigger.Entry { eventID = EventTriggerType.Drag };
|
||||
ev.callback.AddListener(e => OnDrag((PointerEventData)e));
|
||||
m_ctn.triggers.Add(ev);
|
||||
ev = new EventTrigger.Entry { eventID = EventTriggerType.EndDrag };
|
||||
ev.callback.AddListener(e => OnEndDrag((PointerEventData)e));
|
||||
m_ctn.triggers.Add(ev);
|
||||
ev = new EventTrigger.Entry { eventID = EventTriggerType.PointerClick };
|
||||
ev.callback.AddListener(e => OnPointerClick((PointerEventData)e));
|
||||
m_ctn.triggers.Add(ev);
|
||||
|
||||
m_handleArea.sizeDelta = new Vector2(m_handle.rect.height - m_handle.rect.width, 0);
|
||||
if (MaxStep != 0) SetRatio(0.5f);
|
||||
}
|
||||
|
||||
void Update() {
|
||||
if (use && MaxStep != 0) {
|
||||
SetRatio(GetRatioFromPos(pp));
|
||||
SetValueFromPos(pp);
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
Vector2 pp;
|
||||
bool use, nouse;
|
||||
public void OnInitializePotentialDrag(PointerEventData eventData) {
|
||||
eventData.useDragThreshold = false;
|
||||
pp = eventData.position;
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData) {
|
||||
if (nouse) return;
|
||||
if (!use) {
|
||||
var delta = eventData.position - pp;
|
||||
float dx = Mathf.Abs(delta.x), dy = Mathf.Abs(delta.y);
|
||||
if (dx > dy) use = true;
|
||||
else if (dx < dy) nouse = true;
|
||||
}
|
||||
if (use) {
|
||||
pp = eventData.position;
|
||||
if (MaxStep == 0) SetValueFromPos(eventData.position);
|
||||
eventData.Use();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEndDrag(PointerEventData eventData) {
|
||||
if (!nouse) {
|
||||
SetValueFromPos(eventData.position);
|
||||
Callback(Value);
|
||||
if (MaxStep != 0) SetRatio(0.5f);
|
||||
eventData.Use();
|
||||
use = false;
|
||||
}
|
||||
nouse = false;
|
||||
}
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData) {
|
||||
SetValueFromPos(eventData.position);
|
||||
Callback(Value);
|
||||
eventData.Use();
|
||||
}
|
||||
|
||||
float GetRatioFromPos(Vector2 pos) {
|
||||
Vector2 lp;
|
||||
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(m_handleArea, pos, null, out lp)) {
|
||||
lp -= m_handleArea.rect.position;
|
||||
return Mathf.Clamp01(lp.x / m_handleArea.rect.width);
|
||||
}
|
||||
return float.NegativeInfinity;
|
||||
}
|
||||
|
||||
void SetValueFromPos(Vector2 pos) {
|
||||
double ratio = GetRatioFromPos(pos);
|
||||
double result;
|
||||
if (MaxStep == 0) {
|
||||
if (LogarithmicMode) throw new NotImplementedException();
|
||||
else result = (1 - ratio) * Range.Value.x + ratio * Range.Value.y;
|
||||
}
|
||||
else {
|
||||
double delta = (ratio - 0.5f) * 2 * MaxStep * Time.deltaTime;
|
||||
if (LogarithmicMode) result = Math.Pow(Math.E, Math.Log(m_value) + delta);
|
||||
else result = m_value + delta;
|
||||
}
|
||||
if (Range != null) {
|
||||
if (result < Range.Value.x) result = Range.Value.x;
|
||||
else if (result > Range.Value.y) result = Range.Value.y;
|
||||
}
|
||||
Value = result;
|
||||
}
|
||||
|
||||
void SetRatio(float ratio) {
|
||||
m_handle.anchorMin = new Vector2(ratio, m_handle.anchorMin.y);
|
||||
m_handle.anchorMax = new Vector2(ratio, m_handle.anchorMax.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Cryville/Crtr/Browsing/PVPNumber.cs.meta
Normal file
11
Assets/Cryville/Crtr/Browsing/PVPNumber.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1eb74ffd69f934d4a8eca80aa3077b6c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
27
Assets/Cryville/Crtr/Browsing/PathPart.cs
Normal file
27
Assets/Cryville/Crtr/Browsing/PathPart.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Crtr.Browsing {
|
||||
internal class PathPart : MonoBehaviour {
|
||||
private int _id;
|
||||
private Text _exp;
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
void Awake() {
|
||||
_exp = transform.Find("__text__").GetComponent<Text>();
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
internal void Load(int id, string exp) {
|
||||
_id = id;
|
||||
_exp.text = Parse(exp);
|
||||
}
|
||||
string Parse(string exp) {
|
||||
if (exp == "") return "(root)";
|
||||
else return exp;
|
||||
}
|
||||
public void OnClick() {
|
||||
GetComponentInParent<ResourceBrowser>().OnPathClicked(_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Browsing/PathPart.cs.meta
Normal file
12
Assets/Cryville/Crtr/Browsing/PathPart.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d443a346e9a19d4eabbb0fa9ec7016f
|
||||
timeCreated: 1637566071
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
55
Assets/Cryville/Crtr/Browsing/PropertyCategoryPanel.cs
Normal file
55
Assets/Cryville/Crtr/Browsing/PropertyCategoryPanel.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Cryville.Common.Unity.UI;
|
||||
using System;
|
||||
|
||||
namespace Cryville.Crtr.Browsing {
|
||||
public class PropertyCategoryPanel : MonoBehaviour {
|
||||
[SerializeField]
|
||||
private GameObject m_propertyPrefab;
|
||||
|
||||
Text _nameLabel = null;
|
||||
|
||||
string _name;
|
||||
public string Name {
|
||||
get { return _name; }
|
||||
set { _name = value; UpdateName(); }
|
||||
}
|
||||
|
||||
bool _collapsed = false;
|
||||
public bool Collapsed {
|
||||
get { return _collapsed; }
|
||||
set { _collapsed = value; UpdateName(); }
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
void Awake() {
|
||||
_nameLabel = transform.Find("Name/__text__").GetComponent<Text>();
|
||||
transform.Find("Name").GetComponent<Button>().onClick.AddListener(ToggleCollapsed);
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
public void Load(string name, IEnumerable<PropertyInfo> props, object target) {
|
||||
Name = name.ToUpper();
|
||||
foreach (var prop in props) {
|
||||
var obj = GameObject.Instantiate<GameObject>(m_propertyPrefab);
|
||||
obj.transform.SetParent(transform, false);
|
||||
obj.GetComponent<PropertyPanel>().Load(prop, target);
|
||||
obj.GetComponent<AspectRatioLayoutElement>().ContainerTransform = (RectTransform)transform;
|
||||
}
|
||||
}
|
||||
|
||||
void ToggleCollapsed() {
|
||||
Collapsed = !Collapsed;
|
||||
for (int i = 1; i < transform.childCount; i++) {
|
||||
transform.GetChild(i).gameObject.SetActive(!Collapsed);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateName() {
|
||||
_nameLabel.text = (Collapsed ? "+ " : "- ") + Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Browsing/PropertyCategoryPanel.cs.meta
Normal file
12
Assets/Cryville/Crtr/Browsing/PropertyCategoryPanel.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a13b7ea14b96e54ea8a7e6ba1275281
|
||||
timeCreated: 1638435211
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
73
Assets/Cryville/Crtr/Browsing/PropertyPanel.cs
Normal file
73
Assets/Cryville/Crtr/Browsing/PropertyPanel.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using Cryville.Common.ComponentModel;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using RangeAttribute = Cryville.Common.ComponentModel.RangeAttribute;
|
||||
|
||||
namespace Cryville.Crtr.Browsing {
|
||||
public class PropertyPanel : MonoBehaviour {
|
||||
[SerializeField]
|
||||
GameObject m_bool;
|
||||
[SerializeField]
|
||||
GameObject m_number;
|
||||
|
||||
PropertyInfo _property;
|
||||
object _target;
|
||||
|
||||
Text _key;
|
||||
Transform _valueContainer;
|
||||
PropertyValuePanel _value;
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
void Awake() {
|
||||
_key = transform.Find("Key").GetComponent<Text>();
|
||||
_valueContainer = transform.Find("Value");
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
public void Load(PropertyInfo prop, object target) {
|
||||
_target = target;
|
||||
_property = prop;
|
||||
_key.text = prop.Name;
|
||||
|
||||
GameObject vp;
|
||||
if (prop.PropertyType == typeof(bool)) vp = m_bool;
|
||||
else if (prop.PropertyType == typeof(float) || prop.PropertyType == typeof(int)) vp = m_number;
|
||||
else return;
|
||||
_value = GameObject.Instantiate(vp, _valueContainer).GetComponent<PropertyValuePanel>();
|
||||
if (_value is PVPNumber) {
|
||||
var t = (PVPNumber)_value;
|
||||
t.IntegerMode = prop.PropertyType == typeof(int);
|
||||
var attr = prop.GetCustomAttributes(typeof(RangeAttribute), true);
|
||||
if (attr.Length > 0) {
|
||||
var u = (RangeAttribute)attr[0];
|
||||
t.Range = new Vector2(u.Min, u.Max);
|
||||
}
|
||||
attr = prop.GetCustomAttributes(typeof(PrecisionAttribute), true);
|
||||
if (attr.Length > 0) {
|
||||
var u = (PrecisionAttribute)attr[0];
|
||||
t.Precision = u.Precision;
|
||||
}
|
||||
attr = prop.GetCustomAttributes(typeof(StepAttribute), true);
|
||||
if (attr.Length > 0) {
|
||||
var u = (StepAttribute)attr[0];
|
||||
t.MaxStep = u.Step;
|
||||
}
|
||||
attr = prop.GetCustomAttributes(typeof(LogarithmicScaleAttribute), true);
|
||||
if (attr.Length > 0) {
|
||||
t.LogarithmicMode = true;
|
||||
}
|
||||
}
|
||||
_value.Callback = SetValueToObject;
|
||||
GetValueFromObject();
|
||||
}
|
||||
|
||||
void GetValueFromObject() {
|
||||
_value.Value = _property.GetValue(_target, null);
|
||||
}
|
||||
|
||||
void SetValueToObject(object value) {
|
||||
_property.SetValue(_target, value, null);
|
||||
GetValueFromObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Browsing/PropertyPanel.cs.meta
Normal file
12
Assets/Cryville/Crtr/Browsing/PropertyPanel.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bcca29fea992ac24698a213f0e2baedc
|
||||
timeCreated: 1638435590
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Cryville/Crtr/Browsing/PropertyValuePanel.cs
Normal file
9
Assets/Cryville/Crtr/Browsing/PropertyValuePanel.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Browsing {
|
||||
public abstract class PropertyValuePanel : MonoBehaviour {
|
||||
public Action<object> Callback { protected get; set; }
|
||||
public abstract object Value { get; set; }
|
||||
}
|
||||
}
|
||||
11
Assets/Cryville/Crtr/Browsing/PropertyValuePanel.cs.meta
Normal file
11
Assets/Cryville/Crtr/Browsing/PropertyValuePanel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fca3da10a8b0677439885f6732ac3b6e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
73
Assets/Cryville/Crtr/Browsing/ResourceBrowser.cs
Normal file
73
Assets/Cryville/Crtr/Browsing/ResourceBrowser.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using Cryville.Common.Unity;
|
||||
using Cryville.Common.Unity.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Crtr.Browsing {
|
||||
public class ResourceBrowser : ResourceBrowserUnit {
|
||||
public IResourceManager<ChartDetail> ResourceManager;
|
||||
public ScrollableItemGrid PathContainer;
|
||||
public ScrollableItemGrid ItemContainer;
|
||||
|
||||
FileDialog _dialog;
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
protected void Start() {
|
||||
PathContainer.LoadItem = LoadPathPart;
|
||||
ItemContainer.LoadItem = LoadItem;
|
||||
ItemContainer.ItemCount = ResourceManager.ChangeDirectory(new string[] { "" });
|
||||
PathContainer.ItemCount = ResourceManager.CurrentDirectory.Length;
|
||||
|
||||
_dialog = GameObject.Instantiate(Resources.Load<GameObject>("Common/FileDialog")).GetComponent<FileDialog>();
|
||||
_dialog.gameObject.SetActive(false);
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
private bool LoadPathPart(int id, GameObject obj) {
|
||||
var item = ResourceManager.CurrentDirectory[id];
|
||||
obj.GetComponent<PathPart>().Load(id, item);
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool LoadItem(int id, GameObject obj) {
|
||||
var bi = obj.GetComponent<BrowserItem>();
|
||||
if (bi.Id == id) return true;
|
||||
var item = ResourceManager.GetItemMeta(id);
|
||||
bi.Load(id, item);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnDirectoryItemClicked(int id) {
|
||||
ItemContainer.ItemCount = ResourceManager.OpenDirectory(id);
|
||||
PathContainer.ItemCount = ResourceManager.CurrentDirectory.Length;
|
||||
if (PathContainer.ItemCount >= PathContainer.VisibleLines - 1)
|
||||
PathContainer.GetComponentInParent<ScrollRect>().velocity = new Vector2(-Screen.width, 0);
|
||||
}
|
||||
|
||||
public void OnObjectItemClicked(int id) {
|
||||
Master.ShowDetail(id, ResourceManager.GetItemDetail(id));
|
||||
}
|
||||
|
||||
public void OnPathClicked(int id) {
|
||||
ItemContainer.ItemCount = ResourceManager.ReturnToDirectory(id);
|
||||
PathContainer.ItemCount = ResourceManager.CurrentDirectory.Length;
|
||||
}
|
||||
|
||||
public void OnAddButtonClicked() {
|
||||
_dialog.Callback = OnAddDialogClosed;
|
||||
_dialog.Filter = ResourceManager.GetSupportedFormats();
|
||||
_dialog.Show();
|
||||
}
|
||||
|
||||
private void OnAddDialogClosed() {
|
||||
if (_dialog.FileName == null) return;
|
||||
if (ResourceManager.ImportItemFrom(_dialog.FileName)) {
|
||||
Debug.Log("Import succeeded"); // TODO
|
||||
OnPathClicked(ResourceManager.CurrentDirectory.Length - 1);
|
||||
}
|
||||
else {
|
||||
Debug.Log("Import failed"); // TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Browsing/ResourceBrowser.cs.meta
Normal file
12
Assets/Cryville/Crtr/Browsing/ResourceBrowser.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c6b4df13dea0e4a469d7e54e7e8fb428
|
||||
timeCreated: 1637234060
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
113
Assets/Cryville/Crtr/Browsing/ResourceBrowserMaster.cs
Normal file
113
Assets/Cryville/Crtr/Browsing/ResourceBrowserMaster.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Unity.UI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Crtr.Browsing {
|
||||
public class ResourceBrowserMaster : MonoBehaviour {
|
||||
[SerializeField]
|
||||
private Button m_playButton;
|
||||
[SerializeField]
|
||||
private Button m_configButton;
|
||||
|
||||
private DockLayoutGroup _group;
|
||||
public ResourceBrowser MainBrowser { get; private set; }
|
||||
private DetailPanel _detailPanel;
|
||||
private SettingsPanel _settingsPanel;
|
||||
readonly List<ResourceBrowserUnit> _units = new List<ResourceBrowserUnit>();
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
void Awake() {
|
||||
_group = GetComponent<DockLayoutGroup>();
|
||||
MainBrowser = transform.GetChild(0).GetComponent<ResourceBrowser>();
|
||||
MainBrowser.ResourceManager = new LegacyResourceManager(Settings.Default.GameDataPath);
|
||||
_detailPanel = transform.GetChild(1).GetComponent<DetailPanel>();
|
||||
_settingsPanel = transform.GetChild(2).GetComponent<SettingsPanel>();
|
||||
_units.Add(MainBrowser);
|
||||
_units.Add(_detailPanel);
|
||||
}
|
||||
|
||||
int _slideDest = 0;
|
||||
void Update() {
|
||||
var cv = _group.SlideIndex;
|
||||
_group.SlideIndex = (cv - _slideDest) * 0.86f + _slideDest;
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
public void ShowDetail(int id, ChartDetail detail) {
|
||||
SlideIntoView(1);
|
||||
_detailPanel.Load(id, detail);
|
||||
m_playButton.gameObject.SetActive(true);
|
||||
m_configButton.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
/*[Obsolete]
|
||||
public void ShowSettings(int id, ChartDetail detail) {
|
||||
SlideIntoView(2);
|
||||
_settingsPanel.Load(id, detail);
|
||||
}*/
|
||||
|
||||
public bool Back() {
|
||||
if (_slideDest == 0) return false;
|
||||
SlideIntoView(_slideDest - 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SlideIntoView(int v) {
|
||||
v = Mathf.Clamp(v, 0, _units.Count - 1);
|
||||
var cv = _group.SlideIndex;
|
||||
if (cv < v) _slideDest = v - 1;
|
||||
else _slideDest = v;
|
||||
_units[_slideDest].SlideToLeft();
|
||||
_units[_slideDest + 1].SlideToRight();
|
||||
}
|
||||
|
||||
public void Open(int id) {
|
||||
SetDataSettings(id);
|
||||
#if UNITY_5_3_OR_NEWER
|
||||
SceneManager.LoadScene("Play", LoadSceneMode.Additive);
|
||||
#else
|
||||
Application.LoadLevelAdditive("Play");
|
||||
#endif
|
||||
GameObject.Find("/Master").GetComponent<Master>().HideMenu();
|
||||
}
|
||||
|
||||
public void OpenConfig(int id) {
|
||||
SetDataSettings(id);
|
||||
#if UNITY_5_3_OR_NEWER
|
||||
SceneManager.LoadScene("Config", LoadSceneMode.Additive);
|
||||
#else
|
||||
Application.LoadLevelAdditive("Config");
|
||||
#endif
|
||||
GameObject.Find("/Master").GetComponent<Master>().HideMenu();
|
||||
}
|
||||
|
||||
void SetDataSettings(int id) {
|
||||
Settings.Default.LoadRuleset = "key/.umgr";
|
||||
Settings.Default.LoadSkin = "key/0/.umgs";
|
||||
Settings.Default.LoadChart = MainBrowser.ResourceManager.GetItemPath(id);
|
||||
}
|
||||
}
|
||||
|
||||
public struct ChartDetail {
|
||||
public AsyncDelivery<Texture2D> Cover { get; set; }
|
||||
public ChartMeta Meta { get; set; }
|
||||
}
|
||||
|
||||
#pragma warning disable IDE1006
|
||||
public struct ChartMeta {
|
||||
public MetaInfo song { get; set; }
|
||||
public MetaInfo chart { get; set; }
|
||||
public struct MetaInfo {
|
||||
public string name { get; set; }
|
||||
public string author { get; set; }
|
||||
public float length { get; set; }
|
||||
}
|
||||
public string ruleset { get; set; }
|
||||
public int note_count { get; set; }
|
||||
}
|
||||
#pragma warning restore IDE1006
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Browsing/ResourceBrowserMaster.cs.meta
Normal file
12
Assets/Cryville/Crtr/Browsing/ResourceBrowserMaster.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 256d7d3efda1f9b4c882eb42e608cc8e
|
||||
timeCreated: 1638414803
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
14
Assets/Cryville/Crtr/Browsing/ResourceBrowserUnit.cs
Normal file
14
Assets/Cryville/Crtr/Browsing/ResourceBrowserUnit.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Browsing {
|
||||
public abstract class ResourceBrowserUnit : MonoBehaviour {
|
||||
protected ResourceBrowserMaster Master { get; private set; }
|
||||
#pragma warning disable IDE0051
|
||||
protected virtual void Awake() {
|
||||
Master = GetComponentInParent<ResourceBrowserMaster>();
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
public virtual void SlideToLeft() { }
|
||||
public virtual void SlideToRight() { }
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Browsing/ResourceBrowserUnit.cs.meta
Normal file
12
Assets/Cryville/Crtr/Browsing/ResourceBrowserUnit.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a69c80e5f3e7bd04485bc3afc5826584
|
||||
timeCreated: 1638415083
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
33
Assets/Cryville/Crtr/Browsing/ResourceConverter.cs
Normal file
33
Assets/Cryville/Crtr/Browsing/ResourceConverter.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
namespace Cryville.Crtr.Browsing {
|
||||
public abstract class ResourceConverter {
|
||||
public abstract string[] GetSupportedFormats();
|
||||
public abstract IEnumerable<Resource> ConvertFrom(FileInfo file);
|
||||
}
|
||||
public abstract class Resource {
|
||||
protected Resource(string name) {
|
||||
Name = name;
|
||||
}
|
||||
public string Name { get; private set; }
|
||||
}
|
||||
public class ChartResource : Resource {
|
||||
public ChartResource(string name, Chart main, ChartMeta meta) : base(name) {
|
||||
Main = main; Meta = meta;
|
||||
}
|
||||
public Chart Main { get; private set; }
|
||||
public ChartMeta Meta { get; private set; }
|
||||
}
|
||||
public class CoverResource : Resource {
|
||||
public CoverResource(string name, FileInfo src) : base(name) {
|
||||
Source = src;
|
||||
}
|
||||
public FileInfo Source { get; private set; }
|
||||
}
|
||||
public class SongResource : Resource {
|
||||
public SongResource(string name, FileInfo src) : base(name) {
|
||||
Source = src;
|
||||
}
|
||||
public FileInfo Source { get; private set; }
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Browsing/ResourceConverter.cs.meta
Normal file
12
Assets/Cryville/Crtr/Browsing/ResourceConverter.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2546fb1d514348842a14a03531be192d
|
||||
timeCreated: 1637982768
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
91
Assets/Cryville/Crtr/CastedList.cs
Normal file
91
Assets/Cryville/Crtr/CastedList.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class CastedList<T> : IList<T>, IList, IReadOnlyList<T> {
|
||||
IList _list;
|
||||
public CastedList(IList list) {
|
||||
_list = list;
|
||||
}
|
||||
|
||||
public T this[int index] {
|
||||
get { return (T)_list[index]; }
|
||||
set { _list[index] = value; }
|
||||
}
|
||||
|
||||
object IList.this[int index] {
|
||||
get { return _list[index]; }
|
||||
set { _list[index] = value; }
|
||||
}
|
||||
|
||||
public int Count { get { return _list.Count; } }
|
||||
|
||||
public bool IsReadOnly { get { return _list.IsReadOnly; } }
|
||||
|
||||
public bool IsFixedSize { get { return _list.IsFixedSize; } }
|
||||
|
||||
public bool IsSynchronized { get { return _list.IsSynchronized; } }
|
||||
|
||||
public object SyncRoot { get { return _list.SyncRoot; } }
|
||||
|
||||
public void Add(T item) { _list.Add(item); }
|
||||
|
||||
public int Add(object value) { return _list.Add(value); }
|
||||
|
||||
public void Clear() { _list.Clear(); }
|
||||
|
||||
public bool Contains(T item) { return _list.Contains(item); }
|
||||
|
||||
public bool Contains(object value) { return _list.Contains(value); }
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex) { _list.CopyTo(array, arrayIndex); }
|
||||
|
||||
public void CopyTo(Array array, int index) { _list.CopyTo(array, index); }
|
||||
|
||||
public IEnumerator<T> GetEnumerator() { return new Enumerator(this); }
|
||||
class Enumerator : IEnumerator<T> {
|
||||
readonly CastedList<T> _list;
|
||||
int _index;
|
||||
|
||||
public T Current { get; private set; }
|
||||
|
||||
object IEnumerator.Current { get { return Current; } }
|
||||
|
||||
public Enumerator(CastedList<T> list) {
|
||||
_list = list;
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
|
||||
public bool MoveNext() {
|
||||
if (_index >= _list.Count) return false;
|
||||
Current = _list[_index];
|
||||
_index++;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Reset() { _index = 0; }
|
||||
}
|
||||
|
||||
public int IndexOf(T item) { return _list.IndexOf(item); }
|
||||
|
||||
public int IndexOf(object value) { return _list.IndexOf(value); }
|
||||
|
||||
public void Insert(int index, T item) { _list.Insert(index, item); }
|
||||
|
||||
public void Insert(int index, object value) { _list.Insert(index, value); }
|
||||
|
||||
public bool Remove(T item) {
|
||||
if (!_list.Contains(item)) return false;
|
||||
_list.Remove(item);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Remove(object value) { _list.Remove(value); }
|
||||
|
||||
public void RemoveAt(int index) { _list.RemoveAt(index); }
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() { return _list.GetEnumerator(); }
|
||||
}
|
||||
}
|
||||
11
Assets/Cryville/Crtr/CastedList.cs.meta
Normal file
11
Assets/Cryville/Crtr/CastedList.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4772e6a04d244554d963e3ed64094417
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
477
Assets/Cryville/Crtr/Chart.cs
Normal file
477
Assets/Cryville/Crtr/Chart.cs
Normal file
@@ -0,0 +1,477 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
[JsonConverter(typeof(BeatTimeConverter))]
|
||||
public struct BeatTime {
|
||||
[JsonConstructor()]
|
||||
public BeatTime(int _b, int _n, int _d) {
|
||||
b = _b;
|
||||
n = _n;
|
||||
d = _d;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public int b;
|
||||
|
||||
[JsonIgnore]
|
||||
public int n;
|
||||
|
||||
[JsonIgnore]
|
||||
public int d;
|
||||
}
|
||||
|
||||
public class BeatTimeConverter : JsonConverter {
|
||||
public override bool CanConvert(Type objectType) {
|
||||
return objectType == typeof(int[]);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
|
||||
int b = (int)reader.ReadAsInt32();
|
||||
int n = (int)reader.ReadAsInt32();
|
||||
int d = (int)reader.ReadAsInt32();
|
||||
reader.Read();
|
||||
return new BeatTime(b, n, d);
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
|
||||
BeatTime obj = (BeatTime)value;
|
||||
writer.WriteStartArray();
|
||||
writer.WriteValue(obj.b);
|
||||
writer.WriteValue(obj.n);
|
||||
writer.WriteValue(obj.d);
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ChartEvent {
|
||||
public BeatTime? time;
|
||||
|
||||
[JsonIgnore]
|
||||
public float BeatPosition {
|
||||
get {
|
||||
return time.Value.b + time.Value.n / (float)time.Value.d + BeatOffset;
|
||||
}
|
||||
}
|
||||
|
||||
public BeatTime? endtime;
|
||||
|
||||
[JsonIgnore]
|
||||
public float EndBeatPosition {
|
||||
get {
|
||||
if (endtime == null) return BeatPosition;
|
||||
return endtime.Value.b + endtime.Value.n / (float)endtime.Value.d + BeatOffset;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public float BeatOffset;
|
||||
|
||||
[JsonIgnore]
|
||||
public abstract int Priority {
|
||||
get;
|
||||
}
|
||||
|
||||
public ChartEvent Clone() {
|
||||
return (ChartEvent)MemberwiseClone();
|
||||
}
|
||||
|
||||
/*[DefaultValue(0.0f)][Obsolete]
|
||||
public float duration = 0.0f;*/
|
||||
|
||||
[JsonIgnore]
|
||||
public float Duration {
|
||||
get {
|
||||
if (endtime == null) return 0;
|
||||
return EndBeatPosition - BeatPosition;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public bool IsLong {
|
||||
get { return Duration > 0; }
|
||||
}
|
||||
|
||||
/*[JsonIgnore]
|
||||
public float EndBeatPosition {
|
||||
get {
|
||||
return BeatPosition + duration;
|
||||
}
|
||||
}*/
|
||||
|
||||
private InstantEvent attev = null;
|
||||
[JsonIgnore]
|
||||
public InstantEvent AttackEvent {
|
||||
get {
|
||||
if (attev == null) attev = new InstantEvent(this);
|
||||
return attev;
|
||||
}
|
||||
}
|
||||
|
||||
private InstantEvent relev = null;
|
||||
[JsonIgnore]
|
||||
public InstantEvent ReleaseEvent {
|
||||
get {
|
||||
if (relev == null) relev = new InstantEvent(this, true);
|
||||
return relev;
|
||||
}
|
||||
}
|
||||
|
||||
/*[JsonIgnore]
|
||||
[Obsolete]
|
||||
public Dictionary<string, Func<object>> Properties { get; private set; }
|
||||
[Obsolete]
|
||||
protected void SubmitProperty(string name, Func<object> property) {
|
||||
Properties.Add(name, property);
|
||||
}*/
|
||||
|
||||
[JsonIgnore]
|
||||
public Dictionary<string, PropSrc> PropSrcs { get; private set; }
|
||||
protected void SubmitPropSrc(string name, PropSrc property) {
|
||||
PropSrcs.Add(name, property);
|
||||
}
|
||||
[JsonIgnore]
|
||||
public Dictionary<string, PropOp> PropOps { get; private set; }
|
||||
protected void SubmitPropOp(string name, PropOp property) {
|
||||
PropOps.Add(name, property);
|
||||
}
|
||||
|
||||
protected ChartEvent() {
|
||||
/*
|
||||
Properties = new Dictionary<string, Func<object>>();
|
||||
SubmitProperty("long", () => @long);
|
||||
*/
|
||||
PropSrcs = new Dictionary<string, PropSrc>();
|
||||
SubmitPropSrc("long", new PropSrc.Boolean(() => IsLong));
|
||||
PropOps = new Dictionary<string, PropOp>();
|
||||
}
|
||||
}
|
||||
|
||||
public class InstantEvent : ChartEvent {
|
||||
public readonly ChartEvent Original;
|
||||
public bool IsRelease;
|
||||
|
||||
public InstantEvent(ChartEvent orig, bool release = false) {
|
||||
IsRelease = release;
|
||||
if (orig != null) {
|
||||
Original = orig;
|
||||
time = orig.time;
|
||||
if (IsRelease)
|
||||
BeatOffset = orig.Duration;
|
||||
}
|
||||
}
|
||||
|
||||
public override int Priority {
|
||||
get {
|
||||
return Original.Priority + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
public abstract class EventContainer : ChartEvent {
|
||||
public List<Chart.Motion> motions = new List<Chart.Motion>();
|
||||
|
||||
[JsonIgnore]
|
||||
public virtual IEnumerable<ChartEvent> Events {
|
||||
get {
|
||||
return motions.Cast<ChartEvent>();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual EventList GetEventsOfType(string type) {
|
||||
switch (type) {
|
||||
case "motions": return new EventList<Chart.Motion>(motions);
|
||||
default: throw new ArgumentException("Unknown type");
|
||||
}
|
||||
}
|
||||
}
|
||||
public abstract class EventList : ChartEvent {
|
||||
public IList<ChartEvent> Events { get; private set; }
|
||||
protected EventList(IList<ChartEvent> events) {
|
||||
Events = events;
|
||||
SubmitPropSrc("count", new PropSrc.Float(() => Events.Count));
|
||||
SubmitPropOp("count", new ListCountOp(() => Events));
|
||||
}
|
||||
public abstract ChartEvent Create();
|
||||
public override int Priority {
|
||||
get { throw new NotSupportedException("Fake event"); }
|
||||
}
|
||||
class ListCountOp : PropOp {
|
||||
readonly Func<IList<ChartEvent>> _cb;
|
||||
|
||||
public ListCountOp(Func<IList<ChartEvent>> cb) {
|
||||
_cb = cb;
|
||||
}
|
||||
|
||||
protected override void Execute() {
|
||||
int ac = _cb().Count;
|
||||
int ec = (int)Math.Round(GetOperand(0).AsNumber());
|
||||
if (ac != ec) {
|
||||
throw new RulesetViolationException(string.Format(
|
||||
"Event count not matched, expected {0}, got {1}", ec, ac
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public class EventList<T> : EventList where T : ChartEvent, new() {
|
||||
public EventList(List<T> events) : base(new CastedList<ChartEvent>(events)) { }
|
||||
public override ChartEvent Create() {
|
||||
return new T();
|
||||
}
|
||||
}
|
||||
|
||||
public class Chart : EventContainer {
|
||||
[JsonRequired]
|
||||
public long format; // Format Version
|
||||
|
||||
public string ruleset;
|
||||
|
||||
public List<Group> groups = new List<Group>();
|
||||
|
||||
public override IEnumerable<ChartEvent> Events {
|
||||
get {
|
||||
return base.Events
|
||||
.Concat(groups.Cast<ChartEvent>())
|
||||
.Concat(sigs.Cast<ChartEvent>())
|
||||
.Concat(sounds.Cast<ChartEvent>());
|
||||
}
|
||||
}
|
||||
|
||||
public override EventList GetEventsOfType(string type) {
|
||||
switch (type) {
|
||||
case "groups": return new EventList<Group>(groups);
|
||||
default: return base.GetEventsOfType(type);
|
||||
}
|
||||
}
|
||||
|
||||
public override int Priority {
|
||||
get { return 0; }
|
||||
}
|
||||
|
||||
public class Group : EventContainer {
|
||||
public List<Track> tracks = new List<Track>();
|
||||
public List<Note> notes = new List<Note>();
|
||||
public override IEnumerable<ChartEvent> Events {
|
||||
get {
|
||||
return tracks.Cast<ChartEvent>()
|
||||
.Concat(notes.Cast<ChartEvent>()
|
||||
.Concat(motions.Cast<ChartEvent>()
|
||||
));
|
||||
}
|
||||
}
|
||||
public override EventList GetEventsOfType(string type) {
|
||||
switch (type) {
|
||||
case "tracks": return new EventList<Track>(tracks);
|
||||
case "notes": return new EventList<Note>(notes);
|
||||
default: return base.GetEventsOfType(type);
|
||||
}
|
||||
}
|
||||
public override int Priority {
|
||||
get { return 0; }
|
||||
}
|
||||
}
|
||||
|
||||
public class Track : EventContainer {
|
||||
public override int Priority {
|
||||
get { return 0; }
|
||||
}
|
||||
}
|
||||
|
||||
public class Motion : ChartEvent {
|
||||
#pragma warning disable IDE1006
|
||||
[JsonRequired]
|
||||
public string motion {
|
||||
get { return ToString(); }
|
||||
set { LoadFromString(value); }
|
||||
}
|
||||
#pragma warning restore IDE1006
|
||||
|
||||
private void LoadFromString(string s) {
|
||||
Match m = Regex.Match(s, @"^(.+?)(#(\d+))?(@(.+?))?(\^(.+?))?(\*(.+?))?(:(.+))?$");
|
||||
if (!m.Success) throw new ArgumentException(); // TODO
|
||||
name = new MotionName(m.Groups[1].Value);
|
||||
var registry = ChartPlayer.motionRegistry[name.MainName];
|
||||
if (m.Groups[3].Success) {
|
||||
ushort id = ushort.Parse(m.Groups[3].Value);
|
||||
Vec1 time = m.Groups[5].Success ? new Vec1(m.Groups[5].Value) : null;
|
||||
byte? trs = m.Groups[7].Success ? byte.Parse(m.Groups[7].Value) : (byte?)null;
|
||||
Vec1 rate = m.Groups[9].Success ? new Vec1(m.Groups[9].Value) : null;
|
||||
Vector value = m.Groups[11].Success ? Vector.Construct(registry.Type, m.Groups[11].Value) : null;
|
||||
RelativeNode = new MotionNode() {
|
||||
Id = id,
|
||||
Time = time,
|
||||
Transition = (TransitionType?)trs,
|
||||
Rate = rate,
|
||||
Value = value
|
||||
};
|
||||
}
|
||||
else {
|
||||
AbsoluteValue = Vector.Construct(registry.Type, m.Groups[11].Value);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
string result = Name.ToString();
|
||||
if (RelativeNode != null) {
|
||||
var node = RelativeNode;
|
||||
result += "#" + node.Id;
|
||||
if (node.Time != null) result += "@" + node.Time.ToString();
|
||||
if (node.Transition != null) result = "^" + node.Transition.ToString();
|
||||
if (node.Rate != null) result += "*" + node.Rate.ToString();
|
||||
if (node.Value != null) result += ":" + node.Value.ToString();
|
||||
}
|
||||
else {
|
||||
result += ":" + AbsoluteValue.ToString();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private MotionName name;
|
||||
[JsonIgnore]
|
||||
public MotionName Name {
|
||||
get {
|
||||
return name;
|
||||
}
|
||||
private set {
|
||||
MotionRegistry reg;
|
||||
if (!ChartPlayer.motionRegistry.TryGetValue(value.MainName, out reg))
|
||||
throw new ArgumentException("Invalid motion name");
|
||||
if (RelativeNode != null) RelativeNode.Value = reg.InitValue;
|
||||
else AbsoluteValue = reg.InitValue;
|
||||
name = value;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public Vector AbsoluteValue;
|
||||
[JsonIgnore]
|
||||
public MotionNode RelativeNode;
|
||||
/*public struct Node {
|
||||
public ushort Id;
|
||||
public Vec1 Time;
|
||||
public TransitionType? Transition;
|
||||
public Vec1 Rate;
|
||||
public Vector Value;
|
||||
|
||||
public Node LerpWith(MotionNode start, float lerpedTime) {
|
||||
Vec1 time = Time == null ? null : (Vec1)Time.LerpWith(start.Time, lerpedTime);
|
||||
Vec1 rate = Rate == null ? null : (Vec1)Rate.LerpWith(start.Rate, lerpedTime);
|
||||
Vector value = Value == null ? null : Value.LerpWith(start.Value, lerpedTime);
|
||||
return new Node() {
|
||||
Id = Id,
|
||||
Time = time,
|
||||
Transition = Transition,
|
||||
Rate = rate,
|
||||
Value = value
|
||||
};
|
||||
}
|
||||
}*/
|
||||
|
||||
[DefaultValue(TransitionType.Ease)]
|
||||
public TransitionType transition = TransitionType.Ease;
|
||||
[DefaultValue(1.0f)]
|
||||
public float rate = 1.0f;
|
||||
[DefaultValue(0.0f)]
|
||||
public float sumfix = 0.0f;
|
||||
|
||||
public override int Priority {
|
||||
get { return -2; }
|
||||
}
|
||||
|
||||
public Motion() {
|
||||
SubmitPropSrc("value", new VectorSrc(() => {
|
||||
if (RelativeNode != null) return RelativeNode.Value;
|
||||
else return AbsoluteValue;
|
||||
}));
|
||||
SubmitPropOp("motion", new PropOp.String(v => motion = v));
|
||||
SubmitPropOp("name", new PropOp.String(v => {
|
||||
var n = new MotionName(v);
|
||||
if (Name.Equals(n)) { }
|
||||
else if (Name.Equals(default(MotionName))) Name = n;
|
||||
else throw new RulesetViolationException(string.Format(
|
||||
"Motion name not matched, expected {0}, got {1}", n, Name
|
||||
));
|
||||
}));
|
||||
SubmitPropOp("value", new VectorOp(v => {
|
||||
var vec = Vector.Construct(ChartPlayer.motionRegistry[Name.MainName].Type, v);
|
||||
if (RelativeNode != null) RelativeNode.Value = vec;
|
||||
else AbsoluteValue = vec;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public class Note : EventContainer {
|
||||
public Note() : base() {
|
||||
/*
|
||||
SubmitProperty("judge", () => judge);
|
||||
SubmitProperty("endjudge", () => endjudge);
|
||||
SubmitProperty("track", () => {
|
||||
if (_track == null) {
|
||||
var i = motions.FirstOrDefault(m => m.RelativeNode == null && m.Name.MainName == "track");
|
||||
if (i == null) _track = ((Vec1)ChartPlayer.motionRegistry["track"].InitValue).Value;
|
||||
else _track = ((Vec1)i.AbsoluteValue).Value;
|
||||
}
|
||||
return _track.Value;
|
||||
});
|
||||
*/
|
||||
|
||||
SubmitPropSrc("judge", new PropSrc.String(() => judge));
|
||||
SubmitPropSrc("endjudge", new PropSrc.String(() => endjudge));
|
||||
SubmitPropSrc("track", new PropSrc.Float(() => {
|
||||
var i = motions.FirstOrDefault(m => m.RelativeNode == null && m.Name.MainName == "track");
|
||||
if (i == null) return ((Vec1)ChartPlayer.motionRegistry["track"].InitValue).Value;
|
||||
else return ((Vec1)i.AbsoluteValue).Value;
|
||||
}));
|
||||
SubmitPropOp("judge", new PropOp.String(v => judge = v));
|
||||
SubmitPropOp("endjudge", new PropOp.String(v => endjudge = v));
|
||||
}
|
||||
|
||||
/*[DefaultValue(false)][Obsolete]
|
||||
public bool wipe = false;*/
|
||||
|
||||
public string judge;
|
||||
public string endjudge;
|
||||
|
||||
public override int Priority {
|
||||
get { return 2; }
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public class InternalJudgement : ChartEvent {
|
||||
public Note Parent;
|
||||
|
||||
public override int Priority {
|
||||
get { return 0; }
|
||||
}
|
||||
}*/
|
||||
|
||||
// TODO will likely be deprecated in the future
|
||||
public List<Signature> sigs; // Signatures
|
||||
// TODO [Obsolete]
|
||||
public class Signature : ChartEvent {
|
||||
public float? tempo;
|
||||
|
||||
public override int Priority {
|
||||
get { return -4; }
|
||||
}
|
||||
}
|
||||
|
||||
public List<Sound> sounds;
|
||||
public class Sound : ChartEvent {
|
||||
[JsonRequired]
|
||||
public string id;
|
||||
|
||||
// TODO [Obsolete]
|
||||
public float offset;
|
||||
|
||||
public override int Priority {
|
||||
get { return 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Chart.cs.meta
Normal file
12
Assets/Cryville/Crtr/Chart.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd30e195a83a9cd47ba89121475b89fa
|
||||
timeCreated: 1591683606
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
164
Assets/Cryville/Crtr/ChartHandler.cs
Normal file
164
Assets/Cryville/Crtr/ChartHandler.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
//#define NO_SOUND
|
||||
|
||||
using Cryville.Audio.Source;
|
||||
using Cryville.Crtr.Event;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class ChartHandler : ContainerHandler {
|
||||
//private StampedState cs;
|
||||
|
||||
public Chart chart;
|
||||
//readonly Dictionary<string, Sound> sounds = new Dictionary<string, Sound>();
|
||||
readonly List<LibavFileAudioSource> sounds = new List<LibavFileAudioSource>();
|
||||
|
||||
public ChartHandler(Chart _chart, DirectoryInfo dir) : base() {
|
||||
if (dir == null) throw new ArgumentNullException("dir");
|
||||
|
||||
chart = _chart;
|
||||
|
||||
/*foreach (Chart.Group g in chart.groups) {
|
||||
var gh = new GroupHandler(g, this);
|
||||
// cs.AddChild(new StampedState(new StampedState(chart, sevs)));
|
||||
}*/
|
||||
|
||||
//PrehandleEvents();
|
||||
}
|
||||
|
||||
public override string TypeName {
|
||||
get {
|
||||
return "chart";
|
||||
}
|
||||
}
|
||||
|
||||
public override void PreInit() {
|
||||
base.PreInit();
|
||||
}
|
||||
|
||||
public override void Init() {
|
||||
base.Init();
|
||||
#if !NO_SOUND
|
||||
/*foreach (Chart.Sound ev in chart.sounds) {
|
||||
sounds.Add(ev, new LibavFileAudioSource(
|
||||
Game.GameDataPath + "/songs/" + ev.id + "/.ogg"
|
||||
));
|
||||
Logger.Log("main", 0, "Load", "Loading song: {0}", ev.id);
|
||||
}*/
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void Dispose() {
|
||||
if (Disposed) return;
|
||||
base.Dispose();
|
||||
// foreach (var h in handlers) h.Dispose();
|
||||
foreach (var s in sounds) s.Dispose();
|
||||
}
|
||||
|
||||
/*List<StampedEvent> sevs = new List<StampedEvent>();
|
||||
public void PrehandleEvents() {
|
||||
EventPrehandler ph = new EventPrehandler(
|
||||
chart,
|
||||
chart.motions.Cast<Chart.Event>()
|
||||
.Concat<Chart.Event>(chart.signs.Cast<Chart.Event>())
|
||||
.Concat<Chart.Event>(chart.sounds.Cast<Chart.Event>())
|
||||
);
|
||||
// foreach (var h in handlers) h.StartPrehandler(ph);
|
||||
ph.Forward(ev => {
|
||||
if (ev is Chart.Sound) {
|
||||
Chart.Sound tev = (Chart.Sound)ev;
|
||||
sevs.Add(new StampedEvent.PlaySound() {
|
||||
Time = ph.Time - tev.offset + Settings.Default.SoundOffset,
|
||||
Event = tev
|
||||
});
|
||||
}
|
||||
// foreach (var h in handlers) h.PrehandleToTime(ph.Time);
|
||||
});
|
||||
|
||||
sevs = sevs.Concat(ph.Result).ToList();
|
||||
cs = new StampedState(chart, sevs);
|
||||
// foreach (var h in handlers) h.EndPrehandler(cs);
|
||||
}*/
|
||||
|
||||
public override void Update(ContainerState s, StampedEvent ev) {
|
||||
base.Update(s, ev);
|
||||
if (s.CloneType == 16) {
|
||||
if (ev == null) { }
|
||||
else if (ev.Unstamped == null) { }
|
||||
else if (ev.Unstamped is Chart.Sound) {
|
||||
Chart.Sound tev = (Chart.Sound)ev.Unstamped;
|
||||
var source = new LibavFileAudioSource(
|
||||
Game.GameDataPath + "/songs/" + tev.id + "/.ogg"
|
||||
);
|
||||
source.SelectStream();
|
||||
sounds.Add(source);
|
||||
Game.AudioSession.Sequence(
|
||||
s.Time - tev.offset + ChartPlayer.soundOffset,
|
||||
source
|
||||
);
|
||||
/*var l = new List<StampedEvent> {
|
||||
new StampedEvent.PlaySound() {
|
||||
Time = s.Time - tev.offset + ChartPlayer.soundOffset,
|
||||
Container = chart,
|
||||
Unstamped = tev
|
||||
}
|
||||
};
|
||||
cs.Bus.IssuePatch(l);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExUpdate(ContainerState s, StampedEvent ev) {
|
||||
base.ExUpdate(s, ev);
|
||||
if (s.CloneType == 0) {
|
||||
/*#if !NO_SOUND
|
||||
if (ev is StampedEvent.PlaySound) {
|
||||
StampedEvent.PlaySound tev = (StampedEvent.PlaySound)ev;
|
||||
// sounds[tev.Event.file.ToLower()].audioSource.time = toTime - cs.Time;
|
||||
sounds[tev.Unstamped.id].audioSource.Play();
|
||||
}
|
||||
#endif*/
|
||||
}
|
||||
}
|
||||
|
||||
public override void EndUpdate(ContainerState s) {
|
||||
base.EndUpdate(s);
|
||||
// TODO End of chart
|
||||
}
|
||||
|
||||
/*public void SendInput(int id, TouchPhase phase, Vector2 pos) {
|
||||
// Vector2 jpos = Camera.main.ScreenToWorldPoint(new Vector3(pos.x, pos.y, -cameraZ));
|
||||
/*foreach (var h in handlers) {
|
||||
h.SendInput(id, phase, jpos);
|
||||
}*
|
||||
}
|
||||
|
||||
int hits = 0;
|
||||
int misses = 0;
|
||||
public void ReportJudge(bool hit) {
|
||||
if (hit) hits++;
|
||||
else misses++;
|
||||
GameObject.Find("Status").GetComponent<Text>().text = string.Format("Hits: {0}\nMisses: {1}", hits, misses);
|
||||
}*/
|
||||
}
|
||||
|
||||
/*public class ChartState : ChartEventStateBase {
|
||||
public ChartState(Chart c) : base(
|
||||
c,
|
||||
c.motions.Cast<Chart.Event>()
|
||||
.Concat<Chart.Event>(c.signs.Cast<Chart.Event>())
|
||||
.Concat<Chart.Event>(c.sounds.Cast<Chart.Event>())
|
||||
) { }
|
||||
|
||||
protected override void Handle(Chart.Event ev) {
|
||||
/*if (ev is Chart.Signature) {
|
||||
Chart.Signature tev = (Chart.Signature)ev;
|
||||
float tempo = tev.tempo;
|
||||
if (tempo != 0)
|
||||
Tempo = tempo;
|
||||
}*
|
||||
base.Handle(ev);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
12
Assets/Cryville/Crtr/ChartHandler.cs.meta
Normal file
12
Assets/Cryville/Crtr/ChartHandler.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8339b62359a4eb428e5d7939a0e8fe4
|
||||
timeCreated: 1593870951
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
630
Assets/Cryville/Crtr/ChartPlayer.cs
Normal file
630
Assets/Cryville/Crtr/ChartPlayer.cs
Normal file
@@ -0,0 +1,630 @@
|
||||
//#define NO_THREAD
|
||||
#define BUILD
|
||||
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Plist;
|
||||
using Cryville.Crtr.Event;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.UI;
|
||||
using diag = System.Diagnostics;
|
||||
using Logger = Cryville.Common.Logger;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class ChartPlayer : MonoBehaviour, IDisposable {
|
||||
Chart chart;
|
||||
Skin skin;
|
||||
PdtSkin pskin;
|
||||
Ruleset ruleset;
|
||||
public static PdtRuleset pruleset;
|
||||
public static Dictionary<string, Texture2D> texs;
|
||||
public static Dictionary<string, Cocos2dFrames.Frame> frames;
|
||||
List<Cocos2dFrames> plists;
|
||||
|
||||
readonly Queue<string> texLoadQueue = new Queue<string>();
|
||||
#if UNITY_5_4_OR_NEWER
|
||||
DownloadHandlerTexture texHandler;
|
||||
UnityWebRequest texLoader = null;
|
||||
#else
|
||||
WWW texLoader = null;
|
||||
#endif
|
||||
|
||||
// ChartHandler handler;
|
||||
// StampedState cs;
|
||||
EventBus cbus;
|
||||
EventBus bbus;
|
||||
EventBus tbus;
|
||||
EventBus nbus;
|
||||
Judge judge;
|
||||
bool started = false;
|
||||
|
||||
static bool initialized;
|
||||
static Text logs;
|
||||
Text status;
|
||||
// static EventSystem eventSystem;
|
||||
// static MetaDatabase metadb;
|
||||
|
||||
public static Rect hitRect;
|
||||
public static Vector2 screenSize;
|
||||
public static Plane[] frustumPlanes;
|
||||
|
||||
public static bool disableGC = true;
|
||||
public static float clippingDist = 1f;
|
||||
public static float judgeTolerance = 0.1f;
|
||||
public static float renderDist = 6f;
|
||||
public static float renderStep = 0.05f;
|
||||
public static float actualRenderStep = 0f;
|
||||
public static bool autoRenderStep = false;
|
||||
public static float soundOffset = 0;
|
||||
public static float startOffset = 0;
|
||||
public static float sv = 16f;
|
||||
|
||||
public static Dictionary<string, MotionRegistry> motionRegistry = new Dictionary<string, MotionRegistry>();
|
||||
|
||||
// public static AudioMixerGroup mixer;
|
||||
|
||||
public static PdtEvaluator etor;
|
||||
|
||||
~ChartPlayer() {
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
#if !NO_THREAD
|
||||
if (loadThread != null) loadThread.Abort();
|
||||
#endif
|
||||
if (texLoader != null) texLoader.Dispose();
|
||||
}
|
||||
|
||||
void Start() {
|
||||
var logobj = GameObject.Find("Logs");
|
||||
if (logobj != null)
|
||||
logs = logobj.GetComponent<Text>();
|
||||
if (!initialized) {
|
||||
Game.Init();
|
||||
// mixer = Resources.Load<AudioMixerGroup>("GameAudioMixer");
|
||||
GenericResources.LoadDefault();
|
||||
// eventSystem = GameObject.Find("EventSystem").GetComponent<EventSystem>();
|
||||
// metadb = new MetaDatabase(new DirectoryInfo(persistentDataPath + "/db/cryville.github.io"));
|
||||
initialized = true;
|
||||
}
|
||||
OnSettingsUpdate();
|
||||
|
||||
status = GameObject.Find("Status").GetComponent<Text>();
|
||||
|
||||
texHandler = new DownloadHandlerTexture();
|
||||
|
||||
Game.NetworkTaskWorker.SuspendBackgroundTasks();
|
||||
|
||||
#if BUILD
|
||||
Play();
|
||||
#endif
|
||||
|
||||
// metadb.GetObject(new Guid(""));
|
||||
// Camera.main.RenderToCubemap();
|
||||
}
|
||||
|
||||
void Update() {
|
||||
if (Input.GetKeyDown(KeyCode.Return)) TogglePlay();
|
||||
// if (Input.GetKeyDown(KeyCode.Escape)) ReturnToConsole();
|
||||
if (started) {
|
||||
try {
|
||||
if (Screen.width != screenSize.x || Screen.height != screenSize.y)
|
||||
throw new InvalidOperationException("Window resized while playing");
|
||||
//cs.ForwardByTime(Time.deltaTime);
|
||||
float dt = firstFrame
|
||||
? 1f / Application.targetFrameRate
|
||||
: Time.deltaTime;
|
||||
firstFrame = false;
|
||||
cbus.ForwardByTime(dt);
|
||||
bbus.ForwardByTime(dt);
|
||||
UnityEngine.Profiling.Profiler.BeginSample("ChartPlayer.FeedJudge");
|
||||
judge.StartFrame();
|
||||
Game.InputManager.EnumerateEvents(ev => {
|
||||
// Logger.Log("main", 0, "Input", ev.ToString());
|
||||
judge.Feed(ev);
|
||||
});
|
||||
judge.EndFrame();
|
||||
UnityEngine.Profiling.Profiler.EndSample();
|
||||
/*StampedState ts = (StampedState)cs.Clone();
|
||||
ts.ForwardStepToTime(cs.Time + fogDist, renderStep);
|
||||
ts.BroadcastEndUpdate();*/
|
||||
UnityEngine.Profiling.Profiler.BeginSample("ChartPlayer.Forward");
|
||||
UnityEngine.Profiling.Profiler.BeginSample("EventBus.Copy");
|
||||
bbus.CopyTo(2, tbus);
|
||||
bbus.CopyTo(3, nbus);
|
||||
UnityEngine.Profiling.Profiler.EndSample();
|
||||
float step = autoRenderStep ? ( firstFrame
|
||||
? 1f / Application.targetFrameRate
|
||||
: Time.smoothDeltaTime
|
||||
) : renderStep;
|
||||
actualRenderStep = step;
|
||||
|
||||
nbus.ForwardStepByTime(clippingDist, step);
|
||||
nbus.BroadcastEndUpdate();
|
||||
nbus.Anchor();
|
||||
|
||||
tbus.ForwardStepByTime(clippingDist, step);
|
||||
tbus.ForwardStepByTime(renderDist, step);
|
||||
tbus.BroadcastEndUpdate();
|
||||
UnityEngine.Profiling.Profiler.EndSample();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Game.LogException("Game", "An error occured while playing", ex);
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
#if !NO_THREAD
|
||||
else if (loadThread != null) {
|
||||
if (texLoader != null) {
|
||||
string url = texLoader.url;
|
||||
string name = StringUtils.TrimExt(url.Substring(url.LastIndexOfAny(new char[] {'/', '\\'}) + 1));
|
||||
#if UNITY_5_4_OR_NEWER
|
||||
if (texHandler.isDone) {
|
||||
var tex = texHandler.texture;
|
||||
texs.Add(name, tex);
|
||||
Logger.Log("main", 0, "Load/MainThread", "Loaded texture {0} ({1} bytes)", name, texLoader.downloadedBytes);
|
||||
texLoader.Dispose();
|
||||
texHandler.Dispose();
|
||||
texLoader = null;
|
||||
}
|
||||
else if (texLoader.downloadProgress != 0) {
|
||||
Logger.Log("main", 0, "Load/MainThread", "Loading texture {0} {1:P0}", name, texLoader.downloadProgress);
|
||||
}
|
||||
#else
|
||||
if (texLoader.isDone) {
|
||||
var tex = texLoader.texture;
|
||||
texs.Add(name, tex);
|
||||
Logger.Log("main", 0, "Load/MainThread", "Loaded texture {0} ({1} bytes)", name, texLoader.bytesDownloaded);
|
||||
texLoader.Dispose();
|
||||
texLoader = null;
|
||||
}
|
||||
else if (texLoader.progress != 0) {
|
||||
Logger.Log("main", 0, "Load/MainThread", "Loading texture {0} {1:P0}", name, texLoader.progress);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (texLoader == null)
|
||||
if (texLoadQueue.Count > 0) {
|
||||
#if UNITY_5_4_OR_NEWER
|
||||
texHandler = new DownloadHandlerTexture();
|
||||
texLoader = new UnityWebRequest(Game.FileProtocolPrefix + texLoadQueue.Dequeue(), "GET", texHandler, null);
|
||||
texLoader.SendWebRequest();
|
||||
#else
|
||||
texLoader = new WWW(Game.FileProtocolPrefix + texLoadQueue.Dequeue());
|
||||
#endif
|
||||
}
|
||||
else if (!texloaddone) {
|
||||
texloaddone = true;
|
||||
texloadtimer.Stop();
|
||||
Logger.Log("main", 1, "Load/MainThread", "Main thread done ({0}ms)", texloadtimer.Elapsed.TotalMilliseconds);
|
||||
}
|
||||
if (!loadThread.IsAlive) {
|
||||
if (cbus == null) {
|
||||
Logger.Log("main", 4, "Load/MainThread", "Load failed");
|
||||
loadThread = null;
|
||||
#if BUILD
|
||||
ReturnToMenu();
|
||||
#endif
|
||||
}
|
||||
else if (texLoader == null) {
|
||||
Prehandle();
|
||||
loadThread = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (logEnabled) {
|
||||
string _logs = logs.text;
|
||||
Game.MainLogger.Enumerate((level, module, msg) => {
|
||||
string color;
|
||||
switch (level) {
|
||||
case 0: color = "#888888"; break;
|
||||
case 1: color = "#bbbbbb"; break;
|
||||
case 2: color = "#0088ff"; break;
|
||||
case 3: color = "#ffff00"; break;
|
||||
case 4: color = "#ff0000"; break;
|
||||
case 5: color = "#bb0000"; break;
|
||||
default: color = "#ff00ff"; break;
|
||||
}
|
||||
_logs += string.Format(
|
||||
"\r\n<color={1}bb><{2}> {3}</color>",
|
||||
DateTime.UtcNow.ToString("s"), color, module, msg
|
||||
);
|
||||
});
|
||||
logs.text = _logs.Substring(Mathf.Max(0, _logs.IndexOf('\n', Mathf.Max(0, _logs.Length - 4096))));
|
||||
var sttext = string.Format(
|
||||
"FPS: i{0:0} / s{1:0}\nSMem: {2:N0} / {3:N0}\nIMem: {4:N0} / {5:N0}",
|
||||
1 / Time.deltaTime,
|
||||
1 / Time.smoothDeltaTime,
|
||||
#if UNITY_5_6_OR_NEWER
|
||||
UnityEngine.Profiling.Profiler.GetMonoUsedSizeLong(),
|
||||
UnityEngine.Profiling.Profiler.GetMonoHeapSizeLong(),
|
||||
UnityEngine.Profiling.Profiler.GetTotalAllocatedMemoryLong(),
|
||||
UnityEngine.Profiling.Profiler.GetTotalReservedMemoryLong()
|
||||
#else
|
||||
UnityEngine.Profiling.Profiler.GetMonoUsedSize(),
|
||||
UnityEngine.Profiling.Profiler.GetMonoHeapSize(),
|
||||
UnityEngine.Profiling.Profiler.GetTotalAllocatedMemory(),
|
||||
UnityEngine.Profiling.Profiler.GetTotalReservedMemory()
|
||||
#endif
|
||||
);
|
||||
if (judge != null) sttext += "\n== Scores ==\n" + judge.GetFullFormattedScoreString();
|
||||
status.text = sttext;
|
||||
}
|
||||
else {
|
||||
Game.MainLogger.Enumerate((level, module, msg) => { });
|
||||
}
|
||||
}
|
||||
|
||||
/*public void ReturnToConsole() {
|
||||
Application.LoadLevel("Console");
|
||||
}*/
|
||||
|
||||
private void ReturnToMenu() {
|
||||
#if UNITY_EDITOR
|
||||
Invoke(nameof(_returnToMenu), 4);
|
||||
#else
|
||||
_returnToMenu();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void _returnToMenu() {
|
||||
GameObject.Find("Master").GetComponent<Master>().ShowMenu();
|
||||
GameObject.Destroy(gameObject);
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
SceneManager.UnloadSceneAsync("Play");
|
||||
#elif UNITY_5_3_OR_NEWER
|
||||
SceneManager.UnloadScene("Play");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool logEnabled = true;
|
||||
public void ToggleLogs() {
|
||||
logs.text = "";
|
||||
status.text = "";
|
||||
logEnabled = !logEnabled;
|
||||
}
|
||||
|
||||
public void TogglePlay() {
|
||||
if (started) Stop();
|
||||
else {
|
||||
if (loadThread == null) Play();
|
||||
else Logger.Log("main", 2, "Load/MainThread", "The chart is currently loading");
|
||||
}
|
||||
}
|
||||
|
||||
void Play() {
|
||||
disableGC = Settings.Default.DisableGC;
|
||||
clippingDist = Settings.Default.BackwardClippingDistance;
|
||||
renderDist = Settings.Default.RenderDistance;
|
||||
renderStep = Settings.Default.RenderStep;
|
||||
actualRenderStep = renderStep;
|
||||
autoRenderStep = renderStep == 0;
|
||||
soundOffset = Settings.Default.SoundOffset;
|
||||
startOffset = Settings.Default.StartOffset;
|
||||
sv = Settings.Default.ScrollVelocity;
|
||||
firstFrame = true;
|
||||
#if !NO_THREAD
|
||||
texloaddone = false;
|
||||
#endif
|
||||
|
||||
Game.AudioSession = Game.AudioSequencer.NewSession();
|
||||
|
||||
var hitPlane = new Plane(Vector3.forward, Vector3.zero);
|
||||
var r0 = Camera.main.ViewportPointToRay(new Vector3(0, 0, 1));
|
||||
float dist;
|
||||
hitPlane.Raycast(r0, out dist);
|
||||
var p0 = r0.GetPoint(dist);
|
||||
var r1 = Camera.main.ViewportPointToRay(new Vector3(1, 1, 1));
|
||||
hitPlane.Raycast(r1, out dist);
|
||||
var p1 = r1.GetPoint(dist);
|
||||
hitRect = new Rect(p0, p1 - p0);
|
||||
|
||||
screenSize = new Vector2(Screen.width, Screen.height);
|
||||
frustumPlanes = GeometryUtility.CalculateFrustumPlanes(Camera.main);
|
||||
|
||||
FileInfo chartFile = new FileInfo(
|
||||
Game.GameDataPath + "/charts/" + Settings.Default.LoadChart
|
||||
);
|
||||
FileInfo rulesetFile = new FileInfo(
|
||||
Game.GameDataPath + "/rulesets/" + Settings.Default.LoadRuleset
|
||||
);
|
||||
FileInfo skinFile = new FileInfo(
|
||||
Game.GameDataPath + "/skins/" + Settings.Default.LoadSkin
|
||||
);
|
||||
|
||||
Logger.Log("main", 0, "Load/MainThread", "Loading textures...");
|
||||
texloadtimer = new diag::Stopwatch();
|
||||
texloadtimer.Start();
|
||||
texs = new Dictionary<string, Texture2D>();
|
||||
var flist = skinFile.Directory.GetFiles("*.png");
|
||||
foreach (FileInfo f in flist) {
|
||||
#if NO_THREAD
|
||||
using (WWW w = new WWW("file:///" + f.FullName)) {
|
||||
string name = StringUtils.TrimExt(f.Name);
|
||||
while (!w.isDone);
|
||||
texs.Add(name, w.texture);
|
||||
}
|
||||
#else
|
||||
texLoadQueue.Enqueue(f.FullName);
|
||||
#endif
|
||||
}
|
||||
#if NO_THREAD
|
||||
texloadtimer.Stop();
|
||||
Logger.LogFormat("main", 0, "Load/MainThread", "Textures loaded successfully ({0}ms)", texloadtimer.Elapsed.TotalMilliseconds);
|
||||
Load(new LoadInfo(){
|
||||
chartFile = chartFile,
|
||||
rulesetFile = rulesetFile,
|
||||
skinFile = skinFile,
|
||||
});
|
||||
Prehandle();
|
||||
#else
|
||||
loadThread = new Thread(new ParameterizedThreadStart(Load));
|
||||
loadThread.Start(new LoadInfo(){
|
||||
chartFile = chartFile,
|
||||
rulesetFile = rulesetFile,
|
||||
skinFile = skinFile,
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void Prehandle() {
|
||||
try {
|
||||
diag::Stopwatch timer = new diag::Stopwatch();
|
||||
timer.Reset(); timer.Start();
|
||||
Logger.Log("main", 0, "Load/Prehandle", "Prehandling (iteration 3)");
|
||||
foreach (var i in plists) i.Init(texs);
|
||||
foreach (var t in texs) {
|
||||
if (frames.ContainsKey(t.Key)) {
|
||||
Logger.Log("main", 3, "Load/Prehandle", "Duplicated texture name: {0}", t.Key);
|
||||
continue;
|
||||
}
|
||||
var f = new Cocos2dFrames.Frame(t.Value);
|
||||
f.Init();
|
||||
frames.Add(t.Key, f);
|
||||
}
|
||||
// etor.Context = new EvaluatorContext() { Reservations = cruleset.scores.Keys.ToList() };
|
||||
// pskin.PreEval(etor);
|
||||
//cs.BroadcastInit();
|
||||
Logger.Log("main", 0, "Load/Prehandle", "Initializing states");
|
||||
cbus.BroadcastInit();
|
||||
Game.InputManager.Activate();
|
||||
if (logEnabled) ToggleLogs();
|
||||
Logger.Log("main", 0, "Load/Prehandle", "Cleaning up");
|
||||
GC.Collect();
|
||||
if (disableGC) GarbageCollector.GCMode = GarbageCollector.Mode.Disabled;
|
||||
timer.Stop();
|
||||
Logger.Log("main", 1, "Load/Prehandle", "Prehandling done ({0}ms)", timer.Elapsed.TotalMilliseconds);
|
||||
Game.AudioSequencer.Playing = true;
|
||||
Thread.Sleep((int)(Game.AudioClient.BufferPosition - Game.AudioClient.Position));
|
||||
Game.InputManager.SyncTime(cbus.Time);
|
||||
started = true;
|
||||
// cs.ForwardByTime(startOffset);
|
||||
// bus.ForwardByTime(startOffset);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Game.LogException("Load/Prehandle", "An error occured while prehandling the data", ex);
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
|
||||
struct LoadInfo {
|
||||
public FileInfo chartFile;
|
||||
public FileInfo rulesetFile;
|
||||
public FileInfo skinFile;
|
||||
}
|
||||
diag::Stopwatch texloadtimer = new diag::Stopwatch();
|
||||
bool firstFrame;
|
||||
|
||||
#if !NO_THREAD
|
||||
Thread loadThread = null;
|
||||
diag::Stopwatch workerTimer;
|
||||
bool texloaddone;
|
||||
#endif
|
||||
void Load(object _info) {
|
||||
var info = (LoadInfo)_info;
|
||||
try {
|
||||
workerTimer = new diag::Stopwatch();
|
||||
workerTimer.Start();
|
||||
RMVPool.Prepare();
|
||||
LoadChart(info);
|
||||
workerTimer.Stop();
|
||||
Logger.Log("main", 1, "Load/WorkerThread", "Worker thread done ({0}ms)", workerTimer.Elapsed.TotalMilliseconds);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Game.LogException("Load/WorkerThread", "An error occured while loading the data", ex);
|
||||
}
|
||||
}
|
||||
|
||||
void LoadChart(LoadInfo info) {
|
||||
DirectoryInfo dir = info.chartFile.Directory;
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Loading chart: {0}", info.chartFile);
|
||||
|
||||
using (StreamReader reader = new StreamReader(info.chartFile.FullName, Encoding.UTF8)) {
|
||||
chart = JsonConvert.DeserializeObject<Chart>(reader.ReadToEnd(), new JsonSerializerSettings() {
|
||||
MissingMemberHandling = MissingMemberHandling.Error
|
||||
});
|
||||
|
||||
if (chart.format != 1) throw new FormatException("Invalid chart file format version");
|
||||
|
||||
etor = new PdtEvaluator();
|
||||
|
||||
LoadRuleset(info.rulesetFile);
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Applying ruleset (iteration 1)");
|
||||
pruleset.PrePatch(chart);
|
||||
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Batching events");
|
||||
var batcher = new EventBatcher(chart);
|
||||
batcher.Forward();
|
||||
// cruleset.PatchChart(batcher);
|
||||
cbus = batcher.Batch();
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Batched {0} event batches", cbus.events.Count);
|
||||
|
||||
judge = new Judge();
|
||||
etor.ContextJudge = judge;
|
||||
|
||||
LoadSkin(info.skinFile);
|
||||
|
||||
cbus.AttachSystems(pskin, judge);
|
||||
// handler = new ChartHandler(chart, dir);
|
||||
// cs = new StampedState(chart);
|
||||
|
||||
/*var cph = new EventPrehandler(chart, chart, chart.Events);
|
||||
foreach (var g in chart.groups) {
|
||||
var gph = new EventPrehandler(chart, g, g.Events, cph);
|
||||
foreach (var i in g.Children) {
|
||||
new EventPrehandler(chart, i, i.Events, gph);
|
||||
}
|
||||
}
|
||||
cph.Forward(ev => {
|
||||
if (ev is Chart.Sound) {
|
||||
Chart.Sound tev = (Chart.Sound)ev;
|
||||
cph.Result.Add(new StampedEvent.PlaySound() {
|
||||
Time = cph.Time/* - tev.offset* + soundOffset,
|
||||
Event = tev
|
||||
});
|
||||
}
|
||||
});*/
|
||||
|
||||
/*var ch = new ChartHandler(chart, dir);
|
||||
cs = new StampedState(chart, cph.Result, cskin, cph.StampedEvent);
|
||||
cs.AttachHandler(ch);
|
||||
foreach (var gph in cph.Children) {
|
||||
var gh = new GroupHandler((Chart.Group)gph.Container, ch);
|
||||
var gs = new StampedState(chart, gph.Result, cskin, gph.StampedEvent, cs);
|
||||
gs.AttachHandler(gh);
|
||||
foreach (var tph in gph.Children) {
|
||||
StampedEventHandler th;
|
||||
if (tph.Container is Chart.Note) {
|
||||
th = new NoteHandler(gh, tph.StampedEvent);
|
||||
}
|
||||
else {
|
||||
th = new TrackHandler(gh, (Chart.Track)tph.Container);
|
||||
}
|
||||
StampedState ts;
|
||||
ts = new StampedState(chart, tph.Result, cskin, tph.StampedEvent, gs);
|
||||
ts.AttachHandler(th);
|
||||
}
|
||||
}*/
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Attaching handlers");
|
||||
var ch = new ChartHandler(chart, dir);
|
||||
cbus.RootState.AttachHandler(ch);
|
||||
foreach (var gs in cbus.RootState.Children) {
|
||||
var gh = new GroupHandler((Chart.Group)gs.Key, ch);
|
||||
gs.Value.AttachHandler(gh);
|
||||
foreach (var ts in gs.Value.Children) {
|
||||
ContainerHandler th;
|
||||
if (ts.Key is Chart.Note) {
|
||||
th = new NoteHandler(gh, (Chart.Note)ts.Key, judge);
|
||||
}
|
||||
else {
|
||||
th = new TrackHandler(gh, (Chart.Track)ts.Key);
|
||||
}
|
||||
ts.Value.AttachHandler(th);
|
||||
}
|
||||
}
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Prehandling (iteration 1)");
|
||||
cbus.Clone(16).Forward();
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Patching events");
|
||||
cbus.DoPatch();
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Prehandling (iteration 2)");
|
||||
cbus.Clone(17).Forward();
|
||||
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Cloning states (type 1)");
|
||||
bbus = cbus.Clone(1, -clippingDist);
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Cloning states (type 2)");
|
||||
tbus = bbus.Clone(2);
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Cloning states (type 3)");
|
||||
nbus = bbus.Clone(3);
|
||||
}
|
||||
}
|
||||
|
||||
void LoadRuleset(FileInfo file) {
|
||||
DirectoryInfo dir = file.Directory;
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Loading ruleset: {0}", file);
|
||||
using (StreamReader reader = new StreamReader(file.FullName, Encoding.UTF8)) {
|
||||
ruleset = JsonConvert.DeserializeObject<Ruleset>(reader.ReadToEnd(), new JsonSerializerSettings() {
|
||||
MissingMemberHandling = MissingMemberHandling.Error
|
||||
});
|
||||
if (ruleset.format != 1) throw new FormatException("Invalid ruleset file version");
|
||||
ruleset.LoadPdt(dir);
|
||||
pruleset = ruleset.Root;
|
||||
}
|
||||
}
|
||||
|
||||
void LoadSkin(FileInfo file) {
|
||||
DirectoryInfo dir = file.Directory;
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Loading skin: {0}", file);
|
||||
using (StreamReader reader = new StreamReader(file.FullName, Encoding.UTF8)) {
|
||||
skin = JsonConvert.DeserializeObject<Skin>(reader.ReadToEnd(), new JsonSerializerSettings() {
|
||||
MissingMemberHandling = MissingMemberHandling.Error
|
||||
});
|
||||
if (skin.format != 1) throw new FormatException("Invalid skin file version");
|
||||
skin.LoadPdt(dir);
|
||||
pskin = skin.Root;
|
||||
pskin.Optimize(etor);
|
||||
}
|
||||
plists = new List<Cocos2dFrames>();
|
||||
frames = new Dictionary<string, Cocos2dFrames.Frame>();
|
||||
foreach (FileInfo f in file.Directory.GetFiles("*.plist")) {
|
||||
var pobj = PlistConvert.Deserialize<Cocos2dFrames>(f.FullName);
|
||||
plists.Add(pobj);
|
||||
foreach (var i in pobj.frames)
|
||||
frames.Add(StringUtils.TrimExt(i.Key), i.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop() {
|
||||
try {
|
||||
Logger.Log("main", 1, "Game", "Stopping");
|
||||
chart = null;
|
||||
Game.AudioSession = Game.AudioSequencer.NewSession();
|
||||
if (cbus != null) cbus.Dispose();
|
||||
if (bbus != null) bbus.Dispose();
|
||||
if (tbus != null) tbus.Dispose();
|
||||
if (nbus != null) nbus.Dispose();
|
||||
//cs.Dispose();
|
||||
Game.InputManager.Deactivate();
|
||||
foreach (var t in texs) Texture.Destroy(t.Value);
|
||||
Logger.Log("main", 1, "Game", "Stopped");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
if (!logEnabled) ToggleLogs();
|
||||
Game.LogException("Game", "An error occured while stopping", ex);
|
||||
}
|
||||
finally {
|
||||
if (started) {
|
||||
if (disableGC) GarbageCollector.GCMode = GarbageCollector.Mode.Enabled;
|
||||
GC.Collect();
|
||||
started = false;
|
||||
}
|
||||
}
|
||||
Game.NetworkTaskWorker.ResumeBackgroundTasks();
|
||||
#if BUILD
|
||||
ReturnToMenu();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*public void ShowSettings() {
|
||||
var editor = GameObject.Instantiate<GameObject>(UnityEngine.Resources.Load<GameObject>("Common/PropertyEditor")).GetComponent<PropertyEditor>();
|
||||
editor.Callback = () => {
|
||||
Settings.Default.Save();
|
||||
OnSettingsUpdate();
|
||||
};
|
||||
editor.TargetObject = Settings.Default;
|
||||
}*/
|
||||
void OnSettingsUpdate() {
|
||||
Application.targetFrameRate = Settings.Default.TargetFrameRate;
|
||||
QualitySettings.vSyncCount = Settings.Default.VSync ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/ChartPlayer.cs.meta
Normal file
12
Assets/Cryville/Crtr/ChartPlayer.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c42a45f576ad8249b2ed00675127e76
|
||||
timeCreated: 1617585799
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
188
Assets/Cryville/Crtr/Cocos2dFrames.cs
Normal file
188
Assets/Cryville/Crtr/Cocos2dFrames.cs
Normal file
@@ -0,0 +1,188 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine;
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Plist;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
[BinderAttribute(typeof(Cocos2dFramesBinder))]
|
||||
public class Cocos2dFrames {
|
||||
public Metadata metadata;
|
||||
public class Metadata {
|
||||
public int format;
|
||||
public Vector2 size;
|
||||
public string textureFileName;
|
||||
}
|
||||
|
||||
public Dictionary<string, Frame> frames;
|
||||
public class Frame {
|
||||
Rect _frame;
|
||||
public Rect frame {
|
||||
get { return _frame; }
|
||||
set { _frame = value; }
|
||||
}
|
||||
public Rect textureRect {
|
||||
get { return _frame; }
|
||||
set { _frame = value; }
|
||||
}
|
||||
|
||||
public Vector2 offset;
|
||||
|
||||
bool _rotated = false;
|
||||
public bool rotated {
|
||||
get { return _rotated; }
|
||||
set { _rotated = value; }
|
||||
}
|
||||
public bool textureRotated {
|
||||
get { return _rotated; }
|
||||
set { _rotated = value; }
|
||||
}
|
||||
|
||||
public Rect sourceColorRect;
|
||||
public Vector2 sourceSize;
|
||||
private Rect _uv;
|
||||
private Vector2[] cuv;
|
||||
public Rect UV {
|
||||
get {
|
||||
return _uv;
|
||||
}
|
||||
private set {
|
||||
_uv = value;
|
||||
float x0 = Mathf.Min(_uv.xMin, _uv.xMax);
|
||||
float x1 = Mathf.Max(_uv.xMin, _uv.xMax);
|
||||
float y0 = Mathf.Min(_uv.yMin, _uv.yMax);
|
||||
float y1 = Mathf.Max(_uv.yMin, _uv.yMax);
|
||||
if (_rotated) cuv = new Vector2[]{
|
||||
new Vector2(x0, y1),
|
||||
new Vector2(x1, y0),
|
||||
new Vector2(x0, y0),
|
||||
new Vector2(x1, y1),
|
||||
};
|
||||
else cuv = new Vector2[]{
|
||||
new Vector2(x0, y0),
|
||||
new Vector2(x1, y1),
|
||||
new Vector2(x1, y0),
|
||||
new Vector2(x0, y1),
|
||||
};
|
||||
}
|
||||
}
|
||||
public Vector2 GetUV(Vector2 uv) {
|
||||
return GetUV(uv.x, uv.y);
|
||||
}
|
||||
public Vector2 GetUV(float u, float v) {
|
||||
Vector2 uv00 = cuv[0], uv11 = cuv[1],
|
||||
uv10 = cuv[2], uv01 = cuv[3];
|
||||
return (1 - u - v) * uv00
|
||||
+ u * uv10
|
||||
+ v * uv01
|
||||
+ u * v * (uv00 + uv11 - uv10 - uv01);
|
||||
}
|
||||
public Texture2D Texture {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public Vector2 Size {
|
||||
get {
|
||||
return new Vector2(Texture.width, Texture.height);
|
||||
}
|
||||
}
|
||||
|
||||
public void Init() {
|
||||
if (Texture == null)
|
||||
throw new InvalidOperationException(); // TODO
|
||||
_frame = new Rect(Vector2.zero, Size);
|
||||
var w = _frame.width;
|
||||
var h = _frame.height;
|
||||
float x = _frame.x / w;
|
||||
float y = 1 - _frame.y / h;
|
||||
float tw = (_rotated ? _frame.height : _frame.width) / w;
|
||||
float th = (_rotated ? _frame.width : _frame.height) / h;
|
||||
if (_rotated) UV = new Rect(x, y, tw, -th);
|
||||
else UV = new Rect(x, y, tw, -th);
|
||||
}
|
||||
|
||||
public void Init(int w, int h, Texture2D _base) {
|
||||
if (Texture != null)
|
||||
throw new InvalidOperationException(); // TODO
|
||||
Texture = _base;
|
||||
float x = _frame.x / w;
|
||||
float y = 1 - _frame.y / h;
|
||||
float tw = (_rotated ? _frame.height : _frame.width) / w;
|
||||
float th = (_rotated ? _frame.width : _frame.height) / h;
|
||||
if (_rotated) UV = new Rect(x, y, tw, -th);
|
||||
else UV = new Rect(x, y, tw, -th);
|
||||
}
|
||||
public Frame() { }
|
||||
public Frame(Texture2D tex) {
|
||||
Texture = tex;
|
||||
}
|
||||
}
|
||||
|
||||
Texture2D _base;
|
||||
|
||||
public void Init(Dictionary<string, Texture2D> texs) {
|
||||
_base = texs[StringUtils.TrimExt(metadata.textureFileName)];
|
||||
var w = (int)metadata.size.x;
|
||||
var h = (int)metadata.size.y;
|
||||
if (w == 0 || h == 0) {
|
||||
w = _base.width;
|
||||
h = _base.height;
|
||||
}
|
||||
foreach (var f in frames) {
|
||||
f.Value.Init(w, h, _base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*public class RectConverter : TypeConverter {
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
|
||||
if (sourceType == typeof(string))
|
||||
return true;
|
||||
return base.CanConvertFrom(context, sourceType);
|
||||
}
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
|
||||
return base.ConvertFrom(context, culture, value);
|
||||
}
|
||||
}*/
|
||||
|
||||
public class Cocos2dFramesBinder : EmptyBinder {
|
||||
public override object ChangeType(object value, Type type, CultureInfo culture) {
|
||||
if (value is string) {
|
||||
var str = (string)value;
|
||||
if (type == typeof(Rect)) {
|
||||
var m = Regex.Match(str, @"^{({.*?}),({.*?})}$");
|
||||
var p = (Vector2)ChangeType(m.Groups[1].Value, typeof(Vector2), culture);
|
||||
var s = (Vector2)ChangeType(m.Groups[2].Value, typeof(Vector2), culture);
|
||||
return new Rect(p, s);
|
||||
}
|
||||
else if (type == typeof(Vector2)) {
|
||||
var m = Regex.Match(str, @"^{(.*?),(.*?)}$");
|
||||
var w = float.Parse(m.Groups[1].Value);
|
||||
var h = float.Parse(m.Groups[2].Value);
|
||||
return new Vector2(w, h);
|
||||
}
|
||||
}
|
||||
else if (typeof(IDictionary).IsAssignableFrom(value.GetType())) {
|
||||
var dict = (IDictionary)value;
|
||||
if (type == typeof(Rect)) {
|
||||
var x = float.Parse((string)dict["x"]);
|
||||
var y = float.Parse((string)dict["y"]);
|
||||
var w = float.Parse((string)dict["w"]);
|
||||
var h = float.Parse((string)dict["h"]);
|
||||
return new Rect(x, y, w, h);
|
||||
}
|
||||
else if (type == typeof(Vector2)) {
|
||||
var w = float.Parse((string)dict["w"]);
|
||||
var h = float.Parse((string)dict["h"]);
|
||||
return new Vector2(w, h);
|
||||
}
|
||||
}
|
||||
return base.ChangeType(value, type, culture);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Cocos2dFrames.cs.meta
Normal file
12
Assets/Cryville/Crtr/Cocos2dFrames.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2dede1bb66852cb4a911916107d6581f
|
||||
timeCreated: 1608801352
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Cryville/Crtr/Components.meta
Normal file
9
Assets/Cryville/Crtr/Components.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ccb6283af616de43881e90749df8f19
|
||||
folderAsset: yes
|
||||
timeCreated: 1609142378
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
291
Assets/Cryville/Crtr/Components/SectionalGameObject.cs
Normal file
291
Assets/Cryville/Crtr/Components/SectionalGameObject.cs
Normal file
@@ -0,0 +1,291 @@
|
||||
using Cryville.Common.Buffers;
|
||||
using Cryville.Common.Pdt;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Components {
|
||||
public abstract class SectionalGameObject : SkinComponent {
|
||||
protected bool headGenerated;
|
||||
protected Vector3 prevpt;
|
||||
protected int vertCount = 0;
|
||||
protected MeshWrapper mesh = new MeshWrapper();
|
||||
|
||||
protected override void OnDestroy() {
|
||||
mesh.Destroy();
|
||||
}
|
||||
|
||||
public override void Init() {
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void AppendPoint(Vector3 p) {
|
||||
AppendPoint(p, Quaternion.identity);
|
||||
}
|
||||
|
||||
public void AppendPoint(Vector3 p, Quaternion r) {
|
||||
AppendPointInternal(p, r);
|
||||
// if (!headGenerated) Logger.Log("main", 0, "Skin/Polysec", "{0}", r);
|
||||
headGenerated = true;
|
||||
prevpt = p;
|
||||
vertCount++;
|
||||
}
|
||||
|
||||
protected abstract void AppendPointInternal(Vector3 wp, Quaternion r);
|
||||
|
||||
public abstract void Seal();
|
||||
|
||||
public virtual void Reset() {
|
||||
vertCount = 0;
|
||||
headGenerated = false;
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
: base() {
|
||||
/*
|
||||
SubmitProperty("head", new Property(typeof(string), () => head.frame, v => head.frame = (string)v));
|
||||
SubmitProperty("body", new Property(typeof(string), () => body.frame, v => body.frame = (string)v));
|
||||
SubmitProperty("tail", new Property(typeof(string), () => tail.frame, v => tail.frame = (string)v));
|
||||
SubmitProperty("transparent", new Property(typeof(bool), () => transparent, v => transparent = (bool)v));
|
||||
SubmitProperty("shape", new Property(typeof(Vector2[]), () => _shape, v => _shape = (Vector2[])v));
|
||||
*/
|
||||
|
||||
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("transparent", new PropOp.Boolean(v => transparent = v));
|
||||
SubmitProperty("shape", new op_set_shape(this));
|
||||
}
|
||||
|
||||
#pragma warning disable IDE1006
|
||||
public class op_set_shape : PdtOperator {
|
||||
readonly PolygonSGO _self;
|
||||
public op_set_shape(PolygonSGO self) : base(1) {
|
||||
_self = self;
|
||||
}
|
||||
protected unsafe override 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);
|
||||
var ptr = (Vector2*)o.TrustedAsOfLength(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] = ptr[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
#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();
|
||||
|
||||
public bool transparent;
|
||||
List<Vector3> vertices;
|
||||
List<float> lengths;
|
||||
float sumLength = 0;
|
||||
|
||||
public override void Init() {
|
||||
base.Init();
|
||||
|
||||
head.Load();
|
||||
body.Load();
|
||||
tail.Load();
|
||||
|
||||
mesh.Init(transform, transparent);
|
||||
|
||||
List<Material> materials = new List<Material>();
|
||||
if (head.FrameName != null) AddMat(materials, head.FrameName);
|
||||
if (body.FrameName != null) AddMat(materials, body.FrameName);
|
||||
if (tail.FrameName != null) AddMat(materials, tail.FrameName);
|
||||
mesh.Renderer.materials = materials.ToArray();
|
||||
}
|
||||
|
||||
void AddMat(List<Material> list, string frame) {
|
||||
var mat = mesh.NewMaterial;
|
||||
mat.mainTexture = ChartPlayer.frames[frame].Texture;
|
||||
list.Add(mat);
|
||||
}
|
||||
|
||||
protected override void OnDestroy() {
|
||||
base.OnDestroy();
|
||||
Reset();
|
||||
foreach (var m in mesh.Renderer.materials) Material.Destroy(m);
|
||||
if (_shape != null) _shapePool.Return(_shape);
|
||||
if (vertices != null) {
|
||||
_ptPool.Return(vertices);
|
||||
_lPool.Return(lengths);
|
||||
}
|
||||
}
|
||||
|
||||
// Vector3 prevp = Vector3.zero;
|
||||
protected override void AppendPointInternal(Vector3 p, Quaternion r) {
|
||||
if (vertices == null) {
|
||||
vertices = _ptPool.Rent();
|
||||
lengths = _lPool.Rent();
|
||||
}
|
||||
|
||||
/*
|
||||
r = new Vector3(0, 0, 0);
|
||||
|
||||
Quaternion rotq = Quaternion.Euler(r);
|
||||
p = prevp + rotq * (p - prevpt);
|
||||
prevp = p;*/
|
||||
|
||||
for (int i = 0; i < _shapeLength; i++) {
|
||||
Vector2 sp = r * _shape[i];
|
||||
vertices.Add(p + (Vector3)sp);
|
||||
// uv.Add(new Vector2(i / (shape.Length - 1), vertCount));
|
||||
}
|
||||
|
||||
if (headGenerated) {
|
||||
float len = (p - prevpt).magnitude;
|
||||
lengths.Add(len);
|
||||
sumLength += len;
|
||||
}
|
||||
}
|
||||
|
||||
List<Vector3> verts;
|
||||
List<Vector2> uvs;
|
||||
List<int> trih = null, trib = null, trit = null;
|
||||
|
||||
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.FrameName != null) headLength = width / head.Ratio;
|
||||
float tailLength = 0;
|
||||
if (tail.FrameName != 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; int m = 0;
|
||||
if (head.FrameName != null) { m++; GenerateMeshTo(verts, uvs, out trih, head, ref i, ref t, ref l, 0, headLength, vcpsec, hvc); }
|
||||
if (body.FrameName != null) { m++; GenerateMeshTo(verts, uvs, out trib, body, ref i, ref t, ref l, headLength, sumLength - tailLength, vcpsec, hvc + bvc); }
|
||||
if (tail.FrameName != null) { m++; GenerateMeshTo(verts, uvs, out trit, tail, ref i, ref t, ref l, sumLength - tailLength, sumLength, vcpsec, vc); }
|
||||
|
||||
mesh.Mesh.subMeshCount = m;
|
||||
m = 0;
|
||||
mesh.Mesh.SetVertices(verts);
|
||||
mesh.Mesh.SetUVs(0, uvs);
|
||||
if (head.FrameName != null) mesh.Mesh.SetTriangles(trih, m++);
|
||||
if (body.FrameName != null) mesh.Mesh.SetTriangles(trib, m++);
|
||||
if (tail.FrameName != null) mesh.Mesh.SetTriangles(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Components/SectionalGameObject.cs.meta
Normal file
12
Assets/Cryville/Crtr/Components/SectionalGameObject.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f2666d577419bd43aec55ad614a43f4
|
||||
timeCreated: 1596633346
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
76
Assets/Cryville/Crtr/Components/SkinComponent.cs
Normal file
76
Assets/Cryville/Crtr/Components/SkinComponent.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using Cryville.Common.Pdt;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Components {
|
||||
public abstract class SkinComponent : MonoBehaviour {
|
||||
#if false
|
||||
/// <summary>
|
||||
/// The properties of the component.
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
public Dictionary<string, Property> Properties { get; private set; }
|
||||
/// <summary>
|
||||
/// Submits a property.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the property.</param>
|
||||
/// <param name="property">The property itself.</param>
|
||||
[Obsolete]
|
||||
protected void SubmitProperty(string name, Property property) {
|
||||
Properties.Add(name, property);
|
||||
}
|
||||
/// <summary>
|
||||
/// The property of a skin component.
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
public struct Property {
|
||||
/// <summary>
|
||||
/// The type of the property.
|
||||
/// </summary>
|
||||
public readonly Type Type;
|
||||
/// <summary>
|
||||
/// The callback that gets the property value.
|
||||
/// </summary>
|
||||
public readonly Func<object> Get;
|
||||
/// <summary>
|
||||
/// The callback that sets the property value.
|
||||
/// </summary>
|
||||
public readonly Action<object> Set;
|
||||
/// <summary>
|
||||
/// Creates a property.
|
||||
/// </summary>
|
||||
/// <param name="type">The type of the property.</param>
|
||||
/// <param name="get">The callback that gets the property value.</param>
|
||||
/// <param name="set">The callback that sets the property value.</param>
|
||||
public Property(Type type, Func<object> get, Action<object> set) {
|
||||
Type = type; Get = get; Set = set;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// The property operators of the component.
|
||||
/// </summary>
|
||||
public Dictionary<string, PdtOperator> PropOps { get; private set; }
|
||||
/// <summary>
|
||||
/// Submits a property.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the property.</param>
|
||||
/// <param name="property">The property operator.</param>
|
||||
protected void SubmitProperty(string name, PdtOperator property) {
|
||||
PropOps.Add(name, property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a skin component
|
||||
/// </summary>
|
||||
protected SkinComponent() {
|
||||
// Properties = new Dictionary<string, Property>();
|
||||
PropOps = new Dictionary<string, PdtOperator>();
|
||||
}
|
||||
|
||||
public virtual void Init() { }
|
||||
protected abstract void OnDestroy();
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Components/SkinComponent.cs.meta
Normal file
12
Assets/Cryville/Crtr/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:
|
||||
155
Assets/Cryville/Crtr/Components/SpriteBase.cs
Normal file
155
Assets/Cryville/Crtr/Components/SpriteBase.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
using Cryville.Common.Pdt;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Components {
|
||||
public abstract class SpriteBase : SkinComponent {
|
||||
public SpriteBase()
|
||||
: base() {
|
||||
/*
|
||||
SubmitProperty("bound", new Property(typeof(BoundInfo), null, v => Bound = (BoundInfo)v));
|
||||
SubmitProperty("transparent", new Property(typeof(bool), () => transparent, v => transparent = (bool)v));
|
||||
SubmitProperty("pivot", new Property(typeof(Vector2), () => Pivot, v => Pivot = (Vector2)v));
|
||||
SubmitProperty("scale", new Property(typeof(Vector2), () => Scale, v => Scale = (Vector2)v));
|
||||
SubmitProperty("ui", new Property(typeof(bool), () => UI, v => UI = (bool)v));
|
||||
SubmitProperty("zindex", new Property(typeof(short), () => ZIndex, v => ZIndex = (short)v));
|
||||
*/
|
||||
|
||||
SubmitProperty("bound", new op_set_bound(this));
|
||||
SubmitProperty("transparent", new PropOp.Boolean(v => transparent = v));
|
||||
SubmitProperty("pivot", new PropOp.Vector2(v => Pivot = v));
|
||||
SubmitProperty("scale", new PropOp.Vector2(v => Scale = v));
|
||||
SubmitProperty("ui", new PropOp.Boolean(v => UI = v));
|
||||
SubmitProperty("zindex", new PropOp.Integer(v => ZIndex = (short)v));
|
||||
}
|
||||
|
||||
#pragma warning disable IDE1006
|
||||
class op_set_bound : PdtOperator {
|
||||
readonly SpriteBase _self;
|
||||
public op_set_bound(SpriteBase self) : base(2) {
|
||||
_self = self;
|
||||
}
|
||||
protected unsafe override void Execute() {
|
||||
_self.SetBound(
|
||||
*(Vector2*)GetOperand(0).TrustedAsOfLength(sizeof(Vector2)),
|
||||
*(Vector3*)GetOperand(1).TrustedAsOfLength(sizeof(Vector3))
|
||||
);
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE1006
|
||||
|
||||
protected MeshWrapper mesh = new MeshWrapper();
|
||||
|
||||
protected override void OnDestroy() {
|
||||
mesh.Destroy();
|
||||
}
|
||||
|
||||
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; }
|
||||
}
|
||||
|
||||
#if false
|
||||
[Obsolete]
|
||||
public struct BoundInfo : IConstructable {
|
||||
public Vector2 Pivot;
|
||||
public Vector3 Position;
|
||||
public void Load(object data, IEvaluator etor) {
|
||||
var d = (IList)data;
|
||||
Pivot = (Vector2)etor.Cast(typeof(Vector2), d[0]);
|
||||
Position = (Vector3)etor.Cast(typeof(Vector3), d[1]);
|
||||
}
|
||||
}
|
||||
[Obsolete]
|
||||
public BoundInfo Bound {
|
||||
set {
|
||||
var r = Quaternion.Inverse(transform.rotation);
|
||||
var da = value.Pivot - Pivot;
|
||||
var dp = r * (value.Position - transform.localPosition);
|
||||
if (da.x != 0) _scale.x = dp.x / da.x;
|
||||
if (da.y != 0) _scale.y = dp.z / da.y;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
short _zindex;
|
||||
public short ZIndex {
|
||||
get {
|
||||
return _zindex;
|
||||
}
|
||||
set {
|
||||
_zindex = value;
|
||||
UpdateZIndex();
|
||||
}
|
||||
}
|
||||
protected void UpdateZIndex() {
|
||||
if (!mesh.Initialized) return;
|
||||
mesh.Renderer.sortingOrder = _zindex;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
public bool transparent = false;
|
||||
|
||||
protected void InternalInit(string meshName = "quad") {
|
||||
mesh.Init(transform, transparent);
|
||||
mesh.Mesh = GenericResources.Meshes[meshName];
|
||||
UpdateScale();
|
||||
UpdateZIndex();
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Cryville/Crtr/Components/SpriteBase.cs.meta
Normal file
12
Assets/Cryville/Crtr/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:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user