Files
5.24BuYu/Assets/MyGame/aa/Game/DefaultDieEffect/Prop/FishKillProp.cs
T
2026-10-21 02:56:13 +08:00

141 lines
5.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Assets.Framework.Tool;
using Assets.MyGame.Scripts.Net;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 鱼死亡掉落道具脚本(与 CoinScript 同级,均继承 BJBase)。
/// 行为类似金币:原地掉落并散开 → 停留片刻 → 飞向击杀者座位 → 回收。
/// 掉落数据由服务端 RoomKillNotice.drop 下发(propNumber/propName/count),
/// 道具图标按 /uploads/{propNumber}.png 从服务端下载。
/// </summary>
public class FishKillProp : BJBase
{
/// <summary>飞向座位耗时(秒),与金币 coinEvent 保持一致</summary>
private const float FlyDuration = 0.5f;
/// <summary>道具图标(Inspector 绑定)</summary>
public Image propIco;
/// <summary>当前飞行补间(池复用时需要先 Kill,防止旧回调回收新道具)</summary>
private Tween _flyTween;
/// <summary>本次生命周期是否已开始飞行,防止重复调用导致重复回收</summary>
private bool _flying;
private void OnEnable()
{
// ⭐ 池复用重置:上一次的飞行补间若还在,其完成回调会把刚复用的新道具直接回池
// 表现就是"道具刚出现就消失",这里清干净
_flying = false;
if (_flyTween != null && _flyTween.IsActive()) _flyTween.Kill(false);
_flyTween = null;
transform.DOKill(false);
// ⭐ 预制体/复用对象上若残留自动回收组件,会在 0.3s 后无条件回池,同样导致瞬间消失
var auto = GetComponent<EffectAutoReturn>();
if (auto != null) auto.enabled = false;
}
/// <summary>
/// 重写基类方法:道具不显示金币数字,而是下载并设置道具图标。
/// 和 CoinScript.SetCoinCount() 对称,供外部统一调用。
/// </summary>
public override void SetCoinCount()
{
// 修正 z 轴(和 CoinScript 一致,防止 UI 层级下 z 不为 0 导致被遮挡)
var v3 = transform.position;
v3.z = 0;
transform.position = v3;
}
/// <summary>
/// 初始化道具(扩展 BJBase.Init,增加道具编号)。
/// 由 CreateFishManager 在收到服务端掉落推送时调用。
/// </summary>
/// <param name="propNumber">道具编号(用于下载图标 /uploads/编号.png)</param>
/// <param name="propCount">掉落数量(服务端下发总量,仅供展示/扩展)</param>
/// <param name="startPoint">掉落起点(鱼死亡位置,已含随机散开偏移)</param>
/// <param name="endPoint">飞行终点(击杀者座位位置)</param>
/// <param name="userID">击杀者 ID</param>
/// <param name="sitID">座位 ID</param>
/// <param name="jobj">附加数据(透传,回调时原样返回)</param>
public void InitProp(string propNumber, int propCount, Vector3 startPoint, Vector3 endPoint,
string userID = "", int sitID = 999, object jobj = null)
{
this.startPoint = startPoint;
// 复用基类 Init 设置通用字段(道具不涉及金币数量,coinCount 传 0)
Init(0, endPoint, userID, sitID, jobj);
// 下载道具图标:固定格式 /uploads/{propNumber}.png
DownloadPropIcon(propNumber);
}
/// <summary>道具图标缓存(同一次掉落可能生成多个道具,避免重复下载同一张图)</summary>
private static readonly System.Collections.Generic.Dictionary<string, Sprite> _iconCache
= new System.Collections.Generic.Dictionary<string, Sprite>();
/// <summary>
/// 从服务端下载道具图标并设置到 propIco。
/// 失败时 propIco 保留预制体上配置好的默认图(不强制兜底重试)。
/// </summary>
private void DownloadPropIcon(string propNumber)
{
if (string.IsNullOrEmpty(propNumber) || propIco == null) return;
// 命中缓存直接使用
if (_iconCache.TryGetValue(propNumber, out var cached) && cached != null)
{
ApplyIcon(cached);
return;
}
string url = APIManager.baseURL + "/uploads/" + propNumber + ".png";
WebTool.DownImage(url, tex =>
{
if (tex != null)
{
var sprite = Sprite.Create(tex,
new Rect(0, 0, tex.width, tex.height),
Vector2.one * 0.5f);
_iconCache[propNumber] = sprite;
}
// 回调时本物体可能已被销毁(飞到座位后回池/切场景),需判空
if (this == null || propIco == null) return;
if (_iconCache.TryGetValue(propNumber, out var sprite2) && sprite2 != null)
ApplyIcon(sprite2);
});
}
/// <summary>把图标应用到 propIco。</summary>
private void ApplyIcon(Sprite sprite)
{
propIco.sprite = sprite;
propIco.SetNativeSize();
propIco.gameObject.SetActive(true);
}
/// <summary>
/// 飞到座位位置并回收(效果同 coinEvent.HuiShou)。
/// </summary>
/// <param name="delay">起飞前停留时长(秒),让道具先展示一会儿再回收,观感与金币一致</param>
public void FlyToSeat(float delay = 0f)
{
if (_flying) return; // 防止重复调用导致重复回收
_flying = true;
if (_flyTween != null && _flyTween.IsActive()) _flyTween.Kill(false);
_flyTween = transform.DOMove(endPoint, FlyDuration)
.SetDelay(Mathf.Max(0f, delay))
.OnComplete(() =>
{
// 拾取回调(由 CreateFishManager 设置 JiaFen)
JiaFen?.Invoke(0);
// 拾取音效(复用金币拾取音效)
AudioManager.Instance.PlayerFX(61009);
// 池化回收
EffectPool.Instance.Return(gameObject);
});
}
}