From 63ef1f9e191e53e77f1fef52adfb38d5df9d4d8b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=A3=AE2003?= <2384017988@qq.com>
Date: Fri, 3 Jul 2026 18:55:56 +0800
Subject: [PATCH] 1
---
Assets/MyGame/Scenes/UIScene.unity | 22 ++---
.../Scripts/Items/Bullits/BullitMove.cs | 25 ++++++
.../Net/APIRequest/Params/HallRequest.cs | 7 ++
.../MyGame/Scripts/Net/APIRequestList_Hall.cs | 5 +-
.../Scripts/Net/APIResponses/HallResponses.cs | 21 +++++
.../aa/UI/Game/GameMainPanel_FishBase.cs | 86 ++++++++++++++++---
.../MyGame/aa/UI/Home/Sub/ZhanLing_Panel.cs | 25 ++++--
7 files changed, 154 insertions(+), 37 deletions(-)
diff --git a/Assets/MyGame/Scenes/UIScene.unity b/Assets/MyGame/Scenes/UIScene.unity
index e2d2470c8..d9036957e 100644
--- a/Assets/MyGame/Scenes/UIScene.unity
+++ b/Assets/MyGame/Scenes/UIScene.unity
@@ -5552,11 +5552,6 @@ PrefabInstance:
serializedVersion: 3
m_TransformParent: {fileID: 1096182889}
m_Modifications:
- - target: {fileID: 2189820374461339302, guid: f206f68250e35c54481406a83c165790,
- type: 3}
- propertyPath: m_IsActive
- value: 0
- objectReference: {fileID: 0}
- target: {fileID: 4683725052380794649, guid: f206f68250e35c54481406a83c165790,
type: 3}
propertyPath: m_Pivot.x
@@ -5660,12 +5655,12 @@ PrefabInstance:
- target: {fileID: 5436103631707523789, guid: f206f68250e35c54481406a83c165790,
type: 3}
propertyPath: m_SizeDelta.x
- value: 0
+ value: -683
objectReference: {fileID: 0}
- target: {fileID: 6568873253317409902, guid: f206f68250e35c54481406a83c165790,
type: 3}
propertyPath: m_SizeDelta.y
- value: 0
+ value: 14
objectReference: {fileID: 0}
- target: {fileID: 7032782682867687973, guid: f206f68250e35c54481406a83c165790,
type: 3}
@@ -5697,17 +5692,12 @@ PrefabInstance:
propertyPath: m_Name
value: ZhanLing
objectReference: {fileID: 0}
- - target: {fileID: 7077596146806315097, guid: f206f68250e35c54481406a83c165790,
+ - target: {fileID: 7033739248829094286, guid: f206f68250e35c54481406a83c165790,
type: 3}
- propertyPath: m_AnchorMax.y
+ propertyPath: m_IsActive
value: 0
objectReference: {fileID: 0}
- - target: {fileID: 7741008535677535188, guid: f206f68250e35c54481406a83c165790,
- type: 3}
- propertyPath: m_AnchorMax.y
- value: 1
- objectReference: {fileID: 0}
- - target: {fileID: 8156378713621244176, guid: f206f68250e35c54481406a83c165790,
+ - target: {fileID: 7077596146806315097, guid: f206f68250e35c54481406a83c165790,
type: 3}
propertyPath: m_AnchorMax.y
value: 1
@@ -5715,7 +5705,7 @@ PrefabInstance:
- target: {fileID: 8876291267844903025, guid: f206f68250e35c54481406a83c165790,
type: 3}
propertyPath: m_SizeDelta.x
- value: 0
+ value: 235.37
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
diff --git a/Assets/MyGame/Scripts/Items/Bullits/BullitMove.cs b/Assets/MyGame/Scripts/Items/Bullits/BullitMove.cs
index 00ea890ee..a6472d879 100644
--- a/Assets/MyGame/Scripts/Items/Bullits/BullitMove.cs
+++ b/Assets/MyGame/Scripts/Items/Bullits/BullitMove.cs
@@ -198,9 +198,34 @@ public class BullitMove : MonoBehaviour
if (userid == GameManager.Instance.user.id)
{
+ // 真人玩家击杀
var v2 = GameManager.Instance.gameData.currRoomData;
WebSocketSendList.KillFish(v2.roomId, userid, monster.monsterData.fishTypeConfig.fishNumber, monster.guid, (int)CreateFishManager.Instance.currGameType.currSitData.consumeGoldNum, bulletID, "63215f0afa3f5b25");
}
+ else if (!string.IsNullOrEmpty(userid) && userid.StartsWith("bot_"))
+ {
+ // 机器人击杀:只有房主客户端发送 BotKillFish
+ if (SitPosData.roomOwnerSit != null && SitPosData.roomOwnerSit.user == GameManager.Instance.user.id)
+ {
+ var v2 = GameManager.Instance.gameData.currRoomData;
+ // 从 bot 座位获取炮倍
+ long gold = 100;
+ var panel = CreateFishManager.Instance.currGameType;
+ if (panel != null && panel.list_Sits != null)
+ {
+ var sit = panel.list_Sits.Find(s => s.user == userid);
+ if (sit != null) gold = sit.consumeGoldNum;
+ }
+ WebSocketSendList.BotKillFish(
+ v2.roomId,
+ userid,
+ monster.monsterData.fishTypeConfig.fishNumber,
+ monster.guid,
+ gold,
+ bulletID
+ );
+ }
+ }
monster.OnHurt();
Destroy(gameObject);
diff --git a/Assets/MyGame/Scripts/Net/APIRequest/Params/HallRequest.cs b/Assets/MyGame/Scripts/Net/APIRequest/Params/HallRequest.cs
index f29ffc35d..13e2e88d4 100644
--- a/Assets/MyGame/Scripts/Net/APIRequest/Params/HallRequest.cs
+++ b/Assets/MyGame/Scripts/Net/APIRequest/Params/HallRequest.cs
@@ -187,4 +187,11 @@ namespace Assets.MyGame.Scripts.Net.APIRequest.Params
{
public int type; // ½ø½×ÀàÐÍ 1=¾«Ӣ 2=ÖÁ×ð
}
+
+ /// »ñȡÓû§ÈÎÎñÁбí£¨GET£©
+ [Serializable]
+ public class GetUserTaskListParam : RequestParamBase
+ {
+ public int taskType = -1; // -1=ȫ²¿
+ }
}
diff --git a/Assets/MyGame/Scripts/Net/APIRequestList_Hall.cs b/Assets/MyGame/Scripts/Net/APIRequestList_Hall.cs
index 4b524ca98..8bd10a339 100644
--- a/Assets/MyGame/Scripts/Net/APIRequestList_Hall.cs
+++ b/Assets/MyGame/Scripts/Net/APIRequestList_Hall.cs
@@ -207,9 +207,10 @@ namespace Assets.MyGame.Scripts.Net
/// 参数:用户ID
/// 返回:UserTaskListResponse(任务列表)
///
- public static void GetUserTaskList(Action callback)
+ public static void GetUserTaskList(Action> callback)
{
- APIManager.Response(APIType.Hall_GetUserTaskList, callback);
+ APIManager.Response>(APIType.Hall_GetUserTaskList,
+ new GetUserTaskListParam { taskType = -1 }, callback);
}
///
diff --git a/Assets/MyGame/Scripts/Net/APIResponses/HallResponses.cs b/Assets/MyGame/Scripts/Net/APIResponses/HallResponses.cs
index 1e830a07d..653cce4eb 100644
--- a/Assets/MyGame/Scripts/Net/APIResponses/HallResponses.cs
+++ b/Assets/MyGame/Scripts/Net/APIResponses/HallResponses.cs
@@ -284,4 +284,25 @@ namespace Assets.MyGame.Scripts.Net.APIResponses
public string message;
public List purchasedAdvances;
}
+
+ /// 用户任务 DTO(/api/Hall/GetUserTaskList?taskType=-1)
+ [Serializable]
+ public class UserTaskDto
+ {
+ public string id;
+ public string userId;
+ public string number;
+ public string remark;
+ public int taskType; // 任务类型
+ public int taskEvent; // 任务事件
+ public int taskCount; // 任务次数要求
+ public int count; // 当前完成次数
+ public bool isFinish; // 是否完成
+ public string otherId;
+ public bool isGet; // 是否已领取
+ public int taskAddTime;
+ public long taskEndTime;
+ public long taskFinishTime;
+ public int exp; // 奖励经验
+ }
}
\ No newline at end of file
diff --git a/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs b/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs
index 823f88149..3cec76910 100644
--- a/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs
+++ b/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs
@@ -149,10 +149,16 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
[Header("攻击参数")]
public float attackTime = 0.5f;
+ [Header("人机参数")]
+ public float botRotateSpeed = 360f; // 人机炮台旋转速度(度/秒)
+ public float botTargetHoldTime = 2.5f; // 人机锁定目标保持时间(秒)
float clickTime = 0;
private Dictionary botFireTimer = new Dictionary();
private Dictionary botLastAngle = new Dictionary(); // botUserId → 最后一次开火角度
private Dictionary> botBulletIds = new Dictionary>(); // botUserId → 子弹ID列表 // 人机开火计时
+ // bot 目标锁定:posID → (目标guid, 切换时间戳)
+ private Dictionary botTargetGuid = new Dictionary();
+ private Dictionary botTargetSwitchTime = new Dictionary();
public GameObject bullet_Test;
public GameObject bulletParent;
float changeTurretTime = 0f;
@@ -1862,6 +1868,10 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
sit.goldNum = goldNum;
sit.consumeGoldNum = consumeGold;
+ // ⭐ 在 ShowPlayer 之前标记 isBot,否则 ShowPlayer 里的 AssignRoomOwner 会把 bot 设为房主
+ if (!string.IsNullOrEmpty(user) && user.StartsWith("bot_"))
+ sit.isBot = true;
+
sit.tMP_GoldNum.text = goldNum.ToString();
sit.tMP_DiamondNum.text = diamondNum.ToString();
sit.tMP_TurretConsumeNum.text = consumeGold.ToString();
@@ -1870,6 +1880,13 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
if (!string.IsNullOrEmpty(cannonId) && int.TryParse(cannonId, out int turretNum))
sit.LoadTurret(turretNum);
+ else if (sit.isBot)
+ {
+ // bot 没有炮台ID时给一个默认炮台
+ var turretList = TurretResourcesData.GetTurretDataByType(1);
+ if (turretList != null && turretList.Count > 0)
+ sit.LoadTurret(turretList[0].turretNumber);
+ }
if (!string.IsNullOrEmpty(wingId) && int.TryParse(wingId, out int wingNum))
sit.LoadWing(wingNum);
@@ -1899,17 +1916,54 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
if (!sit.isBot || sit.gameObject.activeSelf == false) continue;
if (sit.tra_CurrTurret == null) continue;
- // 找最近鱼
- MonsterContral target = null;
- float bestDist = float.MaxValue;
Vector3 turretPos = sit.tra_CurrTurret.position;
- foreach (var kv in fishList.fishDatas_hashCodekey)
+
+ // ---- 目标锁定:优先沿用当前目标,失效/超时才换新 ----
+ MonsterContral target = null;
+ float now = Time.time;
+
+ // 检查当前锁定的目标是否还可用
+ if (botTargetGuid.TryGetValue(sit.posID, out string currGuid))
{
- var m = kv.Value;
- if (m == null || !m.gameObject.activeInHierarchy) continue;
- float d = (m.transform.position - turretPos).sqrMagnitude;
- if (d < bestDist) { bestDist = d; target = m; }
+ if (fishList.fishDatas_hashCodekey.TryGetValue(currGuid, out var m)
+ && m != null && m.gameObject.activeInHierarchy)
+ {
+ // 目标还活着,检查是否超时
+ float switchT = botTargetSwitchTime.ContainsKey(sit.posID) ? botTargetSwitchTime[sit.posID] : 0f;
+ if (now < switchT)
+ {
+ // 检查目标是否还在炮台前方
+ Vector3 fishPos = m.transform.position;
+ bool inFront = sit.IsFlipped ? (fishPos.y < turretPos.y) : (fishPos.y > turretPos.y);
+ if (inFront) target = m;
+ }
+ }
}
+
+ // 目标失效 → 找新目标
+ if (target == null)
+ {
+ float bestDist = float.MaxValue;
+ foreach (var kv in fishList.fishDatas_hashCodekey)
+ {
+ var m = kv.Value;
+ if (m == null || !m.gameObject.activeInHierarchy) continue;
+
+ Vector3 fishPos = m.transform.position;
+ if (sit.IsFlipped && fishPos.y >= turretPos.y) continue;
+ if (!sit.IsFlipped && fishPos.y <= turretPos.y) continue;
+
+ float d = (fishPos - turretPos).sqrMagnitude;
+ if (d < bestDist) { bestDist = d; target = m; }
+ }
+
+ if (target != null)
+ {
+ botTargetGuid[sit.posID] = target.guid;
+ botTargetSwitchTime[sit.posID] = now + botTargetHoldTime;
+ }
+ }
+
if (target == null) continue;
// 旋转朝向鱼(仅本地旋转,不广播 SyncRotate)
@@ -1937,16 +1991,22 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
}
}
- /// 人机炮台旋转:直接用世界坐标算角度,仅本地旋转,不广播
+ /// 人机炮台旋转:和 RotateToLockTarget 完全一致的坐标转换,仅本地旋转不广播
private void RotateBotToTarget(SitPosData sit, Vector3 fishWorldPos)
{
- Vector3 turretWorldPos = sit.tra_CurrTurret.position;
- Vector2 dir = (Vector2)(fishWorldPos - turretWorldPos);
- if (dir.sqrMagnitude < 1f) return;
+ Vector2 screenPos = Camera.main.WorldToScreenPoint(fishWorldPos);
+
+ RectTransformUtility.ScreenPointToLocalPointInRectangle(
+ sit.tra_CurrTurret.transform.parent as RectTransform,
+ screenPos, null, out Vector2 localPos);
+
+ Vector2 dir = localPos - sit.tra_CurrTurret.GetComponent().anchoredPosition;
+
+ // 鱼太近时 dir 接近零向量,Atan2 不稳定 → 跳过
+ if (dir.sqrMagnitude < 25f) return;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg - 90f;
- // 上方座位(2,3)炮台默认朝上,加180°让它朝下打鱼
if (sit.IsFlipped) angle = (angle + 180f) % 360f;
sit.SetRotation(angle);
diff --git a/Assets/MyGame/aa/UI/Home/Sub/ZhanLing_Panel.cs b/Assets/MyGame/aa/UI/Home/Sub/ZhanLing_Panel.cs
index eccbeb929..5adea061f 100644
--- a/Assets/MyGame/aa/UI/Home/Sub/ZhanLing_Panel.cs
+++ b/Assets/MyGame/aa/UI/Home/Sub/ZhanLing_Panel.cs
@@ -160,10 +160,17 @@ public class ZhanLing_Panel : SubUIBase
if (lv100 != null && levelGiftitem_100 != null)
{
bool showDuiGou = claimedSet.Contains(_maxLevel);
+ bool reachedLevel = level >= _maxLevel;
+
+ LevelGiftType giftType100 = LevelGiftType.MianFei;
+ if (lv100.luxuryGiftType > 0 && _userData.isLuxury) giftType100 |= LevelGiftType.JingYing;
+ if (lv100.supremeGiftType > 0 && _userData.isSupreme) giftType100 |= LevelGiftType.ZhiZun;
+
levelGiftitem_100.Init(
GetIconUrl(lv100.normalGiftType), lv100.normalGiftCount,
- "", 0, "", 0,
- _maxLevel, LevelGiftType.MianFei, level >= _maxLevel && showDuiGou);
+ GetIconUrl(lv100.luxuryGiftType), lv100.luxuryGiftCount,
+ GetIconUrl(lv100.supremeGiftType), lv100.supremeGiftCount,
+ _maxLevel, giftType100, reachedLevel && showDuiGou);
levelGiftitem_100.gameObject.SetActive(true);
}
}
@@ -177,11 +184,17 @@ public class ZhanLing_Panel : SubUIBase
for (int i = renWuItemParent.childCount - 1; i >= 0; i--)
Destroy(renWuItemParent.GetChild(i).gameObject);
- // 示例任务(后续对接任务列表 API)
- CreateTaskItem(10, 10, 20, "每日登录", 0.5f, UIPanel.None);
- CreateTaskItem(20, 10, 20, "捕鱼10条", 0.5f, UIPanel.None);
- CreateTaskItem(30, 0, 30, "充值任意金额", 0f, UIPanel.None);
+ APIRequestList.GetUserTaskList(tasks =>
+ {
+ if (tasks == null) return;
+ foreach (var t in tasks)
+ {
+ float progress = t.taskCount > 0 ? (float)t.count / t.taskCount : 0f;
+ CreateTaskItem(t.exp, t.count, t.taskCount, t.remark, progress, UIPanel.None);
+ }
+ });
}
+
private void CreateTaskItem(int expCount, int currJinDu, int maxJinDu, string label, float progress, UIPanel targetPanel)
{