Ship the WeChat hot-update catalogs and the camp, TideWhale T2, UI atlas, and animation-lab work.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
udx
2026-10-24 18:04:41 +08:00
co-authored by Cursor
parent 6ebc9401ce
commit 45e62132c8
1432 changed files with 2971856 additions and 2798 deletions
@@ -0,0 +1,27 @@
using UnityEngine;
namespace HotUpdate.Gameplay
{
/// <summary>Plays Idle or Walk on the camp guide from how far the root moved.</summary>
public sealed class ExplorerLocomotion : MonoBehaviour
{
Animator _animator;
Vector3 _last;
void Awake()
{
_animator = GetComponentInChildren<Animator>();
if (_animator != null) _animator.applyRootMotion = false;
_last = transform.position;
}
void LateUpdate()
{
if (_animator == null) return;
Vector3 delta = transform.position - _last;
_last = transform.position;
float speed = new Vector2(delta.x, delta.z).magnitude / Mathf.Max(Time.deltaTime, 0.0001f);
_animator.SetInteger("Motion", speed > 0.04f ? 1 : 0);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6fc4bdf17f036674c8192f73149401bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -31,18 +31,6 @@ namespace HotUpdate.Gameplay
{
WireNet();
StartCoroutine(EnsureUi());
var plaza = gameObject.AddComponent<TownSquareSpawner>();
plaza.Bind(_ctx);
StartCoroutine(SpawnWorld(plaza));
}
System.Collections.IEnumerator SpawnWorld(TownSquareSpawner plaza)
{
yield return plaza.SpawnCo();
var spawner = gameObject.AddComponent<CharacterSpawner>();
spawner.Bind(_ctx);
spawner.Spawn();
}
System.Collections.IEnumerator EnsureUi()
@@ -57,6 +45,11 @@ namespace HotUpdate.Gameplay
_hud = hudGo != null ? hudGo.GetComponent<MainHudView>() : null;
if (_hud == null && hudGo != null)
_hud = hudGo.AddComponent<MainHudView>();
if (_hud == null)
{
if (_ctx != null) _ctx.MainUiError = "主界面资源加载失败,请检查 Art 资源包";
yield break;
}
_hud?.Bind();
_hud?.SetStatus(_maintenanceLock ? "服务器维护中" : FriendlyStatus(_net?.Status));
_hud?.SetPid(_net?.Session?.Pid ?? 0);
@@ -66,6 +59,8 @@ namespace HotUpdate.Gameplay
_hud.OnReconnectClicked += () => _net?.RequestReconnect();
_hud.OnHomeActionClicked += ShowHomeFeature;
}
if (_ctx != null) _ctx.MainUiReady = true;
Debug.Log("[UI] Main HUD ready");
GameObject dlgGo = null;
yield return mgr.OpenAsync(ConfirmDialogView.PrefabName, go => dlgGo = go);
@@ -329,6 +329,12 @@ namespace HotUpdate.Gameplay
{
yield return Renew(body, session.Token, done); yield break;
}
if (req.responseCode == 404)
{
Debug.LogError("[GameApi] Gameplay endpoint missing (HTTP 404): " + req.url);
done(null, "service_not_ready");
yield break;
}
PrototypeReply reply = null;
try { reply = JsonUtility.FromJson<PrototypeReply>(req.downloadHandler.text); }
catch (Exception) { /* A partial/malformed response leaves the durable request untouched. */ }
@@ -27,7 +27,11 @@ namespace HotUpdate.Gameplay
Go = go;
_texts = go.GetComponentsInChildren<TextMeshProUGUI>(true).ToDictionary(t => t.name);
_buttons = go.GetComponentsInChildren<Button>(true).ToDictionary(t => t.name);
_nodes = go.GetComponentsInChildren<Transform>(true).ToDictionary(t => t.name);
// TMP creates one submesh per label/material. Those rendering-only
// children share names across labels and are not authored UI bindings.
_nodes = go.GetComponentsInChildren<Transform>(true)
.Where(t => t.GetComponent(typeof(TMP_SubMeshUI)) == null)
.ToDictionary(t => t.name);
}
public void Text(string name, string value) { _texts["Txt_" + name].text = value; }
public Button Button(string name) => _buttons["Btn_" + name];
@@ -127,6 +131,7 @@ namespace HotUpdate.Gameplay
{
switch (code)
{
case "service_not_ready": return "游戏服务暂不可用,请稍后重试。";
case "insufficient_balls": return "弹珠不足。每10分钟自然恢复一枚,也可领取每日任务、签到和免费补给。";
case "mail_not_found": return "这封邮件已不可用,请刷新后重试。";
case "mail_expired": return "邮件已到期,附件无法领取。";
@@ -191,7 +196,7 @@ namespace HotUpdate.Gameplay
case "shop_limit": return "今天的这份补给已经领完或买完,明天零点刷新。";
case "goods_locked": return "请先通过商品上标注的关卡。";
case "invalid_goods": return "商品暂不可用,请重新打开商店。";
default: return "暂时无法连接游戏服务,请检查本地 AIServer 是否已更新并启动。";
default: return "暂时无法连接游戏服务,请检查网络后重试。";
}
}
void Apply(PrototypeReply r)