技能主要更新,修复卡顿并加入动画,以及各种其他更新。

This commit is contained in:
FloatGaming
2026-02-07 21:05:17 +08:00
parent abeca51be5
commit 1ac3cd0104
1349 changed files with 1526749 additions and 24850 deletions
+293
View File
@@ -0,0 +1,293 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
[Serializable]
public class UI_FunctionHoverEntry
{
public string path;
[TextArea(2, 6)]
public string text;
public string iconPath;
public Sprite icon;
}
[CreateAssetMenu(menuName = "UI/Function Hover Config", fileName = "UI_FunctionHoverConfig")]
public class UI_FunctionHoverConfig : ScriptableObject
{
public List<UI_FunctionHoverEntry> entries = new List<UI_FunctionHoverEntry>();
#if UNITY_EDITOR
[ContextMenu("Import From 素材/指向")]
private void ImportFromDefaultFile()
{
ImportFromFile("素材/指向");
}
[ContextMenu("Import From UI_FunctionHoverConfig.json")]
private void ImportFromDefaultJson()
{
ImportFromJsonFile("Assets/Resources/UI_FunctionHoverConfig.json");
}
public void ImportFromFile(string relativePath)
{
if (string.IsNullOrEmpty(relativePath)) return;
string fullPath = Path.Combine(Application.dataPath, "..", relativePath);
if (!File.Exists(fullPath))
{
Debug.LogWarning("UI_FunctionHoverConfig: file not found: " + fullPath);
return;
}
string content = File.ReadAllText(fullPath, Encoding.UTF8);
var parsed = ParseConfig(content);
if (parsed.Count > 0)
{
entries = parsed;
EditorUtility.SetDirty(this);
AssetDatabase.SaveAssets();
}
}
public void ImportFromJsonFile(string relativePath)
{
if (string.IsNullOrEmpty(relativePath)) return;
string fullPath = Path.Combine(Application.dataPath, "..", relativePath);
if (!File.Exists(fullPath))
{
Debug.LogWarning("UI_FunctionHoverConfig: json not found: " + fullPath);
return;
}
string content = File.ReadAllText(fullPath, Encoding.UTF8);
var parsed = ParseJson(content);
if (parsed.Count > 0)
{
entries = parsed;
EditorUtility.SetDirty(this);
AssetDatabase.SaveAssets();
}
}
#endif
private static List<UI_FunctionHoverEntry> ParseConfig(string content)
{
var result = new List<UI_FunctionHoverEntry>();
if (string.IsNullOrEmpty(content)) return result;
var blocks = content.Split(new[] { "\r\n\r\n", "\n\n" }, StringSplitOptions.RemoveEmptyEntries);
foreach (var block in blocks)
{
string pathLine = null;
string textLine = null;
string iconLine = null;
var lines = block.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
if (line.StartsWith("路径")) pathLine = line;
else if (line.StartsWith("文本")) textLine = line;
else if (line.StartsWith("显示icon")) iconLine = line;
}
if (pathLine == null || textLine == null) continue;
string pathsRaw = GetValueAfterColon(pathLine);
string text = GetValueAfterColon(textLine);
string iconPath = iconLine != null ? GetValueAfterColon(iconLine) : null;
var paths = SplitPaths(pathsRaw);
var icon = LoadIcon(iconPath);
foreach (var p in paths)
{
if (string.IsNullOrWhiteSpace(p)) continue;
result.Add(new UI_FunctionHoverEntry
{
path = p.Trim(),
text = text,
iconPath = iconPath,
icon = icon
});
}
}
return result;
}
[Serializable]
private class JsonRoot
{
public List<JsonEntry> entries;
}
[Serializable]
private class JsonEntry
{
public List<string> paths;
public string text;
public string icon;
}
private static List<UI_FunctionHoverEntry> ParseJson(string content)
{
var result = new List<UI_FunctionHoverEntry>();
if (string.IsNullOrEmpty(content)) return result;
JsonRoot root = null;
try
{
root = JsonUtility.FromJson<JsonRoot>(content);
}
catch
{
root = null;
}
if (root == null || root.entries == null) return result;
for (int i = 0; i < root.entries.Count; i++)
{
var entry = root.entries[i];
if (entry == null || entry.paths == null) continue;
Sprite icon = LoadIcon(entry.icon);
for (int p = 0; p < entry.paths.Count; p++)
{
var path = entry.paths[p];
if (string.IsNullOrWhiteSpace(path)) continue;
result.Add(new UI_FunctionHoverEntry
{
path = path.Trim(),
text = entry.text,
iconPath = entry.icon,
icon = icon
});
}
}
return result;
}
private static string GetValueAfterColon(string line)
{
int idx = line.IndexOf('');
if (idx < 0) idx = line.IndexOf(':');
if (idx < 0) return line.Trim();
return line.Substring(idx + 1).Trim();
}
private static string[] SplitPaths(string raw)
{
if (string.IsNullOrEmpty(raw)) return Array.Empty<string>();
string tmp = raw.Replace("和", "|")
.Replace("、", "|")
.Replace("", "|")
.Replace(",", "|")
.Replace(";", "|")
.Replace("", "|");
return tmp.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
}
private static Sprite LoadIcon(string iconPath)
{
if (string.IsNullOrWhiteSpace(iconPath)) return null;
string path = NormalizeAssetPath(iconPath);
if (!path.StartsWith("Assets", StringComparison.OrdinalIgnoreCase))
path = "Assets/" + path;
#if UNITY_EDITOR
Sprite direct = TryLoadByPath(path);
if (direct != null) return direct;
string name = Path.GetFileName(path);
string folder = Path.GetDirectoryName(path);
List<string> searchFolders = new List<string>();
if (!string.IsNullOrEmpty(folder) && Directory.Exists(Path.Combine(Application.dataPath, "..", folder)))
searchFolders.Add(folder);
string uiUiFolder = "Assets/artworks/UI_UI";
if (Directory.Exists(Path.Combine(Application.dataPath, "..", uiUiFolder)))
searchFolders.Add(uiUiFolder);
string artworksFolder = "Assets/artworks";
if (Directory.Exists(Path.Combine(Application.dataPath, "..", artworksFolder)))
searchFolders.Add(artworksFolder);
string[] folders = searchFolders.Count > 0 ? searchFolders.ToArray() : null;
var guids = AssetDatabase.FindAssets(name + " t:Sprite", folders);
if (guids.Length == 0)
guids = AssetDatabase.FindAssets(name + " t:Texture2D", folders);
if (guids.Length > 0)
{
string best = PickBestAssetPath(guids, name, folder);
var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(best);
if (sprite != null) return sprite;
var tex = AssetDatabase.LoadAssetAtPath<Texture2D>(best);
if (tex != null)
return Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f));
}
#endif
return null;
}
private static string NormalizeAssetPath(string raw)
{
if (string.IsNullOrWhiteSpace(raw)) return string.Empty;
string path = raw.Replace('>', '/').Replace('\\', '/').Trim();
path = path.Replace("Ul_Ul", "UI_UI");
path = path.Replace("", " (").Replace("", ")");
path = path.Replace(" ", " ").Trim();
return path;
}
#if UNITY_EDITOR
private static Sprite TryLoadByPath(string path)
{
if (string.IsNullOrWhiteSpace(path)) return null;
string[] candidates = path.IndexOf('.') >= 0
? new[] { path }
: new[]
{
path + ".png",
path + ".jpg",
path + ".jpeg"
};
for (int i = 0; i < candidates.Length; i++)
{
string p = candidates[i];
var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(p);
if (sprite != null) return sprite;
var tex = AssetDatabase.LoadAssetAtPath<Texture2D>(p);
if (tex != null)
return Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f));
}
return null;
}
private static string PickBestAssetPath(string[] guids, string name, string preferredFolder)
{
if (guids == null || guids.Length == 0) return null;
string best = AssetDatabase.GUIDToAssetPath(guids[0]);
if (guids.Length == 1) return best;
string preferredLower = (preferredFolder ?? string.Empty).Replace('\\', '/').ToLowerInvariant();
string uiUiFolder = "assets/artworks/ui_ui";
for (int i = 0; i < guids.Length; i++)
{
string path = AssetDatabase.GUIDToAssetPath(guids[i]);
if (string.IsNullOrEmpty(path)) continue;
string lower = path.ToLowerInvariant();
if (!string.IsNullOrEmpty(preferredLower) && lower.Contains(preferredLower))
return path;
if (lower.Contains(uiUiFolder))
best = path;
}
return best;
}
#endif
}