备份CatanBuilding瘦身独立工程
This commit is contained in:
8
Assets/Scripts/UI/ScratchTicket/Data.meta
Normal file
8
Assets/Scripts/UI/ScratchTicket/Data.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: defa652e288f2404b9b6cf9a48c44ad9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,105 @@
|
||||
using asap.core;
|
||||
using cfg;
|
||||
using GameCore;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class EventScratchTicketChainPackData : IChainPackData
|
||||
{
|
||||
private const int SlotCount = 6;
|
||||
private List<int> ChainList { get; set; }
|
||||
private Pack[] Packs { get; set; }
|
||||
public bool IsEndGame => ChainProgress > ChainList.Count - SlotCount;
|
||||
public int ChainListCount => ChainList.Count;
|
||||
private int m_ChainProgress = 0;
|
||||
public int ChainProgress
|
||||
{
|
||||
set
|
||||
{
|
||||
EventScratchTicketDataManager dataManager = GContext.container.Resolve<EventScratchTicketDataManager>();
|
||||
m_ChainProgress = value;
|
||||
dataManager.SetChainProgress(m_ChainProgress);
|
||||
}
|
||||
get
|
||||
{
|
||||
EventScratchTicketDataManager dataManager = GContext.container.Resolve<EventScratchTicketDataManager>();
|
||||
m_ChainProgress = dataManager.GetChainProgress();
|
||||
return m_ChainProgress;
|
||||
}
|
||||
}
|
||||
//public int ChainProgress { get; set; }
|
||||
public int EventId { get; set; }
|
||||
private DateTime ExpireTime { get; set; }
|
||||
public TimeSpan RemainingTime => ExpireTime - ZZTimeHelper.UtcNow();
|
||||
|
||||
public bool IsChainPackDepleted => ChainProgress >= ChainListCount;
|
||||
|
||||
public bool DoNeedPackRedPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsChainPackDepleted && ChainProgress < ChainListCount)
|
||||
return Packs[ChainProgress].IAPID == 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public string RedPointKey => RedPointName.Home_ScratchTicket + ".pack";
|
||||
|
||||
public EventScratchTicketChainPackData(List<int> chainList, DateTime expireTime, Pack[] packs, int eventId, int chainProgress)
|
||||
{
|
||||
ChainList = chainList;
|
||||
ChainProgress = chainProgress;
|
||||
EventId = eventId;
|
||||
ExpireTime = expireTime;
|
||||
Packs = packs;
|
||||
}
|
||||
|
||||
public Pack GetChainPackByChainProgress(int chainProgress)
|
||||
{
|
||||
// Debug.Log($"[EventBreak] chainProgress: {chainProgress}");
|
||||
return Packs[chainProgress];
|
||||
}
|
||||
|
||||
public int GetChainProgressBySlotIdx(int slotIdx)
|
||||
{
|
||||
int res;
|
||||
if (ChainProgress > ChainList.Count - SlotCount)
|
||||
res = ChainList.Count - SlotCount + slotIdx;
|
||||
else
|
||||
res = ChainProgress + slotIdx;
|
||||
Assert.IsTrue(res < ChainList.Count, $"Progress {res} out of range: {ChainListCount}");
|
||||
// Debug.Log($"[EventBreak] slotIdx: {slotIdx}, chainProgress: {res}");
|
||||
return res;
|
||||
}
|
||||
|
||||
// Is this needed or what?
|
||||
public List<int> GetTokenProgressRewardAfterAddingToken(int tokenAdded)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void UploadData()
|
||||
{
|
||||
EventScratchTicketDataManager dataManager = GContext.container.Resolve<EventScratchTicketDataManager>();
|
||||
dataManager.ScratchTicketData.ChainPackProgress = ChainProgress;
|
||||
dataManager.SyncData();
|
||||
}
|
||||
|
||||
public void OnBuySuccess()
|
||||
{
|
||||
ChainProgress++;
|
||||
UploadData();
|
||||
}
|
||||
|
||||
public List<ItemData> GetItemsByPackDropId(int dropId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 06183f569011c7a42a7f7d0dcc6b2d59
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
236
Assets/Scripts/UI/ScratchTicket/EditablePolygon.cs
Normal file
236
Assets/Scripts/UI/ScratchTicket/EditablePolygon.cs
Normal file
@@ -0,0 +1,236 @@
|
||||
using GameCore;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace game
|
||||
{
|
||||
[RequireComponent(typeof(PolygonCollider2D))]
|
||||
[RequireComponent(typeof(Image))]
|
||||
public class EditablePolygon : MonoBehaviour
|
||||
{
|
||||
public Color polygonColor = new Color(0.5f, 0.5f, 1f, 0.5f);
|
||||
public Vector2[] points = new Vector2[]
|
||||
{
|
||||
new Vector2(0, 0),
|
||||
new Vector2(100, 50),
|
||||
new Vector2(50, 100),
|
||||
new Vector2(-50, 50)
|
||||
};
|
||||
|
||||
private PolygonCollider2D polygonCollider;
|
||||
private Image image;
|
||||
|
||||
void OnValidate()
|
||||
{
|
||||
UpdatePolygon();
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
UpdatePolygon();
|
||||
}
|
||||
|
||||
public void UpdatePolygon()
|
||||
{
|
||||
if (polygonCollider == null) polygonCollider = GetComponent<PolygonCollider2D>();
|
||||
if (image == null) image = GetComponent<Image>();
|
||||
|
||||
polygonCollider.points = points;
|
||||
image.color = polygonColor;
|
||||
}
|
||||
public bool IsDown()
|
||||
{
|
||||
if (EventSystem.current == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
PointerEventData pointerEventData = new PointerEventData(EventSystem.current)
|
||||
{
|
||||
position = Input.mousePosition
|
||||
};
|
||||
|
||||
List<RaycastResult> results = new List<RaycastResult>();
|
||||
EventSystem.current.RaycastAll(pointerEventData, results);
|
||||
if (results.Count > 0 && results[0].gameObject == gameObject)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public bool ContainsPoint(Vector2 position)
|
||||
{
|
||||
if (!IsDown())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
RectTransformUtility.ScreenPointToLocalPointInRectangle(
|
||||
transform as RectTransform,
|
||||
position,
|
||||
UIManager.Instance.UICanvas.worldCamera,
|
||||
out Vector2 localPoint);
|
||||
|
||||
//bool flag = polygonCollider.OverlapPoint(localPoint);
|
||||
|
||||
//if (IsPointInPolygon(localPoint, polygonCollider.points))
|
||||
//{
|
||||
// Debug.LogError("点在多边形内");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// Debug.LogError("点不在多边形内");
|
||||
//}
|
||||
|
||||
return IsPointInPolygon(localPoint, points);
|
||||
}
|
||||
|
||||
bool IsPointInPolygon(Vector2 point, Vector2[] polygon)
|
||||
{
|
||||
int polygonLength = polygon.Length;
|
||||
bool inside = false;
|
||||
|
||||
// 从点向右发射水平射线
|
||||
for (int i = 0, j = polygonLength - 1; i < polygonLength; j = i++)
|
||||
{
|
||||
Vector2 pi = polygon[i];
|
||||
Vector2 pj = polygon[j];
|
||||
|
||||
// 检查点是否在顶点上
|
||||
if (Mathf.Approximately(point.x, pi.x) && Mathf.Approximately(point.y, pi.y))
|
||||
return true;
|
||||
|
||||
// 检查边是否与射线相交
|
||||
if (((pi.y > point.y) != (pj.y > point.y)) &&
|
||||
(point.x < (pj.x - pi.x) * (point.y - pi.y) / (pj.y - pi.y) + pi.x))
|
||||
{
|
||||
inside = !inside;
|
||||
}
|
||||
}
|
||||
return inside;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace game
|
||||
{
|
||||
using UnityEditor;
|
||||
|
||||
[CustomEditor(typeof(EditablePolygon))]
|
||||
public class EditablePolygonEditor : Editor
|
||||
{
|
||||
private EditablePolygon polygon;
|
||||
private SerializedProperty pointsProperty;
|
||||
private SerializedProperty colorProperty;
|
||||
|
||||
private const float handleSize = 10f;
|
||||
private int selectedIndex = -1;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
polygon = (EditablePolygon)target;
|
||||
pointsProperty = serializedObject.FindProperty("points");
|
||||
colorProperty = serializedObject.FindProperty("polygonColor");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.PropertyField(colorProperty);
|
||||
EditorGUILayout.LabelField("多边形顶点", EditorStyles.boldLabel);
|
||||
|
||||
for (int i = 0; i < pointsProperty.arraySize; i++)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PropertyField(pointsProperty.GetArrayElementAtIndex(i),
|
||||
new GUIContent("顶点 " + i));
|
||||
|
||||
if (GUILayout.Button("删除", GUILayout.Width(50)))
|
||||
{
|
||||
pointsProperty.DeleteArrayElementAtIndex(i);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
polygon.UpdatePolygon();
|
||||
return;
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("添加顶点"))
|
||||
{
|
||||
pointsProperty.arraySize++;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
polygon.UpdatePolygon();
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
void OnSceneGUI()
|
||||
{
|
||||
RectTransform rectTransform = polygon.GetComponent<RectTransform>();
|
||||
|
||||
for (int i = 0; i < polygon.points.Length; i++)
|
||||
{
|
||||
Vector2 point = polygon.points[i];
|
||||
Vector3 worldPoint = rectTransform.TransformPoint(point);
|
||||
|
||||
Handles.color = i == selectedIndex ? Color.red : Color.green;
|
||||
|
||||
// 绘制可拖拽的handle
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var fmh_147_21_638823244657839550 = Quaternion.identity; Vector3 newWorldPoint = Handles.FreeMoveHandle(
|
||||
worldPoint,
|
||||
handleSize,
|
||||
Vector3.zero,
|
||||
Handles.CircleHandleCap);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(polygon, "Move Polygon Point");
|
||||
polygon.points[i] = rectTransform.InverseTransformPoint(newWorldPoint);
|
||||
polygon.UpdatePolygon();
|
||||
}
|
||||
|
||||
// 检查点击选择
|
||||
if (Event.current.type == EventType.MouseDown &&
|
||||
Event.current.button == 0 &&
|
||||
Vector2.Distance(HandleUtility.WorldToGUIPoint(worldPoint),
|
||||
Event.current.mousePosition) < handleSize)
|
||||
{
|
||||
selectedIndex = i;
|
||||
Event.current.Use();
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制多边形线框
|
||||
Handles.color = polygon.polygonColor;
|
||||
Vector3[] worldPoints = new Vector3[polygon.points.Length + 1];
|
||||
for (int i = 0; i < polygon.points.Length; i++)
|
||||
{
|
||||
worldPoints[i] = rectTransform.TransformPoint(polygon.points[i]);
|
||||
}
|
||||
worldPoints[worldPoints.Length - 1] = worldPoints[0];
|
||||
Handles.DrawPolyLine(worldPoints);
|
||||
|
||||
// 删除选中的顶点
|
||||
if (selectedIndex != -1 && Event.current.type == EventType.KeyDown &&
|
||||
Event.current.keyCode == KeyCode.Delete)
|
||||
{
|
||||
Undo.RecordObject(polygon, "Delete Polygon Point");
|
||||
var newPoints = new Vector2[polygon.points.Length - 1];
|
||||
for (int i = 0, j = 0; i < polygon.points.Length; i++)
|
||||
{
|
||||
if (i != selectedIndex) newPoints[j++] = polygon.points[i];
|
||||
}
|
||||
polygon.points = newPoints;
|
||||
selectedIndex = -1;
|
||||
polygon.UpdatePolygon();
|
||||
Event.current.Use();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
Assets/Scripts/UI/ScratchTicket/EditablePolygon.cs.meta
Normal file
11
Assets/Scripts/UI/ScratchTicket/EditablePolygon.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f284c763bda1f684d95a2c04ad4d58b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,77 @@
|
||||
using asap.core;
|
||||
using cfg;
|
||||
using GameCore;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UniRx;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class EventScratchTicket2FestPackPanel : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private TMP_Text textTimer, textPriceLeft, textPriceRight, textCountLeft, textCountRight, textDiscount;
|
||||
[SerializeField] private Button btnClose, btnBuyLeft, btnBuyRight;
|
||||
private IAPItemList _iapLeft, _iapRight;
|
||||
private PlayerItemData _playerItemData;
|
||||
private DateTime _expireTime;
|
||||
private TimeSpan RemainingTime => _expireTime - ZZTimeHelper.UtcNow();
|
||||
private int _eventId;
|
||||
private Pack _packLeft, _packRight;
|
||||
|
||||
public void Init(EventBreakNormalPackInfo info)
|
||||
{
|
||||
btnClose.onClick.AddListener(OnClickClose);
|
||||
_eventId = info.EventId;
|
||||
_packLeft = info.PackLeft;
|
||||
_packRight = info.PackRight;
|
||||
_expireTime = info.ExpireTime;
|
||||
_playerItemData = GContext.container.Resolve<PlayerItemData>();
|
||||
textTimer.text = ConvertTools.ConvertTime2(RemainingTime);
|
||||
Observable.Interval(TimeSpan.FromSeconds(1.0f)).Subscribe(_ =>
|
||||
{
|
||||
textTimer.text = ConvertTools.ConvertTime2(RemainingTime);
|
||||
if (RemainingTime.TotalSeconds <= 0) OnClickClose();
|
||||
}).AddTo(this);
|
||||
_playerItemData.ResolveIapId(_packLeft.IAPID, out _iapLeft, textPriceLeft);
|
||||
_playerItemData.ResolveIapId(_packRight.IAPID, out _iapRight, textPriceRight);
|
||||
btnBuyLeft.onClick.AddListener(() => _ = OnClickBuy(_packLeft.DropID, _iapLeft));
|
||||
btnBuyRight.onClick.AddListener(() => _ = OnClickBuy(_packRight.DropID, _iapRight));
|
||||
textCountLeft.text =
|
||||
((int)_playerItemData.GetItemDataByDropId(_packLeft.DropID)[0].count).ToString();
|
||||
textCountRight.text =
|
||||
((int)_playerItemData.GetItemDataByDropId(_packRight.DropID)[0].count).ToString();
|
||||
textDiscount.text = LocalizationMgr.GetFormatTextValue("UI_FishingShopPanel_2", GetDiscountNumber());
|
||||
}
|
||||
|
||||
private int GetDiscountNumber()
|
||||
{
|
||||
float discount = _packRight.Rebate * 100;
|
||||
return (int)discount;
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task OnClickBuy(int dropId, IAPItemList iapItemList)
|
||||
{
|
||||
if (RemainingTime.TotalSeconds <= 0)
|
||||
return;
|
||||
bool res = await GContext.container.Resolve<PlayerShopData>().OnBuy(dropId,
|
||||
new ShopBuyTypeData { type = ShopBuyType.EventPack, ID = _eventId }, iapItemList,
|
||||
_playerItemData.GetItemDataByDropId(dropId));
|
||||
if (res)
|
||||
{
|
||||
ShootingRangeAct.EventAggregator.Publish(new ShootingRangeAct.EventAmmoBought());
|
||||
OnClickClose();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClickClose()
|
||||
{
|
||||
// RedPointManager.Instance.SetRedPointState(EventShootingRangeData.PackRedPointId, false);
|
||||
UIManager.Instance.DestroyUI(gameObject.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0c50907e3830c314d9996c8e4146aba8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
using asap.core;
|
||||
using GameCore;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class EventScratchTicketInfoPopupPanel : BasePanel
|
||||
{
|
||||
Button btn_close;
|
||||
|
||||
#region UI
|
||||
private async void OnBtnCloseClickListener()
|
||||
{
|
||||
EventScratchTicketDataManager dataManager = GContext.container.Resolve<EventScratchTicketDataManager>();
|
||||
|
||||
await UIManager.Instance.ShowUI(dataManager.GetUIPanel());
|
||||
UIManager.Instance.DestroyUI(dataManager.GetInfoPanel());
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
// Start is called before the first frame update
|
||||
protected override void Start()
|
||||
{
|
||||
btn_close = transform.Find("btn_close").GetComponent<Button>();
|
||||
btn_close.onClick.RemoveAllListeners();
|
||||
btn_close.onClick.AddListener(OnBtnCloseClickListener);
|
||||
|
||||
base.Start();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5689ae0c325fe264d992b8916b04616b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
917
Assets/Scripts/UI/ScratchTicket/EventScratchTicketPanel.cs
Normal file
917
Assets/Scripts/UI/ScratchTicket/EventScratchTicketPanel.cs
Normal file
@@ -0,0 +1,917 @@
|
||||
using asap.core;
|
||||
using cfg;
|
||||
using GameCore;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using TMPro;
|
||||
using UniRx;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class EventScratchTicketPanel : BasePanel
|
||||
{
|
||||
[Header("奖励设置")]
|
||||
[SerializeField] private float m_ProgressBarSpeed = 0.5f;
|
||||
[SerializeField] private float m_PauseTimeAfterProgressBarIsFull = 0.1f;
|
||||
[SerializeField] private List<EventScratchTicketStampRewardView> m_StampRewardList;
|
||||
[SerializeField] private GameObject m_RewardFlyPrefab;
|
||||
|
||||
[Header("brush设置")]
|
||||
[SerializeField] private float m_Auto_Brush_Waiting_Time = 0.1f;
|
||||
|
||||
[Header("动画效果")]
|
||||
[SerializeField] private string m_AnimScratchStart = "scratch_start";
|
||||
[SerializeField] private float m_AnimScratchStartDurationTime = 0.3f;
|
||||
[SerializeField] private string m_AnimScrachEnd = "scrach_end";
|
||||
[SerializeField] private float m_AnimScrachEndDurationTime = 0.2f;
|
||||
[SerializeField] private Animation m_AnimEmptyRewardAnim;
|
||||
[SerializeField] private string m_AnimEmptyReward = "emoji_show";
|
||||
[SerializeField] private float m_AnimEmptyRewardDurationTime = 0.5f;
|
||||
[SerializeField] private string m_AnimMaskShow = "mask_show";
|
||||
[SerializeField] private string m_AnimMaskDisappear = "mask_disappear";
|
||||
[SerializeField] private float m_AnimMaskWaitingTime = 0.3f;
|
||||
|
||||
[Header("位置")]
|
||||
[SerializeField] private List<Transform> m_RewardFlyTransformList1 = new List<Transform>();
|
||||
[SerializeField] private List<Transform> m_RewardFlyTransformList2 = new List<Transform>();
|
||||
[SerializeField] private List<Transform> m_RewardFlyTransformList3 = new List<Transform>();
|
||||
[SerializeField] private List<Transform> m_RewardFlyTransformList4 = new List<Transform>();
|
||||
[SerializeField] private List<Transform> m_RewardFlyTransformList5 = new List<Transform>();
|
||||
|
||||
#region 新手引导
|
||||
public async void InitGuidance()
|
||||
{
|
||||
//var scratchMain = m_DataManager.GetCurrentEventScratchMain();
|
||||
//GContext.container.Resolve<GuideDataCenter>().InspectTriggerGuide(scratchMain.UIPanel, curPanelName: gameObject.name);
|
||||
|
||||
if (m_DataManager.HasSaveKey(EventScratchTicketConfig.key_first_in)) return;
|
||||
|
||||
m_DataManager.SaveData(EventScratchTicketConfig.key_first_in, "ok");
|
||||
|
||||
await UIManager.Instance.ShowUI(m_DataManager.GetInfoPanel());
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 刮刮卡相关
|
||||
private void StartScratch1()
|
||||
{
|
||||
brush_coin2.gameObject.SetActive(true);
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketChangeScratchTypeData()
|
||||
{
|
||||
ScratchType = EventScratchTicketScratchType.TypeScratch1
|
||||
});
|
||||
}
|
||||
private int m_Scratch5MaxNum = 5;
|
||||
private int m_Scratch5CumulativeNum = 0;
|
||||
private void StartScratch5()
|
||||
{
|
||||
brush_coin2.gameObject.SetActive(true);
|
||||
if (m_Scratch5CumulativeNum >= m_Scratch5MaxNum)
|
||||
{
|
||||
// 5连刮奖励
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketStampRewardFlyData()
|
||||
{
|
||||
ScratchType = EventScratchTicketScratchType.TypeScratch5
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// 更换卡片
|
||||
m_DataManager.UpdateLuckyValueAndWeight();
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketUpdateEventScratchCardData());
|
||||
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketChangeScratchTypeData()
|
||||
{
|
||||
ScratchType = EventScratchTicketScratchType.TypeScratch5
|
||||
});
|
||||
StartCoroutine(StartAutoBrush());
|
||||
++m_Scratch5CumulativeNum;
|
||||
}
|
||||
}
|
||||
private IEnumerator StartAutoBrush()
|
||||
{
|
||||
yield return new WaitForSeconds(m_Auto_Brush_Waiting_Time);
|
||||
int count = brush_coin2_anim_list.Count;
|
||||
int index = UnityEngine.Random.Range(0, count);
|
||||
string anim = brush_coin2_anim_list[index];
|
||||
brush_coin2.Play(brush_coin2_anim_list[index]);
|
||||
|
||||
Debug.LogWarning("--- 当前五连刮使用动画:" + anim);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 链式礼包 & 普通礼包 & 奖励等
|
||||
private async void GotoChainPack()
|
||||
{
|
||||
EventScratchTicketChainPackData chainPackData = m_DataManager.GetChainPackData();
|
||||
if (chainPackData == null) return;
|
||||
|
||||
if (chainPackData.IsChainPackDepleted)
|
||||
{
|
||||
// 普通礼包
|
||||
GameObject go = await UIManager.Instance.ShowUI(m_DataManager.GetPackPanel());
|
||||
var normalPackPanel = go.GetComponent<EventScratchTicket2FestPackPanel>();
|
||||
normalPackPanel.Init(m_DataManager.GetNormalPackData());
|
||||
}
|
||||
else
|
||||
{
|
||||
// 链式礼包
|
||||
GameObject go = await UIManager.Instance.ShowUI(m_DataManager.GetChainPackPanel());
|
||||
var chainPackPanel = go.GetComponent<ChainPackPanel>();
|
||||
chainPackPanel.Init(chainPackData);
|
||||
}
|
||||
}
|
||||
private void CheckForStampReward(EventScratchTicketScratchType scratchType)
|
||||
{
|
||||
if (m_DataManager.GetStampRewardNum() > 0)
|
||||
{
|
||||
HandleStampRewardList(scratchType);
|
||||
}
|
||||
else
|
||||
{
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketPanelPlayEndAnimData()
|
||||
{
|
||||
ScratchType = scratchType
|
||||
});
|
||||
}
|
||||
}
|
||||
private async void HandleStampRewardList(EventScratchTicketScratchType scratchType)
|
||||
{
|
||||
if (m_DataManager.GetStampRewardNum() > 0)
|
||||
{
|
||||
PlayerItemData playerItemData = GContext.container.Resolve<PlayerItemData>();
|
||||
EventScratchCard card = m_DataManager.GetFirstStampReward();
|
||||
if (card != null)
|
||||
{
|
||||
ItemData rewardItem = playerItemData.GetItemDataOne(card.DropReward);
|
||||
|
||||
m_DataManager.RemoveFirstStampReward();
|
||||
|
||||
GameObject go = await UIManager.Instance.ShowUI(m_DataManager.GetRewardPanel());
|
||||
var rewardPopupPanel = go.GetComponent<EventScratchTicketRewardPopupPanel>();
|
||||
rewardPopupPanel.Init(rewardItem, card, () =>
|
||||
{
|
||||
HandleStampRewardList(scratchType);
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await HandleReward(scratchType);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 动画相关
|
||||
private IEnumerator ScratchStartAnim(Action action)
|
||||
{
|
||||
m_animation.Play(m_AnimScratchStart);
|
||||
yield return new WaitForSeconds(m_AnimScratchStartDurationTime);
|
||||
if (action != null)
|
||||
{
|
||||
action.Invoke();
|
||||
}
|
||||
}
|
||||
private IEnumerator ScratchEndAnim(EventScratchTicketScratchType scratchType, Action<EventScratchTicketScratchType> action)
|
||||
{
|
||||
m_animation.Play(m_AnimScrachEnd);
|
||||
yield return new WaitForSeconds(m_AnimScrachEndDurationTime);
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketChangeScratchTypeData()
|
||||
{
|
||||
ScratchType = EventScratchTicketScratchType.TypeInvalid
|
||||
});
|
||||
if (action != null)
|
||||
{
|
||||
action.Invoke(scratchType);
|
||||
}
|
||||
}
|
||||
private void StopScratch()
|
||||
{
|
||||
brush_coin2.gameObject.SetActive(false);
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketChangeScratchTypeData()
|
||||
{
|
||||
ScratchType = EventScratchTicketScratchType.TypeTemporary
|
||||
});
|
||||
}
|
||||
|
||||
private List<Transform> GetRewardFlyTransformList(int count)
|
||||
{
|
||||
switch (count)
|
||||
{
|
||||
case 5:
|
||||
return m_RewardFlyTransformList5;
|
||||
case 4:
|
||||
return m_RewardFlyTransformList4;
|
||||
case 3:
|
||||
return m_RewardFlyTransformList3;
|
||||
case 2:
|
||||
return m_RewardFlyTransformList2;
|
||||
case 1:
|
||||
return m_RewardFlyTransformList1;
|
||||
default:
|
||||
return m_RewardFlyTransformList5;
|
||||
}
|
||||
}
|
||||
private async Task PlayRewardFlyAnim(EventScratchTicketStampRewardFlyData data)
|
||||
{
|
||||
if (data.ScratchType == EventScratchTicketScratchType.TypeScratch1)
|
||||
{
|
||||
await PlayStampRewardFlyAnimInTypeScratch1(data);
|
||||
|
||||
await HandleReward(data.ScratchType);
|
||||
}
|
||||
else if (data.ScratchType == EventScratchTicketScratchType.TypeScratch5)
|
||||
{
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketStartStampRewardCountUpdateData());
|
||||
//mask.gameObject.SetActive(true);
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketStartMaskData());
|
||||
|
||||
var taskList = new List<Task>();
|
||||
|
||||
int count = m_DataManager.ScratchStampList.Count;
|
||||
|
||||
List<Transform> transformList = GetRewardFlyTransformList(count);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int cardID = m_DataManager.ScratchStampList[i];
|
||||
EventScratchCard card = m_DataManager.GetEventScratchCard(cardID);
|
||||
|
||||
if (card.DropReward > 0)
|
||||
{
|
||||
taskList.Add(PlayStampRewardFlyAnimInTypeScratch5(data, card, transformList, i));
|
||||
}
|
||||
}
|
||||
|
||||
if (taskList.Count > 0)
|
||||
{
|
||||
await Task.WhenAll(taskList.ToArray());
|
||||
}
|
||||
|
||||
m_DataManager.ClearScratchStampList();
|
||||
|
||||
//mask.gameObject.SetActive(false);
|
||||
StopMask();
|
||||
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketStopStampRewardCountUpdateData());
|
||||
|
||||
await HandleReward(data.ScratchType);
|
||||
}
|
||||
}
|
||||
private async Task HandleReward(EventScratchTicketScratchType scratchType)
|
||||
{
|
||||
int count = m_StampRewardList.Count;
|
||||
var taskArr = new Task<bool>[count];
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
taskArr[i] = m_StampRewardList[i].CheckReward();
|
||||
}
|
||||
|
||||
await Task.WhenAll(taskArr);
|
||||
|
||||
bool flag = false;
|
||||
|
||||
foreach (var task in taskArr)
|
||||
{
|
||||
if (task.Result)
|
||||
{
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_DataManager.SyncData();
|
||||
|
||||
if (flag)
|
||||
{
|
||||
CheckForStampReward(scratchType);
|
||||
}
|
||||
else
|
||||
{
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketPanelPlayEndAnimData()
|
||||
{
|
||||
ScratchType = scratchType
|
||||
});
|
||||
}
|
||||
}
|
||||
private async Task PlayStampRewardFlyAnimInTypeScratch1(EventScratchTicketStampRewardFlyData data)
|
||||
{
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketStartStampRewardCountUpdateData());
|
||||
|
||||
//mask.gameObject.SetActive(true);
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketStartMaskData());
|
||||
|
||||
EventScratchCard scratchCard = m_DataManager.GetFirstScratchStamp();
|
||||
|
||||
EventScratchTicketStampRewardView stampRewardView = null;
|
||||
foreach (var item in m_StampRewardList)
|
||||
{
|
||||
if (item.EventScratchQuality == scratchCard.Quality)
|
||||
{
|
||||
stampRewardView = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (stampRewardView == null)
|
||||
{
|
||||
Debug.LogError("--- PlayRewardFlyAnimStep 数据错误,找不到对应的 EventScratchTicketStampRewardView");
|
||||
return;
|
||||
}
|
||||
Sprite icon = m_DataManager.SpriteAtlas.GetSprite(scratchCard.Icon);
|
||||
Vector3 srcPosition = data.SrcPosition;
|
||||
var targetImg = stampRewardView.GetFirstEmptyImage();
|
||||
Vector3 destPosition = targetImg.rectTransform.position;
|
||||
Vector3 localScale = data.LocalScale;
|
||||
float iconSize = targetImg.rectTransform.rect.width;
|
||||
|
||||
int rewardNum = stampRewardView.RewardNum;
|
||||
var recordData = m_DataManager.AddRecordData();
|
||||
recordData.TicketID = scratchCard.ID;
|
||||
recordData.SetScratchType(data.ScratchType);
|
||||
recordData.TicketFinishID = ((rewardNum % scratchCard.Count) == 0) ? scratchCard.DropReward : 0;
|
||||
|
||||
CollectionItemFly collectionItemFly = new CollectionItemFly()
|
||||
{
|
||||
icon = m_DataManager.SpriteAtlas.GetSprite(scratchCard.Icon),
|
||||
numStr = "",
|
||||
sourcePos = data.SrcPosition,
|
||||
destPos = destPosition,
|
||||
scale = data.LocalScale,
|
||||
isPlayOpen = true,
|
||||
isPlayClose = true,
|
||||
isDestinationRewardStash = false,
|
||||
// isDestinationRewardStash = false,
|
||||
targetIconSize = iconSize
|
||||
};
|
||||
//var rewardFly = m_RewardFlyList[0];
|
||||
var rewardFly = Instantiate(m_RewardFlyPrefab, m_RewardFlyPrefab.transform.parent).GetComponent<RewardFly>();
|
||||
rewardFly.gameObject.SetActive(true);
|
||||
|
||||
await rewardFly.ShowAsync(collectionItemFly);
|
||||
|
||||
Destroy(rewardFly.gameObject);
|
||||
//mask.gameObject.SetActive(false);
|
||||
StopMask();
|
||||
|
||||
targetImg.gameObject.SetActive(true);
|
||||
|
||||
m_DataManager.ClearScratchStampList();
|
||||
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketStopStampRewardCountUpdateData());
|
||||
}
|
||||
private async Task PlayStampRewardFlyAnimInTypeScratch5(EventScratchTicketStampRewardFlyData data, EventScratchCard scratchCard, List<Transform> transformList, int index)
|
||||
{
|
||||
EventScratchTicketStampRewardView stampRewardView = null;
|
||||
foreach (var item in m_StampRewardList)
|
||||
{
|
||||
if (item.EventScratchQuality == scratchCard.Quality)
|
||||
{
|
||||
stampRewardView = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (stampRewardView == null)
|
||||
{
|
||||
Debug.LogError("--- PlayRewardFlyAnimStep 数据错误,找不到对应的 EventScratchTicketStampRewardView");
|
||||
return;
|
||||
}
|
||||
Sprite icon = m_DataManager.SpriteAtlas.GetSprite(scratchCard.Icon);
|
||||
Vector3 srcPosition = data.SrcPosition;
|
||||
var targetImg = stampRewardView.GetFirstEmptyImage();
|
||||
Vector3 destPosition = targetImg.rectTransform.position;
|
||||
Vector3 localScale = data.LocalScale;
|
||||
float iconSize = targetImg.rectTransform.rect.width;
|
||||
|
||||
var rewardFlyTransform = transformList[index];
|
||||
|
||||
int rewardNum = stampRewardView.RewardNum;
|
||||
var recordData = m_DataManager.AddRecordData();
|
||||
recordData.TicketID = scratchCard.ID;
|
||||
recordData.SetScratchType(data.ScratchType);
|
||||
recordData.TicketFinishID = ((rewardNum % scratchCard.Count) == 0) ? scratchCard.DropReward : 0;
|
||||
|
||||
CollectionItemFly collectionItemFly = new CollectionItemFly()
|
||||
{
|
||||
icon = m_DataManager.SpriteAtlas.GetSprite(scratchCard.Icon),
|
||||
numStr = "",
|
||||
sourcePos = rewardFlyTransform.position,
|
||||
destPos = destPosition,
|
||||
scale = rewardFlyTransform.localScale,
|
||||
isPlayOpen = true,
|
||||
isPlayClose = true,
|
||||
isDestinationRewardStash = false,
|
||||
// isDestinationRewardStash = false,
|
||||
targetIconSize = iconSize
|
||||
};
|
||||
var rewardFly = Instantiate(m_RewardFlyPrefab, m_RewardFlyPrefab.transform.parent).GetComponent<RewardFly>();
|
||||
rewardFly.gameObject.SetActive(true);
|
||||
|
||||
await rewardFly.ShowAsync(collectionItemFly);
|
||||
|
||||
Destroy(rewardFly.gameObject);
|
||||
|
||||
targetImg.gameObject.SetActive(true);
|
||||
}
|
||||
private IEnumerator PlayRewardEmptyAnim(EventScratchTicketRewardEmptyData data)
|
||||
{
|
||||
// 播放空奖动画
|
||||
m_AnimEmptyRewardAnim.gameObject.SetActive(true);
|
||||
m_AnimEmptyRewardAnim.Play(m_AnimEmptyReward);
|
||||
yield return new WaitForSeconds(m_AnimEmptyRewardDurationTime);
|
||||
m_AnimEmptyRewardAnim.gameObject.SetActive(false);
|
||||
|
||||
EventScratchCard scratchCard = m_DataManager.GetCurrentEventScratchCard();
|
||||
var recordData = m_DataManager.AddRecordData();
|
||||
recordData.TicketID = scratchCard.ID;
|
||||
recordData.SetScratchType(data.ScratchType);
|
||||
recordData.TicketFinishID = 0;
|
||||
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketOutData()
|
||||
{
|
||||
ScratchType = data.ScratchType
|
||||
});
|
||||
|
||||
//if (data.ScratchType == EventScratchTicketScratchType.TypeScratch1)
|
||||
//{
|
||||
// FishingScratchTicketAct.Publish(new EventScratchTicketPanelPlayEndAnimData()
|
||||
// {
|
||||
// ScratchType = data.ScratchType
|
||||
// });
|
||||
//}
|
||||
//else if (data.ScratchType == EventScratchTicketScratchType.TypeScratch5)
|
||||
//{
|
||||
// FishingScratchTicketAct.Publish(new EventScratchTicketPlayScratchType5());
|
||||
//}
|
||||
}
|
||||
private IEnumerator StartMask()
|
||||
{
|
||||
mask.gameObject.SetActive(true);
|
||||
|
||||
mask.Play(m_AnimMaskShow);
|
||||
|
||||
yield return new WaitForSeconds(m_AnimMaskWaitingTime);
|
||||
|
||||
mask.Play(m_AnimMaskDisappear);
|
||||
}
|
||||
private void StopMask()
|
||||
{
|
||||
// 停止播放动画
|
||||
|
||||
mask.gameObject.SetActive(false);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 事件相关
|
||||
private void InitEvent()
|
||||
{
|
||||
FishingScratchTicketAct.Subscribe<EventScratchTicketTokenUpdateData>(UpdateToken);
|
||||
FishingScratchTicketAct.Subscribe<EventScratchTicketStampRewardFlyData>(OnStampRewardFlyEvent);
|
||||
FishingScratchTicketAct.Subscribe<EventScratchTicketPanelPlayEndAnimData>(PlayScratchEndAnim);
|
||||
FishingScratchTicketAct.Subscribe<EventScratchTicketRewardTaskUpdateData>(UpdateRewardTask);
|
||||
FishingScratchTicketAct.Subscribe<EventScratchTicketPlayScratchType5>(PlayScratchType5);
|
||||
FishingScratchTicketAct.Subscribe<EventScratchTicketRewardEmptyData>(OnRewardEmptyEvent);
|
||||
FishingScratchTicketAct.Subscribe<EventScratchTicketRevealedAllData>(OnScratchCardRevealedAll);
|
||||
FishingScratchTicketAct.Subscribe<EventScratchTicketStartMaskData>(OnStartMaskEvent);
|
||||
|
||||
// 监听关闭奖励面板
|
||||
GContext.OnEvent<RewardPanelClose>().Subscribe(OnRewardPanelClose).AddTo(FishingScratchTicketAct.Disposables);
|
||||
}
|
||||
private void OnStartMaskEvent(EventScratchTicketStartMaskData data)
|
||||
{
|
||||
StartCoroutine(StartMask());
|
||||
}
|
||||
private void OnScratchCardRevealedAll(EventScratchTicketRevealedAllData data)
|
||||
{
|
||||
if (brush_coin2 == null) return;
|
||||
|
||||
brush_coin2.Stop();
|
||||
brush_coin2.gameObject.SetActive(false);
|
||||
}
|
||||
private void OnRewardEmptyEvent(EventScratchTicketRewardEmptyData data)
|
||||
{
|
||||
this.StartCoroutine(PlayRewardEmptyAnim(data));
|
||||
}
|
||||
private void OnRewardPanelClose(RewardPanelClose data)
|
||||
{
|
||||
//FishingScratchTicketAct.Publish(new EventScratchTicketPanelPlayEndAnimData());
|
||||
}
|
||||
private void PlayScratchType5(EventScratchTicketPlayScratchType5 data)
|
||||
{
|
||||
StartScratch5();
|
||||
}
|
||||
private void PlayScratchEndAnim(EventScratchTicketPanelPlayEndAnimData data)
|
||||
{
|
||||
if (m_DataManager.ScratchTicketData.ConsumedToken > 0)
|
||||
{
|
||||
StartCoroutine(ScratchEndAnim(data.ScratchType, CheckTokenReward));
|
||||
}
|
||||
else
|
||||
{
|
||||
StartCoroutine(ScratchEndAnim(data.ScratchType, null));
|
||||
}
|
||||
StopScratch();
|
||||
}
|
||||
private void CheckTokenReward(EventScratchTicketScratchType scratchType)
|
||||
{
|
||||
// token 消费积分奖励
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketRewardTaskUpdateData()
|
||||
{
|
||||
ScratchType = scratchType,
|
||||
Token = m_DataManager.ScratchTicketData.ConsumedToken
|
||||
});
|
||||
}
|
||||
private async void OnStampRewardFlyEvent(EventScratchTicketStampRewardFlyData data)
|
||||
{
|
||||
if (data == null) return;
|
||||
await PlayRewardFlyAnim(data);
|
||||
}
|
||||
private void UpdateToken(EventScratchTicketTokenUpdateData data)
|
||||
{
|
||||
if (m_DataManager == null || token_text_num == null) return;
|
||||
|
||||
int token = m_DataManager.GetToken();
|
||||
token_text_num.text = "" + token;
|
||||
}
|
||||
private async void UpdateRewardTask(EventScratchTicketRewardTaskUpdateData data)
|
||||
{
|
||||
if (m_DataManager == null) return;
|
||||
|
||||
PlayerItemData playerItemData = GContext.container.Resolve<PlayerItemData>();
|
||||
|
||||
EventScratchReward finalReward = m_DataManager.GetEventScratchFinalReward();
|
||||
var finalDataItem = playerItemData.GetItemDataOne(finalReward.DropReward);
|
||||
top_reward.SetData(finalDataItem, abbr: true);
|
||||
|
||||
if (data == null && m_DataManager.ScratchTicketData.ConsumedToken > 0)
|
||||
{
|
||||
data = new EventScratchTicketRewardTaskUpdateData()
|
||||
{
|
||||
ScratchType = EventScratchTicketScratchType.TypeInvalid,
|
||||
Token = m_DataManager.ScratchTicketData.ConsumedToken
|
||||
};
|
||||
}
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
EventScratchReward curReward = m_DataManager.GetEventScratchReward(m_DataManager.ScratchTicketData.EventScratchRewardTaskID);
|
||||
var curDataItem = playerItemData.GetItemDataOne(curReward.DropReward);
|
||||
reward.SetData(curDataItem, abbr: true);
|
||||
|
||||
img_bar.fillAmount = (float)m_DataManager.ScratchTicketData.RewardTaskConsumedToken / curReward.TokenRequired;
|
||||
text_progress.text = m_DataManager.ScratchTicketData.RewardTaskConsumedToken + "/" + curReward.TokenRequired;
|
||||
}
|
||||
else
|
||||
{
|
||||
await StartUpdateProgressBar(data);
|
||||
}
|
||||
}
|
||||
private Queue<EventScratchTicketRewardDisplayUpdateData> GetRewardDisplayUpdateDataQueue(EventScratchTicketRewardTaskUpdateData data)
|
||||
{
|
||||
Queue<EventScratchTicketRewardDisplayUpdateData> updateQueue = new Queue<EventScratchTicketRewardDisplayUpdateData>();
|
||||
|
||||
int fromToken = m_DataManager.ScratchTicketData.RewardTaskConsumedToken;
|
||||
int targetToken = fromToken + data.Token;
|
||||
|
||||
int taskID = m_DataManager.ScratchTicketData.EventScratchRewardTaskID;
|
||||
EventScratchReward curScratchReward = m_DataManager.GetEventScratchReward(taskID);
|
||||
|
||||
while (targetToken >= curScratchReward.TokenRequired)
|
||||
{
|
||||
EventScratchTicketRewardDisplayUpdateData rewardDisplayUpdateData = new EventScratchTicketRewardDisplayUpdateData();
|
||||
rewardDisplayUpdateData.TaskID = taskID;
|
||||
rewardDisplayUpdateData.Reward = m_DataManager.GetEventScratchReward(rewardDisplayUpdateData.TaskID);
|
||||
rewardDisplayUpdateData.FromToken = fromToken;
|
||||
rewardDisplayUpdateData.TargetToken = curScratchReward.TokenRequired;
|
||||
rewardDisplayUpdateData.LevelToken = curScratchReward.TokenRequired;
|
||||
rewardDisplayUpdateData.FromRatio = (float)rewardDisplayUpdateData.FromToken / rewardDisplayUpdateData.LevelToken;
|
||||
rewardDisplayUpdateData.TargetRatio = (float)rewardDisplayUpdateData.TargetToken / rewardDisplayUpdateData.LevelToken;
|
||||
|
||||
updateQueue.Enqueue(rewardDisplayUpdateData);
|
||||
|
||||
fromToken = 0;
|
||||
targetToken -= curScratchReward.TokenRequired;
|
||||
|
||||
taskID = curScratchReward.NextTask;
|
||||
curScratchReward = m_DataManager.GetEventScratchReward(taskID);
|
||||
}
|
||||
|
||||
{
|
||||
EventScratchTicketRewardDisplayUpdateData rewardDisplayUpdateData = new EventScratchTicketRewardDisplayUpdateData();
|
||||
rewardDisplayUpdateData.TaskID = taskID;
|
||||
rewardDisplayUpdateData.Reward = m_DataManager.GetEventScratchReward(rewardDisplayUpdateData.TaskID);
|
||||
rewardDisplayUpdateData.FromToken = fromToken;
|
||||
rewardDisplayUpdateData.TargetToken = targetToken;
|
||||
rewardDisplayUpdateData.LevelToken = curScratchReward.TokenRequired;
|
||||
rewardDisplayUpdateData.FromRatio = (float)rewardDisplayUpdateData.FromToken / rewardDisplayUpdateData.LevelToken;
|
||||
rewardDisplayUpdateData.TargetRatio = (float)rewardDisplayUpdateData.TargetToken / rewardDisplayUpdateData.LevelToken;
|
||||
updateQueue.Enqueue(rewardDisplayUpdateData);
|
||||
}
|
||||
return updateQueue;
|
||||
}
|
||||
public async Task StartUpdateProgressBar(EventScratchTicketRewardTaskUpdateData data)
|
||||
{
|
||||
Queue<EventScratchTicketRewardDisplayUpdateData> updateQueue = GetRewardDisplayUpdateDataQueue(data);
|
||||
|
||||
bool syncData = updateQueue.Count > 0;
|
||||
|
||||
PlayerItemData playerItemData = GContext.container.Resolve<PlayerItemData>();
|
||||
|
||||
EventScratchReward curReward = null;
|
||||
|
||||
int finalToken = 0;
|
||||
|
||||
while (updateQueue.Count > 0)
|
||||
{
|
||||
var item = updateQueue.Dequeue();
|
||||
|
||||
int fromToken = item.FromToken;
|
||||
int targetToken = item.TargetToken;
|
||||
int levelToken = item.LevelToken;
|
||||
float fromRatio = item.FromRatio;
|
||||
float targetRatio = item.TargetRatio;
|
||||
|
||||
finalToken = targetToken;
|
||||
|
||||
curReward = item.Reward;
|
||||
|
||||
var curDataItem = playerItemData.GetItemDataOne(curReward.DropReward);
|
||||
reward.SetData(curDataItem, abbr: true);
|
||||
|
||||
text_progress.text = fromToken + "/" + levelToken;
|
||||
img_bar.fillAmount = fromRatio;
|
||||
|
||||
await Awaiters.NextFrame;
|
||||
|
||||
while (fromRatio < targetRatio)
|
||||
{
|
||||
fromRatio += m_ProgressBarSpeed * Time.deltaTime;
|
||||
fromToken = (int)(levelToken * fromRatio);
|
||||
|
||||
text_progress.text = fromToken + "/" + levelToken;
|
||||
img_bar.fillAmount = fromRatio;
|
||||
|
||||
await Awaiters.NextFrame;
|
||||
}
|
||||
|
||||
text_progress.text = targetToken + "/" + levelToken;
|
||||
img_bar.fillAmount = targetRatio;
|
||||
|
||||
if (targetToken >= levelToken && curReward.DropReward > 0)
|
||||
{
|
||||
await HandleTokenReward(curReward.DropReward);
|
||||
}
|
||||
|
||||
if (fromToken >= 0f)
|
||||
{
|
||||
await Awaiters.Seconds(m_PauseTimeAfterProgressBarIsFull);
|
||||
}
|
||||
else
|
||||
{
|
||||
await Awaiters.NextFrame;
|
||||
}
|
||||
}
|
||||
|
||||
m_DataManager.RecordStatisticalData();
|
||||
|
||||
m_DataManager.ScratchTicketData.EventScratchRewardTaskID = curReward.TaskID;
|
||||
m_DataManager.ScratchTicketData.ConsumedToken = 0;
|
||||
m_DataManager.ScratchTicketData.RewardTaskConsumedToken = finalToken;
|
||||
m_DataManager.SyncData();
|
||||
|
||||
m_DataManager.ClearRecordList();
|
||||
}
|
||||
private async Task HandleTokenReward(int rewardId)
|
||||
{
|
||||
//mask.gameObject.SetActive(true);
|
||||
|
||||
ItemData itemData = GContext.container.Resolve<PlayerItemData>().GetItemDataOne(rewardId);
|
||||
|
||||
Vector3 srcPosition = reward.transform.position;
|
||||
//var targetImg = stampRewardView.GetFirstEmptyImage();
|
||||
Vector3 destPosition = m_BtnPack.transform.position;
|
||||
float iconSize = m_BtnPack.Icon.rect.width;
|
||||
|
||||
CollectionItemFly collectionItemFly = new CollectionItemFly()
|
||||
{
|
||||
itemID = itemData.id,
|
||||
numStr = "",
|
||||
sourcePos = srcPosition,
|
||||
destPos = destPosition,
|
||||
scale = reward.icon.rectTransform.localScale,
|
||||
isPlayOpen = true,
|
||||
isPlayClose = true,
|
||||
isDestinationRewardStash = false,
|
||||
// isDestinationRewardStash = false,
|
||||
targetIconSize = iconSize
|
||||
};
|
||||
var rewardFly = Instantiate(m_RewardFlyPrefab, m_RewardFlyPrefab.transform.parent).GetComponent<RewardFly>();
|
||||
rewardFly.gameObject.SetActive(true);
|
||||
|
||||
await rewardFly.ShowAsync(collectionItemFly);
|
||||
|
||||
Destroy(rewardFly.gameObject);
|
||||
//mask.gameObject.SetActive(false);
|
||||
|
||||
List<ItemData> rewardList = new List<ItemData>();
|
||||
rewardList.Add(itemData);
|
||||
|
||||
// GContext.container.Resolve<PlayerItemData>().AddItem(rewardList);
|
||||
GContext.Publish(new DeferredRewardStashService.EventStashItems { Items = rewardList });
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UI
|
||||
// animation
|
||||
private Animation m_animation;
|
||||
|
||||
// questionmark
|
||||
private Button btn_questionmark;
|
||||
|
||||
private TMP_Text text_time;
|
||||
|
||||
// 关闭按钮
|
||||
private Button btn_close;
|
||||
|
||||
// icon_ticket
|
||||
private TMP_Text token_text_num;
|
||||
private Button icon_ticket;
|
||||
|
||||
// mask
|
||||
private Image click_mask;
|
||||
private Animation mask;
|
||||
|
||||
// reward_fly
|
||||
//private List<RewardFly> m_RewardFlyList = new List<RewardFly>();
|
||||
|
||||
// scratch 1 & scratch 5
|
||||
private Button btn_scratch_1;
|
||||
private Button btn_scratch_5;
|
||||
|
||||
// brush
|
||||
private Image brush_coin1;
|
||||
private Animation brush_coin2;
|
||||
private List<string> brush_coin2_anim_list = new List<string>();
|
||||
|
||||
// bar
|
||||
private Animation anim_bar;
|
||||
private RewardItemNew top_reward;
|
||||
private Image img_bar;
|
||||
private RewardItemNew reward;
|
||||
private TMP_Text text_progress;
|
||||
|
||||
// pack
|
||||
private DeferredRewardStashButton m_BtnPack;
|
||||
|
||||
private void InitUI()
|
||||
{
|
||||
// animation
|
||||
m_animation = transform.GetComponent<Animation>();
|
||||
|
||||
// btn_questionmark
|
||||
btn_questionmark = transform.Find("root/title/btn_questionmark").GetComponent<Button>();
|
||||
btn_questionmark.onClick.AddListener(OnBtnQuestionmarkClickListener);
|
||||
|
||||
text_time = transform.Find("root/title/text_time").GetComponent<TMP_Text>();
|
||||
text_time.text = LocalizationMgr.GetFormatTextValue("UI_COMMON_end", ConvertTools.ConvertTime2(m_DataManager.RemainingTime));
|
||||
Observable.Interval(TimeSpan.FromSeconds(1.0f)).Subscribe(_ =>
|
||||
{
|
||||
text_time.text = LocalizationMgr.GetFormatTextValue("UI_COMMON_end", ConvertTools.ConvertTime2(m_DataManager.RemainingTime));
|
||||
}).AddTo(this);
|
||||
|
||||
// 关闭按钮
|
||||
btn_close = transform.Find("btn_close").GetComponent<Button>();
|
||||
btn_close.onClick.AddListener(OnBtnCloseClickListener);
|
||||
|
||||
// icon_ticket
|
||||
icon_ticket = transform.Find("root/icon_ticket").GetComponent<Button>();
|
||||
icon_ticket.onClick.AddListener(OnBtnIconTicketClickListener);
|
||||
token_text_num = icon_ticket.transform.Find("text_num").GetComponent<TMP_Text>();
|
||||
|
||||
// mask
|
||||
click_mask = transform.Find("click_mask").GetComponent<Image>();
|
||||
click_mask.gameObject.SetActive(false);
|
||||
mask = transform.Find("mask").GetComponent<Animation>();
|
||||
mask.gameObject.SetActive(false);
|
||||
|
||||
// reward_fly
|
||||
//for (int i = 1; i < 6; ++i)
|
||||
//{
|
||||
// var rewardFly = transform.Find($"RewardFly{i}").GetComponent<RewardFly>();
|
||||
// rewardFly.gameObject.SetActive(false);
|
||||
// m_RewardFlyList.Add(rewardFly);
|
||||
//}
|
||||
|
||||
// scratch 1 & scratch 5
|
||||
btn_scratch_1 = transform.Find("root/btn_scratch_1/btn_green").GetComponent<Button>();
|
||||
btn_scratch_1.onClick.AddListener(OnBtnScratch1ClickListener);
|
||||
btn_scratch_5 = transform.Find("root/btn_scratch_5/btn_green").GetComponent<Button>();
|
||||
btn_scratch_5.onClick.AddListener(OnBtnScratch5ClickListener);
|
||||
|
||||
// brush
|
||||
brush_coin1 = transform.Find("root/coin1").GetComponent<Image>();
|
||||
brush_coin1.gameObject.SetActive(true);
|
||||
brush_coin2 = transform.Find("root/coin2").GetComponent<Animation>();
|
||||
brush_coin2.gameObject.SetActive(false);
|
||||
brush_coin2_anim_list.Clear();
|
||||
foreach (AnimationState animation in brush_coin2)
|
||||
{
|
||||
brush_coin2_anim_list.Add(animation.name);
|
||||
}
|
||||
|
||||
// bar
|
||||
anim_bar = transform.Find("root/bar").GetComponent<Animation>();
|
||||
top_reward = anim_bar.transform.Find("top_reward").GetComponent<RewardItemNew>();
|
||||
img_bar = anim_bar.transform.Find("bar").GetComponent<Image>();
|
||||
reward = anim_bar.transform.Find("reward").GetComponent<RewardItemNew>();
|
||||
text_progress = anim_bar.transform.Find("text_progress").GetComponent<TMP_Text>();
|
||||
|
||||
// pack
|
||||
m_BtnPack = transform.Find("root/btn_pack").GetComponent<DeferredRewardStashButton>();
|
||||
}
|
||||
private void OnBtnScratch1ClickListener()
|
||||
{
|
||||
// 更换卡片
|
||||
m_DataManager.GetNextScratchTicketData();
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketUpdateEventScratchCardData());
|
||||
|
||||
m_DataManager.SyncTempRecordData();
|
||||
|
||||
bool flag = m_DataManager.ConsumeTokens(1);
|
||||
if (flag)
|
||||
{
|
||||
StartCoroutine(ScratchStartAnim(StartScratch1));
|
||||
}
|
||||
else
|
||||
{
|
||||
GotoChainPack();
|
||||
}
|
||||
}
|
||||
private void OnBtnScratch5ClickListener()
|
||||
{
|
||||
// 更换卡片
|
||||
m_DataManager.GetNextScratchTicketData();
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketUpdateEventScratchCardData());
|
||||
|
||||
m_DataManager.SyncTempRecordData();
|
||||
|
||||
m_Scratch5CumulativeNum = 0;
|
||||
bool flag = m_DataManager.ConsumeTokens(5);
|
||||
if (flag)
|
||||
{
|
||||
StartCoroutine(ScratchStartAnim(StartScratch5));
|
||||
}
|
||||
else
|
||||
{
|
||||
GotoChainPack();
|
||||
}
|
||||
}
|
||||
private async void OnBtnQuestionmarkClickListener()
|
||||
{
|
||||
await UIManager.Instance.ShowUI(m_DataManager.GetInfoPanel());
|
||||
//UIManager.Instance.HideUI(m_DataManager.GetUIPanel());
|
||||
}
|
||||
public void OnBtnCloseClickListener()
|
||||
{
|
||||
// 关闭当前Act
|
||||
GContext.Publish(new UnloadActToNextAct());
|
||||
}
|
||||
private void OnBtnIconTicketClickListener()
|
||||
{
|
||||
GotoChainPack();
|
||||
}
|
||||
public void RefreshData()
|
||||
{
|
||||
UpdateToken(null);
|
||||
|
||||
UpdateRewardTask(null);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
private EventScratchTicketDataManager m_DataManager;
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
m_DataManager = GContext.container.Resolve<EventScratchTicketDataManager>();
|
||||
|
||||
InitUI();
|
||||
|
||||
InitEvent();
|
||||
|
||||
RefreshData();
|
||||
|
||||
InitGuidance();
|
||||
}
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d384948f13c6efa459676a4ded5b3704
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,43 @@
|
||||
using asap.core;
|
||||
using cfg;
|
||||
using GameCore;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UniRx;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class EventScratchTicketRewardPopupPanel : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private RewardItemNew reward;
|
||||
//[SerializeField] private GameObject[] gemBanners;
|
||||
[SerializeField] private Image banner;
|
||||
[SerializeField] private Button btnClaim;
|
||||
private Action _action;
|
||||
|
||||
public void Init(ItemData rewardItem, EventScratchCard eventScratchCard, Action claimMark = null)
|
||||
{
|
||||
var dataManager = GContext.container.Resolve<EventScratchTicketDataManager>();
|
||||
|
||||
// Debug.Log($"[EventBreak] Init!!!!!!!!!!", this);
|
||||
reward.SetData(rewardItem, abbr: true);
|
||||
//for (int i = 0; i < gemBanners.Length; i++)
|
||||
// gemBanners[i].SetActive(i == tunnelIdx);
|
||||
banner.sprite = dataManager.SpriteAtlas.GetSprite(eventScratchCard.RewardIcon);
|
||||
btnClaim.onClick.AddListener(OnClaim);
|
||||
_action = claimMark;
|
||||
}
|
||||
|
||||
private void OnClaim()
|
||||
{
|
||||
// Debug.Log($"[EventBreak] Claim!!!!!!!!!!", this);
|
||||
var dataManager = GContext.container.Resolve<EventScratchTicketDataManager>();
|
||||
UIManager.Instance.DestroyUI(dataManager.GetRewardPanel());
|
||||
_action?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 092b9949be49496429c1164759a9dde2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,306 @@
|
||||
using asap.core;
|
||||
using cfg;
|
||||
using GameCore;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class EventScratchTicketStampRewardView : MonoBehaviour
|
||||
{
|
||||
[Header("印花设置")]
|
||||
[SerializeField] private int m_EventScratchQuality = 1;
|
||||
public int EventScratchQuality { get => m_EventScratchQuality; }
|
||||
|
||||
[Header("UI设置")]
|
||||
[SerializeField] private List<Image> m_GrayStampList = new List<Image>();
|
||||
[SerializeField] private List<Image> m_LightStampList = new List<Image>();
|
||||
|
||||
[Header("奖励设置")]
|
||||
[SerializeField] private RewardItemNew m_Reward;
|
||||
|
||||
[Header("动画设置")]
|
||||
[SerializeField] private Animation m_Animation;
|
||||
[SerializeField] private float m_AnimWaitingForFullTime = 0.1f;
|
||||
[SerializeField] private string m_AnimRewardRefresh = "reward_refresh";
|
||||
[SerializeField] private float m_AnimRewardRefreshDurationTime = 0.29f;
|
||||
[SerializeField] private string m_AnimRewardOut = "reward_out";
|
||||
[SerializeField] private float m_AnimRewardOutDurationTime = 0.37f;
|
||||
[SerializeField] private string m_AnimRewardFull = "reward_full";
|
||||
[SerializeField] private float m_AnimRewardFullDurationTime = 0.45f;
|
||||
|
||||
#region 数据相关
|
||||
private static object o = new object();
|
||||
public Image GetFirstEmptyImage()
|
||||
{
|
||||
lock (o)
|
||||
{
|
||||
if (m_IsCounting)
|
||||
{
|
||||
m_RewardNum++;
|
||||
}
|
||||
|
||||
if (m_EmptyTargetIndex >= m_LightStampList.Count)
|
||||
{
|
||||
m_EmptyTargetIndex = m_LightStampList.Count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return m_LightStampList[m_EmptyTargetIndex++];
|
||||
}
|
||||
public void ResetLightStampList()
|
||||
{
|
||||
foreach (var item in m_LightStampList)
|
||||
{
|
||||
item.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
private EventScratchCard m_ScratchCard = null;
|
||||
public EventScratchCard GetEventScratchCard()
|
||||
{
|
||||
return m_ScratchCard;
|
||||
}
|
||||
public async Task<bool> CheckReward()
|
||||
{
|
||||
if (m_IsFull)
|
||||
{
|
||||
m_Animation.Play(m_AnimRewardOut);
|
||||
|
||||
await Awaiters.Seconds(m_AnimRewardOutDurationTime);
|
||||
|
||||
PlayLightStampFlash();
|
||||
|
||||
m_Animation.Play(m_AnimRewardRefresh);
|
||||
|
||||
await Awaiters.Seconds(m_AnimRewardRefreshDurationTime);
|
||||
}
|
||||
|
||||
if (m_RewardNum < m_ScratchCard.Count)
|
||||
{
|
||||
PlayLightStampFlash();
|
||||
|
||||
m_IsFull = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
PlayLightStampFlash();
|
||||
|
||||
m_DataManager.AddStampReward(m_ScratchCard.ID);
|
||||
|
||||
await Awaiters.Seconds(m_AnimWaitingForFullTime);
|
||||
|
||||
m_Animation.Play(m_AnimRewardFull);
|
||||
|
||||
await Awaiters.Seconds(m_AnimRewardFullDurationTime);
|
||||
|
||||
ItemData itemData = GContext.container.Resolve<PlayerItemData>().GetItemDataOne(m_ScratchCard.DropReward);
|
||||
|
||||
List<ItemData> rewardList = new List<ItemData>();
|
||||
rewardList.Add(itemData);
|
||||
|
||||
// GContext.container.Resolve<PlayerItemData>().AddItem(rewardList);
|
||||
GContext.Publish(new DeferredRewardStashService.EventStashItems { Items = rewardList });
|
||||
|
||||
ResetRewardNum();
|
||||
|
||||
m_IsFull = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
public void ResetRewardNum()
|
||||
{
|
||||
m_RewardNum -= m_ScratchCard.Count;
|
||||
m_EmptyFromIndex = 0;
|
||||
m_EmptyTargetIndex = m_RewardNum;
|
||||
}
|
||||
public void SyncStampData()
|
||||
{
|
||||
int num = 0;
|
||||
foreach (var item in m_LightStampList)
|
||||
{
|
||||
if (item.gameObject.activeSelf)
|
||||
{
|
||||
num++;
|
||||
}
|
||||
}
|
||||
if (m_DataManager.ScratchTicketData.StampRewardDict.ContainsKey(m_EventScratchQuality))
|
||||
{
|
||||
var data = m_DataManager.ScratchTicketData.StampRewardDict[m_EventScratchQuality];
|
||||
data.EventScratchCardID = m_ScratchCard.ID;
|
||||
data.Count = num;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_DataManager.ScratchTicketData.StampRewardDict[m_EventScratchQuality] = new EventScratchTicketOwnedStampRewardData()
|
||||
{
|
||||
EventScratchCardID = m_ScratchCard.ID,
|
||||
Count = num
|
||||
};
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 动画相关
|
||||
private void PlayLightStampFlash()
|
||||
{
|
||||
int count = m_LightStampList.Count;
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
var item = m_LightStampList[i];
|
||||
if (i < m_EmptyTargetIndex)
|
||||
{
|
||||
item.gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
SyncStampData();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 事件相关
|
||||
private void InitEvent()
|
||||
{
|
||||
FishingScratchTicketAct.Subscribe<EventScratchTicketStampRewardUpdateData>(UpdateStampReward);
|
||||
FishingScratchTicketAct.Subscribe<EventScratchTicketStartStampRewardCountUpdateData>(StartStampRewardCount);
|
||||
FishingScratchTicketAct.Subscribe<EventScratchTicketStopStampRewardCountUpdateData>(StopStampRewardCount);
|
||||
}
|
||||
private bool m_IsFull = false;
|
||||
private int m_EmptyFromIndex, m_EmptyTargetIndex = 0, m_RewardNum = 0;
|
||||
public int RewardNum { get => m_RewardNum; }
|
||||
private bool m_IsCounting = false;
|
||||
private void StartStampRewardCount(EventScratchTicketStartStampRewardCountUpdateData data)
|
||||
{
|
||||
int count = m_LightStampList.Count;
|
||||
m_EmptyTargetIndex = 0;
|
||||
m_EmptyFromIndex = 0;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
if (!m_LightStampList[i].gameObject.activeInHierarchy)
|
||||
{
|
||||
m_EmptyFromIndex = i;
|
||||
m_EmptyTargetIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_RewardNum = m_EmptyTargetIndex;
|
||||
m_IsCounting = true;
|
||||
m_IsFull = false;
|
||||
}
|
||||
private void StopStampRewardCount(EventScratchTicketStopStampRewardCountUpdateData data)
|
||||
{
|
||||
m_IsCounting = false;
|
||||
}
|
||||
private void UpdateStampReward(EventScratchTicketStampRewardUpdateData data)
|
||||
{
|
||||
if (m_DataManager == null || m_DataManager.ScratchTicketData == null) return;
|
||||
|
||||
if (m_DataManager.ScratchTicketData.StampRewardDict != null)
|
||||
{
|
||||
if (m_DataManager.ScratchTicketData.StampRewardDict.ContainsKey(m_EventScratchQuality))
|
||||
{
|
||||
var stampReward = m_DataManager.ScratchTicketData.StampRewardDict[m_EventScratchQuality];
|
||||
int num = stampReward.Count;
|
||||
int count = m_LightStampList.Count;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (i < num)
|
||||
{
|
||||
if (!m_LightStampList[i].gameObject.activeInHierarchy)
|
||||
{
|
||||
m_LightStampList[i].gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_LightStampList[i].gameObject.activeInHierarchy)
|
||||
{
|
||||
m_LightStampList[i].gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UI相关
|
||||
private void InitUI()
|
||||
{
|
||||
InitStampReward();
|
||||
}
|
||||
private void InitStampReward()
|
||||
{
|
||||
if (m_DataManager == null || m_DataManager.ScratchTicketData == null) return;
|
||||
|
||||
EventScratchMain eventScratchMain = m_DataManager.GetCurrentEventScratchMain();
|
||||
|
||||
foreach (var cardID in eventScratchMain.CardList)
|
||||
{
|
||||
EventScratchCard card = m_DataManager.GetEventScratchCard(cardID);
|
||||
if (card != null && card.Quality == m_EventScratchQuality)
|
||||
{
|
||||
m_ScratchCard = card;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ScratchCard != null)
|
||||
{
|
||||
foreach (var item in m_GrayStampList)
|
||||
{
|
||||
item.sprite = m_DataManager.SpriteAtlas.GetSprite(m_ScratchCard.Icon2);
|
||||
}
|
||||
foreach(var item in m_LightStampList)
|
||||
{
|
||||
item.sprite = m_DataManager.SpriteAtlas.GetSprite(m_ScratchCard.Icon);
|
||||
}
|
||||
}
|
||||
|
||||
PlayerItemData playerItemData = GContext.container.Resolve<PlayerItemData>();
|
||||
|
||||
var dataItem = playerItemData.GetItemDataOne(m_ScratchCard.DropReward);
|
||||
m_Reward.SetData(dataItem, abbr: true);
|
||||
|
||||
foreach (var item in m_GrayStampList)
|
||||
{
|
||||
item.gameObject.SetActive(true);
|
||||
}
|
||||
foreach (var item in m_LightStampList)
|
||||
{
|
||||
item.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
private void RefreshData()
|
||||
{
|
||||
if (m_DataManager == null || m_DataManager.ScratchTicketData == null) return;
|
||||
|
||||
UpdateStampReward(null);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
private EventScratchTicketDataManager m_DataManager;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
m_DataManager = GContext.container.Resolve<EventScratchTicketDataManager>();
|
||||
|
||||
InitUI();
|
||||
InitEvent();
|
||||
RefreshData();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e3ef1d1d1f7d7e419e61c6402178495
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,78 @@
|
||||
using asap.core;
|
||||
using DG.Tweening;
|
||||
using UniRx;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Game;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class EventScratchTicketStashButtonFxCtrl : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private DeferredRewardStashButton rewardStashButton;
|
||||
[SerializeField] private GameObject rewardFly;
|
||||
[SerializeField] private float jiandaRewardShowDuration = 2.0f;
|
||||
|
||||
private EventScratchTicketDataManager m_DataManager;
|
||||
private void Start()
|
||||
{
|
||||
m_DataManager = GContext.container.Resolve<EventScratchTicketDataManager>();
|
||||
|
||||
//EventBreakAct.EventAggregator.GetEvent<EventBreakBlockBreak>().Subscribe(OnBlockBreak).AddTo(this);
|
||||
}
|
||||
|
||||
private async void MakeRewardFly(EventBreakBlockBreak e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fly = Instantiate(rewardFly, transform).GetComponent<RewardItemNew>();
|
||||
fly.SetRewardPopupData(e.Item);
|
||||
fly.transform.position = e.BreakPos;
|
||||
fly.gameObject.SetActive(true);
|
||||
if (EventBreakAct.Ctx.IsItemFishCard(e.Item))
|
||||
{
|
||||
// Debug.Log($"[EventBreak] FishCard: From {rewardFly.transform.position} to {transform.position}");
|
||||
_ = PlayFishCardBundleAudio();
|
||||
fly.GetComponent<Animation>().Play("reward_common_open");
|
||||
await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(jiandaRewardShowDuration));
|
||||
fly.GetComponent<Animation>().Play("reward_common_close");
|
||||
await System.Threading.Tasks.Task.Delay(24 * 1000 / 60);
|
||||
fly.GetComponent<CanvasGroup>().alpha = 1;
|
||||
await Awaiters.NextFrame;
|
||||
await DOTween.To(() => fly.transform.position,
|
||||
value => fly.transform.position = value, transform.position, 1.1f)
|
||||
.AsyncWaitForCompletion();
|
||||
rewardStashButton.PlayReceiveAnimationWithDelay(0f);
|
||||
EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.Unblock));
|
||||
Destroy(fly.gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
fly.GetComponent<Animation>().Play("reward_common_open");
|
||||
await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(jiandaRewardShowDuration));
|
||||
fly.GetComponent<Animation>().Play("reward_common_close");
|
||||
await System.Threading.Tasks.Task.Delay(16 * 1000 / 60);
|
||||
rewardStashButton.PlayReceiveAnimationWithDelay(1f);
|
||||
await Awaiters.NextFrame;
|
||||
await fly.ParticleAttractor();
|
||||
// await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(1.1f));
|
||||
EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.Unblock));
|
||||
Destroy(fly.gameObject);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Log($"[EventBreak] BreakBlockError: {ex.Message}\n{ex.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task PlayFishCardBundleAudio()
|
||||
{
|
||||
GContext.Publish(new EventUISound("audio_ui_break_rewardfly"));
|
||||
await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(0.25f));
|
||||
GContext.Publish(new EventUISound("audio_ui_break_rewardget"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce915ed8442747d41ba2505b41804027
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/UI/ScratchTicket/ScratchCard.meta
Normal file
8
Assets/Scripts/UI/ScratchTicket/ScratchCard.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e7ce83232753434eac4e1f050a51e3f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
576
Assets/Scripts/UI/ScratchTicket/ScratchCard/ScratchCard.cs
Normal file
576
Assets/Scripts/UI/ScratchTicket/ScratchCard/ScratchCard.cs
Normal file
@@ -0,0 +1,576 @@
|
||||
using asap.core;
|
||||
using cfg;
|
||||
using DG.Tweening;
|
||||
using GameCore;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class ScratchCard : MonoBehaviour, IBeginDragHandler, IDragHandler
|
||||
{
|
||||
[Header("Mask")]
|
||||
public List<ScratchCardMaskUGUI> m_MaskList = new List<ScratchCardMaskUGUI>();
|
||||
[SerializeField] private int m_CDFrame = 5;
|
||||
[SerializeField] private string m_Ticket_Mask_Texture_Name = "sp_scratchticket_ticket_mask";
|
||||
|
||||
[Header("Brush")]
|
||||
[SerializeField] private EditablePolygon m_OperatingArea;
|
||||
[SerializeField] private GameObject m_BrushRoot;
|
||||
[SerializeField] private Image m_Brush;
|
||||
|
||||
[SerializeField] private float m_BrushDurationTime = 1.0f;
|
||||
[SerializeField] private float m_BrushSpeed = 1000.0f;
|
||||
[SerializeField] private Material m_BrushMaterial;
|
||||
[SerializeField] private Vector2 m_BrushSize = new Vector2(50f, 50f);
|
||||
[SerializeField] private int m_InterpolationMaxCount = 4;
|
||||
[SerializeField] private int m_InterpolationMinDistance = 8;
|
||||
[SerializeField] private EventScratchTicketScratchType m_ScratchType = EventScratchTicketScratchType.TypeInvalid;
|
||||
|
||||
[Header("Animation")]
|
||||
[SerializeField] private Animation m_Animation;
|
||||
[SerializeField] private string m_Anim_Ticket_Out = "ticket_out";
|
||||
[SerializeField] private float m_Anim_Ticket_Out_DurationTime = 1.1f;
|
||||
|
||||
[SerializeField] private CanvasGroup m_ShadowCanvasGroup;
|
||||
[SerializeField] private CanvasGroup m_TicketCanvasGroup;
|
||||
|
||||
[Header("音效")]
|
||||
[SerializeField] private List<OutPlaySound> m_ScratchOutPlaySoundList = new List<OutPlaySound>();
|
||||
[SerializeField] private List<float> m_ScratchOutPlaySoundTimeList = new List<float>();
|
||||
|
||||
[Header("Toast相关")]
|
||||
[SerializeField] private float m_ToastIntervalTime = 1.0f;
|
||||
|
||||
private int m_CumulativeFrame = 0;
|
||||
private int m_MaskIndex = 0;
|
||||
private float m_BrushCumulativeTime = 0f;
|
||||
|
||||
#region 音效相关
|
||||
private bool m_IsPlayingSound = false;
|
||||
private float m_PlayingSoundTime = 0;
|
||||
private float m_PlayingSoundCumulativeTime = 0f;
|
||||
private void PlayScratchSound()
|
||||
{
|
||||
int count = m_ScratchOutPlaySoundList.Count;
|
||||
if (count < 1) return;
|
||||
|
||||
foreach (var item in m_ScratchOutPlaySoundList)
|
||||
{
|
||||
if (item.gameObject.activeSelf)
|
||||
{
|
||||
item.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
int index = UnityEngine.Random.Range(0, count);
|
||||
|
||||
m_IsPlayingSound = true;
|
||||
m_PlayingSoundTime = m_ScratchOutPlaySoundTimeList[index];
|
||||
m_PlayingSoundCumulativeTime = 0f;
|
||||
|
||||
m_ScratchOutPlaySoundList[index].gameObject.SetActive(true);
|
||||
}
|
||||
private void StopScratchSound()
|
||||
{
|
||||
foreach (var item in m_ScratchOutPlaySoundList)
|
||||
{
|
||||
item.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
m_IsPlayingSound = false;
|
||||
m_PlayingSoundTime = float.MaxValue;
|
||||
m_PlayingSoundCumulativeTime = float.MinValue;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ScratchCardMask 相关
|
||||
public void InitMaskList()
|
||||
{
|
||||
foreach (var item in m_MaskList)
|
||||
{
|
||||
item.InitMaskUGUI(m_BrushMaterial, m_BrushSize, m_InterpolationMaxCount, m_InterpolationMinDistance);
|
||||
//item.RevealProgressChanged = OnRevealProgressChangedCallback;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRevealProgressChangedCallback(ScratchCardMask mask, float progress, bool isRevealed)
|
||||
{
|
||||
//Debug.LogError("--- ScratchCard OnRevealProgressChangedCallback mask:" + mask + ", progress:" + progress + ", isRevealed:" + isRevealed);
|
||||
|
||||
bool flag = true;
|
||||
foreach (var item in m_MaskList)
|
||||
{
|
||||
if (!item.IsRevealed())
|
||||
{
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//if (flag)
|
||||
//{
|
||||
// Debug.LogError("--- they have all revealed");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// Debug.LogError("--- they have not all revealed");
|
||||
//}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Brush 相关
|
||||
private bool m_IsBrushPainting = false;
|
||||
public void SetBrushPosition(Vector2 screenPosition)
|
||||
{
|
||||
if (!m_OperatingArea.ContainsPoint(screenPosition))
|
||||
{
|
||||
return;
|
||||
}
|
||||
RectTransformUtility.ScreenPointToLocalPointInRectangle(
|
||||
transform as RectTransform,
|
||||
screenPosition,
|
||||
UIManager.Instance.UICanvas.worldCamera,
|
||||
out Vector2 localPoint);
|
||||
|
||||
|
||||
if (!m_Brush.gameObject.activeSelf)
|
||||
{
|
||||
m_Brush.gameObject.SetActive(true);
|
||||
|
||||
m_Brush.rectTransform.localPosition = localPoint;
|
||||
}
|
||||
|
||||
float distance = Vector2.Distance(m_Brush.rectTransform.localPosition, localPoint);
|
||||
|
||||
float time = distance / m_BrushSpeed;
|
||||
|
||||
m_Brush.rectTransform.DOKill();
|
||||
m_Brush.rectTransform.DOLocalMove(localPoint, time).SetEase(Ease.Linear);
|
||||
|
||||
//m_BrushCumulativeTime = 0f;
|
||||
}
|
||||
private void OnMaskBeginDrag()
|
||||
{
|
||||
Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(UIManager.Instance.UICanvas.worldCamera, m_Brush.transform.position);
|
||||
foreach (var item in m_MaskList)
|
||||
{
|
||||
item.OnMaskBeginDrag(screenPoint);
|
||||
}
|
||||
}
|
||||
private void OnMaskDrag()
|
||||
{
|
||||
bool flag = false;
|
||||
Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(UIManager.Instance.UICanvas.worldCamera, m_Brush.transform.position);
|
||||
foreach (var item in m_MaskList)
|
||||
{
|
||||
if (item.OnMaskDrag(screenPoint))
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
//if (flag)
|
||||
//{
|
||||
// bool isAllRevealed = true;
|
||||
// foreach (var item in m_MaskList)
|
||||
// {
|
||||
// if (!item.IsRevealed())
|
||||
// {
|
||||
// isAllRevealed = false;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (isAllRevealed)
|
||||
// {
|
||||
// Debug.LogError("=== ok");
|
||||
// }
|
||||
//}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IBeginDragHandler + IDragHandler 相关
|
||||
public void OnBeginDrag(PointerEventData eventData)
|
||||
{
|
||||
if (m_ScratchType != EventScratchTicketScratchType.TypeScratch1) return;
|
||||
//Debug.LogWarning("---- ScratchCard OnBeginDrag");
|
||||
|
||||
SetBrushPosition(eventData.position);
|
||||
|
||||
m_BrushCumulativeTime = 0f;
|
||||
|
||||
//foreach (var item in m_MaskList)
|
||||
//{
|
||||
// item.OnMaskBeginDrag(eventData.position);
|
||||
//}
|
||||
}
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
if (m_ScratchType != EventScratchTicketScratchType.TypeScratch1) return;
|
||||
//Debug.LogWarning("---- ScratchCard OnDrag");
|
||||
|
||||
SetBrushPosition(eventData.position);
|
||||
|
||||
m_BrushCumulativeTime = 0f;
|
||||
|
||||
//bool flag = false;
|
||||
//foreach (var item in m_MaskList)
|
||||
//{
|
||||
// if (item.OnMaskDrag(eventData.position))
|
||||
// {
|
||||
// flag = true;
|
||||
// }
|
||||
//}
|
||||
//if (flag)
|
||||
//{
|
||||
// bool isAllRevealed = true;
|
||||
// foreach (var item in m_MaskList)
|
||||
// {
|
||||
// if (!item.IsRevealed())
|
||||
// {
|
||||
// isAllRevealed = false;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (isAllRevealed)
|
||||
// {
|
||||
// Debug.LogError("=== ok");
|
||||
// }
|
||||
//}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TypeScratch1 动画等相关
|
||||
private IEnumerator PlayTicketOutAnim(EventScratchTicketScratchType scratchType)
|
||||
{
|
||||
// 播放 m_Anim_Ticket_Out
|
||||
m_Animation.Play(m_Anim_Ticket_Out);
|
||||
yield return new WaitForSeconds(m_Anim_Ticket_Out_DurationTime);
|
||||
|
||||
// 重置 ScratchCard 图片资源,并将ticket和shadow的alpha设置为1(显示)
|
||||
foreach (var item in m_MaskList)
|
||||
{
|
||||
item.Restore();
|
||||
//item.Reload();
|
||||
}
|
||||
m_ShadowCanvasGroup.alpha = 1.0f;
|
||||
m_TicketCanvasGroup.alpha = 1.0f;
|
||||
|
||||
if (scratchType == EventScratchTicketScratchType.TypeScratch1)
|
||||
{
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketPanelPlayEndAnimData()
|
||||
{
|
||||
ScratchType = scratchType
|
||||
});
|
||||
}
|
||||
else if (scratchType == EventScratchTicketScratchType.TypeScratch5)
|
||||
{
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketPlayScratchType5());
|
||||
}
|
||||
}
|
||||
private IEnumerator PlayCardRevealedAnimInScratch1(EventScratchTicketScratchType scratchType)
|
||||
{
|
||||
// 隐藏笔刷
|
||||
m_Brush.gameObject.SetActive(false);
|
||||
// 确认奖励
|
||||
EventScratchCard scratchCard = m_DataManager.GetCurrentEventScratchCard();
|
||||
if (scratchCard.DropReward == 0)
|
||||
{
|
||||
// 空奖
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketRewardEmptyData()
|
||||
{
|
||||
ScratchType = EventScratchTicketScratchType.TypeScratch1
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// 播放 m_Anim_Ticket_Out
|
||||
m_Animation.Play(m_Anim_Ticket_Out);
|
||||
yield return new WaitForSeconds(m_Anim_Ticket_Out_DurationTime);
|
||||
|
||||
// 重置 ScratchCard 图片资源,并将ticket和shadow的alpha设置为1(显示)
|
||||
foreach (var item in m_MaskList)
|
||||
{
|
||||
item.Restore();
|
||||
//item.Reload();
|
||||
}
|
||||
m_ShadowCanvasGroup.alpha = 1.0f;
|
||||
m_TicketCanvasGroup.alpha = 1.0f;
|
||||
|
||||
// RewardFly
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketStampRewardFlyData()
|
||||
{
|
||||
ScratchType = scratchType,
|
||||
SrcPosition = ticket_reward.transform.position,
|
||||
LocalScale = ticket_reward.transform.localScale,
|
||||
IconSize = ticket_reward.rectTransform.sizeDelta.x
|
||||
});
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TypeScratch5 动画等相关
|
||||
private IEnumerator PlayCardRevealedAnimInScratch5(EventScratchTicketScratchType scratchType)
|
||||
{
|
||||
// 隐藏笔刷
|
||||
m_Brush.gameObject.SetActive(false);
|
||||
|
||||
// 确认奖励
|
||||
EventScratchCard scratchCard = m_DataManager.GetCurrentEventScratchCard();
|
||||
if (scratchCard.DropReward == 0)
|
||||
{
|
||||
// 空奖
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketRewardEmptyData()
|
||||
{
|
||||
ScratchType = scratchType
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// 播放 m_Anim_Ticket_Out
|
||||
m_Animation.Play(m_Anim_Ticket_Out);
|
||||
yield return new WaitForSeconds(m_Anim_Ticket_Out_DurationTime);
|
||||
|
||||
// 重置 ScratchCard 图片资源,并将ticket和shadow的alpha设置为1(显示)
|
||||
foreach (var item in m_MaskList)
|
||||
{
|
||||
item.Restore();
|
||||
//item.Reload();
|
||||
}
|
||||
m_ShadowCanvasGroup.alpha = 1.0f;
|
||||
m_TicketCanvasGroup.alpha = 1.0f;
|
||||
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketPlayScratchType5());
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 事件
|
||||
private void InitEvent()
|
||||
{
|
||||
FishingScratchTicketAct.Subscribe<EventScratchTicketChangeScratchTypeData>(ChangeScratchType);
|
||||
FishingScratchTicketAct.Subscribe<EventScratchTicketRevealedAllData>(OnScratchCardRevealedAll);
|
||||
FishingScratchTicketAct.Subscribe<EventScratchTicketUpdateEventScratchCardData>(UpdateEventScratchCardData);
|
||||
FishingScratchTicketAct.Subscribe<EventScratchTicketOutData>(OnEventScratchTicketOutDataListener);
|
||||
}
|
||||
private void OnEventScratchTicketOutDataListener(EventScratchTicketOutData data)
|
||||
{
|
||||
StartCoroutine(PlayTicketOutAnim(data.ScratchType));
|
||||
}
|
||||
private void UpdateEventScratchCardData(EventScratchTicketUpdateEventScratchCardData data)
|
||||
{
|
||||
var scratchCard = m_DataManager.GetCurrentEventScratchCard();
|
||||
if (scratchCard == null) return;
|
||||
|
||||
var sprite = m_DataManager.GetSprite(scratchCard.Card);
|
||||
|
||||
ticket_reward.sprite = sprite;
|
||||
|
||||
ticket_maskCore.UpdateScratchCardMask(sprite.texture);
|
||||
ticket_maskCore.Restore();
|
||||
ticket_maskCore.SetThreshold(scratchCard.CorePercent);
|
||||
|
||||
ticket_mask.Restore();
|
||||
}
|
||||
private void OnScratchCardRevealedAll(EventScratchTicketRevealedAllData data)
|
||||
{
|
||||
StopScratchSound();
|
||||
EventScratchCard scratchCard = m_DataManager.GetCurrentEventScratchCard();
|
||||
if (scratchCard.DropReward > 0)
|
||||
{
|
||||
m_DataManager.AddScratchStamp(scratchCard.ID);
|
||||
}
|
||||
|
||||
if (data.ScratchType == EventScratchTicketScratchType.TypeScratch1)
|
||||
{
|
||||
StartCoroutine(PlayCardRevealedAnimInScratch1(EventScratchTicketScratchType.TypeScratch1));
|
||||
}
|
||||
else if (data.ScratchType == EventScratchTicketScratchType.TypeScratch5)
|
||||
{
|
||||
StartCoroutine(PlayCardRevealedAnimInScratch5(EventScratchTicketScratchType.TypeScratch5));
|
||||
}
|
||||
}
|
||||
private void ChangeScratchType(EventScratchTicketChangeScratchTypeData data)
|
||||
{
|
||||
m_ScratchType = data.ScratchType;
|
||||
if (m_ScratchType != EventScratchTicketScratchType.TypeInvalid)
|
||||
{
|
||||
m_BrushRoot.SetActive(true);
|
||||
m_Brush.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UI
|
||||
private Image ticket_reward;
|
||||
private ScratchCardMaskUGUI ticket_maskCore;
|
||||
private ScratchCardMaskUGUI ticket_mask;
|
||||
|
||||
private void InitUI()
|
||||
{
|
||||
ticket_reward = transform.Find("ticket_reward").GetComponent<Image>();
|
||||
ticket_maskCore = transform.Find("ticket_maskCore").GetComponent<ScratchCardMaskUGUI>();
|
||||
ticket_mask = transform.Find("ticket_mask").GetComponent<ScratchCardMaskUGUI>();
|
||||
}
|
||||
|
||||
public void RefreshData()
|
||||
{
|
||||
UpdateEventScratchCardData(null);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
private EventScratchTicketDataManager m_DataManager;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
m_DataManager = GContext.container.Resolve<EventScratchTicketDataManager>();
|
||||
|
||||
InitUI();
|
||||
|
||||
InitMaskList();
|
||||
|
||||
InitEvent();
|
||||
|
||||
RefreshData();
|
||||
}
|
||||
|
||||
private bool m_IsToasting = false;
|
||||
private float m_CumulativeToastIntervalTime = 0f;
|
||||
private void Update()
|
||||
{
|
||||
if (m_ScratchType == EventScratchTicketScratchType.TypeInvalid)
|
||||
{
|
||||
if (Input.GetMouseButtonDown(0) || Input.GetMouseButton(0))
|
||||
{
|
||||
if (!m_IsToasting && m_OperatingArea.ContainsPoint(Input.mousePosition))
|
||||
{
|
||||
ToastPanel.Show(LocalizationMgr.GetText("UI_EventScratchTicketPanel_9"));
|
||||
m_IsToasting = true;
|
||||
m_CumulativeToastIntervalTime = 0f;
|
||||
}
|
||||
}
|
||||
if (m_IsToasting)
|
||||
{
|
||||
if (m_CumulativeToastIntervalTime >= m_ToastIntervalTime)
|
||||
{
|
||||
m_CumulativeToastIntervalTime = 0f;
|
||||
m_IsToasting = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CumulativeToastIntervalTime += Time.deltaTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_ScratchType == EventScratchTicketScratchType.TypeScratch1)
|
||||
{
|
||||
bool flag = false;
|
||||
if (!Input.GetMouseButtonDown(0) && !Input.GetMouseButton(0))
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
else if (!m_OperatingArea.ContainsPoint(Input.mousePosition))
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
if (m_BrushCumulativeTime >= m_BrushDurationTime)
|
||||
{
|
||||
if (m_Brush.gameObject.activeSelf)
|
||||
{
|
||||
m_Brush.gameObject.SetActive(false);
|
||||
m_IsBrushPainting = false;
|
||||
StopScratchSound();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_BrushCumulativeTime += Time.deltaTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_ScratchType != EventScratchTicketScratchType.TypeInvalid)
|
||||
{
|
||||
if (m_Brush.gameObject.activeSelf)
|
||||
{
|
||||
if (m_IsPlayingSound)
|
||||
{
|
||||
m_PlayingSoundCumulativeTime += Time.deltaTime;
|
||||
if (m_PlayingSoundCumulativeTime >= m_PlayingSoundTime)
|
||||
{
|
||||
PlayScratchSound();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayScratchSound();
|
||||
}
|
||||
|
||||
if (m_IsBrushPainting == false)
|
||||
{
|
||||
m_IsBrushPainting = true;
|
||||
|
||||
OnMaskBeginDrag();
|
||||
}
|
||||
else
|
||||
{
|
||||
OnMaskDrag();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (m_ScratchType == EventScratchTicketScratchType.TypeInvalid || m_ScratchType == EventScratchTicketScratchType.TypeTemporary) return;
|
||||
if (m_BrushRoot.activeInHierarchy == false || m_Brush.gameObject.activeSelf == false) return;
|
||||
|
||||
if (m_CumulativeFrame > m_CDFrame)
|
||||
{
|
||||
m_CumulativeFrame = 1;
|
||||
m_MaskIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
++m_CumulativeFrame;
|
||||
}
|
||||
|
||||
int count = m_MaskList.Count;
|
||||
int step = Mathf.CeilToInt((float)count / m_CDFrame);
|
||||
int endIndex = m_MaskIndex + step;
|
||||
|
||||
while (m_MaskIndex < count && m_MaskIndex < endIndex)
|
||||
{
|
||||
m_MaskList[m_MaskIndex].UpdateTempTexture();
|
||||
++m_MaskIndex;
|
||||
}
|
||||
|
||||
bool flag = true;
|
||||
foreach (var mask in m_MaskList)
|
||||
{
|
||||
if (!mask.IsRevealed())
|
||||
{
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
//Debug.LogError("--- all ok");
|
||||
FishingScratchTicketAct.Publish(new EventScratchTicketRevealedAllData
|
||||
{
|
||||
ScratchType = m_ScratchType
|
||||
});
|
||||
m_ScratchType = EventScratchTicketScratchType.TypeTemporary;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d76a92f177c3b424aa14c040bfd5b8f1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public abstract class ScratchCardMask : MonoBehaviour
|
||||
{
|
||||
//public Action<ScratchCardMask, float, bool> RevealProgressChanged;
|
||||
|
||||
public bool IsRevealed()
|
||||
{
|
||||
if (m_Threshold <= 0f) return true;
|
||||
return GetRevealProgress() >= m_Threshold;
|
||||
}
|
||||
public void SetThreshold(float threshold)
|
||||
{
|
||||
m_Threshold = threshold;
|
||||
}
|
||||
|
||||
[Header("Mask")]
|
||||
[Range(0f, 1.0f)]
|
||||
[SerializeField] protected float m_Threshold = 0.75f;
|
||||
[SerializeField] protected float m_AlphaThreshold = 0.5f;
|
||||
|
||||
public abstract float GetRevealProgress();
|
||||
|
||||
//protected void OnRevealProgressChanged()
|
||||
//{
|
||||
// float progress = 0f;
|
||||
// bool isRevealed = false;
|
||||
|
||||
// if (m_Threshold <= 0)
|
||||
// {
|
||||
// isRevealed = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// progress = GetRevealProgress();
|
||||
// isRevealed = progress >= m_Threshold;
|
||||
// }
|
||||
|
||||
// //RevealProgressChanged?.Invoke(this, progress, isRevealed);
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad3f7edb405dd0a479a0fb223cc7ede7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,348 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace game
|
||||
{
|
||||
[RequireComponent(typeof(RawImage))]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
public class ScratchCardMaskUGUI : ScratchCardMask
|
||||
{
|
||||
private static readonly int OffsetScalePropertyId = Shader.PropertyToID("_OffsetScale");
|
||||
|
||||
internal RawImage Image
|
||||
{
|
||||
get
|
||||
{
|
||||
if (image == null)
|
||||
{
|
||||
image = GetComponent<RawImage>();
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
private RectTransform RectTransform
|
||||
{
|
||||
get
|
||||
{
|
||||
if (rectTransform == null)
|
||||
{
|
||||
rectTransform = GetComponent<RectTransform>();
|
||||
}
|
||||
|
||||
return rectTransform;
|
||||
}
|
||||
}
|
||||
|
||||
[Header("Brush")]
|
||||
[SerializeField]
|
||||
private Material m_BrushMaterial;
|
||||
[SerializeField] private Vector2 m_BrushSize = new Vector2(50f, 50f);
|
||||
[SerializeField]
|
||||
private int m_InterpolationMaxCount = 4;
|
||||
[SerializeField]
|
||||
private int m_InterpolationMinDistance = 8;
|
||||
|
||||
[Header("Mask Texture")]
|
||||
[SerializeField]
|
||||
private float maskTextureScale = 1.0f;
|
||||
[SerializeField]
|
||||
private float maxMaskTextureSize = 512;
|
||||
|
||||
private bool baseTextureSaved;
|
||||
private Material brush;
|
||||
|
||||
private RectTransform rectTransform;
|
||||
private RenderTexture targetTexture;
|
||||
private Texture baseTexture;
|
||||
private RawImage image;
|
||||
private Vector2 prevDrawPosition;
|
||||
|
||||
private float m_Progress = 0f;
|
||||
|
||||
#region 笔刷相关
|
||||
private Texture2D m_TempTexture;
|
||||
private void CreateTempTexture()
|
||||
{
|
||||
m_TempTexture = ScratchCardUtils.GetReadableCopy(targetTexture);
|
||||
}
|
||||
|
||||
public void UpdateTempTexture()
|
||||
{
|
||||
if (m_Threshold <= 0f)
|
||||
{
|
||||
//Debug.LogWarning("---- " + gameObject.name + " ok");
|
||||
return;
|
||||
}
|
||||
|
||||
m_TempTexture.Reinitialize(targetTexture.width, targetTexture.height);
|
||||
|
||||
ScratchCardUtils.UpdateTexture2D(m_TempTexture, targetTexture, targetTexture.width, targetTexture.height);
|
||||
|
||||
Color[] colorArray = m_TempTexture.GetPixels();
|
||||
|
||||
int count = 0;
|
||||
int total = colorArray.Length;
|
||||
for (int i = 0; i < total; ++i)
|
||||
{
|
||||
if (colorArray[i].a <= m_AlphaThreshold)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
m_Progress = (float)count / total;
|
||||
|
||||
//if (m_Progress >= m_Threshold)
|
||||
//{
|
||||
// Debug.LogWarning("---- " + gameObject.name + " ok 当前进度为: " + m_Progress);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// Debug.LogWarning("---- " + gameObject.name + " 当前进度为: " + m_Progress);
|
||||
//}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
private void Awake()
|
||||
{
|
||||
SaveBaseTexture();
|
||||
|
||||
m_Progress = 0f;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
Reload();
|
||||
|
||||
m_Progress = 0f;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
DisposeTargetTexture();
|
||||
DisposeBrush();
|
||||
}
|
||||
|
||||
private void OnRectTransformDimensionsChange()
|
||||
{
|
||||
SaveBaseTexture();
|
||||
Reload();
|
||||
|
||||
m_Progress = 0f;
|
||||
}
|
||||
public void UpdateScratchCardMask(Texture texture)
|
||||
{
|
||||
baseTexture = texture;
|
||||
baseTextureSaved = true;
|
||||
|
||||
m_Progress = 0f;
|
||||
}
|
||||
|
||||
public void InitMaskUGUI(Material brushMaterial, Vector2 brushSize, int interpolationMaxCount, int interpolationMinDistance)
|
||||
{
|
||||
this.m_BrushMaterial = brushMaterial;
|
||||
this.m_BrushSize = brushSize;
|
||||
this.m_InterpolationMaxCount = interpolationMaxCount;
|
||||
this.m_InterpolationMinDistance = interpolationMinDistance;
|
||||
|
||||
CreateBrush();
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void Reload()
|
||||
{
|
||||
var rect = RectTransform.rect;
|
||||
if (rect.width <= 0 || rect.height <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AcquireTargetTexture(rect);
|
||||
}
|
||||
|
||||
private void SaveBaseTexture()
|
||||
{
|
||||
if (!baseTextureSaved)
|
||||
{
|
||||
if (Image.texture != null)
|
||||
{
|
||||
baseTexture = Image.texture;
|
||||
}
|
||||
|
||||
baseTextureSaved = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateBrush()
|
||||
{
|
||||
if (m_BrushMaterial == null)
|
||||
{
|
||||
m_BrushMaterial = Resources.Load<Material>("Materials/ScratchCard_DefaultBrush");
|
||||
}
|
||||
|
||||
DisposeBrush();
|
||||
|
||||
brush = new Material(m_BrushMaterial);
|
||||
}
|
||||
|
||||
private void DisposeBrush()
|
||||
{
|
||||
if (brush != null)
|
||||
{
|
||||
Destroy(brush);
|
||||
brush = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void AcquireTargetTexture(Rect rect)
|
||||
{
|
||||
var aspect = rect.height / rect.width;
|
||||
var width = (int)Mathf.Min(maxMaskTextureSize, rect.width * maskTextureScale);
|
||||
var height = (int)(width * aspect);
|
||||
|
||||
if (targetTexture != null && (targetTexture.width != width || targetTexture.height != height))
|
||||
{
|
||||
DisposeTargetTexture();
|
||||
}
|
||||
|
||||
if (targetTexture == null)
|
||||
{
|
||||
targetTexture = RenderTexture.GetTemporary(width, height, -1, RenderTextureFormat.ARGB32);
|
||||
Image.texture = targetTexture;
|
||||
|
||||
ClearTexture();
|
||||
|
||||
CreateTempTexture();
|
||||
}
|
||||
}
|
||||
|
||||
private void DisposeTargetTexture()
|
||||
{
|
||||
if (targetTexture != null)
|
||||
{
|
||||
RenderTexture.ReleaseTemporary(targetTexture);
|
||||
targetTexture = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearTargetWithColor(Color color)
|
||||
{
|
||||
var tmp = RenderTexture.active;
|
||||
RenderTexture.active = targetTexture;
|
||||
GL.Clear(true, true, color);
|
||||
RenderTexture.active = tmp;
|
||||
}
|
||||
|
||||
private void ClearTexture()
|
||||
{
|
||||
if (baseTexture != null)
|
||||
{
|
||||
ClearTargetWithColor(Color.clear);
|
||||
Graphics.Blit(baseTexture, targetTexture, Image.material);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearTargetWithColor(Color.white);
|
||||
}
|
||||
}
|
||||
|
||||
public override float GetRevealProgress()
|
||||
{
|
||||
return m_Progress;
|
||||
}
|
||||
|
||||
public bool IsComputeShaderSupported()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[ContextMenu("Restore")]
|
||||
public void Restore()
|
||||
{
|
||||
ClearTexture();
|
||||
m_Progress = 0f;
|
||||
}
|
||||
|
||||
public void OnMaskBeginDrag(Vector2 position)
|
||||
{
|
||||
prevDrawPosition = position;
|
||||
}
|
||||
|
||||
public bool OnMaskDrag(Vector2 position)
|
||||
{
|
||||
if (targetTexture == null || brush == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var drawPosition = position;
|
||||
var progressChanged = false;
|
||||
|
||||
var delta = drawPosition - prevDrawPosition;
|
||||
if (delta != drawPosition)
|
||||
{
|
||||
var distance = delta.magnitude;
|
||||
var count = Mathf.Min(m_InterpolationMaxCount, (int)distance / m_InterpolationMinDistance);
|
||||
|
||||
for (int i = 1; i < count; ++i)
|
||||
{
|
||||
progressChanged |= DrawAt(prevDrawPosition + delta * ((float)i / count));
|
||||
}
|
||||
}
|
||||
|
||||
progressChanged |= DrawAt(drawPosition);
|
||||
prevDrawPosition = drawPosition;
|
||||
|
||||
if (progressChanged)
|
||||
{
|
||||
//OnRevealProgressChanged();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool DrawAt(Vector2 screenPoint)
|
||||
{
|
||||
var point = EventScratchTicketConfig.ScreenToGraphicLocalPoint(Image, screenPoint); // 将屏幕坐标转换为Image的本地坐标
|
||||
var rect = RectTransform.rect;
|
||||
|
||||
Vector2 brushScale = new Vector2(m_BrushSize.x / rect.width, m_BrushSize.y / rect.height);
|
||||
|
||||
brush.SetVector(OffsetScalePropertyId, CalculateOffsetScale(RectTransform, point, brushScale));
|
||||
Graphics.Blit(brush.mainTexture, targetTexture, brush);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static Vector4 CalculateOffsetScale(RectTransform rt, Vector2 localPoint, Vector2 scale)
|
||||
{
|
||||
var rect = rt.rect;
|
||||
localPoint += rt.pivot * rect.size; // 从左到右,从下到上,距离左下角原点位置
|
||||
|
||||
var aspect = rect.height / rect.width;
|
||||
var sx = scale.x * aspect;
|
||||
var sy = scale.y;
|
||||
var px = (localPoint.x / rect.width) - (0.5f * sx);
|
||||
var py = (localPoint.y / rect.height) - (0.5f * sy);
|
||||
|
||||
return new Vector4(px, py, 1.0f / sx, 1.0f / sy);
|
||||
}
|
||||
|
||||
private void OnRevealProgressChangedCallback(ScratchCardMask mask, float progress, bool isRevealed)
|
||||
{
|
||||
Debug.LogError("--- mask:" + mask + ", progress:" + progress + ", isRevealed:" + isRevealed);
|
||||
}
|
||||
|
||||
public void DrawInCenter()
|
||||
{
|
||||
int width = UnityEngine.Screen.width;
|
||||
int height = UnityEngine.Screen.height;
|
||||
|
||||
Vector2 center = new Vector2(width >> 1, height >> 1);
|
||||
DrawAt(center);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64dbd9ff05166e44bbf1f72c86c717c5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
101
Assets/Scripts/UI/ScratchTicket/ScratchCard/ScratchCardUtils.cs
Normal file
101
Assets/Scripts/UI/ScratchTicket/ScratchCard/ScratchCardUtils.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class ScratchCardUtils
|
||||
{
|
||||
public static void UpdateTexture2D(Texture2D texture2D, RenderTexture renderTexture, int width, int height)
|
||||
{
|
||||
RenderTexture tmp = RenderTexture.active;
|
||||
RenderTexture.active = renderTexture;
|
||||
texture2D.ReadPixels(new Rect(0, 0, width, height), 0, 0);
|
||||
RenderTexture.active = tmp;
|
||||
texture2D.Apply();
|
||||
}
|
||||
|
||||
public static Texture2D GetReadableCopy(RenderTexture renderTexture, TextureFormat format = TextureFormat.ARGB32, bool mipMaps = false, int width = 0, int height = 0)
|
||||
{
|
||||
var newTexture = default(Texture2D);
|
||||
|
||||
if (renderTexture != null)
|
||||
{
|
||||
if (width <= 0)
|
||||
{
|
||||
width = renderTexture.width;
|
||||
}
|
||||
|
||||
if (height <= 0)
|
||||
{
|
||||
height = renderTexture.height;
|
||||
}
|
||||
|
||||
if (CanReadPixels(format) == true)
|
||||
{
|
||||
newTexture = new Texture2D(width, height, format, mipMaps, false);
|
||||
|
||||
var tmp = RenderTexture.active;
|
||||
RenderTexture.active = renderTexture;
|
||||
newTexture.ReadPixels(new Rect(0, 0, width, height), 0, 0);
|
||||
RenderTexture.active = tmp;
|
||||
|
||||
newTexture.Apply();
|
||||
}
|
||||
}
|
||||
|
||||
return newTexture;
|
||||
}
|
||||
|
||||
public static RenderTexture ReleaseRenderTexture(RenderTexture renderTexture)
|
||||
{
|
||||
return ReleaseTemporary(renderTexture);
|
||||
}
|
||||
|
||||
public static RenderTexture ReleaseTemporary(RenderTexture renderTexture)
|
||||
{
|
||||
if (renderTexture != null)
|
||||
{
|
||||
renderTexture.DiscardContents();
|
||||
|
||||
RenderTexture.ReleaseTemporary(renderTexture);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool CanReadPixels(TextureFormat format)
|
||||
{
|
||||
if (format == TextureFormat.RGBA32 || format == TextureFormat.ARGB32 || format == TextureFormat.RGB24 || format == TextureFormat.RGBAFloat || format == TextureFormat.RGBAHalf)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static RenderTexture GetRenderTexture(RenderTextureDescriptor desc, bool sRGB)
|
||||
{
|
||||
desc.sRGB = sRGB;
|
||||
|
||||
return GetTemporary(desc, "ScratchCardUtils GetRenderTexture");
|
||||
}
|
||||
|
||||
public static RenderTexture GetTemporary(RenderTextureDescriptor desc, string title)
|
||||
{
|
||||
var renderTexture = RenderTexture.GetTemporary(desc);
|
||||
|
||||
// TODO: For some reason RenderTexture.GetTemporary ignores the useMipMap flag?!
|
||||
if (renderTexture.useMipMap != desc.useMipMap)
|
||||
{
|
||||
renderTexture.Release();
|
||||
|
||||
renderTexture.descriptor = desc;
|
||||
|
||||
renderTexture.Create();
|
||||
}
|
||||
|
||||
return renderTexture;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2690d82f025dba34d90f948f4b59367b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/UI/ScratchTicket/Shaders.meta
Normal file
8
Assets/Scripts/UI/ScratchTicket/Shaders.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19aae918d5a1af940819cfc885737797
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,79 @@
|
||||
Shader "Bamboo/ScratchCard/Brush"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_MainTex ("Sprite Texture", 2D) = "white" {}
|
||||
_Color ("Tint", Color) = (1,1,1,1)
|
||||
[PerRendererData] _OffsetScale ("Offset (xy) and Scale (zw)", Float) = (0, 0, 0, 0)
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags
|
||||
{
|
||||
"Queue"="Transparent"
|
||||
"IgnoreProjector"="True"
|
||||
"RenderType"="Transparent"
|
||||
"PreviewType"="Plane"
|
||||
"CanUseSpriteAtlas"="True"
|
||||
}
|
||||
|
||||
Cull Off
|
||||
Lighting Off
|
||||
ZWrite Off
|
||||
BlendOp RevSub
|
||||
Blend Zero One, One One
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "Default"
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma target 2.0
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "UnityUI.cginc"
|
||||
|
||||
struct appdata_t
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float4 color : COLOR;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 vertex : SV_POSITION;
|
||||
fixed4 color : COLOR;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float4 worldPosition : TEXCOORD1;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
fixed4 _Color;
|
||||
float4 _ClipRect;
|
||||
float4 _MainTex_ST;
|
||||
float4 _OffsetScale;
|
||||
|
||||
v2f vert(appdata_t v)
|
||||
{
|
||||
v2f OUT;
|
||||
|
||||
OUT.worldPosition = (v.vertex + float4(_OffsetScale.xy, 0, 0));
|
||||
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
|
||||
OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex) * _OffsetScale.zw;
|
||||
OUT.color = v.color * _Color;
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
fixed4 frag(v2f IN) : SV_Target
|
||||
{
|
||||
half4 color = tex2D(_MainTex, IN.texcoord) * IN.color;
|
||||
return color;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73cfbd2d24f74f242bbeff8af1301850
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user