141 lines
5.8 KiB
C#
141 lines
5.8 KiB
C#
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);
|
||
});
|
||
}
|
||
}
|