1
This commit is contained in:
@@ -583,7 +583,7 @@ PrefabInstance:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 22400762, guid: 67117722a812a2e46ab8cb8eafbf5f5e, type: 3}
|
||||
propertyPath: m_AnchoredPosition.y
|
||||
value: -0.0000076293945
|
||||
value: -0.000015258789
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 22426080, guid: 67117722a812a2e46ab8cb8eafbf5f5e, type: 3}
|
||||
propertyPath: m_AnchorMax.x
|
||||
|
||||
@@ -322,6 +322,17 @@ namespace Assets.MyGame.Scripts.Net
|
||||
APIManager.Response<int>(APIType.Hall_GetChessRoomPartitionCount, callback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 大喇叭消息标识字符(预留位):发送大喇叭时拼在正文最前面。
|
||||
/// 接收端(WebSocketReponseList.LoginBroadcast)凭首字符识别为大喇叭,再补上
|
||||
/// "喇叭图标+打码昵称"前缀渲染;普通公告不带此字符,原样显示。
|
||||
/// 如需更换标识只改这里(前后端需一致)。
|
||||
/// </summary>
|
||||
public const char BroadcastMarker = '§';
|
||||
|
||||
/// <summary>大喇叭正文最大字数:后端整条广播限制20字,标识占1字,故正文最多19字</summary>
|
||||
public const int BroadcastMaxContentLength = 19;
|
||||
|
||||
/// <summary>
|
||||
/// 发送全服广播(GET /api/Hall/SendBroadcast?message=xxx)
|
||||
/// 返回:string
|
||||
|
||||
@@ -726,11 +726,39 @@ namespace Assets.MyGame.Scripts.Net
|
||||
|
||||
/// <summary>
|
||||
/// LoginHub Broadcast — 大厅公告广播
|
||||
/// 首字符命中大喇叭标识(APIRequestList.BroadcastMarker)时按大喇叭格式渲染:
|
||||
/// 去掉标识,补"喇叭图标+打码昵称"前缀;否则原样显示为普通公告。
|
||||
/// </summary>
|
||||
public static void LoginBroadcast(string msg)
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<LoginBroadcastData>>(msg).arguments[0];
|
||||
UIManager.Instance.ShowBoardGongGao(data.message);
|
||||
string message = data?.message;
|
||||
|
||||
if (!string.IsNullOrEmpty(message) && message[0] == APIRequestList.BroadcastMarker)
|
||||
{
|
||||
// 大喇叭:服务端只存了"标识+正文",昵称从广播数据取,展示时再拼接前缀
|
||||
string content = message.Substring(1);
|
||||
string userName = data.userName;
|
||||
if (string.IsNullOrEmpty(userName)) userName = "玩家";
|
||||
UIManager.Instance.ShowBoardGongGao($"<sprite index=0>【{MaskBroadcastName(userName)}】:{content}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 普通公告:原样显示
|
||||
UIManager.Instance.ShowBoardGongGao(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 玩家名打码(大喇叭展示格式):保留首尾字符、中间一个 *("小金鱼"→"小*鱼")。
|
||||
/// 与 GameMainPanel_FishBase / UIHome_BY_BackPackPanel 同格式。
|
||||
/// </summary>
|
||||
private static string MaskBroadcastName(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name)) return name;
|
||||
name = name.Trim();
|
||||
if (name.Length <= 1) return name;
|
||||
return name[0] + "*" + name[name.Length - 1];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -12,6 +12,24 @@ public class LoadingPanel : MonoBehaviour
|
||||
public Image image_Bg;
|
||||
public Action actionEnd;
|
||||
public float fadeTime = 1.3f;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// ⭐ 视频播放期间预载大厅主面板:把 HomeUIRes 的加载提前到这段视频等待时间里,
|
||||
// 登录成功 UILoginPanel.Succeed() 的 ShowAsync(HomeMainPanel) 命中缓存秒开,
|
||||
// 不再出现"登录成功后进大厅白等"。
|
||||
StartCoroutine(PreloadHomeMainRoutine());
|
||||
}
|
||||
|
||||
/// <summary>预载大厅主面板:等 UIManager 就绪后发起(视频这段时间足够 HomeUIRes 加载完)</summary>
|
||||
private IEnumerator PreloadHomeMainRoutine()
|
||||
{
|
||||
while (UIManager.Instance == null)
|
||||
yield return null;
|
||||
yield return null; // 等 UIManager 初始化完成(地址表装载)
|
||||
UIManager.Instance.PreloadPanel(UIPanel.HomeMainPanel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 进入条进度值
|
||||
/// </summary>
|
||||
@@ -20,6 +38,9 @@ public class LoadingPanel : MonoBehaviour
|
||||
{
|
||||
if (count == 100)
|
||||
{
|
||||
// ⭐ 兜底再预载一次:若启动时 UIManager 尚未就绪导致首次发起无效,这里补上
|
||||
if (UIManager.Instance != null)
|
||||
UIManager.Instance.PreloadPanel(UIPanel.HomeMainPanel);
|
||||
GameManager.Instance.btn_Skip.gameObject.SetActive(false);
|
||||
Destroy(gameObject, fadeTime);
|
||||
if (player.gameObject.activeSelf)
|
||||
|
||||
@@ -722,6 +722,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
obj_DaLaBaPanel.SetActive(!obj_DaLaBaPanel.activeSelf);
|
||||
});
|
||||
}
|
||||
// 大喇叭正文限长:后端整条广播≤20字,标识占1字,输入框直接限制19字
|
||||
if (tmp_DaLaBaInput != null)
|
||||
tmp_DaLaBaInput.characterLimit = APIRequestList.BroadcastMaxContentLength;
|
||||
if (btn_DaLaBaSend != null)
|
||||
{
|
||||
btn_DaLaBaSend.onClick.RemoveAllListeners();
|
||||
@@ -1296,30 +1299,35 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
UIManager.Instance.ReleaseHomeUI();
|
||||
SetLoadProgress(0.02f);
|
||||
|
||||
// 路线:2~30(路线文本可能和鱼资源同一个大包,解压耗时由回调实时反映)
|
||||
// 路线:2~30(大包同步解压期间回调不刷新 → 预估进度保证条持续推进)
|
||||
StartCreepProgress(0.02f, 0.30f);
|
||||
await MonsterMoveLine.LoadBezier(p =>
|
||||
{
|
||||
if (flow == _resourceFlowToken) SetLoadProgress(Mathf.Lerp(0.02f, 0.30f, p));
|
||||
if (flow == _resourceFlowToken) SetLoadProgress(Mathf.Max(_loadProgress, Mathf.Lerp(0.02f, 0.30f, p)));
|
||||
});
|
||||
if (flow != _resourceFlowToken) return; // ⭐ 期间已退出/切换,本轮作废
|
||||
|
||||
// 鱼包:30~60,内部子进度实时上报(残留流程不再写面板)
|
||||
// 鱼包:30~60,内部子进度实时上报(预估进度兜底 LZMA 解压阻塞段,不再卡在 30)
|
||||
StartCreepProgress(0.30f, 0.60f);
|
||||
await FishResourcesData.LoadFishAssetsData(p =>
|
||||
{
|
||||
if (flow == _resourceFlowToken) SetLoadProgress(Mathf.Lerp(0.30f, 0.60f, p));
|
||||
if (flow == _resourceFlowToken) SetLoadProgress(Mathf.Max(_loadProgress, Mathf.Lerp(0.30f, 0.60f, p)));
|
||||
});
|
||||
if (flow != _resourceFlowToken) return;
|
||||
|
||||
// 玩法音频:60~78
|
||||
StartCreepProgress(0.60f, 0.78f);
|
||||
await AudioResourcesData.LoadAudioGame(p =>
|
||||
{
|
||||
if (flow == _resourceFlowToken) SetLoadProgress(Mathf.Lerp(0.60f, 0.78f, p));
|
||||
if (flow == _resourceFlowToken) SetLoadProgress(Mathf.Max(_loadProgress, Mathf.Lerp(0.60f, 0.78f, p)));
|
||||
});
|
||||
if (flow != _resourceFlowToken) return;
|
||||
|
||||
// ⭐ 开火音效 PW_Shoot 在 Default Local Group(Audio+PTCBZS 双标签交集检索):
|
||||
// 只命中 Default 小包,不把其它玩法的巨型音频包拉进内存;句柄由 LoadBulletClip 静态保存,离房释放
|
||||
StartCreepProgress(0.78f, 0.84f);
|
||||
await LoadBulletClip();
|
||||
StopCreepProgress();
|
||||
if (flow != _resourceFlowToken) return;
|
||||
SetLoadProgress(0.84f);
|
||||
if (_bulletClipHandle.IsValid() && _bulletClipHandle.Result != null)
|
||||
@@ -1725,12 +1733,48 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
/// <summary>加载段进度写入:切换房间时映射到合并进度条后半段(55~100%),平时直接写面板进度条</summary>
|
||||
private void SetLoadProgress(float p)
|
||||
{
|
||||
p = Mathf.Clamp01(p);
|
||||
_loadProgress = p;
|
||||
if (_changeRoomBar != null)
|
||||
_changeRoomBar.SetProgress(0.55f + p * 0.45f);
|
||||
else if (JinDuTiao != null)
|
||||
JinDuTiao.SetProgress(p);
|
||||
}
|
||||
|
||||
// ---- 预估进度(大包 LZMA 同步解压期间主线程阻塞、回调不刷新 → 条卡死像没响应)----
|
||||
/// <summary>加载进度当前值(真实或预估),预估推进时判断不回退</summary>
|
||||
private float _loadProgress = 0f;
|
||||
private Coroutine _creepRoutine;
|
||||
|
||||
/// <summary>
|
||||
/// 预估进度:等待段内按时间指数逼近"段末-2%",真实进度回调以更大值覆盖。
|
||||
/// 加载完成时直接跳到真实位置,全程条和数字都在动,不会出现"卡住不动"的假死感。
|
||||
/// </summary>
|
||||
private void StartCreepProgress(float from, float to)
|
||||
{
|
||||
StopCreepProgress();
|
||||
if (isActiveAndEnabled) _creepRoutine = StartCoroutine(CreepProgressRoutine(from, to));
|
||||
}
|
||||
|
||||
private void StopCreepProgress()
|
||||
{
|
||||
if (_creepRoutine != null) { StopCoroutine(_creepRoutine); _creepRoutine = null; }
|
||||
}
|
||||
|
||||
private IEnumerator CreepProgressRoutine(float from, float to)
|
||||
{
|
||||
float cap = Mathf.Max(from, to - 0.02f);
|
||||
float elapsed = 0f;
|
||||
while (true)
|
||||
{
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
elapsed += 0.1f;
|
||||
// 指数逼近:前 2.5 秒走完区间约 63%,越接近段末越慢,不会超过 cap
|
||||
float creep = Mathf.Lerp(from, cap, 1f - Mathf.Exp(-elapsed / 2.5f));
|
||||
if (creep > _loadProgress) SetLoadProgress(creep);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>写切换房间合并进度条(网络段:QuickJoin返回/JoinRoom已发送)</summary>
|
||||
private static void SetChangeRoomBarProgress(float p)
|
||||
{
|
||||
@@ -2045,16 +2089,20 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
UIManager.Instance.ShowBoardError("请输入广播内容");
|
||||
return;
|
||||
}
|
||||
// ⭐ 后端整条广播限制20字,标识字符占1字,正文最多19字
|
||||
if (msg.Length > APIRequestList.BroadcastMaxContentLength)
|
||||
{
|
||||
UIManager.Instance.ShowBoardError($"广播内容不能超过{APIRequestList.BroadcastMaxContentLength}个字");
|
||||
return;
|
||||
}
|
||||
|
||||
_isSendingDaLaBa = true;
|
||||
// ⭐ 超时兜底:后端拒绝(字数超限等)时没有回调,靠超时复位防重入标志
|
||||
if (_daLaBaTimeoutRoutine != null) StopCoroutine(_daLaBaTimeoutRoutine);
|
||||
_daLaBaTimeoutRoutine = StartCoroutine(ResetDaLaBaFlagAfterTimeout());
|
||||
|
||||
// ⭐ 显示格式:"<sprite index=0>【小*鱼】:内容"(前面加喇叭图标 TMP 标签;名字打码:首尾保留、中间一个 *)
|
||||
var userName = GameManager.Instance.user?.BaseInfo?.userName;
|
||||
if (string.IsNullOrEmpty(userName)) userName = "玩家";
|
||||
APIRequestList.SendBroadcast($"<sprite index=0>【{MaskBroadcastName(userName)}】:{msg}", (result) =>
|
||||
// ⭐ 只发"标识字符+正文":喇叭图标与打码昵称由接收端(LoginBroadcast)统一补上
|
||||
APIRequestList.SendBroadcast(APIRequestList.BroadcastMarker + msg, (result) =>
|
||||
{
|
||||
// 成功:停掉超时协程并复位标志
|
||||
if (_daLaBaTimeoutRoutine != null)
|
||||
@@ -2085,18 +2133,6 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
_daLaBaTimeoutRoutine = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 玩家名打码(广播格式):保留首尾字符、中间一个 *("小金鱼"→"小*鱼"、"我是大帅哥"→"我*哥")。
|
||||
/// 与召唤卡提示的 MaskUserName(三个星)区分,广播用单星。
|
||||
/// </summary>
|
||||
private static string MaskBroadcastName(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name)) return name;
|
||||
name = name.Trim();
|
||||
if (name.Length <= 1) return name;
|
||||
return name[0] + "*" + name[name.Length - 1];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用召唤卡:从背包找到召唤卡道具(type=11)拿道具编号
|
||||
/// → /api/SummonCard/use 召唤Boss(Boss鱼由服务端 OnFishSpawn 下发给房间所有人)
|
||||
|
||||
@@ -71,6 +71,9 @@ public class UIHome_BY_BackPackPanel : SubUIBase
|
||||
// 大喇叭
|
||||
if (DaLaBaPanel != null)
|
||||
DaLaBaPanel.SetActive(false);
|
||||
// 大喇叭正文限长:后端整条广播≤20字,标识占1字,输入框直接限制19字
|
||||
if (tMPText_DaLaBaLabel != null)
|
||||
tMPText_DaLaBaLabel.characterLimit = APIRequestList.BroadcastMaxContentLength;
|
||||
if (btn_FaSong != null)
|
||||
{
|
||||
// ⭐ 先清再绑:防止面板重复 Show 叠加监听器(点一次发 N 次 = 多扣 N 个大喇叭)
|
||||
@@ -170,16 +173,20 @@ public class UIHome_BY_BackPackPanel : SubUIBase
|
||||
UIManager.Instance.ShowBoardError("请输入广播内容");
|
||||
return;
|
||||
}
|
||||
// ⭐ 后端整条广播限制20字,标识字符占1字,正文最多19字
|
||||
if (content.Length > APIRequestList.BroadcastMaxContentLength)
|
||||
{
|
||||
UIManager.Instance.ShowBoardError($"广播内容不能超过{APIRequestList.BroadcastMaxContentLength}个字");
|
||||
return;
|
||||
}
|
||||
|
||||
_isSendingFaSong = true;
|
||||
// ⭐ 超时兜底:后端拒绝(字数超限等)时没有回调,靠超时复位防重入标志
|
||||
if (_faSongTimeoutRoutine != null) StopCoroutine(_faSongTimeoutRoutine);
|
||||
_faSongTimeoutRoutine = StartCoroutine(ResetFaSongFlagAfterTimeout());
|
||||
|
||||
// ⭐ 显示格式:"<sprite index=0>【小*鱼】:内容"(前面加喇叭图标 TMP 标签;名字打码与游戏内大喇叭同格式)
|
||||
var userName = GameManager.Instance.user?.BaseInfo?.userName;
|
||||
if (string.IsNullOrEmpty(userName)) userName = "玩家";
|
||||
APIRequestList.SendBroadcast($"<sprite index=0>【{MaskBroadcastName(userName)}】:{content}", (result) =>
|
||||
// ⭐ 只发"标识字符+正文":喇叭图标与打码昵称由接收端(LoginBroadcast)统一补上
|
||||
APIRequestList.SendBroadcast(APIRequestList.BroadcastMarker + content, (result) =>
|
||||
{
|
||||
// 成功:停掉超时协程并复位标志
|
||||
if (_faSongTimeoutRoutine != null)
|
||||
@@ -207,18 +214,6 @@ public class UIHome_BY_BackPackPanel : SubUIBase
|
||||
_faSongTimeoutRoutine = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 玩家名打码(广播格式):保留首尾字符、中间一个 *("小金鱼"→"小*鱼")。
|
||||
/// 与 GameMainPanel_FishBase.MaskBroadcastName 同格式(背包面板独立副本)。
|
||||
/// </summary>
|
||||
private static string MaskBroadcastName(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name)) return name;
|
||||
name = name.Trim();
|
||||
if (name.Length <= 1) return name;
|
||||
return name[0] + "*" + name[name.Length - 1];
|
||||
}
|
||||
|
||||
private void OnClickConfirmChangeName()
|
||||
{
|
||||
string newName = tMPText_NewName?.text?.Trim();
|
||||
|
||||
Reference in New Issue
Block a user