加入了浮动小游戏功能和设置界面

运行时请手动修改运行库目录fdBrowser
This commit is contained in:
FloatGaming
2025-12-24 06:02:06 +08:00
parent 1ab80e504e
commit eb9b6ba78a
1131 changed files with 148096 additions and 313 deletions
@@ -0,0 +1,230 @@
using UnityEngine;
using System.IO;
using System.Collections.Generic;
using System.Xml;
public class loadLittleGamesPrefab : MonoBehaviour
{
[Header("Scroll Views")]
public GameObject officialDocs_scrollView_content;
public GameObject officialGames_scrollView_content;
public GameObject thirdPartyGames_scrollView_content;
[Header("Prefab")]
public GameObject littleGames_card_Prefab;
[Header("H5 Root Path (optional, leave empty to use WebViewLauncher settings)")]
public string h5RootPath;
void Start()
{
LoadAllLittleGames();
}
/// <summary>
/// 在 WebViewLauncher 的 h5 目录下扫描 three categories 的所有子文件夹(递归一层),
/// 找到含有 index.html 的目录(例如: ...\h5LG\_thirdPartyGames\kjb\index.html),
/// 读取同目录下的 info.xml(如果存在),并把 prefab 实例化到对应的 content 中。
///
/// info.xml 示例格式(放在同目录下,编码 UTF-8):
/// <?xml version="1.0" encoding="utf-8"?>
/// <Info>
/// <card_name>示例游戏名</card_name>
/// <authorName>作者名</authorName>
/// <description>这里是描述文本</description>
/// <isOfficial>True</isOfficial>
/// <source>来源信息</source>
/// <yyyy_mm_dd>2025-12-23</yyyy_mm_dd>
/// </Info>
///
/// 请保证节点名如上所示以便能被正确读取。
/// </summary>
public void LoadAllLittleGames()
{
string root = GetH5RootPath();
if (string.IsNullOrEmpty(root) || !Directory.Exists(root))
{
Debug.LogWarning("H5 root path not found: " + root);
return;
}
// 目标一级子目录名称(与 WebViewLauncher 中保持一致)
string[] categories = { "_officialDocs", "_officialGames", "_thirdPartyGames" };
foreach (string cat in categories)
{
string catPath = Path.Combine(root, cat);
if (!Directory.Exists(catPath))
continue;
// 遍历 catPath 下的第一层子目录,检查是否含有 index.html
string[] subdirs = Directory.GetDirectories(catPath);
foreach (string subdir in subdirs)
{
string indexPath = Path.Combine(subdir, "index.html");
if (!File.Exists(indexPath))
{
// 也可能 index.html 在更深一层,但按照约定通常是 subdir/index.html
continue;
}
// 读取 info.xml(可选)
string infoXmlPath = Path.Combine(subdir, "info.xml");
var meta = ReadInfoXml(infoXmlPath);
// 根据分类选择目标 content
GameObject targetContent = GetContentByCategory(cat);
if (targetContent == null || littleGames_card_Prefab == null)
{
Debug.LogWarning("Missing prefab or content for category: " + cat);
continue;
}
// 实例化 prefab
GameObject go = Instantiate(littleGames_card_Prefab, targetContent.transform);
// 设置数据(indexPath 使用本地文件绝对路径)
string absIndexPath = indexPath; // 使用绝对路径,WebViewLauncher.OpenUrl 会添加 file://
var prefabComp = go.GetComponent<game_card_Prefab>();
if (prefabComp != null)
{
// 若来自官方分类,覆盖 isOfficial 与 source 字段为固定值
string finalIsOfficial = meta.GetValueOrDefault("isOfficial");
string finalSource = meta.GetValueOrDefault("source");
if (cat == "_officialDocs" || cat == "_officialGames")
{
finalIsOfficial = "官方";
finalSource = "小游戏DLC";
}
else
{
// 非官方分类统一标记为第三方来源
finalIsOfficial = "第三方来源";
// 若 info.xml 没有 source,则可以保留原值或设置默认,这里若无则为空
if (string.IsNullOrEmpty(finalSource))
finalSource = "";
}
// 格式化日期为 yyyy\nmm\ndd 的形式
string rawDate = meta.GetValueOrDefault("yyyy_mm_dd");
string formattedDate = FormatDateWithNewlines(rawDate);
prefabComp.SetData(absIndexPath,
meta.GetValueOrDefault("card_name"),
meta.GetValueOrDefault("authorName"),
meta.GetValueOrDefault("description"),
finalIsOfficial,
finalSource,
formattedDate
);
}
}
}
}
string GetH5RootPath()
{
if (!string.IsNullOrEmpty(h5RootPath) && Directory.Exists(h5RootPath))
return h5RootPath;
// 从 WebViewLauncher 获取编辑器路径
var w = GameObject.FindObjectOfType<WebViewLauncher>();
if (w != null)
{
#if UNITY_EDITOR
return w.h5EditorPath;
#else
return Path.Combine(Application.streamingAssetsPath, "h5LG");
#endif
}
// 作为回退,使用 StreamingAssets/h5LG
return Path.Combine(Application.streamingAssetsPath, "h5LG");
}
GameObject GetContentByCategory(string categoryName)
{
switch (categoryName)
{
case "_officialDocs": return officialDocs_scrollView_content;
case "_officialGames": return officialGames_scrollView_content;
case "_thirdPartyGames": return thirdPartyGames_scrollView_content;
default: return null;
}
}
Dictionary<string, string> ReadInfoXml(string xmlPath)
{
var dict = new Dictionary<string, string>();
if (string.IsNullOrEmpty(xmlPath) || !File.Exists(xmlPath))
return dict;
try
{
var doc = new XmlDocument();
doc.Load(xmlPath);
var root = doc.DocumentElement;
if (root == null)
return dict;
// 读取预定义字段
string[] keys = { "card_name", "authorName", "description", "isOfficial", "source", "yyyy_mm_dd" };
foreach (var k in keys)
{
var node = root.SelectSingleNode(k);
if (node != null)
dict[k] = node.InnerText;
}
}
catch (System.Exception e)
{
Debug.LogWarning("Failed to read info.xml: " + xmlPath + " error: " + e.Message);
}
return dict;
}
// 将日期文本尝试解析成 yyyy\nmm\ndd 格式,若解析失败则做简单替换(支持 2025-12-23, 2025/12/23, 2025_12_23, 20251223 等)
string FormatDateWithNewlines(string raw)
{
if (string.IsNullOrEmpty(raw))
return "";
// 尝试按常见分隔符拆分
char[] seps = new char[] { '-', '/', '_', ' ' };
var parts = raw.Split(seps, System.StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 3)
{
return parts[0] + "\n" + parts[1] + "\n" + parts[2];
}
// 尝试连续数字 8 位
var digits = System.Text.RegularExpressions.Regex.Replace(raw, "\\D", "");
if (digits.Length == 8)
{
string y = digits.Substring(0, 4);
string m = digits.Substring(4, 2);
string d = digits.Substring(6, 2);
return y + "\n" + m + "\n" + d;
}
// 回退:尝试用第一个 4 位作为年,接下来的两位为月,之后为日
if (digits.Length >= 6)
{
string y = digits.Substring(0, 4);
string m = digits.Length >= 6 ? digits.Substring(4, 2) : "";
string d = digits.Length >= 8 ? digits.Substring(6, 2) : "";
return y + "\n" + m + "\n" + d;
}
// 最后回退直接把原文本按字符换行(有限长度)
return raw.Replace("-", "\n").Replace("/", "\n").Replace("_", "\n");
}
// Update is called once per frame
void Update()
{
}
}