This commit is contained in:
MuHua-123
2025-03-07 22:46:13 +08:00
parent 5e819d5257
commit 57a8a6e9a1
83 changed files with 235 additions and 977 deletions
-8
View File
@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 66fc15151bdec0642aa0d9f313f50e72
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,58 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 资源模块
/// </summary>
public class ModuleAssets<Data> {
protected List<Data> datas = new List<Data>();
/// <summary> 核心模块 </summary>
protected virtual ModuleCore ModuleCore => ModuleCore.I;
/// <summary> 更改事件 </summary>
public virtual event Action OnChange;
/// <summary> 数据列表 </summary>
public virtual List<Data> Datas => datas;
/// <summary> 数据计数 </summary>
public virtual int Count => Datas.Count;
/// <summary> 数据计数 </summary
public virtual Data this[int index] => Datas[index];
/// <summary> 添加数据 </summary>
public virtual void Add(Data data) { Datas.Add(data); OnChange?.Invoke(); }
/// <summary> 添加数据 </summary>
public virtual void AddRange(IList<Data> data) { Datas.AddRange(data); OnChange?.Invoke(); }
/// <summary> 删除数据 </summary>
public virtual void Remove(Data data) { Datas.Remove(data); OnChange?.Invoke(); }
/// <summary> 保存数据 </summary>
public virtual void Save() { throw new NotImplementedException(); }
/// <summary> 加载数据 </summary>
public virtual void Load() { throw new NotImplementedException(); }
/// <summary> 循环列表 </summary>
public virtual void ForEach(Action<Data> action) => Datas.ForEach(action);
}
/// <summary>
/// 资源模块工具
/// </summary>
public static class ModuleAssetsTool {
/// <summary> 头尾循环标准化索引 </summary>
public static Data LoopIndex<Data>(this ModuleAssets<Data> assets, int index) {
return assets[LoopIndex(index, assets.Count)];
}
/// <summary> 头尾循环标准化索引 </summary>
public static Data LoopIndex<Data>(this List<Data> list, int index) {
return list[LoopIndex(index, list.Count)];
}
/// <summary> 头尾循环标准化索引 </summary>
public static Data LoopIndex<Data>(this Data[] array, int index) {
return array[LoopIndex(index, array.Length)];
}
/// <summary> 头尾循环标准化索引 </summary>
public static int LoopIndex(int index, int maxIndex) {
return index % maxIndex;
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 96fa067856f57984e975772061a248ca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
-8
View File
@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: e145339febf0e6f469eb3a650e52f3d9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,85 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 相机模块
/// </summary>
public abstract class ModuleCamera : MonoBehaviour {
/// <summary> 默认图层遮罩 </summary>
public static readonly LayerMask DefaultLayerMask = ~(1 << 0) | 1 << 0;
/// <summary> 必须要初始化 </summary>
protected abstract void Awake();
/// <summary> 相机位置 </summary>
public abstract Vector3 Position { get; set; }
/// <summary> 相机旋转 </summary>
public abstract Vector3 EulerAngles { get; set; }
/// <summary> 相机视野 </summary>
public abstract float VisualField { get; set; }
/// <summary> 当前相机 </summary>
public abstract Camera ViewCamera { get; }
/// <summary> 渲染纹理 </summary>
public virtual RenderTexture RenderTexture { get; }
/// <summary> 更新渲染纹理 </summary>
public virtual void UpdateRenderTexture(int x, int y) { }
#region
/// <summary> 屏幕坐标转换视图坐标(0-1) </summary>
public virtual Vector3 ScreenToViewPosition(Vector3 screenPosition) {
return ViewCamera.ScreenToViewportPoint(screenPosition);
}
/// <summary> 屏幕坐标转换世界坐标 </summary>
public virtual Vector3 ScreenToWorldPosition(Vector3 screenPosition) {
return ViewCamera.ScreenToWorldPoint(screenPosition);
}
/// <summary> 视图坐标(0-1)转换屏幕坐标</summary>
public virtual Vector3 ViewToScreenPosition(Vector3 screenPosition) {
return ViewCamera.ViewportToScreenPoint(screenPosition);
}
/// <summary> 视图坐标(0-1)转换世界坐标 </summary>
public virtual Vector3 ViewToWorldPosition(Vector3 screenPosition) {
return ViewCamera.ViewportToWorldPoint(screenPosition);
}
/// <summary> 世界坐标转换屏幕坐标 </summary>
public virtual Vector3 WorldToScreenPosition(Vector3 screenPosition) {
return ViewCamera.WorldToScreenPoint(screenPosition);
}
/// <summary> 世界坐标转换视图坐标(0-1) </summary>
public virtual Vector3 WorldToViewPosition(Vector3 screenPosition) {
return ViewCamera.WorldToViewportPoint(screenPosition);
}
#endregion
#region 线
private Ray ray;
private RaycastHit hitInfo;
/// <summary> 屏幕坐标获取世界对象 </summary>
public virtual bool ScreenToWorldObject<T>(Vector3 screenPosition, out T value) where T : Object {
return ScreenToWorldObject(screenPosition, out value, DefaultLayerMask);
}
/// <summary> 屏幕坐标获取世界对象 </summary>
public virtual bool ScreenToWorldObject<T>(Vector3 screenPosition, out T value, LayerMask planeLayerMask) where T : Object {
ray = ViewCamera.ScreenPointToRay(screenPosition);
Physics.Raycast(ray, out hitInfo, 200, planeLayerMask);
value = hitInfo.transform?.GetComponent<T>();
return value != null;
}
/// <summary> 屏幕坐标获取世界对象的父对象 </summary>
public virtual bool ScreenToWorldObjectParent<T>(Vector3 screenPosition, out T value) where T : Object {
return ScreenToWorldObjectParent(screenPosition, out value, DefaultLayerMask);
}
/// <summary> 屏幕坐标获取世界对象的父对象 </summary>
public virtual bool ScreenToWorldObjectParent<T>(Vector3 screenPosition, out T value, LayerMask planeLayerMask) where T : Object {
ray = ViewCamera.ScreenPointToRay(screenPosition);
Physics.Raycast(ray, out hitInfo, 200, planeLayerMask);
value = hitInfo.transform?.GetComponentInParent<T>();
return value != null;
}
#endregion
protected virtual void Update() {
Debug.DrawRay(ray.origin, ray.direction * 10, Color.yellow);
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 8f795d0a53fb35641be9b8bc9aab0f58
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
-21
View File
@@ -1,21 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 核心模块,实现业务逻辑
/// </summary>
public class ModuleCore : Module<ModuleCore> {
}
/// <summary>
/// 模块基类
/// </summary>
/// <typeparam name="ModuleCore"></typeparam>
public class Module<ModuleCore> where ModuleCore : Module<ModuleCore>, new() {
/// <summary> 模块单例 </summary>
public static ModuleCore I => Instantiate();
private static ModuleCore core;
private static ModuleCore Instantiate() => core == null ? core = new ModuleCore() : core;
}
-11
View File
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: b61954fdf7766ae4eba3f4b79c307057
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
-8
View File
@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 9939a58498acfda448d6f494f52e8da4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,182 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
/// <summary>
/// Web请求执行模块
/// </summary>
public class ExecuteWebRequest : ModuleExecute<DataRequest> {
/// <summary> 发送请求 </summary>
public void Execute(DataRequest request) {
if (request.RequestType == WebRequestType.GET) { Get(request); }
if (request.RequestType == WebRequestType.PostForm) { PostForm(request); }
if (request.RequestType == WebRequestType.PostJson) { PostJson(request); }
if (request.RequestType == WebRequestType.Texture) { Texture(request); }
}
public static async void Get(DataRequest request) {
string url = request.Url;
using UnityWebRequest web = UnityWebRequest.Get(url);
await web.SendWebRequest();
bool isDone = web.isDone && web.result == UnityWebRequest.Result.Success;
request.RequestResultHandle(isDone, web.downloadHandler);
}
public static async void PostForm(DataRequest request) {
string url = request.Url;
WWWForm form = request.Form;
using UnityWebRequest web = UnityWebRequest.Post(url, form);
await web.SendWebRequest();
bool isDone = web.isDone && web.result == UnityWebRequest.Result.Success;
request.RequestResultHandle(isDone, web.downloadHandler);
}
public static async void PostJson(DataRequest request) {
string url = request.Url;
string json = request.Json;
byte[] postBytes = System.Text.Encoding.Default.GetBytes(json);
#if UNITY_2022
using UnityWebRequest web = UnityWebRequest.PostWwwForm(url, "POST");
#else
using UnityWebRequest web = UnityWebRequest.Post(url, "POST");
#endif
web.uploadHandler.Dispose();
web.uploadHandler = new UploadHandlerRaw(postBytes);
web.SetRequestHeader("Content-Type", "application/json");
await web.SendWebRequest();
bool isDone = web.isDone && web.result == UnityWebRequest.Result.Success;
request.RequestResultHandle(isDone, web.downloadHandler);
}
public static async void Texture(DataRequest request) {
string url = request.Url;
using UnityWebRequest web = UnityWebRequestTexture.GetTexture(url);
await web.SendWebRequest();
bool isDone = web.isDone && web.result == UnityWebRequest.Result.Success;
request.RequestResultHandle(isDone, web.downloadHandler);
}
}
/// <summary>
/// Web请求执行模块工具
/// </summary>
public static class ExecuteWebRequestTool {
public static TaskAwaiter<object> GetAwaiter(this UnityWebRequestAsyncOperation op) {
var tcs = new TaskCompletionSource<object>();
op.completed += (obj) => { tcs.SetResult(null); };
return tcs.Task.GetAwaiter();
}
}
/// <summary>
/// Web请求类型
/// </summary>
public enum WebRequestType {
/// <summary> GET </summary>
GET = 0,
/// <summary> POST 表单 </summary>
PostForm = 1,
/// <summary> POST Json </summary>
PostJson = 2,
/// <summary> GET 获取图片 </summary>
Texture = 3
}
/// <summary>
/// 请求数据
/// </summary>
public abstract class DataRequest {
/// <summary> Web请求地址 </summary>
public abstract string Url { get; }
/// <summary> Web请求类型 </summary>
public abstract WebRequestType RequestType { get; }
/// <summary> 提交json数据 </summary>
public virtual string Json { get; }
/// <summary> 提交Form表单数据 </summary>
public virtual WWWForm Form { get; }
/// <summary> Web请求结果处理 </summary>
public abstract void RequestResultHandle(bool isDone, DownloadHandler downloadHandler);
}
/// <summary>
/// Get请求数据
/// </summary>
public class DataRequestGet : DataRequest {
public readonly string url;
public Action<string> OnError;
public Action<string> OnCallback;
public override string Url => url;
public override WebRequestType RequestType => WebRequestType.GET;
/// <summary> Web Get请求数据 </summary>
public DataRequestGet(string url, Action<string> OnCallback = null) {
this.url = url;
this.OnCallback = OnCallback;
}
public override void RequestResultHandle(bool isDone, DownloadHandler downloadHandler) {
if (!isDone) { OnError?.Invoke(downloadHandler.text); return; }
OnCallback?.Invoke(downloadHandler.text);
}
}
/// <summary>
/// Post请求数据
/// </summary>
public class DataRequestPost : DataRequest {
public readonly string url;
public readonly string json;
public readonly WWWForm form;
public readonly WebRequestType type;
public Action<string> OnError;
public Action<string> OnCallback;
public override string Url => url;
public override WebRequestType RequestType => type;
public override string Json => json;
public override WWWForm Form => form;
/// <summary> Web Post请求 提交json数据 </summary>
public DataRequestPost(string url, string json, Action<string> OnCallback = null) {
this.url = url;
this.json = json;
this.OnCallback = OnCallback;
type = WebRequestType.PostJson;
}
/// <summary> Web Post请求 提交WWWForm数据 </summary>
public DataRequestPost(string url, WWWForm form, Action<string> OnCallback = null) {
this.url = url;
this.form = form;
this.OnCallback = OnCallback;
type = WebRequestType.PostForm;
}
public override void RequestResultHandle(bool isDone, DownloadHandler downloadHandler) {
if (!isDone) { OnError?.Invoke(downloadHandler.text); return; }
OnCallback?.Invoke(downloadHandler.text);
}
}
/// <summary>
/// Get下载 Texture
/// </summary>
public class DataRequestTexture : DataRequest {
public readonly string url;
public Action<string> OnError;
public Action<Texture2D> OnCallback;
public override string Url => url;
public override WebRequestType RequestType => WebRequestType.Texture;
/// <summary> Web Get请求 Texture </summary>
public DataRequestTexture(string url, Action<Texture2D> OnCallback = null) {
this.url = url;
this.OnCallback = OnCallback;
}
public override void RequestResultHandle(bool isDone, DownloadHandler downloadHandler) {
if (!isDone) { OnError?.Invoke(downloadHandler.text); return; }
DownloadHandlerTexture dht = downloadHandler as DownloadHandlerTexture;
OnCallback?.Invoke(dht.texture);
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 031fdf250828c30419ed1a945eb538f8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,11 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 执行模块
/// </summary>
public interface ModuleExecute<Data> {
/// <summary> 执行 </summary>
public void Execute(Data data);
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 4661df0b8dac9f640a09daa01cac9ea1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
-8
View File
@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: b0dab98b9033323428c3db1f2c7946c0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,11 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 场景中的固定模块
/// </summary>
public abstract class ModuleFixed : MonoBehaviour {
/// <summary> 核心模块 </summary>
protected virtual ModuleCore ModuleCore => ModuleCore.I;
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 529fed83b6e5fff43b7bdf3eca7dbd0e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
-8
View File
@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: ce17d4a855942e747b3a1a85af3fbf7b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,24 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 数据处理器模块
/// </summary>
public class ModuleHandle<Data> {
/// <summary> 数据 </summary>
protected Data value;
/// <summary> 当前数据 </summary>
public virtual Data Current => value;
/// <summary> 当前数据是否有效 </summary>
public virtual bool IsValid => Current != null;
/// <summary> 改变当前数据 Event </summary>
public virtual event Action<Data> OnChange;
/// <summary> 改变当前数据 </summary>
public virtual void Change() => OnChange?.Invoke(value);
/// <summary> 改变当前数据 </summary>
public virtual void Change(Data value) { this.value = value; OnChange?.Invoke(value); }
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 73ab810e12f76f449ba3e6351467ebcb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
-8
View File
@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: b8989716a20d28b4180f6cceee0898f7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,16 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 预制件模块
/// </summary>
public abstract class ModulePrefab<Data> : MonoBehaviour {
/// <summary> 关联的数据 </summary>
protected Data value;
/// <summary> 关联的数据 </summary>
public virtual Data Value => value;
/// <summary> 更新可视化内容 </summary>
public virtual void UpdateVisual(Data value) => this.value = value;
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 84ffbf591cb4c0e4483f5c577ba37d68
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
-8
View File
@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: fcb15023389a9c141b1b07fe53f06e5c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,31 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 单例模块
/// </summary>
public abstract class ModuleSingle<T> : MonoBehaviour where T : ModuleSingle<T> {
/// <summary> 模块单例 </summary>
public static T I => instance;
/// <summary> 模块单例 </summary>
protected static T instance;
/// <summary> 核心模块 </summary>
protected virtual ModuleCore ModuleCore => ModuleCore.I;
/// <summary> 初始化 </summary>
protected abstract void Awake();
/// <summary> 替换 </summary>
protected virtual void Replace(bool isDontDestroy = true) {
if (instance != null) { Destroy(instance.gameObject); }
instance = (T)this;
if (isDontDestroy) { DontDestroyOnLoad(gameObject); }
}
/// <summary> 不替换 </summary>
protected virtual void NoReplace(bool isDontDestroy = true) {
if (isDontDestroy) { DontDestroyOnLoad(gameObject); }
if (instance == null) { instance = (T)this; }
else { Destroy(gameObject); }
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 121ca341c2100df4b94d707ed24452f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
-8
View File
@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 3161d7f50e461bf4896cdd13d8b508be
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
-35
View File
@@ -1,35 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
/// <summary>json解析与保存</summary>
public static class JsonTool {
/// <summary> 内部包装类 </summary>
private class Pack<T> { public T data; }
/// <summary> 把对象转换为Json字符串 </summary>
/// <param name="obj">对象</param>
public static string ToJson<T>(T obj) {
if (obj == null) return "null";
if (obj.GetType().GetInterface("IList") != null) {
Pack<T> pack = new Pack<T>();
pack.data = obj;
string json = JsonUtility.ToJson(pack);
return json.Substring(8, json.Length - 9);
}
return JsonUtility.ToJson(obj);
}
/// <summary> 解析Json </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="json">Json字符串</param>
public static T FromJson<T>(string json) {
if (json == "null" && typeof(T).IsClass) return default(T);
if (typeof(T).GetInterface("IList") != null) {
json = "{\"data\":{data}}".Replace("{data}", json);
Pack<T> Pack = JsonUtility.FromJson<Pack<T>>(json);
return Pack.data;
}
return JsonUtility.FromJson<T>(json);
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 007e3acdca87e1b49b38f504938206cb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,17 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 图层遮罩工具
/// </summary>
public static class LayerMaskTool {
///// <summary> 板片 </summary>
//public static readonly LayerMask Plate = 1 << LayerMask.NameToLayer("Plate");
///// <summary> 形状 </summary>
//public static readonly LayerMask Shape = 1 << LayerMask.NameToLayer("Shape");
///// <summary> 安排点 </summary>
//public static readonly LayerMask Arrange = 1 << LayerMask.NameToLayer("Arrange");
///// <summary> 模特 </summary>
//public static readonly LayerMask Model = 1 << LayerMask.NameToLayer("Model");
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d32659481db1a124c9b564f885ee75a8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
-8
View File
@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 6f35188dbbe4cee4b823e88d78deef5a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,30 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 生成可视化内容模块
/// </summary>
public interface ModuleVisual<Data> {
/// <summary> 更新可视化内容 </summary>
public void UpdateVisual(Data data);
/// <summary> 释放可视化内容 </summary>
public void ReleaseVisual(Data data);
}
/// <summary>
/// 生成可视化内容模块工具
/// </summary>
public static class VisualTool {
/// <summary> 创建可视化内容 </summary>
public static void Create<T>(ref T value, Transform original, Transform parent) {
if (value != null) { return; }
Transform temp = CreateTransform(original, parent);
value = temp.GetComponent<T>();
}
/// <summary> 创建Transform </summary>
public static Transform CreateTransform(Transform original, Transform parent) {
Transform temp = Transform.Instantiate(original, parent);
temp.gameObject.SetActive(true);
return temp;
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 1681bcfa66dacbd4e810d15939fa7e04
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: