Files
5.24BuYu/Assets/MyGame/Scripts/Characters/Monster/MonsterControl_BossBase.cs
T

320 lines
11 KiB
C#
Raw Normal View History

2026-06-03 18:27:45 +08:00
using Assets.MyGame.Scripts.Net.APIResponses.Enum;
2026-04-26 00:55:55 +08:00
using Assets.MyGame.Scripts.Net.WebResponses;
2026-04-25 18:53:04 +08:00
using DG.Tweening;
using System;
using System.Collections;
2026-03-18 17:26:14 +08:00
using System.Collections.Generic;
2026-04-24 22:51:34 +08:00
using TMPro;
2026-03-18 17:26:14 +08:00
using UnityEngine;
2026-03-27 15:18:35 +08:00
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
2026-03-18 17:26:14 +08:00
using static MonsterMoveLine;
2026-04-25 18:53:04 +08:00
using Random = UnityEngine.Random;
2026-03-18 17:26:14 +08:00
public class MonsterControl_BossBase : MonsterContral
{
2026-06-03 18:27:45 +08:00
// ==================== 基础 ====================
2026-03-18 17:26:14 +08:00
public string bossName;
2026-06-03 18:27:45 +08:00
// ==================== 爆奖 ====================
2026-04-24 22:51:34 +08:00
[Header("爆奖")]
2026-06-03 18:27:45 +08:00
public bool isToUI = true; // 爆奖特效是 UI(RectTransform)还是 3D 场景物体
2026-04-24 22:51:34 +08:00
public LayeredPool layeredPool;
2026-06-03 18:27:45 +08:00
public TextMeshProUGUI tMP_CurrBossScore; // Boss 分数显示文本
public long currBossScoreValue; // 当前滚动分数
public long bossScoreValue; // 累计总分
public int poolNum; // 奖池金币
public int prizeCount = 8; // 爆奖红包数量
public Action<int> JiaFen; // 加分回调
2026-04-25 22:41:38 +08:00
public List<List<RedPacketRecord>> redPacketRecords = new List<List<RedPacketRecord>>();
2026-04-26 20:29:22 +08:00
public Camera ZhuCam;
2026-05-27 19:47:06 +08:00
2026-06-03 18:27:45 +08:00
// ==================== 死亡 ====================
public bool isDieFish;
public float dieTime = 3f;
2026-07-23 01:51:07 +08:00
public Vector3 v3; // 分数飞出目标位置(Inspector 设置)
2026-06-03 18:27:45 +08:00
private long _turretNum;
private bool _isJia;
2026-07-23 01:51:07 +08:00
/// <summary>是否本地玩家击杀(金/银币样式切换用,由 Ws_DieFish 设置)</summary>
public bool isLocalCoin = false;
/// <summary>击杀者座位 ID(人机击杀时由房主代发,但 sitPos 应为人机座位,而非房主自己)</summary>
public int killerSitPos = -1;
2026-06-03 18:27:45 +08:00
// ==================== Unity 生命周期 ====================
2026-04-24 22:51:34 +08:00
public override void Awake()
{
base.Awake();
2026-06-05 01:04:14 +08:00
//isRotate = false;
2026-04-26 20:29:22 +08:00
ZhuCam = GameManager.Instance.ZhuCam;
2026-06-03 18:27:45 +08:00
action_effect_DieAward = obj =>
2026-05-06 01:34:23 +08:00
{
2026-06-03 18:27:45 +08:00
tMP_CurrBossScore = obj.transform.GetChild(0).GetComponent<TextMeshProUGUI>();
2026-07-23 01:51:07 +08:00
// ⭐ 按 isLocalCoin 切金/银:自己击杀=金币,他人=银币
ApplyBossScoreStyle(obj.transform);
2026-05-06 01:34:23 +08:00
};
2026-04-28 01:53:41 +08:00
}
2026-06-03 18:27:45 +08:00
2026-07-23 01:51:07 +08:00
/// <summary>
/// 按 isLocalCoin 切换 Boss 分数 TMP 的 spriteAsset:
/// 自己击杀 → goldSprite
/// 他人击杀 → silverSprite
/// 优先用 BJImage(新预制体),回退 ScoreNumScrollEvent,再回退直接取 TMP。
/// 需对应 sprite 已在 Inspector 赋值,否则跳过不影响原显示。
/// </summary>
private void ApplyBossScoreStyle(Transform root)
{
if (tMP_CurrBossScore == null) return;
var bjImage = root.GetComponentInChildren<BJImage>();
if (bjImage != null)
{
var spriteAsset = isLocalCoin ? bjImage.goldSprite : bjImage.silverSprite;
if (spriteAsset != null)
tMP_CurrBossScore.spriteAsset = spriteAsset;
return;
}
var scrollEvent = root.GetComponentInChildren<ScoreNumScrollEvent>();
if (scrollEvent != null)
{
scrollEvent.SetScoreStyle(isLocalCoin);
}
}
2026-04-29 23:53:55 +08:00
public override void OnEnable()
2026-04-28 01:53:41 +08:00
{
2026-04-29 23:53:55 +08:00
base.OnEnable();
2026-05-06 01:34:23 +08:00
layeredPool = null;
2026-06-03 18:27:45 +08:00
currBossScoreValue = 0;
bossScoreValue = 0;
redPacketRecords.Clear();
_isJia = false;
isDieFish = false;
2026-07-23 01:51:07 +08:00
isLocalCoin = false;
killerSitPos = -1;
2026-04-28 01:53:41 +08:00
2026-06-03 18:27:45 +08:00
var res = FishResourcesData.fishResourcesDatasDic[fishTypeID];
if (res.showAudio != null && res.showAudio.Count > 0)
AudioManager.Instance.PlayerFX(res.showAudio[Random.Range(0, res.showAudio.Count)]);
2026-05-06 01:34:23 +08:00
}
2026-04-29 23:53:55 +08:00
public override void OnDisable()
2026-04-25 18:53:04 +08:00
{
2026-04-29 23:53:55 +08:00
base.OnDisable();
2026-05-01 06:26:50 +08:00
if (isDieFish)
2026-06-03 18:27:45 +08:00
GameManager.Instance.StartCoroutine(YanChiDie());
2026-04-25 22:41:38 +08:00
}
2026-06-03 18:27:45 +08:00
// ==================== 初始化 ====================
public async override void Init(string pathId, float time, bool isyuzhen = false, string yzID = "")
{
isyz = isyuzhen;
this.yzID = yzID;
2026-07-27 23:30:25 +08:00
// ⭐ 创建视频处理:配置了 createVideoClip 时通过 GameMainPanel 的播放器播放
// 播放期间 OnMoveUpdata 会跳过移动,视频结束后才开始走路线
_createVideoDuration = 0f;
_isPlayingCreateVideo = false;
var videoPlayer = CreateFishManager.Instance?.currGameType?.createVideoPlayer;
if (createVideoClip != null && videoPlayer != null)
{
// 显示视频控件
videoPlayer.gameObject.SetActive(true);
videoPlayer.Stop();
videoPlayer.clip = createVideoClip;
// ⭐ 注册播放结束回调:视频播完自动隐藏控件 + 重置状态
videoPlayer.loopPointReached -= OnCreateVideoFinished;
videoPlayer.loopPointReached += OnCreateVideoFinished;
videoPlayer.Play();
_isPlayingCreateVideo = true;
}
2026-06-03 18:27:45 +08:00
// Boss 进场播报
if (GameManager.Instance.gameData.currGameType == GameType.XJMH)
{
var handle = Addressables.LoadAssetAsync<Sprite>($"Assets/Art/XJMH/pw/pw_sprite/handbook/{bossName}.png");
await handle.Task;
CreateFishManager.Instance.currGameType.subUIManager.ShowBoardBoss(handle.Result, bossName);
}
2026-06-18 19:33:39 +08:00
if (isMove)
{
var bezierData = MonsterMoveLine.dic_BezierCurveDatas[bossName + pathId];
monsterData.moveLine.Init(bezierData, time);
}
else
{
transform.position = new Vector3(0, 0, 0);
}
2026-06-03 18:27:45 +08:00
}
2026-07-27 23:30:25 +08:00
/// <summary>
/// 创建视频播放结束回调:隐藏视频控件 + 重置播放状态
/// (用 loopPointReached 事件,比 OnMoveUpdata 检测更可靠,
/// 因为 isMove=false 的 Boss 不会进入 OnMoveUpdata 的视频检测分支)
/// </summary>
private void OnCreateVideoFinished(UnityEngine.Video.VideoPlayer player)
{
_isPlayingCreateVideo = false;
if (player != null)
{
player.Stop();
player.gameObject.SetActive(false);
}
}
2026-06-03 18:27:45 +08:00
// ==================== 爆奖(公共) ====================
/// <summary>确保分数显示文本存在(自动创建)</summary>
private void EnsureScorePanel()
{
if (tMP_CurrBossScore != null) return;
var prefab = CreateFishManager.Instance.dieFXPrefabAwardTmp;
if (prefab == null) return;
2026-07-25 21:04:58 +08:00
var parent = CreateFishManager.Instance.currGameType.subPanelParent;
2026-06-03 18:27:45 +08:00
if (parent == null) return;
2026-07-23 01:51:07 +08:00
var board = Instantiate(prefab, parent);
tMP_CurrBossScore = board.transform.GetChild(0).GetComponent<TextMeshProUGUI>();
// ⭐ 按 isLocalCoin 切金/银:自己击杀=金币,他人=银币
ApplyBossScoreStyle(board.transform);
2026-06-03 18:27:45 +08:00
}
/// <summary>初始化红包分层对象池</summary>
private void EnsureLayeredPool()
{
if (layeredPool == null)
layeredPool = new LayeredPool(poolNum, prizeCount);
}
/// <summary>爆奖:随机红包(min~max 个)</summary>
public void BigPrize(int min = 4, int max = 8)
{
EnsureScorePanel();
EnsureLayeredPool();
2026-07-23 01:51:07 +08:00
var records = layeredPool.BossGlodCoinRandrom(tMP_CurrBossScore.transform.position, min, max, killerSitPos);
2026-06-03 18:27:45 +08:00
AddRedPacket(records);
}
/// <summary>爆奖:固定数量红包</summary>
public void BigPrizeNotFish(int count)
{
EnsureScorePanel();
EnsureLayeredPool();
var records = layeredPool.BossGlodCoinNotFish(count);
AddRedPacket(records);
}
/// <summary>爆奖:全屏小鱼数量红包</summary>
public void BigPrizeAll()
{
int smallFishCount = CreateFishManager.Instance.fishDatas_hashCodekey_Small.Count;
prizeCount = 1;
EnsureScorePanel();
EnsureLayeredPool();
2026-07-23 01:51:07 +08:00
var records = layeredPool.BossGlodCoin(smallFishCount, tMP_CurrBossScore.transform.position, killerSitPos);
2026-06-03 18:27:45 +08:00
AddRedPacket(records);
}
/// <summary>记录红包并开始分数滚动 + 加分</summary>
private void AddRedPacket(List<RedPacketRecord> records)
{
redPacketRecords.Add(records);
foreach (var r in records)
bossScoreValue += r.Amount;
_turretNum = CreateFishManager.Instance.currGameType.currSitData.consumeGoldNum;
GameManager.Instance.StartCoroutine(ShowBigPrize());
GameManager.Instance.StartCoroutine(JiaFenRoutine());
}
// ==================== 分数滚动 ====================
private IEnumerator ShowBigPrize()
{
if (_isJia) yield break;
_isJia = true;
yield return new WaitForSeconds(1f);
_turretNum = Random.Range((int)(_turretNum / 2), (int)_turretNum + 1);
while (currBossScoreValue < bossScoreValue)
{
currBossScoreValue += _turretNum;
if (currBossScoreValue > bossScoreValue)
currBossScoreValue = bossScoreValue;
tMP_CurrBossScore.text = currBossScoreValue.ToString();
yield return null;
}
_isJia = false;
}
private IEnumerator JiaFenRoutine()
{
yield return new WaitForSeconds(1.5f);
Transform parent = tMP_CurrBossScore.transform.parent;
GameObject addScorePrefab = CreateFishManager.Instance.dieFXPrefabAwardTmp_AddScore;
var records = redPacketRecords[0];
redPacketRecords.RemoveAt(0);
foreach (var item in records)
{
yield return new WaitForSeconds(0.15f);
2026-06-15 21:51:42 +08:00
var inst = Instantiate(addScorePrefab, parent.position + Vector3.up * 60, Quaternion.identity, parent);
2026-07-23 01:51:07 +08:00
// ⭐ 按 isLocalCoin 切金/银:优先用 ScoreNumScrollEvent,回退直接赋文本
var scrollEvent = inst.GetComponent<ScoreNumScrollEvent>();
if (scrollEvent != null)
{
scrollEvent.SetScoreStyle(isLocalCoin);
scrollEvent.SetScoreText(CoinScript.NumAdd(item.Amount.ToString()));
}
else
{
inst.transform.GetChild(0).GetComponent<TextMeshProUGUI>().text = CoinScript.NumAdd(item.Amount.ToString());
}
2026-06-03 18:27:45 +08:00
AudioManager.Instance.PlayerFX(61009);
}
}
// ==================== 死亡 ====================
public override void DieFish(RoomKillNotice obj = null)
{
isDieFish = true;
GameManager.Instance.cameraShake.ShakePresets.Explosion2D(3f, 4f, 1f);
if (obj != null)
poolNum = obj.gold;
var res = FishResourcesData.fishResourcesDatasDic[fishTypeID];
if (res.dieAudio != null && res.dieAudio.Count > 0)
AudioManager.Instance.PlayerFX(res.dieAudio[Random.Range(0, res.dieAudio.Count)]);
}
/// <summary>死亡后延迟飞分到座位</summary>
private IEnumerator YanChiDie()
2026-04-25 22:41:38 +08:00
{
2026-04-26 20:29:22 +08:00
yield return new WaitForSeconds(dieTime);
2026-04-25 22:41:38 +08:00
2026-06-03 18:27:45 +08:00
tMP_CurrBossScore.transform.parent
.DOMove(v3, 0.5f)
.OnComplete(() =>
{
JiaFen?.Invoke(0);
Destroy(tMP_CurrBossScore.transform.parent.gameObject);
});
2026-04-25 18:53:04 +08:00
}
2026-03-18 17:26:14 +08:00
}