安卓优化
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AibisDream.SystemEditor
|
||||
{
|
||||
// 帧数据
|
||||
[Serializable]
|
||||
public class FrameData
|
||||
{
|
||||
public string name;
|
||||
public int x;
|
||||
public int y;
|
||||
public int width;
|
||||
public int height;
|
||||
public float duration; // 毫秒
|
||||
}
|
||||
|
||||
// 动画片段数据
|
||||
[Serializable]
|
||||
public class AnimationData
|
||||
{
|
||||
public string name;
|
||||
public List<int> frameIndices;
|
||||
public bool loop;
|
||||
public float? frameDuration; // 可选的,覆盖全局frameDuration
|
||||
public int? sampleRate; // 可选的,覆盖全局sampleRate
|
||||
}
|
||||
|
||||
// Aseprite JSON格式的数据结构
|
||||
[Serializable]
|
||||
public class AsepriteFrameInfo
|
||||
{
|
||||
public AsepriteFrameRect frame;
|
||||
public bool rotated;
|
||||
public bool trimmed;
|
||||
public AsepriteFrameRect spriteSourceSize;
|
||||
public AsepriteSize sourceSize;
|
||||
public float duration; // 毫秒
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class AsepriteFrameRect
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
public int w;
|
||||
public int h;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class AsepriteSize
|
||||
{
|
||||
public int w;
|
||||
public int h;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class AsepriteFrameTag
|
||||
{
|
||||
public string name;
|
||||
public int from;
|
||||
public int to;
|
||||
public string direction;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class AsepriteMeta
|
||||
{
|
||||
public string app;
|
||||
public string version;
|
||||
public string image;
|
||||
public string format;
|
||||
public AsepriteSize size;
|
||||
public string scale;
|
||||
public List<AsepriteFrameTag> frameTags;
|
||||
public List<object> layers;
|
||||
public List<object> slices;
|
||||
}
|
||||
|
||||
// Aseprite JSON的包装类(因为Unity JsonUtility不支持Dictionary)
|
||||
[Serializable]
|
||||
public class AsepriteFrameEntry
|
||||
{
|
||||
public string key;
|
||||
public AsepriteFrameInfo value;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class AsepriteJsonData
|
||||
{
|
||||
public AsepriteMeta meta;
|
||||
// frames将通过手动解析处理
|
||||
}
|
||||
|
||||
// 手动JSON格式的数据结构
|
||||
[Serializable]
|
||||
public class ManualLayout
|
||||
{
|
||||
public int rows;
|
||||
public int columns;
|
||||
public int? frameCount; // 可选
|
||||
public string direction; // "horizontal" 或 "vertical"
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class ManualJsonData
|
||||
{
|
||||
public string type;
|
||||
public ManualLayout layout;
|
||||
public float frameDuration; // 毫秒
|
||||
public int sampleRate;
|
||||
public List<AnimationData> animations;
|
||||
}
|
||||
|
||||
// 统一的内部数据格式
|
||||
public class ProcessedAnimationData
|
||||
{
|
||||
public List<FrameData> frames;
|
||||
public List<ProcessedAnimationClip> animations;
|
||||
}
|
||||
|
||||
public class ProcessedAnimationClip
|
||||
{
|
||||
public string name;
|
||||
public List<int> frameIndices;
|
||||
public bool loop;
|
||||
public float frameDuration; // 毫秒(已应用覆盖逻辑)
|
||||
public int sampleRate; // 已应用覆盖逻辑
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5cd60e41866d0ec418dfc6fdce37a8ba
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,133 @@
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AibisDream.SystemEditor
|
||||
{
|
||||
public class AnimationClipGenerator : EditorWindow
|
||||
{
|
||||
private Texture2D selectedTexture;
|
||||
private TextAsset selectedJson;
|
||||
private DefaultAsset outputFolder;
|
||||
private string outputPath = "";
|
||||
|
||||
// 动画类型选项
|
||||
private enum AnimationTargetType
|
||||
{
|
||||
SpriteRenderer, // Sprite动画
|
||||
Image // UIImage动画
|
||||
}
|
||||
private AnimationTargetType animationType = AnimationTargetType.SpriteRenderer;
|
||||
|
||||
[MenuItem("Tools/Animation Clip Generator")]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
GetWindow<AnimationClipGenerator>("Animation Clip Generator");
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
GUILayout.Label("Animation Clip Generator", EditorStyles.boldLabel);
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// 图片文件选择
|
||||
EditorGUILayout.LabelField("图片文件 (PNG/JPG)", EditorStyles.boldLabel);
|
||||
selectedTexture = (Texture2D)EditorGUILayout.ObjectField(
|
||||
"Texture", selectedTexture, typeof(Texture2D), false);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// JSON文件选择
|
||||
EditorGUILayout.LabelField("JSON文件", EditorStyles.boldLabel);
|
||||
selectedJson = (TextAsset)EditorGUILayout.ObjectField(
|
||||
"JSON", selectedJson, typeof(TextAsset), false);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// 动画类型选择
|
||||
EditorGUILayout.LabelField("动画类型", EditorStyles.boldLabel);
|
||||
animationType = (AnimationTargetType)EditorGUILayout.EnumPopup(
|
||||
"Animation Type", animationType);
|
||||
EditorGUILayout.HelpBox(
|
||||
animationType == AnimationTargetType.SpriteRenderer
|
||||
? "生成用于SpriteRenderer的动画(绑定到m_Sprite属性)"
|
||||
: "生成用于Unity UI Image的动画(绑定到m_Sprite属性)",
|
||||
MessageType.Info);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// 输出目录选择
|
||||
EditorGUILayout.LabelField("输出目录", EditorStyles.boldLabel);
|
||||
outputFolder = (DefaultAsset)EditorGUILayout.ObjectField(
|
||||
"Output Folder", outputFolder, typeof(DefaultAsset), false);
|
||||
|
||||
// 显示输出路径
|
||||
if (outputFolder != null)
|
||||
{
|
||||
outputPath = AssetDatabase.GetAssetPath(outputFolder);
|
||||
EditorGUILayout.HelpBox($"输出路径: {outputPath}", MessageType.Info);
|
||||
}
|
||||
else
|
||||
{
|
||||
outputPath = "";
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// 生成按钮
|
||||
GUI.enabled = selectedTexture != null && selectedJson != null && outputFolder != null;
|
||||
if (GUILayout.Button("生成 AnimationClip", GUILayout.Height(30)))
|
||||
{
|
||||
GenerateAnimationClips();
|
||||
}
|
||||
GUI.enabled = true;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// 说明信息
|
||||
EditorGUILayout.HelpBox(
|
||||
"使用说明:\n" +
|
||||
"1. 选择PNG或JPG图片文件\n" +
|
||||
"2. 选择JSON文件(Aseprite格式或手动格式)\n" +
|
||||
"3. 选择输出目录\n" +
|
||||
"4. 点击生成按钮\n\n" +
|
||||
"注意: 如果图片的SpriteMode是Single,工具会自动根据JSON切图。",
|
||||
MessageType.Info);
|
||||
}
|
||||
|
||||
private void GenerateAnimationClips()
|
||||
{
|
||||
if (selectedTexture == null || selectedJson == null || outputFolder == null)
|
||||
{
|
||||
EditorUtility.DisplayDialog("错误", "请选择图片文件、JSON文件和输出目录", "确定");
|
||||
return;
|
||||
}
|
||||
|
||||
string texturePath = AssetDatabase.GetAssetPath(selectedTexture);
|
||||
string jsonPath = AssetDatabase.GetAssetPath(selectedJson);
|
||||
|
||||
// 验证文件扩展名
|
||||
string textureExt = Path.GetExtension(texturePath).ToLower();
|
||||
if (textureExt != ".png" && textureExt != ".jpg" && textureExt != ".jpeg")
|
||||
{
|
||||
EditorUtility.DisplayDialog("错误", "图片文件必须是PNG或JPG格式", "确定");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
bool isImageAnimation = animationType == AnimationTargetType.Image;
|
||||
AnimationClipGeneratorCore.GenerateClips(texturePath, jsonPath, outputPath, isImageAnimation);
|
||||
EditorUtility.DisplayDialog("成功", $"AnimationClip已生成到: {outputPath}", "确定");
|
||||
|
||||
// 刷新资源数据库
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
EditorUtility.DisplayDialog("错误", $"生成失败: {e.Message}", "确定");
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7472aae8191639b47af5d9ba115b39b5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,603 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.U2D.Sprites;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AibisDream.SystemEditor
|
||||
{
|
||||
public static class AnimationClipGeneratorCore
|
||||
{
|
||||
// 检查SpriteMode
|
||||
public static SpriteImportMode CheckSpriteMode(string texturePath)
|
||||
{
|
||||
TextureImporter textureImporter = AssetImporter.GetAtPath(texturePath) as TextureImporter;
|
||||
if (textureImporter == null)
|
||||
{
|
||||
throw new Exception($"无法加载纹理导入器: {texturePath}");
|
||||
}
|
||||
return textureImporter.spriteImportMode;
|
||||
}
|
||||
|
||||
// 解析Aseprite JSON
|
||||
public static ProcessedAnimationData ParseAsepriteJson(string jsonPath, string texturePath)
|
||||
{
|
||||
string jsonContent = File.ReadAllText(jsonPath);
|
||||
|
||||
// Unity的JsonUtility不支持Dictionary,需要手动解析frames对象
|
||||
// 使用SimpleJSON或手动解析
|
||||
ProcessedAnimationData result = ParseAsepriteJsonManual(jsonContent);
|
||||
|
||||
if (result.frames == null || result.frames.Count == 0)
|
||||
{
|
||||
throw new Exception("无效的Aseprite JSON格式:无法解析frames");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ProcessedAnimationData ParseAsepriteJsonManual(string jsonContent)
|
||||
{
|
||||
List<FrameData> frames = new List<FrameData>();
|
||||
List<ProcessedAnimationClip> animations = new List<ProcessedAnimationClip>();
|
||||
|
||||
try
|
||||
{
|
||||
// 解析meta部分
|
||||
int metaStart = jsonContent.IndexOf("\"meta\":");
|
||||
if (metaStart == -1)
|
||||
{
|
||||
throw new Exception("找不到meta部分");
|
||||
}
|
||||
|
||||
// 找到meta对象的结束位置
|
||||
int metaBraceStart = jsonContent.IndexOf('{', metaStart);
|
||||
int metaBraceEnd = FindMatchingBrace(jsonContent, metaBraceStart);
|
||||
string metaJson = jsonContent.Substring(metaBraceStart, metaBraceEnd - metaBraceStart + 1);
|
||||
|
||||
// 移除可能的尾随逗号
|
||||
metaJson = metaJson.TrimEnd(',', ' ', '\n', '\r');
|
||||
|
||||
AsepriteMeta meta = JsonUtility.FromJson<AsepriteMeta>(metaJson);
|
||||
|
||||
// 解析frameTags
|
||||
if (meta.frameTags != null)
|
||||
{
|
||||
foreach (var tag in meta.frameTags)
|
||||
{
|
||||
List<int> frameIndices = new List<int>();
|
||||
int start = tag.from;
|
||||
int end = tag.to;
|
||||
|
||||
if (tag.direction == "forward" || tag.direction == "pingpong" || string.IsNullOrEmpty(tag.direction))
|
||||
{
|
||||
for (int i = start; i <= end; i++)
|
||||
{
|
||||
frameIndices.Add(i);
|
||||
}
|
||||
}
|
||||
else if (tag.direction == "reverse")
|
||||
{
|
||||
for (int i = end; i >= start; i--)
|
||||
{
|
||||
frameIndices.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
animations.Add(new ProcessedAnimationClip
|
||||
{
|
||||
name = tag.name,
|
||||
frameIndices = frameIndices,
|
||||
loop = true,
|
||||
frameDuration = 0,
|
||||
sampleRate = 100
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 解析frames对象 - 使用正则表达式或手动解析
|
||||
int framesStart = jsonContent.IndexOf("\"frames\":");
|
||||
if (framesStart == -1)
|
||||
{
|
||||
throw new Exception("找不到frames部分");
|
||||
}
|
||||
|
||||
// 找到frames对象的开始和结束
|
||||
int framesBraceStart = jsonContent.IndexOf('{', framesStart);
|
||||
int framesBraceEnd = FindMatchingBrace(jsonContent, framesBraceStart);
|
||||
string framesContent = jsonContent.Substring(framesBraceStart + 1, framesBraceEnd - framesBraceStart - 1);
|
||||
|
||||
// 解析每个帧条目
|
||||
ParseFramesContent(framesContent, frames);
|
||||
|
||||
// 按名称排序帧(确保顺序正确)
|
||||
frames = frames.OrderBy(f => ExtractFrameNumber(f.name)).ThenBy(f => f.name).ToList();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception($"解析Aseprite JSON失败: {e.Message}\n{e.StackTrace}");
|
||||
}
|
||||
|
||||
return new ProcessedAnimationData
|
||||
{
|
||||
frames = frames,
|
||||
animations = animations
|
||||
};
|
||||
}
|
||||
|
||||
private static void ParseFramesContent(string framesContent, List<FrameData> frames)
|
||||
{
|
||||
int pos = 0;
|
||||
while (pos < framesContent.Length)
|
||||
{
|
||||
// 跳过空白字符和逗号
|
||||
while (pos < framesContent.Length && (char.IsWhiteSpace(framesContent[pos]) || framesContent[pos] == ','))
|
||||
pos++;
|
||||
|
||||
if (pos >= framesContent.Length) break;
|
||||
|
||||
// 查找帧名称(在引号中)
|
||||
if (framesContent[pos] != '"')
|
||||
{
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
int nameStart = pos + 1;
|
||||
int nameEnd = framesContent.IndexOf('"', nameStart);
|
||||
if (nameEnd == -1) break;
|
||||
|
||||
string frameName = framesContent.Substring(nameStart, nameEnd - nameStart);
|
||||
pos = nameEnd + 1;
|
||||
|
||||
// 跳过冒号和空白
|
||||
while (pos < framesContent.Length && (char.IsWhiteSpace(framesContent[pos]) || framesContent[pos] == ':'))
|
||||
pos++;
|
||||
|
||||
if (pos >= framesContent.Length) break;
|
||||
|
||||
// 查找帧数据对象
|
||||
if (framesContent[pos] != '{')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int dataStart = pos;
|
||||
int dataEnd = FindMatchingBrace(framesContent, dataStart);
|
||||
if (dataEnd == -1) break;
|
||||
|
||||
string frameDataJson = framesContent.Substring(dataStart, dataEnd - dataStart + 1);
|
||||
pos = dataEnd + 1;
|
||||
|
||||
try
|
||||
{
|
||||
AsepriteFrameInfo frameInfo = JsonUtility.FromJson<AsepriteFrameInfo>(frameDataJson);
|
||||
if (frameInfo.frame != null)
|
||||
{
|
||||
frames.Add(new FrameData
|
||||
{
|
||||
name = frameName,
|
||||
x = frameInfo.frame.x,
|
||||
y = frameInfo.frame.y,
|
||||
width = frameInfo.frame.w,
|
||||
height = frameInfo.frame.h,
|
||||
duration = frameInfo.duration
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning($"解析帧数据失败: {frameName}, 错误: {e.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int ExtractFrameNumber(string frameName)
|
||||
{
|
||||
// 尝试从帧名称中提取数字(例如 "调酒妹侧头 0.aseprite" -> 0)
|
||||
int lastSpace = frameName.LastIndexOf(' ');
|
||||
if (lastSpace >= 0 && lastSpace < frameName.Length - 1)
|
||||
{
|
||||
string numberPart = frameName.Substring(lastSpace + 1);
|
||||
int dotIndex = numberPart.IndexOf('.');
|
||||
if (dotIndex > 0)
|
||||
{
|
||||
numberPart = numberPart.Substring(0, dotIndex);
|
||||
}
|
||||
|
||||
if (int.TryParse(numberPart, out int number))
|
||||
{
|
||||
return number;
|
||||
}
|
||||
}
|
||||
return int.MaxValue; // 如果无法解析,放在最后
|
||||
}
|
||||
|
||||
private static int FindMatchingBrace(string str, int startIndex)
|
||||
{
|
||||
if (startIndex < 0 || startIndex >= str.Length) return -1;
|
||||
|
||||
int braceCount = 0;
|
||||
bool foundStart = false;
|
||||
|
||||
for (int i = startIndex; i < str.Length; i++)
|
||||
{
|
||||
if (str[i] == '{')
|
||||
{
|
||||
braceCount++;
|
||||
foundStart = true;
|
||||
}
|
||||
else if (str[i] == '}')
|
||||
{
|
||||
braceCount--;
|
||||
if (braceCount == 0 && foundStart)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 解析手动JSON
|
||||
public static ProcessedAnimationData ParseManualJson(string jsonPath, string texturePath)
|
||||
{
|
||||
string jsonContent = File.ReadAllText(jsonPath);
|
||||
ManualJsonData manualData = JsonUtility.FromJson<ManualJsonData>(jsonContent);
|
||||
|
||||
if (manualData.layout == null || manualData.animations == null)
|
||||
{
|
||||
throw new Exception("无效的手动JSON格式");
|
||||
}
|
||||
|
||||
// 验证layout参数
|
||||
if (manualData.layout.rows <= 0 || manualData.layout.columns <= 0)
|
||||
{
|
||||
throw new Exception("rows和columns必须大于0");
|
||||
}
|
||||
|
||||
// 读取图片尺寸
|
||||
TextureImporter textureImporter = AssetImporter.GetAtPath(texturePath) as TextureImporter;
|
||||
if (textureImporter == null)
|
||||
{
|
||||
throw new Exception($"无法加载纹理导入器: {texturePath}");
|
||||
}
|
||||
|
||||
Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(texturePath);
|
||||
if (texture == null)
|
||||
{
|
||||
throw new Exception($"无法加载纹理: {texturePath}");
|
||||
}
|
||||
|
||||
int imageWidth = texture.width;
|
||||
int imageHeight = texture.height;
|
||||
|
||||
// 计算sprite尺寸
|
||||
int spriteWidth = imageWidth / manualData.layout.columns;
|
||||
int spriteHeight = imageHeight / manualData.layout.rows;
|
||||
|
||||
// 验证图片尺寸能被行列数整除
|
||||
if (imageWidth % manualData.layout.columns != 0 || imageHeight % manualData.layout.rows != 0)
|
||||
{
|
||||
throw new Exception($"图片尺寸({imageWidth}x{imageHeight})无法被行列数({manualData.layout.columns}x{manualData.layout.rows})整除");
|
||||
}
|
||||
|
||||
// 计算总帧数
|
||||
int totalFrames = manualData.layout.frameCount ?? (manualData.layout.rows * manualData.layout.columns);
|
||||
if (totalFrames > manualData.layout.rows * manualData.layout.columns)
|
||||
{
|
||||
throw new Exception($"frameCount({totalFrames})不能超过rows*columns({manualData.layout.rows * manualData.layout.columns})");
|
||||
}
|
||||
|
||||
// 生成帧数据
|
||||
List<FrameData> frames = new List<FrameData>();
|
||||
bool isHorizontal = manualData.layout.direction == "horizontal";
|
||||
|
||||
for (int frameIndex = 0; frameIndex < totalFrames; frameIndex++)
|
||||
{
|
||||
int row, column;
|
||||
if (isHorizontal)
|
||||
{
|
||||
// 横向排列:按行扫描,从左到右,从上到下
|
||||
row = frameIndex / manualData.layout.columns;
|
||||
column = frameIndex % manualData.layout.columns;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 纵向排列:按列扫描,从上到下,从左到右
|
||||
column = frameIndex / manualData.layout.rows;
|
||||
row = frameIndex % manualData.layout.rows;
|
||||
}
|
||||
|
||||
// Unity Y轴从下往上,需要转换
|
||||
int x = column * spriteWidth;
|
||||
int y = (manualData.layout.rows - 1 - row) * spriteHeight;
|
||||
|
||||
frames.Add(new FrameData
|
||||
{
|
||||
name = $"frame_{frameIndex}",
|
||||
x = x,
|
||||
y = y,
|
||||
width = spriteWidth,
|
||||
height = spriteHeight,
|
||||
duration = manualData.frameDuration
|
||||
});
|
||||
}
|
||||
|
||||
// 处理动画片段
|
||||
List<ProcessedAnimationClip> animations = new List<ProcessedAnimationClip>();
|
||||
foreach (var anim in manualData.animations)
|
||||
{
|
||||
// 应用参数覆盖逻辑
|
||||
float frameDuration = anim.frameDuration ?? manualData.frameDuration;
|
||||
int sampleRate = anim.sampleRate ?? manualData.sampleRate;
|
||||
|
||||
animations.Add(new ProcessedAnimationClip
|
||||
{
|
||||
name = anim.name,
|
||||
frameIndices = anim.frameIndices,
|
||||
loop = anim.loop,
|
||||
frameDuration = frameDuration,
|
||||
sampleRate = sampleRate
|
||||
});
|
||||
}
|
||||
|
||||
return new ProcessedAnimationData
|
||||
{
|
||||
frames = frames,
|
||||
animations = animations
|
||||
};
|
||||
}
|
||||
|
||||
// 根据JSON信息切图
|
||||
public static void SliceSprites(string texturePath, List<FrameData> frames)
|
||||
{
|
||||
TextureImporter textureImporter = AssetImporter.GetAtPath(texturePath) as TextureImporter;
|
||||
if (textureImporter == null)
|
||||
{
|
||||
throw new Exception($"无法加载纹理导入器: {texturePath}");
|
||||
}
|
||||
|
||||
// 设置spriteMode为Multiple
|
||||
textureImporter.spriteImportMode = SpriteImportMode.Multiple;
|
||||
|
||||
// 使用新的Sprite Editor Data Provider API (Unity 2020.2+)
|
||||
var spriteDataProviderFactories = new SpriteDataProviderFactories();
|
||||
spriteDataProviderFactories.Init();
|
||||
var dataProvider = spriteDataProviderFactories.GetSpriteEditorDataProviderFromObject(textureImporter);
|
||||
|
||||
if (dataProvider == null)
|
||||
{
|
||||
throw new Exception($"无法获取Sprite Editor Data Provider: {texturePath}");
|
||||
}
|
||||
|
||||
dataProvider.InitSpriteEditorDataProvider();
|
||||
|
||||
// 创建SpriteRect数组
|
||||
var spriteRects = new SpriteRect[frames.Count];
|
||||
for (int i = 0; i < frames.Count; i++)
|
||||
{
|
||||
var frame = frames[i];
|
||||
spriteRects[i] = new SpriteRect
|
||||
{
|
||||
name = frame.name,
|
||||
rect = new Rect(frame.x, frame.y, frame.width, frame.height),
|
||||
pivot = new Vector2(0.5f, 0.5f),
|
||||
alignment = SpriteAlignment.Center
|
||||
};
|
||||
}
|
||||
|
||||
dataProvider.SetSpriteRects(spriteRects);
|
||||
dataProvider.Apply();
|
||||
|
||||
AssetDatabase.ImportAsset(texturePath, ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
|
||||
// 创建AnimationClip
|
||||
public static AnimationClip CreateAnimationClip(
|
||||
ProcessedAnimationClip animationData,
|
||||
List<FrameData> frames,
|
||||
Sprite[] sprites,
|
||||
string outputPath,
|
||||
bool isImageAnimation = false)
|
||||
{
|
||||
AnimationClip clip = new AnimationClip();
|
||||
clip.name = animationData.name;
|
||||
|
||||
// 设置采样率
|
||||
AnimationClipSettings settings = AnimationUtility.GetAnimationClipSettings(clip);
|
||||
clip.frameRate = animationData.sampleRate;
|
||||
|
||||
// 创建Sprite关键帧
|
||||
List<ObjectReferenceKeyframe> keyframes = new List<ObjectReferenceKeyframe>();
|
||||
float currentTime = 0f;
|
||||
|
||||
foreach (int frameIndex in animationData.frameIndices)
|
||||
{
|
||||
if (frameIndex < 0 || frameIndex >= sprites.Length)
|
||||
{
|
||||
Debug.LogWarning($"帧索引{frameIndex}超出范围,跳过");
|
||||
continue;
|
||||
}
|
||||
|
||||
Sprite sprite = sprites[frameIndex];
|
||||
if (sprite == null)
|
||||
{
|
||||
Debug.LogWarning($"帧索引{frameIndex}的Sprite为空,跳过");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 使用帧的duration(如果是Aseprite格式)或动画的frameDuration(手动格式)
|
||||
float frameDuration = frames[frameIndex].duration > 0
|
||||
? frames[frameIndex].duration / 1000f // 毫秒转秒
|
||||
: animationData.frameDuration / 1000f;
|
||||
|
||||
keyframes.Add(new ObjectReferenceKeyframe
|
||||
{
|
||||
time = currentTime,
|
||||
value = sprite
|
||||
});
|
||||
|
||||
currentTime += frameDuration;
|
||||
}
|
||||
|
||||
if (keyframes.Count == 0)
|
||||
{
|
||||
throw new Exception($"动画片段{animationData.name}没有有效的关键帧");
|
||||
}
|
||||
|
||||
// 设置循环
|
||||
if (animationData.loop && keyframes.Count > 1)
|
||||
{
|
||||
// 添加最后一帧的重复,确保循环
|
||||
keyframes.Add(new ObjectReferenceKeyframe
|
||||
{
|
||||
time = currentTime,
|
||||
value = keyframes[0].value
|
||||
});
|
||||
}
|
||||
|
||||
// 创建EditorCurveBinding - 根据动画类型选择不同的组件
|
||||
EditorCurveBinding curveBinding = new EditorCurveBinding
|
||||
{
|
||||
path = "",
|
||||
type = isImageAnimation ? typeof(UnityEngine.UI.Image) : typeof(SpriteRenderer),
|
||||
propertyName = "m_Sprite"
|
||||
};
|
||||
|
||||
// 设置曲线
|
||||
AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyframes.ToArray());
|
||||
|
||||
// 设置循环
|
||||
settings.loopTime = animationData.loop;
|
||||
AnimationUtility.SetAnimationClipSettings(clip, settings);
|
||||
|
||||
// 保存AnimationClip
|
||||
string fullPath = Path.Combine(outputPath, $"{animationData.name}.anim");
|
||||
string assetPath = fullPath.Replace('\\', '/');
|
||||
if (!assetPath.StartsWith("Assets/"))
|
||||
{
|
||||
// 转换为相对路径
|
||||
string projectPath = Application.dataPath.Replace("Assets", "");
|
||||
if (assetPath.StartsWith(projectPath))
|
||||
{
|
||||
assetPath = assetPath.Substring(projectPath.Length);
|
||||
}
|
||||
}
|
||||
|
||||
AssetDatabase.CreateAsset(clip, assetPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
return clip;
|
||||
}
|
||||
|
||||
// 主流程:生成AnimationClip
|
||||
public static void GenerateClips(string texturePath, string jsonPath, string outputPath, bool isImageAnimation = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("生成AnimationClip", "检查SpriteMode...", 0f);
|
||||
|
||||
// 检查SpriteMode
|
||||
SpriteImportMode spriteMode = CheckSpriteMode(texturePath);
|
||||
if (spriteMode == SpriteImportMode.Multiple)
|
||||
{
|
||||
Debug.Log("图片的SpriteMode已经是Multiple,将使用现有的Sprite切图");
|
||||
}
|
||||
|
||||
EditorUtility.DisplayProgressBar("生成AnimationClip", "解析JSON...", 0.2f);
|
||||
|
||||
// 判断JSON类型并解析
|
||||
ProcessedAnimationData processedData;
|
||||
string jsonContent = File.ReadAllText(jsonPath);
|
||||
|
||||
if (jsonContent.Contains("\"type\":\"manual\"") || jsonContent.Contains("\"type\": \"manual\""))
|
||||
{
|
||||
// 手动格式
|
||||
processedData = ParseManualJson(jsonPath, texturePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Aseprite格式
|
||||
processedData = ParseAsepriteJson(jsonPath, texturePath);
|
||||
}
|
||||
|
||||
EditorUtility.DisplayProgressBar("生成AnimationClip", "切图...", 0.4f);
|
||||
|
||||
// 如果是Single模式,需要切图
|
||||
if (spriteMode == SpriteImportMode.Single)
|
||||
{
|
||||
SliceSprites(texturePath, processedData.frames);
|
||||
// 重新加载以确保sprites可用
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
EditorUtility.DisplayProgressBar("生成AnimationClip", "加载Sprites...", 0.6f);
|
||||
|
||||
// 加载所有Sprites
|
||||
Sprite[] allSpritesArray = AssetDatabase.LoadAllAssetsAtPath(texturePath)
|
||||
.OfType<Sprite>()
|
||||
.ToArray();
|
||||
|
||||
if (allSpritesArray.Length == 0)
|
||||
{
|
||||
throw new Exception("无法加载任何Sprite,请检查切图设置");
|
||||
}
|
||||
|
||||
// 创建Sprite字典以便快速查找
|
||||
Dictionary<string, Sprite> spriteDict = allSpritesArray.ToDictionary(s => s.name, s => s);
|
||||
|
||||
// 按照frames列表的顺序创建Sprite数组
|
||||
Sprite[] allSprites = new Sprite[processedData.frames.Count];
|
||||
for (int i = 0; i < processedData.frames.Count; i++)
|
||||
{
|
||||
string frameName = processedData.frames[i].name;
|
||||
if (spriteDict.TryGetValue(frameName, out Sprite sprite))
|
||||
{
|
||||
allSprites[i] = sprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"找不到名为{frameName}的Sprite");
|
||||
// 尝试使用索引查找
|
||||
if (i < allSpritesArray.Length)
|
||||
{
|
||||
allSprites[i] = allSpritesArray[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 确保输出目录存在
|
||||
if (!Directory.Exists(outputPath))
|
||||
{
|
||||
Directory.CreateDirectory(outputPath);
|
||||
}
|
||||
|
||||
EditorUtility.DisplayProgressBar("生成AnimationClip", "创建AnimationClip...", 0.8f);
|
||||
|
||||
// 为每个动画片段创建AnimationClip
|
||||
int animationCount = processedData.animations.Count;
|
||||
for (int i = 0; i < animationCount; i++)
|
||||
{
|
||||
var anim = processedData.animations[i];
|
||||
EditorUtility.DisplayProgressBar("生成AnimationClip",
|
||||
$"创建动画片段: {anim.name}", 0.8f + (i / (float)animationCount) * 0.2f);
|
||||
|
||||
CreateAnimationClip(anim, processedData.frames, allSprites, outputPath, isImageAnimation);
|
||||
}
|
||||
|
||||
EditorUtility.ClearProgressBar();
|
||||
Debug.Log($"成功生成{animationCount}个AnimationClip到: {outputPath}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
Debug.LogError($"生成AnimationClip失败: {e.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c7abb40962ba935419bb10c937b8b2c7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+2599
-2599
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -19,12 +19,12 @@ MonoBehaviour:
|
||||
m_Key: line:02365db
|
||||
m_Metadata:
|
||||
m_Items:
|
||||
- rid: 4903297761218920450
|
||||
- rid: 4903297902702231610
|
||||
- m_Id: 111869431808
|
||||
m_Key: line:0559767
|
||||
m_Metadata:
|
||||
m_Items:
|
||||
- rid: 4903297761218920451
|
||||
- rid: 4903297902702231611
|
||||
- m_Id: 111869431809
|
||||
m_Key: line:0ee9c21
|
||||
m_Metadata:
|
||||
@@ -39,12 +39,12 @@ MonoBehaviour:
|
||||
m_Key: line:0667c6a
|
||||
m_Metadata:
|
||||
m_Items:
|
||||
- rid: 4903297761218920452
|
||||
- rid: 4903297902702231612
|
||||
- m_Id: 46439178508963840
|
||||
m_Key: line:054b767
|
||||
m_Metadata:
|
||||
m_Items:
|
||||
- rid: 4903297761218920453
|
||||
- rid: 4903297902702231613
|
||||
m_Metadata:
|
||||
m_Items: []
|
||||
m_KeyGenerator:
|
||||
@@ -52,22 +52,22 @@ MonoBehaviour:
|
||||
references:
|
||||
version: 2
|
||||
RefIds:
|
||||
- rid: 4903297761218920450
|
||||
- rid: 4903297902702231610
|
||||
type: {class: LineMetadata, ns: Yarn.Unity.UnityLocalization, asm: YarnSpinner.Unity}
|
||||
data:
|
||||
nodeName: Start
|
||||
tags: []
|
||||
- rid: 4903297761218920451
|
||||
- rid: 4903297902702231611
|
||||
type: {class: LineMetadata, ns: Yarn.Unity.UnityLocalization, asm: YarnSpinner.Unity}
|
||||
data:
|
||||
nodeName: Start
|
||||
tags: []
|
||||
- rid: 4903297761218920452
|
||||
- rid: 4903297902702231612
|
||||
type: {class: LineMetadata, ns: Yarn.Unity.UnityLocalization, asm: YarnSpinner.Unity}
|
||||
data:
|
||||
nodeName: "\u65B9\u5757\u62FC\u56FE\u5B8C\u6210"
|
||||
tags: []
|
||||
- rid: 4903297761218920453
|
||||
- rid: 4903297902702231613
|
||||
type: {class: LineMetadata, ns: Yarn.Unity.UnityLocalization, asm: YarnSpinner.Unity}
|
||||
data:
|
||||
nodeName: "\u65B9\u5757\u62FC\u56FE\u5B8C\u6210"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -463,19 +463,15 @@ MonoBehaviour:
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
_filter:
|
||||
- 0.0048309183
|
||||
- 0.016401261
|
||||
- 0.04532712
|
||||
- 0.08293076
|
||||
- 0.12053438
|
||||
- 0.14946026
|
||||
- 0.1610306
|
||||
- 0.14946026
|
||||
- 0.12053438
|
||||
- 0.08293076
|
||||
- 0.04532712
|
||||
- 0.016401261
|
||||
- 0.0048309183
|
||||
- 0.007228916
|
||||
- 0.043749984
|
||||
- 0.12409639
|
||||
- 0.20444278
|
||||
- 0.24096388
|
||||
- 0.20444278
|
||||
- 0.12409639
|
||||
- 0.043749984
|
||||
- 0.007228916
|
||||
--- !u!114 &-6086986437317696584
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 3
|
||||
|
||||
@@ -12191,6 +12191,43 @@ PlayableDirector:
|
||||
value: {fileID: 0}
|
||||
m_ExposedReferences:
|
||||
m_References: []
|
||||
--- !u!1 &749156594
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 749156595}
|
||||
m_Layer: 5
|
||||
m_Name: Loading
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 0
|
||||
--- !u!224 &749156595
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 749156594}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 1186192817}
|
||||
- {fileID: 1314471602}
|
||||
m_Father: {fileID: 923998313}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 100, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1001 &759307075
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -14585,6 +14622,7 @@ RectTransform:
|
||||
m_Children:
|
||||
- {fileID: 961234236}
|
||||
- {fileID: 398371925}
|
||||
- {fileID: 749156595}
|
||||
- {fileID: 1986521822}
|
||||
m_Father: {fileID: 2091451641}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
@@ -17487,6 +17525,103 @@ MonoBehaviour:
|
||||
m_ChildScaleWidth: 0
|
||||
m_ChildScaleHeight: 0
|
||||
m_ReverseArrangement: 0
|
||||
--- !u!1 &1186192816
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1186192817}
|
||||
- component: {fileID: 1186192820}
|
||||
- component: {fileID: 1186192819}
|
||||
- component: {fileID: 1186192818}
|
||||
m_Layer: 5
|
||||
m_Name: Image
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1186192817
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1186192816}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 749156595}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 68}
|
||||
m_SizeDelta: {x: 182, y: 222}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!95 &1186192818
|
||||
Animator:
|
||||
serializedVersion: 5
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1186192816}
|
||||
m_Enabled: 1
|
||||
m_Avatar: {fileID: 0}
|
||||
m_Controller: {fileID: 9100000, guid: 4efe920582e4eb84eabc738f16624d2b, type: 2}
|
||||
m_CullingMode: 0
|
||||
m_UpdateMode: 0
|
||||
m_ApplyRootMotion: 0
|
||||
m_LinearVelocityBlending: 0
|
||||
m_StabilizeFeet: 0
|
||||
m_WarningMessage:
|
||||
m_HasTransformHierarchy: 1
|
||||
m_AllowConstantClipSamplingOptimization: 1
|
||||
m_KeepAnimatorStateOnDisable: 0
|
||||
m_WriteDefaultValuesOnDisable: 0
|
||||
--- !u!114 &1186192819
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1186192816}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!222 &1186192820
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1186192816}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!1 &1197644599
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -19215,6 +19350,140 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 85815d386fde43dca8b4be1cfd26fe89, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &1314471601
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1314471602}
|
||||
- component: {fileID: 1314471604}
|
||||
- component: {fileID: 1314471603}
|
||||
m_Layer: 5
|
||||
m_Name: Text (TMP)
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1314471602
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1314471601}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 749156595}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 3, y: -30}
|
||||
m_SizeDelta: {x: 200, y: 50}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1314471603
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1314471601}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_text: Loading
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: f242fb3dde1933640859f1c54591c9c8, type: 2}
|
||||
m_sharedMaterial: {fileID: -6659093157667844055, guid: f242fb3dde1933640859f1c54591c9c8, type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_enableVertexGradient: 0
|
||||
m_colorMode: 3
|
||||
m_fontColorGradient:
|
||||
topLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
topRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_fontColorGradientPreset: {fileID: 0}
|
||||
m_spriteAsset: {fileID: 0}
|
||||
m_tintAllSprites: 0
|
||||
m_StyleSheet: {fileID: 0}
|
||||
m_TextStyleHashCode: -1183493901
|
||||
m_overrideHtmlColors: 0
|
||||
m_faceColor:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontSize: 36
|
||||
m_fontSizeBase: 36
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 0
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 72
|
||||
m_fontStyle: 0
|
||||
m_HorizontalAlignment: 2
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
m_horizontalMapping: 0
|
||||
m_verticalMapping: 0
|
||||
m_uvLineOffset: 0
|
||||
m_geometrySortingOrder: 0
|
||||
m_IsTextObjectScaleStatic: 0
|
||||
m_VertexBufferAutoSizeReduction: 0
|
||||
m_useMaxVisibleDescender: 1
|
||||
m_pageToDisplay: 1
|
||||
m_margin: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_isUsingLegacyAnimationComponent: 0
|
||||
m_isVolumetricText: 0
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!222 &1314471604
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1314471601}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!1 &1317294297
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using AibisDream.Utility;
|
||||
|
||||
namespace AibisDream.Kit
|
||||
{
|
||||
internal class LogKit : MonoBehaviour
|
||||
internal static class LogKit
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件名称格式
|
||||
@@ -11,11 +12,6 @@ namespace AibisDream.Kit
|
||||
/// </summary>
|
||||
public static string LogFileName => "Log{0:_yyyy_MM_dd}.txt";
|
||||
|
||||
/// <summary>
|
||||
/// 日志文件路径
|
||||
/// </summary>
|
||||
public static string LogPath => Application.streamingAssetsPath + "/LogFile";
|
||||
|
||||
/// <summary>
|
||||
/// 日志保存最近几天的内容
|
||||
/// </summary>
|
||||
@@ -26,29 +22,41 @@ namespace AibisDream.Kit
|
||||
/// </summary>
|
||||
private static string LogContent => Time + ": {0}\n{1}";
|
||||
|
||||
private FileLogger _fileLogger;
|
||||
private static FileLogger _fileLogger;
|
||||
private static bool _isInitialized;
|
||||
|
||||
private static string Time => DateTime.Now.ToString("[HH:mm:ss.fffd]");
|
||||
|
||||
private void Awake()
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
private static void Initialize()
|
||||
{
|
||||
#if !UNITY_EDITOR
|
||||
DontDestroyOnLoad(gameObject);
|
||||
_fileLogger = new FileLogger(LogFileName, LogPath, SaveDays, Application.version);
|
||||
if (_isInitialized)
|
||||
return;
|
||||
|
||||
_fileLogger = new FileLogger(LogFileName, ConstRef.LogFilePath, SaveDays);
|
||||
LogMessage($"Ver.{Application.version}", "", LogType.Log);
|
||||
Application.logMessageReceivedThreaded += LogMessage;
|
||||
Application.quitting += Shutdown;
|
||||
_isInitialized = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
private void LogMessage(string condition, string stackTrace, LogType type)
|
||||
private static void LogMessage(string condition, string stackTrace, LogType type)
|
||||
{
|
||||
_fileLogger?.Write(string.Format(LogContent, condition, stackTrace));
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
private static void Shutdown()
|
||||
{
|
||||
if (!_isInitialized)
|
||||
return;
|
||||
|
||||
Application.logMessageReceivedThreaded -= LogMessage;
|
||||
Application.quitting -= Shutdown;
|
||||
_fileLogger?.OnDestroy();
|
||||
_fileLogger = null;
|
||||
Application.logMessageReceivedThreaded -= LogMessage;
|
||||
_isInitialized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ using AibisDream.Framework;
|
||||
using AibisDream.Kit;
|
||||
using AibisDream.UI;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
using AibisDream.Utility;
|
||||
|
||||
namespace AibisDream
|
||||
{
|
||||
@@ -12,12 +14,15 @@ namespace AibisDream
|
||||
/// </summary>
|
||||
public class SettingLoader
|
||||
{
|
||||
private static readonly string SettingPath = Application.streamingAssetsPath + "/Config/setting.json";
|
||||
private static readonly string SettingPath = Path.Combine(Application.persistentDataPath, "AllOurBrokenParts", "Config", "setting.json");
|
||||
private static readonly string SettingDefaultPath = Path.Combine(Application.streamingAssetsPath, "Config", "setting.json");
|
||||
|
||||
private readonly ConfigContainer _container;
|
||||
|
||||
private SettingLoader()
|
||||
{
|
||||
// 初始化设置文件(如果不存在)
|
||||
InitSettingFile();
|
||||
// 读取数据
|
||||
_container = new ConfigContainer(SettingPath);
|
||||
LoadAllSetting();
|
||||
@@ -30,6 +35,44 @@ namespace AibisDream
|
||||
_container.OnWrite -= OnSettingChanged;
|
||||
}
|
||||
|
||||
private void InitSettingFile()
|
||||
{
|
||||
// 如果文件存在,则直接返回
|
||||
if (File.Exists(SettingPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果文件不存在,则复制默认设置并根据系统语言设置初始语言值
|
||||
var defaultSetting = JsonUtil.ReadJObject(SettingDefaultPath);
|
||||
|
||||
// 根据当前系统语言设置初始语言值
|
||||
string systemLanguage = GetLanguageBySystemLanguage();
|
||||
defaultSetting["Language"] = systemLanguage;
|
||||
|
||||
// 保存设置文件
|
||||
JsonUtil.SaveJObject(defaultSetting, SettingPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据系统语言获取对应的语言代码
|
||||
/// </summary>
|
||||
/// <returns>语言代码:zh-Hans、en、ja-JP,默认返回 en</returns>
|
||||
private string GetLanguageBySystemLanguage()
|
||||
{
|
||||
SystemLanguage systemLang = Application.systemLanguage;
|
||||
|
||||
return systemLang switch
|
||||
{
|
||||
SystemLanguage.Chinese => "zh-Hans",
|
||||
SystemLanguage.ChineseSimplified => "zh-Hans",
|
||||
SystemLanguage.ChineseTraditional => "zh-Hans",
|
||||
SystemLanguage.Japanese => "ja-JP",
|
||||
SystemLanguage.English => "en",
|
||||
_ => "en",
|
||||
};
|
||||
}
|
||||
|
||||
private void LoadAllSetting()
|
||||
{
|
||||
var settingConfig = _container.ReadAll();
|
||||
@@ -55,7 +98,9 @@ namespace AibisDream
|
||||
break;
|
||||
case "WindowMode":
|
||||
// 屏幕模式
|
||||
#if !UNITY_ANDROID && !UNITY_IOS
|
||||
GameManager.Instance.SetScreenMode(value);
|
||||
#endif
|
||||
break;
|
||||
case "Language":
|
||||
// 确保本地化系统已初始化
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace AibisDream.UI
|
||||
public class InfoPanel : MonoBehaviour, IUIPanel
|
||||
{
|
||||
[SerializeField] private DemoTimer demoTimer;
|
||||
[SerializeField] private GameObject loading;
|
||||
[SerializeField] private VariableBar variableBar;
|
||||
|
||||
public void SetTimerActive(bool isOpen)
|
||||
@@ -35,6 +36,16 @@ namespace AibisDream.UI
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
public void ShowLoading()
|
||||
{
|
||||
loading.SetActive(true);
|
||||
}
|
||||
|
||||
public void HideLoading()
|
||||
{
|
||||
loading.SetActive(false);
|
||||
}
|
||||
|
||||
public bool IsOpen => gameObject.activeSelf;
|
||||
|
||||
public bool IsCloseable => false;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AibisDream.Utility
|
||||
@@ -14,6 +15,7 @@ namespace AibisDream.Utility
|
||||
|
||||
public const string SurveyURL_CN = "https://jsj.top/f/HkmCnH";
|
||||
public const string SurveyURL_EN = "https://jsj.top/f/y501LX";
|
||||
public const string SurveyURL_JP = "https://jsj.top/f/icnVug";
|
||||
|
||||
public const string WishlistURL = "https://store.steampowered.com/app/3473430/_All_Our_Broken_Parts?utm_source=playtest";
|
||||
|
||||
@@ -22,14 +24,18 @@ namespace AibisDream.Utility
|
||||
#if UnityEditor
|
||||
public static readonly string SaveFilePath = Application.persistentDataPath + "/SaveFiles/";
|
||||
#else
|
||||
public static readonly string SaveFilePath = Application.persistentDataPath + "/AllOurBrokenParts/saves/";
|
||||
public static readonly string SaveFilePath = Path.Combine(Application.persistentDataPath, "AllOurBrokenParts", "saves");
|
||||
#endif
|
||||
|
||||
public static readonly string ChapterProgressPath = $"{Application.streamingAssetsPath}/Config/chapter.json";
|
||||
public static readonly string ChapterProgressPath = Path.Combine(Application.persistentDataPath, "AllOurBrokenParts", "Config", "chapter.json");
|
||||
|
||||
public static readonly string CharacterConfigPath = Path.Combine(Application.streamingAssetsPath, "Config", "character.csv");
|
||||
|
||||
public static readonly string LogFilePath = Path.Combine(Application.persistentDataPath, "LogFile");
|
||||
public static readonly string BlockPuzzleDataPath = Path.Combine(Application.streamingAssetsPath, "LevelData", "BlockPuzzle", "BlockPuzzleData.json");
|
||||
public static readonly string BlockShapeDataPath = Path.Combine(Application.streamingAssetsPath, "LevelData", "BlockPuzzle", "BlockShapeData.json");
|
||||
|
||||
public static readonly string BlockShapeDataPath = $"{Application.streamingAssetsPath}/LevelData/BlockPuzzle/BlockShapeData.json";
|
||||
|
||||
public static readonly string BlockPuzzleDataPath = $"{Application.streamingAssetsPath}/LevelData/BlockPuzzle/BlockPuzzleData.json";
|
||||
|
||||
#region 本地化索引
|
||||
|
||||
@@ -63,10 +69,6 @@ namespace AibisDream.Utility
|
||||
|
||||
public const string RecordPrefab = "RecordItem";
|
||||
|
||||
public const string BlockShapePrefab = "BlockShape";
|
||||
|
||||
public const string ShapeCreateButtonPrefab = "ShapeCreateButton";
|
||||
|
||||
#endregion
|
||||
|
||||
#region 动画配置
|
||||
@@ -82,7 +84,7 @@ namespace AibisDream.Utility
|
||||
public const int CharacterDelayTime = 70;
|
||||
public const int LineMaxDelay = 2800;
|
||||
public const int LineMinDelay = 600;
|
||||
public const int AutoHideDelay = 300;
|
||||
public const int AutoHideDelay = 150;
|
||||
public const int FixedDelay = 200;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -9,6 +9,8 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace AibisDream.Utility
|
||||
{
|
||||
@@ -20,13 +22,89 @@ namespace AibisDream.Utility
|
||||
// 默认分隔符
|
||||
private const char FieldSeparator = ',';
|
||||
|
||||
/// <summary>
|
||||
/// 根据平台读取文件内容
|
||||
/// </summary>
|
||||
private static string ReadFileText(string filePath)
|
||||
{
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
// Android 平台需要使用 UnityWebRequest 读取 StreamingAssets
|
||||
if (filePath.Contains(Application.streamingAssetsPath))
|
||||
{
|
||||
// Android 上 StreamingAssets 在 APK 中,需要构建正确的 URL
|
||||
string url = filePath;
|
||||
// 确保使用正确的路径分隔符
|
||||
url = url.Replace("\\", "/");
|
||||
// 如果路径不包含协议前缀,添加 file://
|
||||
if (!url.StartsWith("file://") && !url.StartsWith("jar:file://"))
|
||||
{
|
||||
// 对于 Android APK 中的文件,使用 jar:file:// 协议
|
||||
string relativePath = url.Replace(Application.streamingAssetsPath, "").TrimStart('/');
|
||||
url = "jar:file://" + Application.dataPath + "!/assets/" + relativePath;
|
||||
}
|
||||
|
||||
using (UnityWebRequest www = UnityWebRequest.Get(url))
|
||||
{
|
||||
www.SendWebRequest();
|
||||
|
||||
// 等待请求完成(同步等待)
|
||||
while (!www.isDone)
|
||||
{
|
||||
// 在主线程中等待
|
||||
}
|
||||
|
||||
if (www.result == UnityWebRequest.Result.Success)
|
||||
{
|
||||
return www.downloadHandler.text;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException($"无法读取文件: {filePath}, URL: {url}, 错误: {www.error}");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 非 StreamingAssets 路径,使用普通文件读取
|
||||
return File.ReadAllText(filePath, DefaultEncode);
|
||||
}
|
||||
#else
|
||||
// 其他平台直接使用 File 类
|
||||
return File.ReadAllText(filePath, DefaultEncode);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据平台创建 StreamReader
|
||||
/// </summary>
|
||||
private static StreamReader CreateStreamReader(string filePath)
|
||||
{
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
// Android 平台需要使用 UnityWebRequest 读取 StreamingAssets
|
||||
if (filePath.Contains(Application.streamingAssetsPath))
|
||||
{
|
||||
string fileText = ReadFileText(filePath);
|
||||
MemoryStream stream = new MemoryStream(DefaultEncode.GetBytes(fileText));
|
||||
return new StreamReader(stream, DefaultEncode);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 非 StreamingAssets 路径,使用普通文件读取
|
||||
return new StreamReader(filePath, DefaultEncode);
|
||||
}
|
||||
#else
|
||||
// 其他平台直接使用 File 类
|
||||
return new StreamReader(filePath, DefaultEncode);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static List<string[]> Read(string filePath)
|
||||
{
|
||||
List<string[]> dataList = new List<string[]>();
|
||||
StreamReader reader;
|
||||
StreamReader reader = null;
|
||||
try
|
||||
{
|
||||
using (reader = new StreamReader(filePath, DefaultEncode))
|
||||
using (reader = CreateStreamReader(filePath))
|
||||
{
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
@@ -48,7 +126,7 @@ namespace AibisDream.Utility
|
||||
GC.Collect();
|
||||
Thread.Sleep(50);
|
||||
Console.WriteLine(ex.StackTrace);
|
||||
using (reader = new StreamReader(filePath, DefaultEncode))
|
||||
using (reader = CreateStreamReader(filePath))
|
||||
{
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
@@ -59,8 +137,10 @@ namespace AibisDream.Utility
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reader.Close();
|
||||
finally
|
||||
{
|
||||
reader?.Close();
|
||||
}
|
||||
return dataList;
|
||||
}
|
||||
|
||||
@@ -82,7 +162,7 @@ namespace AibisDream.Utility
|
||||
var props = targetType.GetProperties();
|
||||
|
||||
// 读取CSV
|
||||
using var reader = new StreamReader(filePath, DefaultEncode);
|
||||
using var reader = CreateStreamReader(filePath);
|
||||
|
||||
// 第一行是注释
|
||||
reader.ReadLine();
|
||||
@@ -90,7 +170,7 @@ namespace AibisDream.Utility
|
||||
var titles = reader.ReadLine()?.Split(FieldSeparator);
|
||||
if (titles == null)
|
||||
{
|
||||
Debug.WriteLine("csv无标题");
|
||||
System.Diagnostics.Debug.WriteLine("csv无标题");
|
||||
throw new Exception("csv无标题");
|
||||
}
|
||||
|
||||
@@ -100,7 +180,7 @@ namespace AibisDream.Utility
|
||||
{
|
||||
string newLine = reader.ReadLine();
|
||||
if (string.IsNullOrEmpty(newLine)) break;
|
||||
|
||||
|
||||
string[] rowData = newLine.Split(FieldSeparator);
|
||||
if (rowData == null || rowData.Length == 0) continue;
|
||||
|
||||
@@ -109,13 +189,13 @@ namespace AibisDream.Utility
|
||||
foreach (var prop in props)
|
||||
{
|
||||
string name = prop.Name;
|
||||
if (!titles.Contains(prop.Name))
|
||||
if (!titles.Contains(prop.Name))
|
||||
continue;
|
||||
|
||||
int idx = Array.IndexOf(titles, prop.Name);
|
||||
prop.SetValue(obj, GetDefaultValue(prop, rowData[idx]));
|
||||
}
|
||||
|
||||
|
||||
res.Add(obj as T);
|
||||
}
|
||||
|
||||
@@ -130,7 +210,7 @@ namespace AibisDream.Utility
|
||||
{
|
||||
bool blnFlag = true;
|
||||
|
||||
StreamReader reader = new StreamReader(strPath, DefaultEncode);
|
||||
StreamReader reader = CreateStreamReader(strPath);
|
||||
myCsvDt = new DataTable();
|
||||
while (reader.ReadLine() is { } strLine)
|
||||
{
|
||||
@@ -218,7 +298,7 @@ namespace AibisDream.Utility
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
sw.Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace AibisDream.Utility
|
||||
{
|
||||
@@ -11,6 +13,58 @@ namespace AibisDream.Utility
|
||||
{
|
||||
public const string JsonSuffix = ".json";
|
||||
|
||||
/// <summary>
|
||||
/// 根据平台读取文件内容
|
||||
/// </summary>
|
||||
private static string ReadFileText(string filePath)
|
||||
{
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
// Android 平台需要使用 UnityWebRequest 读取 StreamingAssets
|
||||
if (filePath.Contains(Application.streamingAssetsPath))
|
||||
{
|
||||
// Android 上 StreamingAssets 在 APK 中,需要构建正确的 URL
|
||||
string url = filePath;
|
||||
// 确保使用正确的路径分隔符
|
||||
url = url.Replace("\\", "/");
|
||||
// 如果路径不包含协议前缀,添加 file://
|
||||
if (!url.StartsWith("file://") && !url.StartsWith("jar:file://"))
|
||||
{
|
||||
// 对于 Android APK 中的文件,使用 jar:file:// 协议
|
||||
string relativePath = url.Replace(Application.streamingAssetsPath, "").TrimStart('/');
|
||||
url = "jar:file://" + Application.dataPath + "!/assets/" + relativePath;
|
||||
}
|
||||
|
||||
using (UnityWebRequest www = UnityWebRequest.Get(url))
|
||||
{
|
||||
www.SendWebRequest();
|
||||
|
||||
// 等待请求完成(同步等待)
|
||||
while (!www.isDone)
|
||||
{
|
||||
// 在主线程中等待
|
||||
}
|
||||
|
||||
if (www.result == UnityWebRequest.Result.Success)
|
||||
{
|
||||
return www.downloadHandler.text;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException($"无法读取文件: {filePath}, URL: {url}, 错误: {www.error}");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 非 StreamingAssets 路径,使用普通文件读取
|
||||
return File.ReadAllText(filePath);
|
||||
}
|
||||
#else
|
||||
// 其他平台直接使用 File 类
|
||||
return File.ReadAllText(filePath);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按路径和Key加载
|
||||
/// </summary>
|
||||
@@ -21,7 +75,7 @@ namespace AibisDream.Utility
|
||||
/// <exception cref="Exception">错误</exception>
|
||||
public static T ReadBean<T>(string path, string key)
|
||||
{
|
||||
string json = File.ReadAllText(path);
|
||||
string json = ReadFileText(path);
|
||||
JObject jObject = JObject.Parse(json);
|
||||
|
||||
if (jObject.ContainsKey(key))
|
||||
@@ -40,7 +94,7 @@ namespace AibisDream.Utility
|
||||
/// <returns></returns>
|
||||
public static T ReadBean<T>(string path)
|
||||
{
|
||||
string json = File.ReadAllText(path);
|
||||
string json = ReadFileText(path);
|
||||
return JsonConvert.DeserializeObject<T>(json);
|
||||
}
|
||||
|
||||
@@ -61,7 +115,7 @@ namespace AibisDream.Utility
|
||||
/// <returns>目标Bean</returns>
|
||||
public static T[] ReadBeanArray<T>(string path)
|
||||
{
|
||||
string json = File.ReadAllText(path);
|
||||
string json = ReadFileText(path);
|
||||
return JsonConvert.DeserializeObject<T[]>(json);
|
||||
}
|
||||
|
||||
@@ -73,7 +127,7 @@ namespace AibisDream.Utility
|
||||
/// <returns>目标Bean</returns>
|
||||
public static Dictionary<string, T> ReadBeanDict<T>(string path)
|
||||
{
|
||||
string json = File.ReadAllText(path);
|
||||
string json = ReadFileText(path);
|
||||
return JsonConvert.DeserializeObject<Dictionary<string, T>>(json);
|
||||
}
|
||||
|
||||
@@ -84,7 +138,7 @@ namespace AibisDream.Utility
|
||||
/// <returns>key列表</returns>
|
||||
public static string[] ReadKeys(string path)
|
||||
{
|
||||
string json = File.ReadAllText(path);
|
||||
string json = ReadFileText(path);
|
||||
JObject jObject = JObject.Parse(json);
|
||||
|
||||
return jObject.Properties().Select(jProp => jProp.Name).ToArray();
|
||||
@@ -92,7 +146,7 @@ namespace AibisDream.Utility
|
||||
|
||||
public static JObject ReadJObject(string path)
|
||||
{
|
||||
string json = File.ReadAllText(FormatAsJsonPath(path), System.Text.Encoding.UTF8);
|
||||
string json = ReadFileText(FormatAsJsonPath(path));
|
||||
return JObject.Parse(json);
|
||||
}
|
||||
|
||||
@@ -105,18 +159,21 @@ namespace AibisDream.Utility
|
||||
public static void SaveBean<T>(T bean, string path)
|
||||
{
|
||||
string json = JsonConvert.SerializeObject(bean);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
File.WriteAllText(path, json);
|
||||
}
|
||||
|
||||
public static void SaveJObject(JObject jObject, string path)
|
||||
{
|
||||
string json = jObject.ToString();
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
File.WriteAllText(FormatAsJsonPath(path), json);
|
||||
}
|
||||
|
||||
public static void SaveArray<T>(T[] array, string path)
|
||||
{
|
||||
string json = JsonConvert.SerializeObject(array);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
File.WriteAllText(FormatAsJsonPath(path), json);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f152992d42cac4e4fb88e562812b6013
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,505 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4af5cf244c618df42813f45ce20338ea
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 2
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 4096
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Server
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites:
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_0"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 6e493e316235fe542a153d49c625f134
|
||||
internalID: 1719050414
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_1"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 182
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 52cf602c8b89e284b83d131738790d0a
|
||||
internalID: -1164775371
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_2"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 364
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 774324f9c420dc049813cb468abc2594
|
||||
internalID: -1244389054
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_3"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 546
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 2f8c071d9d5fc9849a68a6e64f984b57
|
||||
internalID: -1957662414
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_4"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 728
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 5b29d8093de8b4c4e9c0b66b82deb1ed
|
||||
internalID: -386358468
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_5"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 910
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: d3dc6fe9812df3049bad7f19730fb6ca
|
||||
internalID: -1287565805
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_6"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 1092
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 4bf8ebffad0c6f44e9abb099429e3722
|
||||
internalID: -2040738244
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_7"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 1274
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 3e080f56cdb5b8b48b4b1ccefabc8de9
|
||||
internalID: 1625432532
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_8"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 1456
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 2360c3e26ec123b48ad8357e748b657d
|
||||
internalID: 1848882051
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_9"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 1638
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 8eab2dccbc20b3f4d9a5b0d9f995fc6f
|
||||
internalID: -1381685395
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_10"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 1820
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 92f5a9e142ea3ec4fae5990f3153dd34
|
||||
internalID: -641158983
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_11"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 2002
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: b37db88e2759412468c4b61d6238fd01
|
||||
internalID: -1931024059
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_12"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 2184
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: d485e426994f5ca4c91c6b0256e63f35
|
||||
internalID: -1103357223
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_13"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 2366
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: b377314d703afef4bbb2da26559342e0
|
||||
internalID: 596276626
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_14"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 2548
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 9ef6d368720f1e14796cf8f3d991c4db
|
||||
internalID: 766679972
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: "LOADING \u7F50\u5934_15"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 2730
|
||||
y: 0
|
||||
width: 182
|
||||
height: 222
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 15c7470169f38ed4184bc11b865b772d
|
||||
internalID: 908783198
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable:
|
||||
"LOADING \u7F50\u5934_0": 1719050414
|
||||
"LOADING \u7F50\u5934_1": -1164775371
|
||||
"LOADING \u7F50\u5934_10": -641158983
|
||||
"LOADING \u7F50\u5934_11": -1931024059
|
||||
"LOADING \u7F50\u5934_12": -1103357223
|
||||
"LOADING \u7F50\u5934_13": 596276626
|
||||
"LOADING \u7F50\u5934_14": 766679972
|
||||
"LOADING \u7F50\u5934_15": 908783198
|
||||
"LOADING \u7F50\u5934_2": -1244389054
|
||||
"LOADING \u7F50\u5934_3": -1957662414
|
||||
"LOADING \u7F50\u5934_4": -386358468
|
||||
"LOADING \u7F50\u5934_5": -1287565805
|
||||
"LOADING \u7F50\u5934_6": -2040738244
|
||||
"LOADING \u7F50\u5934_7": 1625432532
|
||||
"LOADING \u7F50\u5934_8": 1848882051
|
||||
"LOADING \u7F50\u5934_9": -1381685395
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,72 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1102 &-6608008813301334011
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: New State
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions: []
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: 7400000, guid: da64c7b441e509c4f8a07f47647dc313, type: 2}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!91 &9100000
|
||||
AnimatorController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Loading
|
||||
serializedVersion: 5
|
||||
m_AnimatorParameters: []
|
||||
m_AnimatorLayers:
|
||||
- serializedVersion: 5
|
||||
m_Name: Base Layer
|
||||
m_StateMachine: {fileID: 3638069603095265619}
|
||||
m_Mask: {fileID: 0}
|
||||
m_Motions: []
|
||||
m_Behaviours: []
|
||||
m_BlendingMode: 0
|
||||
m_SyncedLayerIndex: -1
|
||||
m_DefaultWeight: 0
|
||||
m_IKPass: 0
|
||||
m_SyncedLayerAffectsTiming: 0
|
||||
m_Controller: {fileID: 9100000}
|
||||
--- !u!1107 &3638069603095265619
|
||||
AnimatorStateMachine:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Base Layer
|
||||
m_ChildStates:
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: -6608008813301334011}
|
||||
m_Position: {x: 390, y: 260, z: 0}
|
||||
m_ChildStateMachines: []
|
||||
m_AnyStateTransitions: []
|
||||
m_EntryTransitions: []
|
||||
m_StateMachineTransitions: {}
|
||||
m_StateMachineBehaviours: []
|
||||
m_AnyStatePosition: {x: 50, y: 20, z: 0}
|
||||
m_EntryPosition: {x: 50, y: 120, z: 0}
|
||||
m_ExitPosition: {x: 800, y: 120, z: 0}
|
||||
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
|
||||
m_DefaultState: {fileID: -6608008813301334011}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4efe920582e4eb84eabc738f16624d2b
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 9100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"type": "manual",
|
||||
"layout": {
|
||||
"rows": 1,
|
||||
"columns": 17,
|
||||
"frameCount": 16,
|
||||
"direction": "horizontal"
|
||||
},
|
||||
"frameDuration": 200,
|
||||
"sampleRate": 60,
|
||||
"animations": [
|
||||
{
|
||||
"name": "loading",
|
||||
"frameIndices": [
|
||||
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||||
],
|
||||
"loop": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16afd6b9dee930748902c25e1db009de
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,120 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!74 &7400000
|
||||
AnimationClip:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: loading
|
||||
serializedVersion: 7
|
||||
m_Legacy: 0
|
||||
m_Compressed: 0
|
||||
m_UseHighQualityCurve: 1
|
||||
m_RotationCurves: []
|
||||
m_CompressedRotationCurves: []
|
||||
m_EulerCurves: []
|
||||
m_PositionCurves: []
|
||||
m_ScaleCurves: []
|
||||
m_FloatCurves: []
|
||||
m_PPtrCurves:
|
||||
- serializedVersion: 2
|
||||
curve:
|
||||
- time: 0
|
||||
value: {fileID: 1719050414, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 0.1
|
||||
value: {fileID: -1164775371, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 0.2
|
||||
value: {fileID: -1244389054, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 0.3
|
||||
value: {fileID: -1957662414, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 0.4
|
||||
value: {fileID: -386358468, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 0.5
|
||||
value: {fileID: -1287565805, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 0.6
|
||||
value: {fileID: -2040738244, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 0.7
|
||||
value: {fileID: 1625432532, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 0.8
|
||||
value: {fileID: 1848882051, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 0.9
|
||||
value: {fileID: -1381685395, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 1
|
||||
value: {fileID: -641158983, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 1.1
|
||||
value: {fileID: -1931024059, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 1.2
|
||||
value: {fileID: -1103357223, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 1.3
|
||||
value: {fileID: 596276626, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 1.4
|
||||
value: {fileID: 766679972, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 1.5
|
||||
value: {fileID: 908783198, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- time: 1.6
|
||||
value: {fileID: 1719050414, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
attribute: m_Sprite
|
||||
path:
|
||||
classID: 114
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
flags: 2
|
||||
m_SampleRate: 120
|
||||
m_WrapMode: 0
|
||||
m_Bounds:
|
||||
m_Center: {x: 0, y: 0, z: 0}
|
||||
m_Extent: {x: 0, y: 0, z: 0}
|
||||
m_ClipBindingConstant:
|
||||
genericBindings:
|
||||
- serializedVersion: 2
|
||||
path: 0
|
||||
attribute: 2015549526
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
typeID: 114
|
||||
customType: 0
|
||||
isPPtrCurve: 1
|
||||
isIntCurve: 0
|
||||
isSerializeReferenceCurve: 0
|
||||
pptrCurveMapping:
|
||||
- {fileID: 1719050414, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: -1164775371, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: -1244389054, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: -1957662414, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: -386358468, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: -1287565805, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: -2040738244, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: 1625432532, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: 1848882051, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: -1381685395, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: -641158983, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: -1931024059, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: -1103357223, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: 596276626, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: 766679972, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: 908783198, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
- {fileID: 1719050414, guid: 4af5cf244c618df42813f45ce20338ea, type: 3}
|
||||
m_AnimationClipSettings:
|
||||
serializedVersion: 2
|
||||
m_AdditiveReferencePoseClip: {fileID: 0}
|
||||
m_AdditiveReferencePoseTime: 0
|
||||
m_StartTime: 0
|
||||
m_StopTime: 1.6083333
|
||||
m_OrientationOffsetY: 0
|
||||
m_Level: 0
|
||||
m_CycleOffset: 0
|
||||
m_HasAdditiveReferencePose: 0
|
||||
m_LoopTime: 1
|
||||
m_LoopBlend: 0
|
||||
m_LoopBlendOrientation: 0
|
||||
m_LoopBlendPositionY: 0
|
||||
m_LoopBlendPositionXZ: 0
|
||||
m_KeepOriginalOrientation: 0
|
||||
m_KeepOriginalPositionY: 1
|
||||
m_KeepOriginalPositionXZ: 0
|
||||
m_HeightFromFeet: 0
|
||||
m_Mirror: 0
|
||||
m_EditorCurves: []
|
||||
m_EulerEditorCurves: []
|
||||
m_HasGenericRootTransform: 0
|
||||
m_HasMotionFloatCurves: 0
|
||||
m_Events: []
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da64c7b441e509c4f8a07f47647dc313
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 7400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user