This commit is contained in:
2026-06-25 17:21:39 +08:00
parent 51fdabc2e6
commit aeea1a1611
8 changed files with 230 additions and 77 deletions
@@ -1,3 +1,4 @@
using Assets.MyGame.Scripts.Net;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
@@ -10,17 +11,14 @@ using UnityEngine.UI;
/// RawImage (prizeImage) ← 最下层:奖品图
/// Text (tmp_AwardName) ← 中间层:奖品文字
/// RawImage (scratchImage) ← 最上层:涂层遮罩(挂本脚本)
///
/// 原理:
/// 涂层遮罩用 ScratchMask.shader,遮罩 RT 全白 = 不透明(未刮),
/// 全黑 = 透明(已刮)。刮擦通过 Graphics.Blit + ScratchErase.shader
/// 在 GPU 内完成,零 CPU 像素操作。
/// </summary>
public class GuaGuaLeGPU : SubUIBase, IPointerDownHandler, IDragHandler
{
[Header("UI 引用(必填)")]
public RawImage scratchImage; // 最上层:涂层遮罩(挂此脚本)
public TextMeshProUGUI tmp_AwardName; // 中间层:奖品文字
public TextMeshProUGUI tmp_AwardName; // 中间层:奖品文字
public GuaGuaLeItem giftPrefab; // 奖品预制体(用于显示奖品图片)
public Transform giftPrefabParent;
[Header("材质(模板)")]
public Material maskMat; // 使用 ScratchMask.shader(涂层遮罩)
@@ -36,10 +34,6 @@ public class GuaGuaLeGPU : SubUIBase, IPointerDownHandler, IDragHandler
[Range(0f, 1f)] public float revealThreshold = 0.6f;
public bool autoReveal = true;
[Header("奖品配置")]
public string[] awards = { "谢谢参与", "一等奖", "二等奖", "三等奖", "再来一次" };
public float[] awardWeights = { 0.50f, 0.05f, 0.10f, 0.15f, 0.20f };
[Header("事件")]
public UnityEngine.Events.UnityEvent onRevealed;
@@ -59,30 +53,24 @@ public class GuaGuaLeGPU : SubUIBase, IPointerDownHandler, IDragHandler
private Texture2D progressReadTex;
private int dragCount;
protected override void OnShow(object args = null)
{
base.OnShow(args);
ResetCard();
}
private void Start()
{
if (scratchImage == null) { Debug.LogError("[GPU] scratchImage 为空!"); return; }
if (maskMat == null) { Debug.LogError("[GPU] maskMat 为空!"); return; }
if (eraseMat == null) { Debug.LogError("[GPU] eraseMat 为空!"); return; }
if (awardWeights == null || awardWeights.Length != awards.Length)
{
awardWeights = new float[awards.Length];
float w = 1f / Mathf.Max(1, awards.Length);
for (int i = 0; i < awardWeights.Length; i++) awardWeights[i] = w;
}
InitCard();
}
private void InitCard()
{
// 1. 遮罩 RT(全白 = 未刮,不透明)
maskRT = new RenderTexture(rtWidth, rtHeight, 0, RenderTextureFormat.ARGB32)
{
filterMode = FilterMode.Bilinear
@@ -90,9 +78,6 @@ public class GuaGuaLeGPU : SubUIBase, IPointerDownHandler, IDragHandler
maskRT.Create();
ClearRT(maskRT, Color.white);
// 3. 最上层:涂层遮罩材质(实例化,避免 UGUI 材质共享问题)
instanceMaskMat = new Material(maskMat);
instanceMaskMat.SetTexture("_MaskTex", maskRT);
instanceMaskMat.SetColor("_CoatColor", coatColor);
@@ -100,20 +85,13 @@ public class GuaGuaLeGPU : SubUIBase, IPointerDownHandler, IDragHandler
scratchImage.material = instanceMaskMat;
scratchImage.texture = null;
// 4. 擦除材质实例
instanceEraseMat = new Material(eraseMat);
instanceEraseMat.SetFloat("_BrushSize", brushSize);
// 5. 摇奖
currentAward = RollAward();
if (tmp_AwardName != null)
tmp_AwardName.text = currentAward;
// 6. 进度读取用纹理
progressReadTex = new Texture2D(rtWidth, rtHeight, TextureFormat.ARGB32, false);
ResetState();
Debug.Log($"[GPU] 初始化完成 {rtWidth}x{rtHeight}");
FetchAward();
}
private void ResetState()
@@ -124,6 +102,34 @@ public class GuaGuaLeGPU : SubUIBase, IPointerDownHandler, IDragHandler
dragCount = 0;
}
// ================================================================
// API 抽奖
// ================================================================
private void FetchAward()
{
APIRequestList.ScratchCardDraw(result =>
{
if (result == null) return;
currentAward = result.prizeName ?? "谢谢参与";
if (tmp_AwardName != null)
tmp_AwardName.text = currentAward;
// 清除旧的奖励物品
for (int i = giftPrefabParent.childCount - 1; i >= 0; i--)
Destroy(giftPrefabParent.GetChild(i).gameObject);
// 显示奖品图片(baseProduct.imageUrl)
string imgUrl = result.baseProduct?.imageUrl;
if (!string.IsNullOrEmpty(imgUrl) && giftPrefab != null)
{
var item = Instantiate(giftPrefab, giftPrefabParent);
item.Init(imgUrl, result.count);
}
});
}
// ================================================================
// 公开方法
// ================================================================
@@ -135,12 +141,10 @@ public class GuaGuaLeGPU : SubUIBase, IPointerDownHandler, IDragHandler
ClearRT(maskRT, Color.white);
ResetState();
currentAward = RollAward();
if (tmp_AwardName != null)
tmp_AwardName.text = currentAward;
if (instanceMaskMat != null)
instanceMaskMat.SetColor("_CoatColor", coatColor);
FetchAward();
}
public void RevealAll()
@@ -284,26 +288,6 @@ public class GuaGuaLeGPU : SubUIBase, IPointerDownHandler, IDragHandler
return uv.x >= 0f && uv.x <= 1f && uv.y >= 0f && uv.y <= 1f;
}
private string RollAward()
{
if (awards == null || awards.Length == 0) return "谢谢参与";
int n = Mathf.Min(awards.Length, awardWeights == null ? 0 : awardWeights.Length);
if (n <= 0) return awards[0];
float sum = 0f;
for (int i = 0; i < n; i++) sum += Mathf.Max(0f, awardWeights[i]);
if (sum <= 0f) return awards[0];
float r = Random.value * sum;
float acc = 0f;
for (int i = 0; i < n; i++)
{
acc += Mathf.Max(0f, awardWeights[i]);
if (r <= acc) return awards[i];
}
return awards[n - 1];
}
public string CurrentAward => currentAward;
public bool IsRevealed => isRevealed;