Files
bansonic_beta_main/Assets/scripts/UI/UI_FunctionHoverConfig.cs
T

294 lines
9.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}