Merge branch 'master' into h5version
# Conflicts:
# Main/ResModule/ResManager.cs
# Main/System/Hero/UIHeroController.cs
| | |
| | |
|
| | | // 加载配置文件
|
| | | HashSet<Type> configTypes = new HashSet<Type>() {
|
| | | typeof(ActLunhuidianTypeConfig),
|
| | | typeof(ADAwardConfig),
|
| | | typeof(BattleMapConfig),
|
| | | typeof(BeautyConfig),
|
| | |
| | | typeof(PlayerAttrConfig),
|
| | | typeof(PlayerFaceConfig),
|
| | | typeof(PresetUnlockConfig),
|
| | | typeof(PriorBundleConfig),
|
| | | typeof(RandomNameConfig),
|
| | | typeof(SignInConfig),
|
| | | typeof(SkillSkinConfig),
|
| | |
| | |
|
| | | public override void Release()
|
| | | {
|
| | | // 清空 ActLunhuidianTypeConfig 字典
|
| | | ClearConfigDictionary<ActLunhuidianTypeConfig>();
|
| | | // 清空 ADAwardConfig 字典
|
| | | ClearConfigDictionary<ADAwardConfig>();
|
| | | // 清空 BattleMapConfig 字典
|
| | |
| | | ClearConfigDictionary<PlayerFaceConfig>();
|
| | | // 清空 PresetUnlockConfig 字典
|
| | | ClearConfigDictionary<PresetUnlockConfig>();
|
| | | // 清空 PriorBundleConfig 字典
|
| | | ClearConfigDictionary<PriorBundleConfig>();
|
| | | // 清空 RandomNameConfig 字典
|
| | | ClearConfigDictionary<RandomNameConfig>();
|
| | | // 清空 SignInConfig 字典
|
| New file |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: Wednesday, February 11, 2026 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | | using System; |
| | | using UnityEngine; |
| | | using LitJson; |
| | | |
| | | public partial class ActLunhuidianTypeConfig : ConfigBase<int, ActLunhuidianTypeConfig> |
| | | { |
| | | static ActLunhuidianTypeConfig() |
| | | { |
| | | // 访问过静态构造函数 |
| | | visit = true; |
| | | } |
| | | |
| | | public int ID; |
| | | public int RoundType; |
| | | public int TabType; |
| | | public int TabSort; |
| | | public string TabName; |
| | | public string bgImage; |
| | | public string TitleBgImage; |
| | | public string InfoBgImage; |
| | | public string InfoImage; |
| | | |
| | | public override int LoadKey(string _key) |
| | | { |
| | | int key = GetKey(_key); |
| | | return key; |
| | | } |
| | | |
| | | public override void LoadConfig(string input) |
| | | { |
| | | try { |
| | | string[] tables = input.Split('\t'); |
| | | int.TryParse(tables[0],out ID); |
| | | |
| | | int.TryParse(tables[1],out RoundType); |
| | | |
| | | int.TryParse(tables[2],out TabType); |
| | | |
| | | int.TryParse(tables[3],out TabSort); |
| | | |
| | | TabName = tables[4]; |
| | | |
| | | bgImage = tables[5]; |
| | | |
| | | TitleBgImage = tables[6]; |
| | | |
| | | InfoBgImage = tables[7]; |
| | | |
| | | InfoImage = tables[8]; |
| | | } |
| | | catch (Exception exception) |
| | | { |
| | | Debug.LogError(exception); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 68536606680071843968c757d340ca39 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: Friday, November 14, 2025
|
| | | // [ Date ]: 2026年2月13日
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | public string RectangleIcon;
|
| | | public string SpineRes;
|
| | | public string InitialSkinName;
|
| | | public string ApearMotionName;
|
| | | public string TransfMotionName;
|
| | | public string LoopMotionName;
|
| | |
|
| | | public override int LoadKey(string _key)
|
| | | {
|
| | |
| | | SpineRes = tables[9];
|
| | |
|
| | | InitialSkinName = tables[10];
|
| | |
|
| | | ApearMotionName = tables[11];
|
| | |
|
| | | TransfMotionName = tables[12];
|
| | |
|
| | | LoopMotionName = tables[13];
|
| | | }
|
| | | catch (Exception exception)
|
| | | {
|
| New file |
| | |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | public partial class ActLunhuidianTypeConfig : ConfigBase<int, ActLunhuidianTypeConfig> |
| | | { |
| | | static List<int> tabIndexList = new List<int>(); |
| | | //<轮回类型,<界面类型,配置ID>> |
| | | static Dictionary<int, Dictionary<int, int>> infoDict = new Dictionary<int, Dictionary<int, int>>(); |
| | | |
| | | protected override void OnConfigParseCompleted() |
| | | { |
| | | if (!infoDict.ContainsKey(RoundType)) |
| | | infoDict[RoundType] = new Dictionary<int, int>(); |
| | | infoDict[RoundType][TabType] = ID; |
| | | } |
| | | |
| | | public static List<int> GetTabList() |
| | | { |
| | | if (tabIndexList.IsNullOrEmpty()) |
| | | { |
| | | tabIndexList = GetKeys().OrderBy(id => Get(id)?.TabSort ?? int.MaxValue).ToList(); |
| | | } |
| | | return tabIndexList; |
| | | } |
| | | |
| | | public static int GetId(int roundType, int tabType) |
| | | { |
| | | return infoDict.TryGetValue(roundType, out var info) && info.TryGetValue(tabType, out var index) ? index : 0; |
| | | } |
| | | |
| | | public static bool TryGetId(int roundType, int tabType, out int id) |
| | | { |
| | | id = 0; |
| | | return infoDict != null && infoDict.TryGetValue(roundType, out var info) && info.TryGetValue(tabType, out id); |
| | | } |
| | | |
| | | public static bool TryGetConfig(int id, out ActLunhuidianTypeConfig config) |
| | | { |
| | | config = null; |
| | | if (!HasKey(id)) |
| | | return false; |
| | | config = Get(id); |
| | | return true; |
| | | } |
| | | |
| | | public static bool TryGetConfig(int roundType, int tabType, out ActLunhuidianTypeConfig config) |
| | | { |
| | | config = null; |
| | | if (!TryGetId(roundType, tabType, out int id)) |
| | | return false; |
| | | return TryGetConfig(id, out config); |
| | | } |
| | | |
| | | |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 2d2ecb0a241fb274ca3795554f869a1b |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | |
| | | // AA 88 轮回殿活动信息 #tagMCActLunhuidianInfo |
| | | |
| | | public class DTCAA88_tagMCActLunhuidianInfo : DtcBasic |
| | | { |
| | | public override void Done(GameNetPackBasic vNetPack) |
| | | { |
| | | base.Done(vNetPack); |
| | | HAA88_tagMCActLunhuidianInfo vNetData = vNetPack as HAA88_tagMCActLunhuidianInfo; |
| | | OperationTimeHepler.Instance.UpdateActLunhuidianInfo(vNetData); |
| | | } |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 449e1ce1e1ee26940a650a40f4b02770 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | |
| | | // AA 89 轮回殿活动玩家信息 #tagMCActLunhuidianPlayerInfo |
| | | |
| | | public class DTCAA89_tagMCActLunhuidianPlayerInfo : DtcBasic { |
| | | public override void Done(GameNetPackBasic vNetPack) { |
| | | base.Done(vNetPack); |
| | | HAA89_tagMCActLunhuidianPlayerInfo vNetData = vNetPack as HAA89_tagMCActLunhuidianPlayerInfo; |
| | | TimeRushManager.Instance.UpdatePlayerInfo(vNetData); |
| | | } |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: af4c2ff45746d0242b3debab8472b7e9 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | Register(typeof(HA001_tagBroadCastInfo), typeof(DTCA001_tagBroadCastInfo)); |
| | | Register(typeof(HA519_tagSCTagFamilyInfo), typeof(DTCA519_tagSCTagFamilyInfo)); |
| | | Register(typeof(HA131_tagSCSettingDataInfo), typeof(DTCA131_tagSCSettingDataInfo)); |
| | | Register(typeof(HAA88_tagMCActLunhuidianInfo), typeof(DTCAA88_tagMCActLunhuidianInfo)); |
| | | Register(typeof(HAA89_tagMCActLunhuidianPlayerInfo), typeof(DTCAA89_tagMCActLunhuidianPlayerInfo)); |
| | | } |
| | | |
| | | //主工程注册封包 |
| New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | |
| | | // AA 88 轮回殿活动信息 #tagMCActLunhuidianInfo |
| | | |
| | | public class HAA88_tagMCActLunhuidianInfo : GameNetPackBasic { |
| | | public byte ActNum; // 活动编号 |
| | | public string StartDate; // 开始日期 y-m-d |
| | | public string EndtDate; // 结束日期 y-m-d |
| | | public byte ResetType; // 重置类型,0-0点重置;1-5点重置 |
| | | public ushort LimitLV; // 限制等级 |
| | | public byte RoundCount; |
| | | public tagMCActLunhuidianRound[] RoundList; // 轮回列表,支持多个不同类型轮回同时开启 |
| | | |
| | | public HAA88_tagMCActLunhuidianInfo () { |
| | | _cmd = (ushort)0xAA88; |
| | | } |
| | | |
| | | public override void ReadFromBytes (byte[] vBytes) { |
| | | TransBytes (out ActNum, vBytes, NetDataType.BYTE); |
| | | TransBytes (out StartDate, vBytes, NetDataType.Chars, 10); |
| | | TransBytes (out EndtDate, vBytes, NetDataType.Chars, 10); |
| | | TransBytes (out ResetType, vBytes, NetDataType.BYTE); |
| | | TransBytes (out LimitLV, vBytes, NetDataType.WORD); |
| | | TransBytes (out RoundCount, vBytes, NetDataType.BYTE); |
| | | RoundList = new tagMCActLunhuidianRound[RoundCount]; |
| | | for (int i = 0; i < RoundCount; i ++) { |
| | | RoundList[i] = new tagMCActLunhuidianRound(); |
| | | TransBytes (out RoundList[i].RoundType, vBytes, NetDataType.BYTE); |
| | | TransBytes (out RoundList[i].AwardType, vBytes, NetDataType.BYTE); |
| | | TransBytes (out RoundList[i].AwardTypeValue, vBytes, NetDataType.DWORD); |
| | | TransBytes (out RoundList[i].RoundMax, vBytes, NetDataType.BYTE); |
| | | TransBytes (out RoundList[i].AwardCount, vBytes, NetDataType.BYTE); |
| | | RoundList[i].AwardList = new tagMCActLunhuidianAward[RoundList[i].AwardCount]; |
| | | for (int j = 0; j < RoundList[i].AwardCount; j ++) { |
| | | RoundList[i].AwardList[j] = new tagMCActLunhuidianAward(); |
| | | TransBytes (out RoundList[i].AwardList[j].AwardIndex, vBytes, NetDataType.BYTE); |
| | | TransBytes (out RoundList[i].AwardList[j].NeedValue, vBytes, NetDataType.DWORD); |
| | | TransBytes (out RoundList[i].AwardList[j].Count, vBytes, NetDataType.BYTE); |
| | | RoundList[i].AwardList[j].AwardItemList = new tagMCActLunhuidianItem[RoundList[i].AwardList[j].Count]; |
| | | for (int k = 0; k < RoundList[i].AwardList[j].Count; k ++) { |
| | | RoundList[i].AwardList[j].AwardItemList[k] = new tagMCActLunhuidianItem(); |
| | | TransBytes (out RoundList[i].AwardList[j].AwardItemList[k].ItemID, vBytes, NetDataType.DWORD); |
| | | TransBytes (out RoundList[i].AwardList[j].AwardItemList[k].ItemCount, vBytes, NetDataType.WORD); |
| | | TransBytes (out RoundList[i].AwardList[j].AwardItemList[k].IsBind, vBytes, NetDataType.BYTE); |
| | | } |
| | | } |
| | | TransBytes (out RoundList[i].CTGIDCount, vBytes, NetDataType.BYTE); |
| | | TransBytes (out RoundList[i].CTGIDList, vBytes, NetDataType.WORD, RoundList[i].CTGIDCount); |
| | | TransBytes (out RoundList[i].ShopType, vBytes, NetDataType.WORD); |
| | | } |
| | | } |
| | | |
| | | public class tagMCActLunhuidianItem { |
| | | public uint ItemID; |
| | | public ushort ItemCount; |
| | | public byte IsBind; |
| | | } |
| | | |
| | | public class tagMCActLunhuidianRound { |
| | | public byte RoundType; // 轮回类型 |
| | | public byte AwardType; // 奖励类型 1-消耗货币;2-寻宝次数 |
| | | public uint AwardTypeValue; // 奖励类型对应值,消耗货币时为对应的货币类型,寻宝时为对应的寻宝类型 |
| | | public byte RoundMax; // 最大可循环轮次 |
| | | public byte AwardCount; |
| | | public tagMCActLunhuidianAward[] AwardList; // 每轮奖励列表 |
| | | public byte CTGIDCount; |
| | | public ushort[] CTGIDList; // CTGID列表 |
| | | public ushort ShopType; // 开放商店类型,可能为0不开放 |
| | | } |
| | | |
| | | public class tagMCActLunhuidianAward { |
| | | public byte AwardIndex; // 奖励记录索引 0~30 |
| | | public uint NeedValue; // 奖励所需值 |
| | | public byte Count; // 奖励物品数 |
| | | public tagMCActLunhuidianItem[] AwardItemList; // 奖励物品列表 |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 43c3e23f4ddcc8c4f9a2e6ffd631b763 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | |
| | | // AA 89 轮回殿活动玩家信息 #tagMCActLunhuidianPlayerInfo |
| | | |
| | | public class HAA89_tagMCActLunhuidianPlayerInfo : GameNetPackBasic { |
| | | public byte ActNum; // 活动编号 |
| | | public byte RoundType; // 轮回类型 |
| | | public byte CurRound; // 当前轮次 |
| | | public uint CurValue; // 累计值 |
| | | public uint AwardRecord; // 当前轮次奖励领奖记录,按奖励索引二进制位存储是否已领取,所有奖励已领取后自动进入下一轮,且重置该奖励状态 |
| | | |
| | | public HAA89_tagMCActLunhuidianPlayerInfo () { |
| | | _cmd = (ushort)0xAA89; |
| | | } |
| | | |
| | | public override void ReadFromBytes (byte[] vBytes) { |
| | | TransBytes (out ActNum, vBytes, NetDataType.BYTE); |
| | | TransBytes (out RoundType, vBytes, NetDataType.BYTE); |
| | | TransBytes (out CurRound, vBytes, NetDataType.BYTE); |
| | | TransBytes (out CurValue, vBytes, NetDataType.DWORD); |
| | | TransBytes (out AwardRecord, vBytes, NetDataType.DWORD); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 4b06e47c41ad471429c77f4c82a23f08 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | managers.Add(GMNotifyManager.Instance);
|
| | | managers.Add(TimingGiftManager.Instance);
|
| | | managers.Add(SettingDataManager.Instance);
|
| | | managers.Add(TimeRushManager.Instance);
|
| | |
|
| | | foreach (var manager in managers)
|
| | | {
|
| | |
| | | } |
| | | else |
| | | { |
| | | prefab = await ResManager.Instance.LoadAssetAsync<GameObject>("UI", uiName); |
| | | prefab = await ResManager.Instance.LoadAssetAsync<GameObject>("UI", uiName, true); |
| | | } |
| | | |
| | | if (prefab == null) |
| | |
| | | LoadAssetAsyncInternal<T>(directory, name, callBack, needExt); |
| | | } |
| | | |
| | | public async UniTask<T> LoadAssetAsync<T>(string directory, string name) where T : UnityEngine.Object |
| | | { |
| | | return await LoadAssetAsync<T>(directory, name, needExt: true); |
| | | } |
| | | |
| | | public async UniTask<T> LoadAssetAsync<T>(string directory, string name, bool needExt = true) where T : UnityEngine.Object |
| | | { |
| | | var tcs = new UniTaskCompletionSource<T>(); |
| | | LoadAssetAsync<T>(directory, name, (isLoaded, asset) => { |
| | | if (isLoaded) |
| | | { |
| | | tcs.TrySetResult(asset as T); |
| | | } |
| | | else |
| | | { |
| | | tcs.TrySetException(new Exception($"Failed to load asset: {directory}/{name}")); |
| | | } |
| | | }, needExt); |
| | | return await tcs.Task; |
| | | } |
| | | |
| | | private void LoadSpriteAsync<T>(string atlasName, string spriteName, Action<bool, UnityEngine.Object> callBack) where T : UnityEngine.Object |
| | | { |
| | | if (!AssetSource.isUseAssetBundle) |
| | |
| | | if (effectDict.TryGetValue(effectId, out effectPlayers)) |
| | | { |
| | | effectPlayers.Remove(effectPlayer); |
| | | GameObject.DestroyImmediate(effectPlayer.gameObject); |
| | | if (null == effectPlayer) |
| | | { |
| | | BattleDebug.LogError("effect player is null, effectid : " + effectId); |
| | | return; |
| | | } |
| | | if (null != effectPlayer.gameObject) |
| | | { |
| | | GameObject.DestroyImmediate(effectPlayer.gameObject); |
| | | } |
| | | effectPlayer = null; |
| | | } |
| | | else |
| | |
| | | public virtual void Init(int _MapID, int _FuncLineID, JsonData _extendData, |
| | | List<TeamBase> _redTeamList, List<TeamBase> _blueTeamList, byte _turnMax) |
| | | { |
| | | SetData(_MapID, _FuncLineID, _extendData, _redTeamList, _blueTeamList, turnMax); |
| | | SetData(_MapID, _FuncLineID, _extendData, _redTeamList, _blueTeamList, _turnMax); |
| | | battleEffectMgr.Init(this); |
| | | battleTweenMgr.Init(this); |
| | | recordPlayer.Init(this); |
| | |
| | | effectPlayers[i].SetActive(isFront); |
| | | } |
| | | // 策划要在释放技能的时候 其他角色隐藏 这里在back的时候就直接设置成0 在最底下 看不到的地方 |
| | | int baseOrder = isFront ? BattleConst.SkillMaskOrder : BattleConst.BattleBackgroundOrder; |
| | | int baseOrder = isFront ? BattleConst.SkillMaskOrder : BattleConst.BattleBackgroundOrder - BattleConst.BattleFrontHeroEffect; |
| | | |
| | | SetSortingOrder(baseOrder); |
| | | } |
| | |
| | | |
| | | public int GetUsedSkinID(int mmID) |
| | | { |
| | | var _list = BeautySkinConfig.GetSkinListByMMID(mmID); |
| | | if (beautyMMDataDict.ContainsKey(mmID)) |
| | | { |
| | | var _beauty = beautyMMDataDict[mmID]; |
| | | if (_beauty.State == 1) |
| | | { |
| | | foreach (var skin in beautyMMSkinDataDict) |
| | | foreach (var skinCfg in _list) |
| | | { |
| | | if (skin.Value.Used == 1) |
| | | beautyMMSkinDataDict.TryGetValue(skinCfg.SkinID, out BeautyMMSkinData skin); |
| | | if (skin != null && skin.Used == 1) |
| | | { |
| | | return skin.Key; |
| | | return skinCfg.SkinID; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | //默认第一个 |
| | | var _list = BeautySkinConfig.GetSkinListByMMID(mmID); |
| | | if (_list.Count > 0) |
| | | { |
| | | return _list[0].SkinID; |
| | |
| | | |
| | | void AddEnergy() |
| | | { |
| | | ItemLogicUtility.Instance.ShowItemBatchUseWin(BeautyMMManager.Instance.addEnergyItemID, ShowTip); |
| | | ItemLogicUtility.Instance.ShowItemBatchUseWin(BeautyMMManager.Instance.addEnergyItemID, ShowTip, Language.Get("GuildBoss22")); |
| | | } |
| | | |
| | | string ShowTip(long useCnt) |
| | |
| | | fmlv = fairyMember.FmLV; |
| | | } |
| | | return Language.Get("Chat16", RichTextMsgReplaceConfig.GetRichReplace("FAMILY", fmlv), data.Name, data.Content); |
| | | case ChatChannel.CrossServer: |
| | | return Language.Get("Chat17", data.Name, data.Content); |
| | | default: |
| | | return data.Content; |
| | | } |
| | |
| | | { |
| | | talkDict.Clear(); |
| | | lastTalkDataDict.Clear(); |
| | | currentDay = -1; |
| | | currentDayDict.Clear(); |
| | | nowChatChannel = ChatChannel.World; |
| | | nowChatTab = ChatTab.World; |
| | | } |
| | |
| | | ChatReport(channelType, content); |
| | | } |
| | | |
| | | void ChatReport(int chatType, string content, string toPlayer="") |
| | | void ChatReport(int chatType, string content, string toPlayer = "") |
| | | { |
| | | try |
| | | { |
| | | var channelName = Language.Get($"ChatTab{chatType}"); |
| | | |
| | | |
| | | OperationLogCollect.Instance.ChatReport(content, channelName, toPlayer, chatType); |
| | | } |
| | | catch (Exception e) |
| | |
| | | } |
| | | } |
| | | |
| | | public int currentDay = -1; |
| | | public Dictionary<ChatChannel, int> currentDayDict = new Dictionary<ChatChannel, int>(); |
| | | public bool TryAddDate(int allSeconds, ChatChannel type, bool isSendBullet) |
| | | { |
| | | DateTime talkTime = TimeUtility.GetTime((uint)allSeconds); |
| | | if (talkTime.Day != currentDay) |
| | | // 确保字典中包含该频道的条目 |
| | | if (!currentDayDict.ContainsKey(type)) |
| | | { |
| | | currentDay = talkTime.Day; |
| | | currentDayDict[type] = -1; |
| | | } |
| | | // 每个频道独立检查日期 |
| | | if (talkTime.Day != currentDayDict[type]) |
| | | { |
| | | currentDayDict[type] = talkTime.Day; |
| | | AddTalkData(type, new TalkData() |
| | | { |
| | | ChannelType = (byte)type, |
| | |
| | | |
| | | public void AddSysData(string msg, ArrayList infoList, ChatChannel type, bool isSendBullet) |
| | | { |
| | | int allSeconds = TimeUtility.AllSeconds; |
| | | int allSeconds = type == ChatChannel.CrossServer ? TimeUtility.GetCommServerTick(GuildManager.Instance.zoneID) : TimeUtility.AllSeconds; |
| | | // 如果隔天,增加日期行 |
| | | TryAddDate(allSeconds, type, isSendBullet); |
| | | |
| | |
| | | talkDict[type] = new List<TalkData>(); |
| | | } |
| | | |
| | | int allSeconds = TimeUtility.AllSeconds; |
| | | int allSeconds = type == ChatChannel.CrossServer ? TimeUtility.GetCommServerTick(GuildManager.Instance.zoneID) : TimeUtility.AllSeconds; |
| | | // 如果隔天,增加日期行 |
| | | TryAddDate(allSeconds, type, true); |
| | | |
| | |
| | | { |
| | | ChatTab.World, |
| | | ChatTab.Guild, |
| | | ChatTab.CrossServer, |
| | | // ChatTab.Person, |
| | | // ChatTab.BlackList, |
| | | }; |
| | |
| | | |
| | | switch (chatTab) |
| | | { |
| | | case ChatTab.World: |
| | | return true; |
| | | case ChatTab.Guild: |
| | | //没有公会 |
| | | if (!PlayerDatas.Instance.fairyData.HasFairy) |
| | |
| | | return false; |
| | | } |
| | | return true; |
| | | case ChatTab.CrossServer: |
| | | //没有合服 |
| | | if (GuildManager.Instance.zoneID <= 0) |
| | | { |
| | | if (isTip) |
| | | SysNotifyMgr.Instance.ShowTip("CrossServerNoOpen"); |
| | | return false; |
| | | } |
| | | return true; |
| | | default: |
| | | return false; |
| | | return true; |
| | | } |
| | | } |
| | | |
| | |
| | | { |
| | | World = 0, //世界 |
| | | Guild = 1, //公会 |
| | | Person = 2, //私聊 |
| | | BlackList = 3, //黑名单 |
| | | CrossServer = 2, //跨服 |
| | | Person = 3, //私聊 |
| | | BlackList = 4, //黑名单 |
| | | } |
| | | public enum ChatChannel |
| | | { |
| | |
| | | string serverName = ServerListCenter.Instance.GetServerName(UIHelper.GetServerIDByAccount(PlayerDatas.Instance.baseData.AccID)); |
| | | m_PlayerName.text = Language.Get("Chat08", serverName, PlayerDatas.Instance.baseData.PlayerName); |
| | | } |
| | | else |
| | | else if (manager.nowChatTab == ChatTab.Guild) |
| | | { |
| | | int fmlv = PlayerDatas.Instance.fairyData.mine.FmLV; |
| | | m_PlayerName.text = Language.Get("Chat08", RichTextMsgReplaceConfig.GetRichReplace("FAMILY", fmlv), PlayerDatas.Instance.baseData.PlayerName); |
| | | } |
| | | else if (manager.nowChatTab == ChatTab.CrossServer) |
| | | { |
| | | string serverName = ServerListCenter.Instance.GetServerName(UIHelper.GetServerIDByAccount(PlayerDatas.Instance.baseData.AccID)); |
| | | m_PlayerName.text = Language.Get("Chat08", serverName, PlayerDatas.Instance.baseData.PlayerName); |
| | | } |
| | | } |
| | | |
| | | public float GetHeight(string content, ArrayList list) |
| | |
| | | string serverName = ServerListCenter.Instance.GetServerName((int)data.ServerID); |
| | | m_PlayerName.text = Language.Get("Chat08", serverName, data.Name); |
| | | } |
| | | else |
| | | else if (manager.nowChatTab == ChatTab.Guild) |
| | | { |
| | | FairyMember fairyMember = PlayerDatas.Instance.fairyData.GetMember((int)data.PlayerID); |
| | | int fmlv = 0; |
| | |
| | | } |
| | | m_PlayerName.text = Language.Get("Chat08", RichTextMsgReplaceConfig.GetRichReplace("FAMILY", fmlv), data.Name); |
| | | } |
| | | |
| | | else if (manager.nowChatTab == ChatTab.CrossServer) |
| | | { |
| | | string serverName = ServerListCenter.Instance.GetServerName((int)data.ServerID); |
| | | m_PlayerName.text = Language.Get("Chat08", serverName, data.Name); |
| | | } |
| | | |
| | | avatarCell.SetListener(() => |
| | | { |
| | | AvatarHelper.TryViewOtherPlayerInfo((int)data.PlayerID, serverID: (int)data.ServerID, viewPlayerLineupType: (int)BattlePreSetType.Arena); |
| | |
| | | [SerializeField] TextEx txtSendChat; |
| | | [SerializeField] ScrollerController scrWorld; |
| | | [SerializeField] ScrollerController scrGuild; |
| | | [SerializeField] ScrollerController scrCrossServer; |
| | | |
| | | [SerializeField] ButtonEx serversBtn; |
| | | private int unreadMsgCount = 0; |
| | | [SerializeField] ButtonEx btnNewMsgTip; |
| | | [SerializeField] TextEx txtNewMsgTip; |
| | |
| | | bool isSettingOpen = false; |
| | | [SerializeField] ChatSettingButton btnWorldSetting; |
| | | [SerializeField] ChatSettingButton btnGuildSetting; |
| | | [SerializeField] ChatSettingButton btnCrossServerSetting; |
| | | ChatManager manager { get { return ChatManager.Instance; } } |
| | | |
| | | protected override void InitComponent() |
| | |
| | | RefreshChat(manager.nowChatChannel, scrGuild); |
| | | ScrollerJump(scrGuild, ChatChannel.Guild); |
| | | } |
| | | else if (manager.nowChatChannel == ChatChannel.CrossServer) |
| | | { |
| | | RefreshChat(manager.nowChatChannel, scrCrossServer); |
| | | ScrollerJump(scrCrossServer, ChatChannel.CrossServer); |
| | | } |
| | | ClearUnreadMsg(); |
| | | }); |
| | | btnSetting.SetListener(() => |
| | |
| | | isSettingOpen = !isSettingOpen; |
| | | transSettings.SetActive(isSettingOpen); |
| | | }); |
| | | |
| | | serversBtn.SetListener(() => |
| | | { |
| | | UIHelper.ShowServersPanel(GuildManager.Instance.crossServerIDList); |
| | | }); |
| | | } |
| | | |
| | | // 清理未读消息状态 |
| | |
| | | manager.OnUpdatePlayerInfoEvent += OnUpdatePlayerInfoEvent; |
| | | |
| | | scrChatTab.OnRefreshCell += OnRefreshChatTabCell; |
| | | |
| | | scrWorld.OnGetDynamicSize += OnGetWorldChatDynamicSize; |
| | | scrWorld.OnRefreshCell += OnRefreshWorldCell; |
| | | scrWorld.mScrollRect.onValueChanged.AddListener(OnWorldScrollValChange); |
| | | |
| | | scrGuild.OnGetDynamicSize += OnGetGuildChatDynamicSize; |
| | | scrGuild.OnRefreshCell += OnRefreshGuildCell; |
| | | scrGuild.mScrollRect.onValueChanged.AddListener(OnGuildScrollValChange); |
| | | |
| | | scrCrossServer.OnGetDynamicSize += OnGetChatDynamicSize; |
| | | scrCrossServer.OnRefreshCell += OnRefreshCell; |
| | | scrCrossServer.mScrollRect.onValueChanged.AddListener(OnCrossServerScrollValChange); |
| | | |
| | | clickScreenOtherSpace.AddListener(OnClickScreenOtherSpace); |
| | | GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; |
| | |
| | | transSettings.SetActive(isSettingOpen); |
| | | btnWorldSetting.SetChannelType(ChatChannel.World); |
| | | btnGuildSetting.SetChannelType(ChatChannel.Guild); |
| | | btnCrossServerSetting.SetChannelType(ChatChannel.CrossServer); |
| | | inputChat.characterLimit = ChatManager.Instance.characterLimit; |
| | | CreaterAll(manager.nowChatTab); |
| | | } |
| | |
| | | scrWorld.OnGetDynamicSize -= OnGetWorldChatDynamicSize; |
| | | scrWorld.OnRefreshCell -= OnRefreshWorldCell; |
| | | scrWorld.mScrollRect.onValueChanged.RemoveListener(OnWorldScrollValChange); |
| | | |
| | | scrGuild.OnGetDynamicSize -= OnGetGuildChatDynamicSize; |
| | | scrGuild.OnRefreshCell -= OnRefreshGuildCell; |
| | | scrGuild.mScrollRect.onValueChanged.RemoveListener(OnGuildScrollValChange); |
| | | |
| | | scrCrossServer.OnGetDynamicSize -= OnGetChatDynamicSize; |
| | | scrCrossServer.OnRefreshCell -= OnRefreshCell; |
| | | scrCrossServer.mScrollRect.onValueChanged.RemoveListener(OnCrossServerScrollValChange); |
| | | |
| | | GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; |
| | | clickScreenOtherSpace.RemoveAllListeners(); |
| | | } |
| | |
| | | else if (channel == ChatChannel.Guild) |
| | | { |
| | | CreateScroller(scrGuild, channel); |
| | | } |
| | | else if (channel == ChatChannel.CrossServer) |
| | | { |
| | | CreateScroller(scrCrossServer, channel); |
| | | } |
| | | } |
| | | |
| | |
| | | { |
| | | if (scrWorld.lockType != EnhanceLockType.LockVerticalBottom) |
| | | scrWorld.lockType = EnhanceLockType.LockVerticalBottom; |
| | | |
| | | if (scrGuild.lockType != EnhanceLockType.LockVerticalBottom) |
| | | scrGuild.lockType = EnhanceLockType.LockVerticalBottom; |
| | | if (scrCrossServer.lockType != EnhanceLockType.LockVerticalBottom) |
| | | scrCrossServer.lockType = EnhanceLockType.LockVerticalBottom; |
| | | // 如果回到底部,直接清零消息 |
| | | ClearUnreadMsg(); |
| | | } |
| | |
| | | { |
| | | if (scrWorld.lockType != EnhanceLockType.KeepVertical) |
| | | scrWorld.lockType = EnhanceLockType.KeepVertical; |
| | | if (scrGuild.lockType != EnhanceLockType.KeepVertical) |
| | | scrGuild.lockType = EnhanceLockType.KeepVertical; |
| | | if (scrCrossServer.lockType != EnhanceLockType.KeepVertical) |
| | | scrCrossServer.lockType = EnhanceLockType.KeepVertical; |
| | | } |
| | | } |
| | | } |
| | |
| | | private void OnGuildScrollValChange(Vector2 _pos) |
| | | { |
| | | OnScrollValChange(scrGuild, _pos); |
| | | } |
| | | private void OnCrossServerScrollValChange(Vector2 _pos) |
| | | { |
| | | OnScrollValChange(scrCrossServer, _pos); |
| | | } |
| | | |
| | | private void OnScrollValChange(ScrollerController scorller, Vector2 _pos) |
| | |
| | | scrGuild.lockType = EnhanceLockType.LockVerticalBottom; // 初始锁定底部 |
| | | scrGuild.SetActive(chatTab == ChatTab.Guild); |
| | | |
| | | transInput.SetActive(chatTab == ChatTab.World || chatTab == ChatTab.Guild); |
| | | scrCrossServer.lockType = EnhanceLockType.LockVerticalBottom; // 初始锁定底部 |
| | | scrCrossServer.SetActive(chatTab == ChatTab.CrossServer); |
| | | |
| | | transInput.SetActive(true); |
| | | serversBtn.SetActive(chatTab == ChatTab.CrossServer); |
| | | |
| | | CreateChatTabScroller(); |
| | | |
| | |
| | | manager.nowChatChannel = ChatChannel.Guild; |
| | | CreateScroller(scrGuild, ChatChannel.Guild); |
| | | ScrollerJump(scrGuild, ChatChannel.Guild); |
| | | ClearUnreadMsg(); |
| | | break; |
| | | case ChatTab.CrossServer: |
| | | manager.nowChatChannel = ChatChannel.CrossServer; |
| | | CreateScroller(scrCrossServer, ChatChannel.CrossServer); |
| | | ScrollerJump(scrCrossServer, ChatChannel.CrossServer); |
| | | ClearUnreadMsg(); |
| | | break; |
| | | } |
| | |
| | | else if (type == ChatChannel.Guild) |
| | | { |
| | | RefreshChat(type, scrGuild, playerId, isUpdatePlayerInfo); |
| | | } |
| | | else if (type == ChatChannel.CrossServer) |
| | | { |
| | | RefreshChat(type, scrCrossServer, playerId, isUpdatePlayerInfo); |
| | | } |
| | | |
| | | } |
| | |
| | | return; |
| | | if (type == ChatChannel.Guild && manager.nowChatTab != ChatTab.Guild) |
| | | return; |
| | | if (type == ChatChannel.CrossServer && manager.nowChatTab != ChatTab.CrossServer) |
| | | return; |
| | | // 1. 自己发送的消息 -> 强制跳转到底部 + 清零 |
| | | if (playerId == PlayerDatas.Instance.PlayerId) |
| | | { |
| | |
| | | } |
| | | |
| | | // 特殊情况:如果未读数量巨大(超过了总显示数量),说明整个列表都被刷新了,直接消零 |
| | | if (unreadMsgCount >= scrWorld.GetNumberOfCells(scrWorld.m_Scorller)) |
| | | if (unreadMsgCount >= scroller.GetNumberOfCells(scroller.m_Scorller)) |
| | | { |
| | | ClearUnreadMsg(); |
| | | } |
| | |
| | | {
|
| | | DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
|
| | | GuildManager.Instance.EnterOrQuitGuildEvent += EnterOrQuitGuildEvent;
|
| | | PlayerDatas.Instance.fairyData.OnRefreshFairyInfo += OnRefreshFairyInfo;
|
| | | ParseConfig();
|
| | | }
|
| | | public override void Release()
|
| | | {
|
| | | DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin;
|
| | | GuildManager.Instance.EnterOrQuitGuildEvent -= EnterOrQuitGuildEvent;
|
| | | PlayerDatas.Instance.fairyData.OnRefreshFairyInfo -= OnRefreshFairyInfo;
|
| | | }
|
| | |
|
| | | void OnBeforePlayerDataInitializeEventOnRelogin()
|
| | |
| | | taofaPlayerData.Clear();
|
| | | }
|
| | |
|
| | | private void OnRefreshFairyInfo()
|
| | | {
|
| | | UpdateRedpoint();
|
| | | }
|
| | |
|
| | | void EnterOrQuitGuildEvent(bool isEnter)
|
| | | {
|
| | |
| | | //时间到了 客户端自己清0 |
| | | layerNum = 0; |
| | | } |
| | | layerNum = (uint)Math.Min(layerNum, GuildBossManager.Instance.bzMaxLevel); |
| | | var superHitRate = GuildBossManager.Instance.initSuperHitRate + (int)layerNum * GuildBossManager.Instance.bzAddAttrs[0]; |
| | | var addHurtPer = (int)layerNum * GuildBossManager.Instance.bzAddAttrs[1]; |
| | | |
| | |
| | | private void OnRefreshFairyInfo()
|
| | | {
|
| | | UpdateRequestRedpoint();
|
| | | UpdateDonateRedPoint();
|
| | | }
|
| | |
|
| | | void OnBeforePlayerDataInitialize()
|
| | |
| | | void OnBeforePlayerDataInitializeEx()
|
| | | {
|
| | | isQueryZBGYet = false;
|
| | | //增量的形式
|
| | | PlayerDatas.Instance.fairyData.ClearData();
|
| | | }
|
| | |
|
| | | void OnPlayerLoginOk()
|
| | |
| | |
|
| | |
|
| | | //珍宝阁(行商)
|
| | | public int zhenbaogeCutState = 0;
|
| | | int m_ZhenbaogeCutState = 0;
|
| | | public int zhenbaogeCutState
|
| | | {
|
| | | get
|
| | | {
|
| | | if (familyZBGActions.Count - 1 >= 50)
|
| | | {
|
| | | //砍价人数超过上限后可直接购买
|
| | | m_ZhenbaogeCutState = 1;
|
| | | }
|
| | | return m_ZhenbaogeCutState;
|
| | | }
|
| | | set
|
| | | {
|
| | |
|
| | | m_ZhenbaogeCutState = value;
|
| | | }
|
| | | }
|
| | | public int zhenbaogeBuyState = 0;
|
| | | public bool needCheckCutCD = false;
|
| | | public event Action UpdateZhenbaogeEvent;
|
| | |
| | | HappyXBModel.Instance.SendXBManyQuest((int)HappXBTitle.HeroCallAdvanced); |
| | | }); |
| | | }); |
| | | scoreBtn.AddListener(() => |
| | | { |
| | | UIManager.Instance.OpenWindow<HeroCallScoreWin>(); |
| | | }); |
| | | //策划改变需求 暂时关闭 |
| | | // scoreBtn.AddListener(() => |
| | | // { |
| | | // UIManager.Instance.OpenWindow<HeroCallScoreWin>(); |
| | | // }); |
| | | |
| | | ruleBtn.AddListener(() => |
| | | { |
| | |
| | | |
| | | using System; |
| | | using Cysharp.Threading.Tasks; |
| | | using Spine; |
| | | using Spine.Unity; |
| | | using UnityEngine; |
| | | using UnityEngine.UI; |
| | |
| | | private int skinID; |
| | | protected SkeletonGraphic skeletonGraphic; |
| | | |
| | | protected Spine.AnimationState spineAnimationState; |
| | | public Spine.AnimationState spineAnimationState; |
| | | private GameObject instanceGO; |
| | | |
| | | public Action onComplete; |
| | |
| | | if (isLh) |
| | | { |
| | | var skinConfigTmp = HeroSkinConfig.Get(skinID); |
| | | if (skinConfigTmp != null && skinConfigTmp.Tachie.Contains("SkeletonData")) |
| | | if (skinConfigTmp != null && skinConfigTmp.Tachie.IsSpine()) |
| | | { |
| | | skeletonGraphic.enabled = true; |
| | | } |
| | |
| | | |
| | | //立绘特殊处理,没有spine动画的改用图片 |
| | | var lhImg = this.AddMissingComponent<RawImage>(); |
| | | if (!skinConfig.Tachie.Contains("SkeletonData")) |
| | | if (!skinConfig.Tachie.IsSpine()) |
| | | { |
| | | //图片替换 |
| | | lhImg.SetTexture2DPNG(skinConfig.Tachie); |
| | |
| | | } |
| | | |
| | | |
| | | public bool HasAnimation(string motionName) |
| | | { |
| | | return skeletonGraphic != null && skeletonGraphic.Skeleton != null && skeletonGraphic.Skeleton.ContainsMotion(motionName); |
| | | } |
| | | |
| | | |
| | | protected void OnDestroy() |
| | |
| | | /// <param name="motionName">动作名</param> |
| | | /// <param name="loop">循环</param> |
| | | /// <param name="replay">如果相同动作是否再次重播,比如跑步重播就会跳帧不顺滑</param> |
| | | public virtual void PlayAnimation(string motionName, bool loop = false, bool replay = true) |
| | | public virtual TrackEntry PlayAnimation(string motionName, bool loop = false, bool replay = true) |
| | | { |
| | | if (spineAnimationState == null) return; |
| | | if (spineAnimationState == null) return null; |
| | | |
| | | if (GetCurrentAnimationName() == motionName && !replay) |
| | | return; |
| | | return null; |
| | | |
| | | // 直接使用 ToString() 而不是调用 GetAnimationName |
| | | spineAnimationState.SetAnimation(0, motionName.ToString(), loop); |
| | | return spineAnimationState.SetAnimation(0, motionName.ToString(), loop); |
| | | } |
| | | |
| | | // 播放第一个动画(作为默认动画) |
| | |
| | | public class ItemBatchUseWin : UIBase |
| | | { |
| | | [SerializeField] ItemCell itemCell; |
| | | [SerializeField] Text itemCntTxt; |
| | | [SerializeField] LongPressButton subBtn; |
| | | [SerializeField] LongPressButton addBtn; |
| | | [SerializeField] Text nameText; |
| | | [SerializeField] Text countText; |
| | | [SerializeField] Text descText; |
| | | [SerializeField] SliderPanel sliderPanel; |
| | | [SerializeField] Text tipText; |
| | | [SerializeField] Button okBtn; |
| | | [SerializeField] Text btnNameText; |
| | | [SerializeField] Text titleText; |
| | | |
| | | public static Func<long, string> ShowTextEvent; |
| | | public static int itemID; |
| | | long curUseCount; |
| | | long maxCount; |
| | | public static string btnName; |
| | | |
| | | |
| | | int useCnt; |
| | | long maxCnt; |
| | | protected override void InitComponent() |
| | | { |
| | | addBtn.SetListener(OnClickPlus); |
| | | addBtn.onPress.AddListener(OnClickPlus); |
| | | subBtn.SetListener(OnClickReduce); |
| | | subBtn.onPress.AddListener(OnClickReduce); |
| | | okBtn.AddListener(OnOK); |
| | | } |
| | | |
| | | |
| | | |
| | | protected override void OnPreOpen() |
| | | { |
| | | useCnt = 1; |
| | | Display(); |
| | | } |
| | | |
| | | void Display() |
| | | { |
| | | |
| | | var key = "UseItemTitle_" + itemID; |
| | | if (LanguageConfig.HasKey(key)) |
| | | { |
| | |
| | | { |
| | | titleText.text = Language.Get("UseItemDefault"); |
| | | } |
| | | maxCount = PackManager.Instance.GetItemCountByID(PackType.Item, itemID); |
| | | curUseCount = maxCount > 0 ? 1 : 0; |
| | | itemCell.Init(new ItemCellModel(itemID, false, curUseCount)); |
| | | maxCnt = PackManager.Instance.GetItemCountByID(PackType.Item, itemID); |
| | | useCnt = maxCnt > 0 ? 1 : 0; |
| | | itemCell.Init(new ItemCellModel(itemID, false, useCnt)); |
| | | itemCell.button.AddListener(() => |
| | | { |
| | | ItemTipUtility.Show(itemID); |
| | | }); |
| | | |
| | | RefreshCount(); |
| | | RefreshBtn(); |
| | | |
| | | var itemConfig = ItemConfig.Get(itemID); |
| | | nameText.text = itemConfig.ItemName; |
| | | countText.text = Language.Get("storename12", maxCnt); |
| | | descText.text = itemConfig.Description; |
| | | |
| | | |
| | | |
| | | OnSliderChange(useCnt); |
| | | sliderPanel.Init((value) => { OnSliderChange(value); }, (int)maxCnt); |
| | | |
| | | btnNameText.text = btnName; |
| | | } |
| | | |
| | | protected override void OnPreClose() |
| | | void OnSliderChange(int value) |
| | | { |
| | | } |
| | | useCnt = value; |
| | | itemCell.countText.text = UIHelper.ReplaceLargeNum(useCnt); |
| | | |
| | | |
| | | |
| | | |
| | | void RefreshCount() |
| | | { |
| | | itemCntTxt.text = curUseCount + "/" + maxCount; |
| | | itemCell.countText.text = curUseCount.ToString(); |
| | | if (ShowTextEvent != null) |
| | | { |
| | | tipText.text = ShowTextEvent(curUseCount); |
| | | tipText.text = ShowTextEvent(useCnt); |
| | | } |
| | | else |
| | | { |
| | |
| | | |
| | | } |
| | | |
| | | void RefreshBtn() |
| | | { |
| | | if (curUseCount >= maxCount) |
| | | { |
| | | addBtn.interactable = false; |
| | | addBtn.SetColorful(null, false); |
| | | } |
| | | else |
| | | { |
| | | addBtn.interactable = true; |
| | | addBtn.SetColorful(null, true); |
| | | } |
| | | |
| | | if (curUseCount == 0) |
| | | { |
| | | subBtn.interactable = false; |
| | | subBtn.SetColorful(null, false); |
| | | } |
| | | else |
| | | { |
| | | subBtn.interactable = true; |
| | | subBtn.SetColorful(null, true); |
| | | } |
| | | } |
| | | |
| | | |
| | | void OnClickPlus() |
| | | { |
| | | if (curUseCount >= maxCount) |
| | | { |
| | | curUseCount = maxCount; |
| | | return; |
| | | } |
| | | curUseCount++; |
| | | RefreshCount(); |
| | | RefreshBtn(); |
| | | } |
| | | |
| | | void OnClickReduce() |
| | | { |
| | | if (curUseCount == 0) |
| | | return; |
| | | |
| | | curUseCount--; |
| | | RefreshCount(); |
| | | RefreshBtn(); |
| | | } |
| | | |
| | | void OnOK() |
| | | { |
| | | CloseWindow(); |
| | | if (curUseCount == 0) |
| | | if (useCnt == 0) |
| | | { |
| | | SysNotifyMgr.Instance.ShowTip("UseItem1"); |
| | | return; |
| | | } |
| | | if (ItemLogicUtility.CheckItemCount(PackType.Item, itemID, curUseCount, 2)) |
| | | if (ItemLogicUtility.CheckItemCount(PackType.Item, itemID, useCnt, 1)) |
| | | { |
| | | ItemLogicUtility.Instance.UseItem(PackManager.Instance.GetItemGUIDByID(itemID), (int)curUseCount); |
| | | ItemLogicUtility.Instance.UseItem(PackManager.Instance.GetItemGUIDByID(itemID), useCnt); |
| | | } |
| | | |
| | | SysNotifyMgr.Instance.ShowTip("UseOK"); |
| | | } |
| | | } |
| | | |
| | |
| | | /// </summary>
|
| | | /// <param name="itemID">要使用的物品</param>
|
| | | /// <param name="showTipEvent">参数为要使用的物品数量,返回值为文本</param>
|
| | | public void ShowItemBatchUseWin(int itemID, Func<long, string> showTipEvent)
|
| | | public void ShowItemBatchUseWin(int itemID, Func<long, string> showTipEvent, string btnName)
|
| | | {
|
| | | if (UIManager.Instance.IsOpened<ItemBatchUseWin>())
|
| | | {
|
| | | UIManager.Instance.CloseWindow<ItemBatchUseWin>();
|
| | | }
|
| | | if (!CheckItemCount(PackType.Item, itemID, 1, 2))
|
| | | //提示类型后续有变化,要约定下如何提示
|
| | | if (!CheckItemCount(PackType.Item, itemID, 1, 1))
|
| | | {
|
| | | return;
|
| | | }
|
| | | ItemBatchUseWin.itemID = itemID;
|
| | | ItemBatchUseWin.ShowTextEvent = showTipEvent;
|
| | | ItemBatchUseWin.btnName = btnName;
|
| | | UIManager.Instance.OpenWindow<ItemBatchUseWin>();
|
| | | }
|
| | |
|
| | |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using Cysharp.Threading.Tasks; |
| | | using DG.Tweening; |
| | | using UnityEngine; |
| | |
| | | [SerializeField] Button osHeroCallBtn; |
| | | [SerializeField] Button osGalaBtn; |
| | | [SerializeField] TimingGiftCell timingGiftCell; |
| | | [SerializeField] TimeRushCell timeRushCell; |
| | | |
| | | //坐骑 |
| | | [SerializeField] Image horseBGImg; |
| | |
| | | ChatManager.Instance.OnUpdateTalkEvent += OnUpdateTalkEvent; |
| | | UIManager.Instance.OnOpenWindow += OnOpenWindow; |
| | | TimingGiftManager.Instance.OnShowGiftIdListAddEvent += OnShowGiftIdListAddEvent; |
| | | OpenServerActivityCenter.Instance.openServerActivityStateChange += OpenServerActivityStateChange; |
| | | TryPlayAutoFightBoss(); |
| | | Display(); |
| | | DisplayFirstChargeBtn(); |
| | | DisplayOSActivity(); |
| | | timingGiftCell.InitUI(); |
| | | // var battleWin = UIManager.Instance.OpenWindow<BattleWin>(); |
| | | // battleWin.SetBattleField(BattleManager.Instance.storyBattleField); |
| | | |
| | | DisplayTimeRush(); |
| | | |
| | | DelayPlayMusic().Forget(); |
| | | |
| | |
| | | ChatManager.Instance.OnUpdateTalkEvent -= OnUpdateTalkEvent; |
| | | UIManager.Instance.OnOpenWindow -= OnOpenWindow; |
| | | TimingGiftManager.Instance.OnShowGiftIdListAddEvent -= OnShowGiftIdListAddEvent; |
| | | OpenServerActivityCenter.Instance.openServerActivityStateChange -= OpenServerActivityStateChange; |
| | | // 关闭的时候把战斗界面也给关了 虽然是在外面开的 |
| | | UIManager.Instance.CloseWindow<BattleWin>(); |
| | | } |
| | | |
| | | private void OpenServerActivityStateChange() |
| | | { |
| | | DisplayTimeRush(); |
| | | } |
| | | |
| | | private void OnShowGiftIdListAddEvent() |
| | |
| | | case ChatChannel.Guild: |
| | | ChatManager.Instance.nowChatTab = ChatTab.Guild; |
| | | ChatManager.Instance.nowChatChannel = ChatChannel.Guild; |
| | | break; |
| | | case ChatChannel.CrossServer: |
| | | ChatManager.Instance.nowChatTab = ChatTab.CrossServer; |
| | | ChatManager.Instance.nowChatChannel = ChatChannel.CrossServer; |
| | | break; |
| | | } |
| | | } |
| | |
| | | { |
| | | timingGiftCell.InitUI(); |
| | | } |
| | | else if (funcId == (int)FuncOpenEnum.TimeRush) |
| | | { |
| | | DisplayTimeRush(); |
| | | } |
| | | } |
| | | |
| | | private void OnUpdateFirstChargeInfo() |
| | |
| | | { |
| | | DisplayOSActivity(); |
| | | } |
| | | |
| | | |
| | | void DisplayTimeRush() |
| | | { |
| | | bool isOpen = TimeRushManager.Instance.IsFuncOpen(); |
| | | timeRushCell.SetActive(isOpen); |
| | | if (!isOpen) |
| | | return; |
| | | timeRushCell.InitUI(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | }
|
| | | }
|
| | |
|
| | | |
| | |
|
| | |
|
| | | // /// <summary>
|
| | | // /// 累计充值
|
| | |
| | | // }
|
| | | // }
|
| | |
|
| | | |
| | |
|
| | |
|
| | | // public void UpdateCollectWordsPackage(HAA40_tagMCActCollectWordsInfo package)
|
| | | // {
|
| | |
| | | // }
|
| | | // }
|
| | |
|
| | | |
| | |
|
| | |
|
| | | // public void UpdateMultiRechargePackage(HAA27_tagMCActRechargePrizeInfo package)
|
| | | // {
|
| | |
| | | // }
|
| | | // }
|
| | |
|
| | | |
| | | |
| | | |
| | |
|
| | |
|
| | |
|
| | |
|
| | | // public void UpdateCrossActLianQiInfo(HAA90_tagMCCrossActLianqiInfo package)
|
| | | // {
|
| | |
| | | // }
|
| | | // }
|
| | |
|
| | | // public void UpdateActLunhuidianInfo(HAA88_tagMCActLunhuidianInfo package)
|
| | | // {
|
| | | // OperationBase operationBase = null;
|
| | | // operationDict.TryGetValue(Operation.default47, out operationBase);
|
| | | // if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate))
|
| | | // {
|
| | | // ForceStopOperation(Operation.default47);
|
| | | // }
|
| | | // else
|
| | | // {
|
| | | // if (operationBase == null)
|
| | | // {
|
| | | // operationBase = new OperationCycleHall();
|
| | | // operationDict.Add(Operation.default47, operationBase);
|
| | | // }
|
| | | // OperationCycleHall operation = operationBase as OperationCycleHall;
|
| | | // operation.Reset();
|
| | | // operation.startDate = ParseOperationDate(package.StartDate);
|
| | | // operation.endDate = ParseOperationDate(package.EndtDate);
|
| | | // operation.resetType = package.ResetType;
|
| | | // operation.limitLv = package.LimitLV;
|
| | | // operation.ParseCycleHallInfo(package);
|
| | | // if (operationTimeUpdateEvent != null)
|
| | | // {
|
| | | // operationTimeUpdateEvent(Operation.default47);
|
| | | // }
|
| | | // }
|
| | | // }
|
| | | public void UpdateActLunhuidianInfo(HAA88_tagMCActLunhuidianInfo package)
|
| | | {
|
| | | OperationBase operationBase = null;
|
| | | operationDict.TryGetValue(OperationType.default47, out operationBase);
|
| | | if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate))
|
| | | {
|
| | | ForceStopOperation(OperationType.default47);
|
| | | }
|
| | | else
|
| | | {
|
| | | if (operationBase == null)
|
| | | {
|
| | | operationBase = new OperationCycleHall();
|
| | | operationDict.Add(OperationType.default47, operationBase);
|
| | | }
|
| | | OperationCycleHall operation = operationBase as OperationCycleHall;
|
| | | operation.Reset();
|
| | | operation.startDate = ParseOperationDate(package.StartDate);
|
| | | operation.endDate = ParseOperationDate(package.EndtDate);
|
| | | operation.resetType = package.ResetType;
|
| | | operation.limitLv = package.LimitLV;
|
| | | operation.ParseCycleHallInfo(package);
|
| | | if (operationTimeUpdateEvent != null)
|
| | | {
|
| | | operationTimeUpdateEvent(OperationType.default47);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | // public void UpdateActYunShiInfo(HAA87_tagMCActYunshiInfo package)
|
| | | // {
|
| | |
| | | // }
|
| | | // }
|
| | |
|
| | | |
| | |
|
| | | // public void UpdateLoginAct(HAA69_tagMCActLoginNew package)
|
| | | // {
|
| | | // OperationBase operationBase = null;
|
| | |
| | |
|
| | | public enum OperationType
|
| | | {
|
| | |
|
| | |
|
| | | MultipleExp,
|
| | | ConsumeRebate,
|
| | | FlashSale,//限时特惠
|
| | |
| | |
|
| | | //历练秘笈
|
| | | public const int RedPoint_LLMJKey = 106;
|
| | | |
| | |
|
| | | //签到
|
| | | public const int RedPoint_SignKey = 107;
|
| | |
|
| | | //坐骑
|
| | | public const int RedPoint_HorseKey = 108;
|
| | | Redpoint redPointHorse = new Redpoint(RedPoint_HorseKey);
|
| | | |
| | |
|
| | | //特权卡
|
| | | public const int RedPoint_PrivilegeCard = 109;
|
| | | Redpoint pcardRedpoint = new Redpoint(RedPoint_PrivilegeCard);
|
| | | |
| | |
|
| | | //自动战斗
|
| | | public const int RedPoint_AutoBattleKey = 110;
|
| | | Redpoint autoBattleRedpoint = new Redpoint(RedPoint_AutoBattleKey);
|
| | |
| | | #endregion
|
| | |
|
| | | public const int BlessLVRedpoint = 399; //祝福等级红点
|
| | | |
| | |
|
| | |
|
| | | #region 仙盟红点
|
| | | //大厅
|
| | |
| | | public const int LoginZhanLingRedpoint = 449; //登录战令
|
| | |
|
| | | public const int FairyEmbleManageRepoint = 462;//仙盟徽章管理入口红点
|
| | | public const int CycleHallRepoint = 463; //轮回殿
|
| | |
|
| | | public const int YunShiRepoint = 464; //运势
|
| | | public const int LianQiRepoint = 465; //仙匠大会
|
| | | public const int FairySiegeRepoint = 466; //仙盟攻城战
|
| | |
| | | public const int HeroFatesRepoint = 475;//宿缘
|
| | | public const int DailyTehui = 476;//每日特惠
|
| | | public const int WarlordPavilionRepoint = 477;//定军阁
|
| | | public const int TimeRushRepoint = 478; //轮回殿
|
| | | public void Register()
|
| | | {
|
| | |
|
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 7332dc3700298964f9961b3ca4da2c98 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| New file |
| | |
| | | using System.Collections.Generic; |
| | | |
| | | |
| | | //轮回殿活动 |
| | | public class OperationCycleHall : OperationBase |
| | | { |
| | | // <轮回类型, HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianRound> |
| | | public Dictionary<int, HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianRound> roundInfoDict = new Dictionary<int, HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianRound>(); |
| | | TimeRushManager model { get { return TimeRushManager.Instance; } } |
| | | public bool TryGetRound(int roundType, out HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianRound round) |
| | | { |
| | | round = null; |
| | | return roundInfoDict != null && roundInfoDict.TryGetValue(roundType, out round) && round != null; |
| | | } |
| | | |
| | | public bool TryGetRoundInfoByIndex(int roundType, int awardIndex, out HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianAward awardInfo, out int listIndex) |
| | | { |
| | | listIndex = 0; |
| | | awardInfo = new HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianAward { }; |
| | | if (!TryGetRound(roundType, out var round) || round.AwardList == null) |
| | | return false; |
| | | for (int i = 0; i < round.AwardList.Length; i++) |
| | | { |
| | | if (round.AwardList[i].AwardIndex == awardIndex) |
| | | { |
| | | awardInfo = round.AwardList[i]; |
| | | listIndex = i; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | public bool TryGetRoundInfoByNeedValue(int roundType, int needValue, out HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianAward awardInfo) |
| | | { |
| | | awardInfo = new HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianAward { }; |
| | | if (!TryGetRound(roundType, out var round) || round.AwardList == null) |
| | | return false; |
| | | for (int i = 0; i < round.AwardList.Length; i++) |
| | | { |
| | | if (round.AwardList[i].NeedValue == needValue) |
| | | { |
| | | awardInfo = round.AwardList[i]; |
| | | return true; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | public override bool SatisfyOpenCondition() |
| | | { |
| | | return PlayerDatas.Instance.baseData.LV >= limitLv; |
| | | } |
| | | |
| | | public override string ToDisplayTime() |
| | | { |
| | | var textBuilder = OperationTimeHepler.textBuilder; |
| | | textBuilder.Length = 0; |
| | | textBuilder.Append(startDate.ToDisplay()); |
| | | if (startDate != endDate) |
| | | { |
| | | textBuilder.Append("—"); |
| | | textBuilder.Append(endDate.ToDisplay()); |
| | | } |
| | | return textBuilder.ToString(); |
| | | } |
| | | |
| | | public override void Reset() |
| | | { |
| | | base.Reset(); |
| | | roundInfoDict.Clear(); |
| | | model.lastCurRoundDict.Clear(); |
| | | model.lastCurValueDict.Clear(); |
| | | } |
| | | |
| | | public void ParseCycleHallInfo(HAA88_tagMCActLunhuidianInfo package) |
| | | { |
| | | roundInfoDict.Clear(); |
| | | for (int i = 0; i < package.RoundList.Length; i++) |
| | | { |
| | | roundInfoDict[package.RoundList[i].RoundType] = package.RoundList[i]; |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0808e48a7e494424ab338530cfbc9c41 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| New file |
| | |
| | | using System.Linq; |
| | | using UnityEngine; |
| | | |
| | | public class TimeRushCell : MonoBehaviour |
| | | { |
| | | [SerializeField] ImageEx bgImage; |
| | | [SerializeField] TextEx titleText; |
| | | [SerializeField] ButtonEx iconButton; |
| | | TimeRushManager manager { get { return TimeRushManager.Instance; } } |
| | | public void InitUI() |
| | | { |
| | | var list = TimeRushManager.Instance.GetTabIDList(); |
| | | if (list.IsNullOrEmpty()) |
| | | return; |
| | | int id = list.First(); |
| | | if (!ActLunhuidianTypeConfig.TryGetConfig(id, out var config)) |
| | | return; |
| | | int roundType = config.RoundType; |
| | | |
| | | bgImage.SetSprite($"TimeRushEntry{roundType}"); |
| | | bgImage.SetNativeSize(); |
| | | titleText.text = Language.Get($"TimeRushEntryTitle{roundType}"); |
| | | iconButton.SetListener(() => |
| | | { |
| | | if (!UIManager.Instance.IsOpened<TimeRushWin>()) |
| | | { |
| | | UIManager.Instance.OpenWindow<TimeRushWin>(0); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: cc10e231ecf97b9489602d412f470819 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| New file |
| | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public class TimeRushGiftCell : MonoBehaviour |
| | | { |
| | | [SerializeField] TextEx titleText; |
| | | [SerializeField] ItemCell[] itemCells; |
| | | [SerializeField] ButtonEx buyButton; |
| | | [SerializeField] ImageEx buyImage; |
| | | [SerializeField] TextEx buyText; |
| | | [SerializeField] TextEx buyText1; |
| | | [SerializeField] ImageEx moneyIconImage; |
| | | [SerializeField] TextEx limitCountText; |
| | | [SerializeField] ImageEx redImage; |
| | | TimeRushManager manager { get { return TimeRushManager.Instance; } } |
| | | StoreModel storeModel { get { return StoreModel.Instance; } } |
| | | public void Display(int index, List<TimeRushGiftItem> giftItems) |
| | | { |
| | | if (giftItems.IsNullOrEmpty() || index < 0 || index >= giftItems.Count) |
| | | return; |
| | | TimeRushGiftItem item = giftItems[index]; |
| | | if (item.type == 0) |
| | | { |
| | | DisplayStore(item.id); |
| | | return; |
| | | } |
| | | |
| | | DisplayCTG(item.id); |
| | | } |
| | | |
| | | private void DisplayCTG(int ctgId) |
| | | { |
| | | redImage.SetActive(false); |
| | | buyText.SetActive(true); |
| | | buyText1.SetActive(false); |
| | | moneyIconImage.SetActive(false); |
| | | |
| | | if (!RechargeManager.Instance.TryGetOrderInfo(ctgId, out var orderConfig)) |
| | | return; |
| | | if (!RechargeManager.Instance.TryGetRechargeCount(ctgId, out var rechargeCount)) |
| | | return; |
| | | if (!CTGConfig.HasKey(ctgId)) |
| | | return; |
| | | if (!RechargeManager.Instance.TryGetRechargeItem(ctgId, out var rechargeItemList)) |
| | | return; |
| | | |
| | | CTGConfig config = CTGConfig.Get(ctgId); |
| | | |
| | | bool isCanBuy = manager.IsCanBuyCTG(ctgId); |
| | | titleText.text = config.Title; |
| | | buyImage.SetSprite(isCanBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2"); |
| | | buyText.text = !isCanBuy ? Language.Get("storename11") : Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderConfig.PayRMBNum)); |
| | | limitCountText.SetActive(true); |
| | | limitCountText.text = Language.Get("TimeRush07", UIHelper.AppendColor(rechargeCount.totalCount >= config.TotalBuyCount ? TextColType.Red : TextColType.LightGreen, Mathf.Max(0, config.TotalBuyCount - rechargeCount.totalCount).ToString())); |
| | | buyButton.interactable = isCanBuy; |
| | | buyButton.SetListener(() => |
| | | { |
| | | RechargeManager.Instance.CTG(ctgId); |
| | | }); |
| | | |
| | | for (int i = 0; i < itemCells.Length; i++) |
| | | { |
| | | var itemBaisc = itemCells[i]; |
| | | if (i < rechargeItemList.Count) |
| | | { |
| | | var itemInfo = rechargeItemList[i]; |
| | | itemBaisc.SetActive(true); |
| | | itemBaisc.Init(new ItemCellModel((int)itemInfo.id, false, itemInfo.countEx)); |
| | | itemBaisc.button.AddListener(() => |
| | | { |
| | | ItemTipUtility.Show((int)itemInfo.id); |
| | | }); |
| | | } |
| | | else |
| | | { |
| | | itemBaisc.SetActive(false); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void DisplayStore(int id) |
| | | { |
| | | if (!StoreConfig.HasKey(id)) |
| | | return; |
| | | StoreConfig storeConfig = StoreConfig.Get(id); |
| | | int remainNum; |
| | | storeModel.TryGetIsSellOut(storeConfig, out remainNum); |
| | | |
| | | bool isFree = manager.IsFree(id); |
| | | titleText.text = storeConfig.Name; |
| | | |
| | | limitCountText.SetActive(!isFree); |
| | | limitCountText.text = Language.Get("TimeRush08", UIHelper.AppendColor(remainNum == 0 ? TextColType.Red : TextColType.LightGreen, Mathf.Max(0, remainNum).ToString(), true)); |
| | | |
| | | bool isCanBuy = manager.IsCanBuyShop(id); |
| | | |
| | | redImage.SetActive(isFree && isCanBuy); |
| | | buyText.SetActive(isFree || !isCanBuy); |
| | | buyText.text = isFree ? Language.Get("L1127") : Language.Get("storename11"); |
| | | buyText1.SetActive(!isFree && isCanBuy); |
| | | buyText1.text = UIHelper.GetMoneyFormat(storeConfig.MoneyNum); |
| | | moneyIconImage.SetActive(!isFree && isCanBuy); |
| | | moneyIconImage.SetIconWithMoneyType(1); |
| | | buyImage.SetSprite(isCanBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2"); |
| | | buyButton.interactable = isCanBuy; |
| | | buyButton.SetListener(() => |
| | | { |
| | | storeModel.SendBuyShopItemWithPopCheck(storeConfig, 1, (int)BuyStoreItemCheckType.ActGift); |
| | | }); |
| | | |
| | | var items = storeModel.GetShopItemlistByIndex(storeConfig); |
| | | for (int i = 0; i < itemCells.Length; i++) |
| | | { |
| | | var itemBaisc = itemCells[i]; |
| | | if (i < items.Count) |
| | | { |
| | | var itemInfo = items[i]; |
| | | itemBaisc.SetActive(true); |
| | | itemBaisc.Init(new ItemCellModel(itemInfo.itemId, false, itemInfo.count)); |
| | | itemBaisc.button.AddListener(() => |
| | | { |
| | | ItemTipUtility.Show(itemInfo.itemId); |
| | | }); |
| | | } |
| | | else |
| | | { |
| | | itemBaisc.SetActive(false); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | public class TimeRushGiftItem |
| | | { |
| | | public int type;//0 商店id 1 充值id |
| | | public int id; |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 8e9f60e895d200241adac4eec9b944d7 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using UnityEngine; |
| | | |
| | | public class TimeRushManager : GameSystemManager<TimeRushManager>, IOpenServerActivity |
| | | { |
| | | |
| | | |
| | | public Action PlayAnimationSync; |
| | | |
| | | private bool isPlayAnimation = false; |
| | | public bool IsPlayAnimation |
| | | { |
| | | get |
| | | { |
| | | return isPlayAnimation; |
| | | } |
| | | set |
| | | { |
| | | isPlayAnimation = value; |
| | | if (isPlayAnimation) |
| | | { |
| | | PlayAnimationSync?.Invoke(); |
| | | } |
| | | isPlayAnimation = false; |
| | | } |
| | | } |
| | | |
| | | public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_Activity2; |
| | | public const int activityID = (int)NewDayActivityID.TimeRushAct; |
| | | public int actNum = 10; |
| | | public static OperationType operaType = OperationType.default47; |
| | | public Redpoint redPoint = new Redpoint(MainRedDot.TimeRushRepoint); |
| | | |
| | | public bool IsOpen => OperationTimeHepler.Instance.SatisfyOpenCondition(operaType); |
| | | |
| | | public bool IsAdvance => OperationTimeHepler.Instance.SatisfyAdvanceCondition(operaType); |
| | | |
| | | public bool priorityOpen => redPoint.state == RedPointState.Simple; |
| | | |
| | | public event Action<int> onStateUpdate; |
| | | |
| | | //类型对应功能ID |
| | | public Dictionary<int, int> funcIdDict = new Dictionary<int, int>(); |
| | | |
| | | public bool TryGetFuncIdByRoundType(int roundType, out int funcId) |
| | | { |
| | | return funcIdDict.TryGetValue(roundType, out funcId); |
| | | } |
| | | |
| | | //类型对应窗口ID |
| | | public Dictionary<int, int> windowIDDict = new Dictionary<int, int>(); |
| | | |
| | | public bool TryGetWindowIDByRoundType(int roundType, out int windowID) |
| | | { |
| | | return windowIDDict.TryGetValue(roundType, out windowID); |
| | | } |
| | | public Dictionary<int, int> moneyTypeDict = new Dictionary<int, int>(); |
| | | public bool TryGetMoneyTypeByRoundType(int roundType, out int windowID) |
| | | { |
| | | return moneyTypeDict.TryGetValue(roundType, out windowID); |
| | | } |
| | | public override void Init() |
| | | { |
| | | OperationTimeHepler.Instance.operationTimeUpdateEvent += OperationTimeUpdateEvent; |
| | | OperationTimeHepler.Instance.operationStartEvent += OperationStartEvent; |
| | | OperationTimeHepler.Instance.operationEndEvent += OperationEndEvent; |
| | | OperationTimeHepler.Instance.operationAdvanceEvent += OperationAdvanceEvent; |
| | | StoreModel.Instance.RefreshBuyShopLimitEvent += RefreshBuyShopLimitEvent; |
| | | //storeModel.RefreshBuyShopLimitEvent += RefreshBuyShopLimitEvent; |
| | | OpenServerActivityCenter.Instance.Register(activityID, this, activityType); |
| | | |
| | | var config = FuncConfigConfig.Get("TimeRush"); |
| | | windowIDDict = ConfigParse.ParseIntDict(config.Numerical1); |
| | | funcIdDict = ConfigParse.ParseIntDict(config.Numerical2); |
| | | moneyTypeDict = ConfigParse.ParseIntDict(config.Numerical3); |
| | | |
| | | } |
| | | |
| | | public override void Release() |
| | | { |
| | | OperationTimeHepler.Instance.operationTimeUpdateEvent -= OperationTimeUpdateEvent; |
| | | OperationTimeHepler.Instance.operationStartEvent -= OperationStartEvent; |
| | | OperationTimeHepler.Instance.operationEndEvent -= OperationEndEvent; |
| | | OperationTimeHepler.Instance.operationAdvanceEvent -= OperationAdvanceEvent; |
| | | StoreModel.Instance.RefreshBuyShopLimitEvent -= RefreshBuyShopLimitEvent; |
| | | } |
| | | |
| | | private void OperationTimeUpdateEvent(OperationType type) |
| | | { |
| | | if (type == operaType) |
| | | { |
| | | UpdateRedpoint(); |
| | | } |
| | | } |
| | | |
| | | private void RefreshBuyShopLimitEvent() |
| | | { |
| | | UpdateRedpoint(); |
| | | } |
| | | |
| | | private void OperationStartEvent(OperationType type, int state) |
| | | { |
| | | if (type == operaType && state == 0) |
| | | { |
| | | if (onStateUpdate != null) |
| | | { |
| | | onStateUpdate(activityID); |
| | | } |
| | | UpdateRedpoint(); |
| | | } |
| | | } |
| | | private void OperationEndEvent(OperationType type, int state) |
| | | { |
| | | if (type == operaType) |
| | | { |
| | | if (onStateUpdate != null) |
| | | { |
| | | onStateUpdate(activityID); |
| | | } |
| | | |
| | | if (UIManager.Instance.IsOpened<TimeRushWin>()) |
| | | { |
| | | UIManager.Instance.CloseWindow<TimeRushWin>(); |
| | | } |
| | | UpdateRedpoint(); |
| | | } |
| | | } |
| | | private void OperationAdvanceEvent(OperationType type) |
| | | { |
| | | if (type == operaType) |
| | | { |
| | | if (onStateUpdate != null) |
| | | { |
| | | onStateUpdate(activityID); |
| | | } |
| | | UpdateRedpoint(); |
| | | } |
| | | } |
| | | |
| | | public bool TryGetOperationInfo(out OperationCycleHall act) |
| | | { |
| | | act = null; |
| | | return OperationTimeHepler.Instance.TryGetOperation(operaType, out act) && act != null; |
| | | } |
| | | |
| | | public bool TryGetInListIndexById(int id, out int index) |
| | | { |
| | | index = -1; |
| | | var list = GetTabIDList(); |
| | | if (list.IsNullOrEmpty() || !list.Contains(id)) |
| | | return false; |
| | | index = list.IndexOf(id); |
| | | return index >= 0; |
| | | } |
| | | |
| | | public bool IsFuncOpen() |
| | | { |
| | | if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.TimeRush)) |
| | | return false; |
| | | if (!IsOpen) |
| | | return false; |
| | | if (!TryGetOperationInfo(out OperationCycleHall act)) |
| | | return false; |
| | | List<int> list = GetTabIDList(); |
| | | if (list.IsNullOrEmpty()) |
| | | return false; |
| | | return true; |
| | | } |
| | | |
| | | |
| | | private int m_NowTabId; |
| | | public event Action OnNowTabIdChangeEvent; |
| | | public int nowTabId |
| | | { |
| | | get { return m_NowTabId; } |
| | | set |
| | | { |
| | | if (m_NowTabId != value) |
| | | m_NowTabId = value; |
| | | OnNowTabIdChangeEvent?.Invoke(); |
| | | } |
| | | } |
| | | |
| | | public List<int> GetTabIDList() |
| | | { |
| | | if (!TryGetOperationInfo(out OperationCycleHall act)) |
| | | return null; |
| | | var list = ActLunhuidianTypeConfig.GetTabList(); |
| | | if (list.IsNullOrEmpty()) |
| | | return null; |
| | | |
| | | List<int> resList = new List<int>(); |
| | | for (int i = 0; i < list.Count; i++) |
| | | { |
| | | int id = list[i]; |
| | | if (!ActLunhuidianTypeConfig.TryGetConfig(id, out var config)) |
| | | continue; |
| | | if (!act.TryGetRound(config.RoundType, out var info)) |
| | | continue; |
| | | |
| | | //没配功能ID直接加入 |
| | | if (!funcIdDict.TryGetValue(config.RoundType, out var funcId)) |
| | | { |
| | | if (!resList.Contains(id)) |
| | | resList.Add(id); |
| | | continue; |
| | | } |
| | | |
| | | //配了功能ID,判断功能是否开启 |
| | | if (FuncOpen.Instance.IsFuncOpen(funcId)) |
| | | { |
| | | if (!resList.Contains(id)) |
| | | resList.Add(id); |
| | | } |
| | | } |
| | | return resList; |
| | | } |
| | | public Dictionary<int, HAA89_tagMCActLunhuidianPlayerInfo> playerInfoDict = new Dictionary<int, HAA89_tagMCActLunhuidianPlayerInfo>(); |
| | | public bool TryGetPlayerInfo(int roundType, out HAA89_tagMCActLunhuidianPlayerInfo playerInfo) |
| | | { |
| | | return playerInfoDict.TryGetValue(roundType, out playerInfo) && playerInfo != null; |
| | | } |
| | | |
| | | public event Action OnUpdatePlayerInfoEvent; |
| | | public void UpdatePlayerInfo(HAA89_tagMCActLunhuidianPlayerInfo netPack) |
| | | { |
| | | if (actNum != netPack.ActNum) |
| | | return; |
| | | if (!playerInfoDict.ContainsKey(netPack.RoundType)) |
| | | playerInfoDict[netPack.RoundType] = new HAA89_tagMCActLunhuidianPlayerInfo(); |
| | | playerInfoDict[netPack.RoundType].RoundType = netPack.RoundType; |
| | | playerInfoDict[netPack.RoundType].CurRound = netPack.CurRound; |
| | | playerInfoDict[netPack.RoundType].CurValue = netPack.CurValue; |
| | | playerInfoDict[netPack.RoundType].AwardRecord = netPack.AwardRecord; |
| | | CheckNewAwardHave(netPack.RoundType, (int)netPack.CurRound, (int)netPack.CurValue); |
| | | OnUpdatePlayerInfoEvent?.Invoke(); |
| | | UpdateRedpoint(); |
| | | } |
| | | |
| | | public int newRoundType; |
| | | public int newAwardType; |
| | | public int newAwardTypeValue; |
| | | public int newAwardIndex; |
| | | // <轮回类型, 上一次的CurRound> |
| | | public Dictionary<int, int> lastCurRoundDict = new Dictionary<int, int>(); |
| | | |
| | | // <轮回类型, 上一次的CurValue> |
| | | public Dictionary<int, int> lastCurValueDict = new Dictionary<int, int>(); |
| | | |
| | | public event Action OnNewAwardHaveEvent; |
| | | public void CheckNewAwardHave(int roundType, int curRound, int curValue) |
| | | { |
| | | if (lastCurRoundDict.ContainsKey(roundType) && lastCurValueDict.ContainsKey(roundType)) |
| | | { |
| | | int lastCurRound = lastCurRoundDict[roundType]; |
| | | int lastCurValue = lastCurValueDict[roundType]; |
| | | if (lastCurRound < curRound) |
| | | { |
| | | lastCurValueDict[roundType] = 0; |
| | | } |
| | | |
| | | lastCurValue = lastCurValueDict[roundType]; |
| | | if (lastCurValue < curValue) |
| | | { |
| | | if (!TryGetOperationInfo(out var act)) |
| | | return; |
| | | if (act.TryGetRound(roundType, out var round) && round.AwardList != null) |
| | | { |
| | | for (int i = 0; i < round.AwardList.Length; i++) |
| | | { |
| | | var Award = round.AwardList[i]; |
| | | int state = GetAwardState(roundType, Award.AwardIndex); |
| | | if (Award.NeedValue > lastCurValue && Award.NeedValue <= curValue && state == 1) |
| | | { |
| | | newRoundType = roundType; |
| | | newAwardType = round.AwardType; |
| | | newAwardTypeValue = (int)round.AwardTypeValue; |
| | | newAwardIndex = Award.AwardIndex; |
| | | if (!UIManager.Instance.IsOpened<TimeRushTipWin>()) |
| | | { |
| | | UIManager.Instance.OpenWindow<TimeRushTipWin>(); |
| | | } |
| | | OnNewAwardHaveEvent?.Invoke(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | lastCurRoundDict[roundType] = curRound; |
| | | lastCurValueDict[roundType] = curValue; |
| | | } |
| | | |
| | | |
| | | public int GetAwardState(int roundType, int awardIndex) |
| | | { |
| | | if (!TryGetPlayerInfo(roundType, out var playerInfo)) |
| | | return 0; |
| | | if (!TryGetOperationInfo(out var act)) |
| | | return 0; |
| | | if (!act.TryGetRoundInfoByIndex(roundType, awardIndex, out var awardInfo, out int listIndex)) |
| | | return 0; |
| | | |
| | | if (playerInfo.CurValue >= awardInfo.NeedValue) |
| | | { |
| | | return (playerInfo.AwardRecord & (1 << awardIndex)) != 0 ? 2 : 1; |
| | | } |
| | | else |
| | | { |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | public void HaveAllMissionAward(int roundType) |
| | | { |
| | | if (!TryGetOperationInfo(out var act)) |
| | | return; |
| | | if (!act.TryGetRound(roundType, out var round) || round.AwardList == null) |
| | | return; |
| | | |
| | | for (int i = 0; i < round.AwardList.Length; i++) |
| | | { |
| | | var award = round.AwardList[i]; |
| | | int state = GetAwardState(roundType, award.AwardIndex); |
| | | if (state == 1) |
| | | { |
| | | SendGetAward(roundType, (int)award.NeedValue); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public bool IsCanBuyCTG(int ctgID) |
| | | { |
| | | if (!RechargeManager.Instance.TryGetRechargeCount(ctgID, out var rechargeCount)) |
| | | return false; |
| | | if (!CTGConfig.HasKey(ctgID)) |
| | | return false; |
| | | CTGConfig config = CTGConfig.Get(ctgID); |
| | | return rechargeCount.totalCount < config.TotalBuyCount; |
| | | } |
| | | |
| | | public bool IsFree(int shopID) |
| | | { |
| | | if (!StoreConfig.HasKey(shopID)) |
| | | return false; |
| | | StoreConfig config = StoreConfig.Get(shopID); |
| | | return config.MoneyNum == 0; |
| | | } |
| | | |
| | | public bool IsCanBuyShop(int shopID) |
| | | { |
| | | if (!StoreConfig.HasKey(shopID)) |
| | | return false; |
| | | StoreConfig config = StoreConfig.Get(shopID); |
| | | |
| | | int remainNum; |
| | | StoreModel.Instance.TryGetIsSellOut(config, out remainNum); |
| | | |
| | | return remainNum > 0; |
| | | } |
| | | |
| | | public List<TimeRushGiftItem> GetGiftItemList(int roundType, bool isSort = false) |
| | | { |
| | | List<TimeRushGiftItem> res = new List<TimeRushGiftItem>(); |
| | | if (TryGetOperationInfo(out var act) && act.TryGetRound(roundType, out var round) && round.CTGIDList != null) |
| | | { |
| | | var list = StoreModel.Instance.storeTypeDict[round.ShopType]; |
| | | if (!list.IsNullOrEmpty()) |
| | | { |
| | | for (int i = 0; i < list.Count; i++) |
| | | { |
| | | var item = list[i]; |
| | | if (item.storeConfig == null) |
| | | continue; |
| | | res.Add(new TimeRushGiftItem |
| | | { |
| | | type = 0, |
| | | id = item.storeConfig.ID, |
| | | }); |
| | | } |
| | | } |
| | | |
| | | for (int i = 0; i < round.CTGIDList.Length; i++) |
| | | { |
| | | var item = round.CTGIDList[i]; |
| | | res.Add(new TimeRushGiftItem |
| | | { |
| | | type = 1, |
| | | id = item, |
| | | }); |
| | | } |
| | | |
| | | if (isSort) |
| | | { |
| | | res = res.OrderBy(item => |
| | | { |
| | | bool isCanBuy = item.type == 0 ? IsCanBuyShop(item.id) : IsCanBuyCTG(item.id); |
| | | return !isCanBuy; |
| | | }) |
| | | .ThenBy(item => item.type) |
| | | .ThenBy(item => item.id) |
| | | .ToList(); |
| | | } |
| | | |
| | | } |
| | | return res; |
| | | } |
| | | |
| | | public List<HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianAward> GetTaskList(int roundType, bool isSort = false) |
| | | { |
| | | if (!TryGetOperationInfo(out var act) || !act.TryGetRound(roundType, out var round) || round.AwardList == null) |
| | | return null; |
| | | |
| | | List<HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianAward> res = round.AwardList.ToList(); |
| | | |
| | | if (isSort) |
| | | { |
| | | // 先获取状态并缓存,避免排序时重复调用 GetAwardState |
| | | res = res.Select(award => new |
| | | { |
| | | Data = award, |
| | | State = GetAwardState(roundType, award.AwardIndex) |
| | | }).OrderBy(x => |
| | | { |
| | | // 定义优先级映射:数字越小,排得越靠前 |
| | | if (x.State == 1) return 0; // 最前:可领取 |
| | | if (x.State == 0) return 1; // 中间:未达成 |
| | | return 2; // 最后:已领取 (state == 2) |
| | | }) |
| | | .ThenBy(x => x.Data.AwardIndex) // 状态相同时,AwardIndex 小的在前 |
| | | .Select(x => x.Data) // 提取回原始数据结构 |
| | | .ToList(); |
| | | } |
| | | return res; |
| | | } |
| | | |
| | | |
| | | public bool IsTabShowRed(int id) |
| | | { |
| | | if (!ActLunhuidianTypeConfig.TryGetConfig(id, out var config)) |
| | | return false; |
| | | int roundType = config.RoundType; |
| | | int tabType = config.TabType; |
| | | if (tabType == 1) |
| | | { |
| | | var taskList = GetTaskList(roundType); |
| | | if (taskList.IsNullOrEmpty()) |
| | | return false; |
| | | for (int i = 0; i < taskList.Count; i++) |
| | | { |
| | | var task = taskList[i]; |
| | | int state = GetAwardState(roundType, task.AwardIndex); |
| | | if (state == 1) |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | var list = GetGiftItemList(roundType); |
| | | if (list.IsNullOrEmpty()) |
| | | return false; |
| | | for (int i = 0; i < list.Count; i++) |
| | | { |
| | | var item = list[i]; |
| | | if (item.type == 0) |
| | | { |
| | | bool isFree = IsFree(item.id); |
| | | bool isCanBuy = IsCanBuyShop(item.id); |
| | | if (isFree && isCanBuy) |
| | | return true; |
| | | |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | public void SendGetAward(int roundType, int needValue) |
| | | { |
| | | CA504_tagCMPlayerGetReward getReward = new CA504_tagCMPlayerGetReward(); |
| | | getReward.RewardType = 78; |
| | | getReward.DataEx = (uint)actNum; |
| | | getReward.DataExStr = StringUtility.Concat(roundType.ToString(), "|", needValue.ToString()); |
| | | getReward.DataExStrLen = (byte)getReward.DataExStr.Length; |
| | | GameNetSystem.Instance.SendInfo(getReward); |
| | | } |
| | | |
| | | public void UpdateRedpoint() |
| | | { |
| | | redPoint.state = RedPointState.None; |
| | | if (!IsFuncOpen()) |
| | | return; |
| | | if (!TryGetOperationInfo(out var act) || act.roundInfoDict == null) |
| | | return; |
| | | foreach (var roundType in act.roundInfoDict.Keys) |
| | | { |
| | | ActLunhuidianTypeConfig config; |
| | | |
| | | if (ActLunhuidianTypeConfig.TryGetConfig(roundType, 1, out config)) |
| | | { |
| | | bool isShow = IsTabShowRed(config.ID); |
| | | if (isShow) |
| | | { |
| | | redPoint.state = RedPointState.Simple; |
| | | return; |
| | | } |
| | | } |
| | | |
| | | if (ActLunhuidianTypeConfig.TryGetConfig(roundType, 2, out config)) |
| | | { |
| | | bool isShow = IsTabShowRed(config.ID); |
| | | if (isShow) |
| | | { |
| | | redPoint.state = RedPointState.Simple; |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 84c9a9bfadc4e62499711a6785fd2ad0 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| New file |
| | |
| | | using UnityEngine; |
| | | |
| | | public class TimeRushTabCell : MonoBehaviour |
| | | { |
| | | [SerializeField] Color unSelectColor; |
| | | [SerializeField] Color selectColor; |
| | | [SerializeField] ImageEx bgImage; |
| | | [SerializeField] TextEx titleText; |
| | | [SerializeField] ImageEx redImage; |
| | | [SerializeField] ButtonEx tabButton; |
| | | TimeRushManager manager { get { return TimeRushManager.Instance; } } |
| | | public void Display(int id) |
| | | { |
| | | if (!ActLunhuidianTypeConfig.TryGetConfig(id, out var config)) |
| | | return; |
| | | bgImage.SetSprite(manager.nowTabId == id ? "TimeRushTabSelect" : "TimeRushTabUnSelect"); |
| | | bgImage.SetNativeSize(); |
| | | titleText.text = config.TabName; |
| | | titleText.color = manager.nowTabId == id ? selectColor : unSelectColor; |
| | | |
| | | redImage.SetActive(manager.IsTabShowRed(id)); |
| | | |
| | | tabButton.SetListener(() => |
| | | { |
| | | manager.nowTabId = id; |
| | | }); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 65202a9b70b44c747913e0d851db8707 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| New file |
| | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public class TimeRushTaskCell : MonoBehaviour |
| | | { |
| | | [SerializeField] ButtonEx clickButton; |
| | | [SerializeField] TextEx titleText; |
| | | [SerializeField] ImageEx sliderImage; |
| | | [SerializeField] ImageEx maskImage; |
| | | [SerializeField] TextEx sliderText; |
| | | [SerializeField] ItemCell[] itemCells; |
| | | [SerializeField] ImageEx[] grays; |
| | | [SerializeField] RotationTween[] tweens; |
| | | [SerializeField] UIEffectPlayer uiEffectPlayer; |
| | | |
| | | int awardIndex; |
| | | int roundType; |
| | | int tabType; |
| | | TimeRushManager manager { get { return TimeRushManager.Instance; } } |
| | | |
| | | private void OnEnable() |
| | | { |
| | | manager.PlayAnimationSync += OnPlaySyncAnimation; |
| | | for (int i = 0; i < tweens.Length; i++) |
| | | { |
| | | tweens[i].Stop(); |
| | | tweens[i].SetStartState(); |
| | | } |
| | | |
| | | if (!manager.TryGetOperationInfo(out var act)) |
| | | return; |
| | | if (!act.TryGetRoundInfoByIndex(roundType, awardIndex, out var awardInfo, out int listIndex) || awardInfo.AwardItemList == null) |
| | | return; |
| | | int state = manager.GetAwardState(roundType, awardIndex); |
| | | for (int i = 0; i < tweens.Length; i++) |
| | | { |
| | | if (i < awardInfo.AwardItemList.Length) |
| | | { |
| | | if (state == 1) |
| | | { |
| | | tweens[i].Play(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | private void OnDisable() |
| | | { |
| | | manager.PlayAnimationSync -= OnPlaySyncAnimation; |
| | | } |
| | | |
| | | private void OnPlaySyncAnimation() |
| | | { |
| | | if (tabType != 1) |
| | | return; |
| | | for (int i = 0; i < tweens.Length; i++) |
| | | { |
| | | tweens[i].Stop(); |
| | | tweens[i].SetStartState(); |
| | | } |
| | | if (!manager.TryGetOperationInfo(out var act)) |
| | | return; |
| | | if (!act.TryGetRoundInfoByIndex(roundType, awardIndex, out var awardInfo, out int listIndex) || awardInfo.AwardItemList == null) |
| | | return; |
| | | int state = manager.GetAwardState(roundType, awardIndex); |
| | | for (int i = 0; i < tweens.Length; i++) |
| | | { |
| | | if (tweens[i].isActiveAndEnabled && state == 1) |
| | | { |
| | | tweens[i].Play(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public void Display(int index, CellView cell, List<HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianAward> taskList) |
| | | { |
| | | |
| | | roundType = cell.info.Value.infoInt1; |
| | | tabType = cell.info.Value.infoInt2; |
| | | if (taskList.IsNullOrEmpty() || index < 0 || index >= taskList.Count) |
| | | return; |
| | | var task = taskList[index]; |
| | | awardIndex = task.AwardIndex; |
| | | if (!manager.TryGetOperationInfo(out var act)) |
| | | return; |
| | | if (!act.TryGetRound(roundType, out var round)) |
| | | return; |
| | | if (!manager.TryGetPlayerInfo(roundType, out var playerInfo)) |
| | | return; |
| | | int state = manager.GetAwardState(roundType, awardIndex); |
| | | maskImage.SetActive(state == 2); |
| | | uiEffectPlayer.SetActive(state == 1); |
| | | titleText.text = Language.Get($"TimeRushTaskTitle_{round.AwardType}_{round.AwardTypeValue}", task.NeedValue); |
| | | sliderImage.fillAmount = playerInfo.CurValue / (float)task.NeedValue; |
| | | sliderText.text = Language.Get("BoneField09", playerInfo.CurValue, task.NeedValue); |
| | | |
| | | for (int i = 0; i < itemCells.Length; i++) |
| | | { |
| | | var itemBaisc = itemCells[i]; |
| | | if (i < task.AwardItemList.Length) |
| | | { |
| | | var itemInfo = task.AwardItemList[i]; |
| | | itemBaisc.SetActive(true); |
| | | grays[i].SetActive(state == 2); |
| | | ItemCellModel cellModel = new ItemCellModel((int)itemInfo.ItemID, false, itemInfo.ItemCount); |
| | | itemBaisc.Init(cellModel); |
| | | itemBaisc.button.AddListener(() => |
| | | { |
| | | if (state == 1) |
| | | { |
| | | manager.HaveAllMissionAward(roundType); |
| | | } |
| | | else |
| | | { |
| | | ItemTipUtility.Show((int)itemInfo.ItemID); |
| | | } |
| | | }); |
| | | } |
| | | else |
| | | { |
| | | itemBaisc.SetActive(false); |
| | | grays[i].SetActive(false); |
| | | } |
| | | } |
| | | |
| | | clickButton.SetListener(() => |
| | | { |
| | | if (state == 1) |
| | | { |
| | | manager.HaveAllMissionAward(roundType); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 9f2398658c04b264eba2671ce96dc050 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| New file |
| | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public class TimeRushTipWin : UIBase |
| | | { |
| | | [SerializeField] RectTransform tip; |
| | | [SerializeField] ButtonEx clickBtn; |
| | | [SerializeField] TextEx awardTipText; |
| | | [SerializeField] List<ItemCell> itemCells = new List<ItemCell>(); |
| | | [SerializeField] PositionTween positionTween; |
| | | [SerializeField] float waitTime = 3.0f; |
| | | [SerializeField] float moveDurationTime = 1.0f; // 移动持续时间 |
| | | [SerializeField] RectTransform startPos; // 初始位置 |
| | | [SerializeField] RectTransform downPos; // 往下移动位置 |
| | | [SerializeField] RectTransform upPos; // 往上移动位置 |
| | | |
| | | int roundType; |
| | | int awardType; |
| | | int awardTypeValue; |
| | | int awardIndex; |
| | | float openTime; |
| | | |
| | | private enum MoveState |
| | | { |
| | | MovingDown, |
| | | Staying, |
| | | MovingUp, |
| | | Finished |
| | | } |
| | | |
| | | MoveState currentState; |
| | | TimeRushManager manager { get { return TimeRushManager.Instance; } } |
| | | |
| | | protected override void InitComponent() |
| | | { |
| | | clickBtn.SetListener(() => |
| | | { |
| | | if (UIManager.Instance.IsOpened<TimeRushWin>()) |
| | | { |
| | | UIManager.Instance.CloseWindow<TimeRushWin>(); |
| | | } |
| | | var list = manager.GetTabIDList(); |
| | | if (list.IsNullOrEmpty()) |
| | | return; |
| | | if (!ActLunhuidianTypeConfig.TryGetConfig(roundType, 1, out var config) || !list.Contains(config.ID)) |
| | | return; |
| | | UIManager.Instance.OpenWindow<TimeRushWin>(config.ID); |
| | | }); |
| | | } |
| | | |
| | | protected override void OnPreOpen() |
| | | { |
| | | manager.OnNewAwardHaveEvent += OnNewAwardHaveEvent; |
| | | ResetAnimation(); |
| | | } |
| | | |
| | | protected override void OnPreClose() |
| | | { |
| | | manager.OnNewAwardHaveEvent -= OnNewAwardHaveEvent; |
| | | } |
| | | |
| | | void LateUpdate() |
| | | { |
| | | |
| | | if (currentState == MoveState.Staying) |
| | | { |
| | | if (Time.time - openTime > waitTime) |
| | | { |
| | | currentState = MoveState.MovingUp; |
| | | positionTween.reversal = true; |
| | | positionTween.from = downPos.anchoredPosition; |
| | | positionTween.to = upPos.anchoredPosition; |
| | | positionTween.duration = moveDurationTime; |
| | | positionTween.Play(OnMoveUpComplete); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void OnMoveDownComplete() |
| | | { |
| | | currentState = MoveState.Staying; |
| | | openTime = Time.time; |
| | | } |
| | | |
| | | private void OnMoveUpComplete() |
| | | { |
| | | currentState = MoveState.Finished; |
| | | if (UIManager.Instance.IsOpened<TimeRushTipWin>()) |
| | | { |
| | | UIManager.Instance.CloseWindow<TimeRushTipWin>(); |
| | | } |
| | | } |
| | | |
| | | private void Display() |
| | | { |
| | | roundType = manager.newRoundType; |
| | | awardType = manager.newAwardType; |
| | | awardTypeValue = manager.newAwardTypeValue; |
| | | awardIndex = manager.newAwardIndex; |
| | | |
| | | |
| | | if (!manager.TryGetOperationInfo(out var act) || !act.TryGetRoundInfoByIndex(roundType, awardIndex, out var award, out int listIndex) || award.AwardItemList == null) |
| | | return; |
| | | |
| | | awardTipText.text = Language.Get($"TimeRushTaskTitle_{awardType}_{awardTypeValue}", award.NeedValue); |
| | | |
| | | for (int i = 0; i < itemCells.Count; i++) |
| | | { |
| | | var itemBaisc = itemCells[i]; |
| | | if (i < award.AwardItemList.Length) |
| | | { |
| | | var itemInfo = award.AwardItemList[i]; |
| | | itemBaisc.SetActive(true); |
| | | itemBaisc.Init(new ItemCellModel((int)itemInfo.ItemID, false, itemInfo.ItemCount)); |
| | | } |
| | | else |
| | | { |
| | | itemBaisc.SetActive(false); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void OnNewAwardHaveEvent() |
| | | { |
| | | ResetAnimation(); |
| | | } |
| | | |
| | | private void ResetAnimation() |
| | | { |
| | | currentState = MoveState.MovingDown; |
| | | openTime = Time.time; |
| | | tip.anchoredPosition = startPos.anchoredPosition; |
| | | positionTween.reversal = false; |
| | | positionTween.from = startPos.anchoredPosition; |
| | | positionTween.to = downPos.anchoredPosition; |
| | | positionTween.duration = moveDurationTime; |
| | | positionTween.Play(OnMoveDownComplete); |
| | | Display(); |
| | | } |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: f5d65c473483e9a468f8c7a9866199ba |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| New file |
| | |
| | | using System.Collections.Generic; |
| | | using Cysharp.Threading.Tasks; |
| | | using UnityEngine; |
| | | |
| | | public class TimeRushWin : UIBase |
| | | { |
| | | [SerializeField] ScrollerController tabScroller; |
| | | [SerializeField] ScrollerController taskScroller; |
| | | [SerializeField] ScrollerController giftScroller; |
| | | [SerializeField] ImageEx bgImage; |
| | | [SerializeField] ImageEx infoBgImage; |
| | | [SerializeField] ImageEx infoImage; |
| | | [SerializeField] ImageEx titleBgImage; |
| | | [SerializeField] GradientText titleText; |
| | | [SerializeField] ImageEx giftBgImage; |
| | | [SerializeField] ImageEx giftIconImage; |
| | | [SerializeField] TextEx timeText; |
| | | [SerializeField] TextEx roundText; |
| | | [SerializeField] ButtonEx goButton; |
| | | [SerializeField] TextEx goText; |
| | | [SerializeField] OwnMoneyCell ownMoneyCell; |
| | | [SerializeField] ButtonEx closeButton; |
| | | TimeRushManager manager { get { return TimeRushManager.Instance; } } |
| | | StoreModel storeModel { get { return StoreModel.Instance; } } |
| | | int tabId; |
| | | protected override void InitComponent() |
| | | { |
| | | closeButton.SetListener(CloseWindow); |
| | | } |
| | | |
| | | protected override void OnPreOpen() |
| | | { |
| | | tabId = functionOrder; |
| | | manager.OnNowTabIdChangeEvent += OnNowTabIdChangeEvent; |
| | | tabScroller.OnRefreshCell += OnRefreshTabCell; |
| | | taskScroller.OnRefreshCell += OnRefreshTaskCell; |
| | | giftScroller.OnRefreshCell += OnRefreshGiftCell; |
| | | GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; |
| | | RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent; |
| | | OperationTimeHepler.Instance.operationTimeUpdateEvent += OperationTimeUpdateEvent; |
| | | storeModel.RefreshBuyShopLimitEvent += RefreshBuyShopLimitEvent; |
| | | manager.OnUpdatePlayerInfoEvent += OnUpdatePlayerInfoEvent; |
| | | |
| | | var list = manager.GetTabIDList(); |
| | | if (list.IsNullOrEmpty()) |
| | | { |
| | | DelayCloseWindow().Forget(); |
| | | return; |
| | | } |
| | | manager.nowTabId = list.Contains(tabId) ? tabId : list[0]; |
| | | |
| | | } |
| | | |
| | | protected override void OnPreClose() |
| | | { |
| | | manager.OnNowTabIdChangeEvent -= OnNowTabIdChangeEvent; |
| | | tabScroller.OnRefreshCell -= OnRefreshTabCell; |
| | | taskScroller.OnRefreshCell -= OnRefreshTaskCell; |
| | | giftScroller.OnRefreshCell -= OnRefreshGiftCell; |
| | | GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; |
| | | RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent; |
| | | OperationTimeHepler.Instance.operationTimeUpdateEvent -= OperationTimeUpdateEvent; |
| | | storeModel.RefreshBuyShopLimitEvent -= RefreshBuyShopLimitEvent; |
| | | manager.OnUpdatePlayerInfoEvent -= OnUpdatePlayerInfoEvent; |
| | | } |
| | | |
| | | private void OnUpdatePlayerInfoEvent() |
| | | { |
| | | RefreshAll(); |
| | | } |
| | | |
| | | private void RefreshBuyShopLimitEvent() |
| | | { |
| | | RefreshAll(); |
| | | } |
| | | |
| | | private void OperationTimeUpdateEvent(OperationType operation) |
| | | { |
| | | if (operation == OperationType.default47) |
| | | { |
| | | var list = manager.GetTabIDList(); |
| | | if (list.IsNullOrEmpty()) |
| | | { |
| | | DelayCloseWindow().Forget(); |
| | | return; |
| | | } |
| | | manager.nowTabId = list[0]; |
| | | CreateAll(); |
| | | } |
| | | } |
| | | |
| | | private void OnRechargeCountEvent(int obj) |
| | | { |
| | | RefreshAll(); |
| | | } |
| | | |
| | | private void OnSecondEvent() |
| | | { |
| | | GetActTime(); |
| | | } |
| | | |
| | | private void OnRefreshTabCell(ScrollerDataType type, CellView cell) |
| | | { |
| | | var _cell = cell.GetComponent<TimeRushTabCell>(); |
| | | _cell?.Display(cell.index); |
| | | } |
| | | |
| | | private void OnRefreshTaskCell(ScrollerDataType type, CellView cell) |
| | | { |
| | | var _cell = cell.GetComponent<TimeRushTaskCell>(); |
| | | _cell?.Display(cell.index, cell, taskList); |
| | | } |
| | | |
| | | private void OnRefreshGiftCell(ScrollerDataType type, CellView cell) |
| | | { |
| | | var _cell = cell.GetComponent<TimeRushGiftCell>(); |
| | | _cell?.Display(cell.index, giftItems); |
| | | manager.PlayAnimationSync?.Invoke(); |
| | | } |
| | | |
| | | private void OnNowTabIdChangeEvent() |
| | | { |
| | | CreateAll(); |
| | | } |
| | | void RefreshAll() |
| | | { |
| | | int id = manager.nowTabId; |
| | | if (!ActLunhuidianTypeConfig.TryGetConfig(id, out var config)) |
| | | return; |
| | | int roundType = config.RoundType; |
| | | int tabType = config.TabType; |
| | | Display(id); |
| | | tabScroller.m_Scorller.RefreshActiveCellViews(); |
| | | |
| | | taskScroller.SetActive(tabType == 1); |
| | | giftScroller.SetActive(tabType == 2); |
| | | |
| | | if (tabType == 1) |
| | | { |
| | | CreateTaskScroller(roundType, tabType); |
| | | return; |
| | | } |
| | | |
| | | if (tabType == 2) |
| | | { |
| | | giftScroller.m_Scorller.RefreshActiveCellViews(); |
| | | return; |
| | | } |
| | | |
| | | } |
| | | |
| | | void CreateAll() |
| | | { |
| | | int id = manager.nowTabId; |
| | | if (!ActLunhuidianTypeConfig.TryGetConfig(id, out var config)) |
| | | return; |
| | | if (!manager.TryGetOperationInfo(out var act)) |
| | | return; |
| | | int roundType = config.RoundType; |
| | | int tabType = config.TabType; |
| | | if (!act.TryGetRound(roundType, out var round)) |
| | | return; |
| | | |
| | | |
| | | Display(id); |
| | | CreateTabScroller(); |
| | | taskScroller.SetActive(tabType == 1); |
| | | giftScroller.SetActive(tabType == 2); |
| | | |
| | | if (tabType == 1) |
| | | { |
| | | CreateTaskScroller(roundType, tabType); |
| | | return; |
| | | } |
| | | |
| | | if (tabType == 2) |
| | | { |
| | | CreateGiftScroller(roundType); |
| | | return; |
| | | } |
| | | |
| | | } |
| | | |
| | | private void Display(int id) |
| | | { |
| | | if (!ActLunhuidianTypeConfig.TryGetConfig(id, out var config)) |
| | | return; |
| | | if (!manager.TryGetOperationInfo(out var act)) |
| | | return; |
| | | int roundType = config.RoundType; |
| | | int tabType = config.TabType; |
| | | if (!act.TryGetRound(roundType, out var round)) |
| | | return; |
| | | if (!manager.TryGetPlayerInfo(roundType, out var playerInfo)) |
| | | return; |
| | | |
| | | GetActTime(); |
| | | bgImage.SetSprite(config.bgImage); |
| | | |
| | | infoBgImage.SetSprite(config.InfoBgImage); |
| | | |
| | | infoImage.SetSprite(config.InfoImage); |
| | | infoImage.SetNativeSize(); |
| | | |
| | | titleBgImage.SetSprite(config.TitleBgImage); |
| | | titleBgImage.SetNativeSize(); |
| | | |
| | | titleText.text = Language.Get($"TimeRushTitle{roundType}"); |
| | | |
| | | roundText.SetActive(tabType == 1); |
| | | roundText.text = tabType == 1 ? Language.Get("TimeRush06", playerInfo.CurRound, round.RoundMax) : string.Empty; |
| | | |
| | | ownMoneyCell.SetActive(tabType == 2); |
| | | ownMoneyCell.moneyType = manager.TryGetMoneyTypeByRoundType(roundType, out int monetyType) ? monetyType : 99; |
| | | ownMoneyCell.Display(true); |
| | | giftBgImage.SetActive(tabType == 2); |
| | | |
| | | giftIconImage.SetActive(tabType == 2); |
| | | giftIconImage.SetSprite($"TimeRushGiftIcon{roundType}"); |
| | | |
| | | DisplayGoButton(config); |
| | | } |
| | | |
| | | |
| | | void DisplayGoButton(ActLunhuidianTypeConfig config) |
| | | { |
| | | int roundType = config.RoundType; |
| | | int tabType = config.TabType; |
| | | bool hasWindowID = manager.TryGetWindowIDByRoundType(roundType, out int windowID); |
| | | goButton.SetActive(tabType == 1 && hasWindowID); |
| | | if (tabType == 1 && hasWindowID) |
| | | { |
| | | goText.text = Language.Get($"TimeRushGoTitle{roundType}"); |
| | | goButton.SetListener(() => |
| | | { |
| | | if (manager.TryGetFuncIdByRoundType(roundType, out int funcId) && !FuncOpen.Instance.IsFuncOpen(funcId, true)) |
| | | return; |
| | | UIJumpManager.Instance.OpenWindow(windowID); |
| | | }); |
| | | } |
| | | } |
| | | |
| | | private void GetActTime() |
| | | { |
| | | if (!manager.TryGetOperationInfo(out var act)) |
| | | { |
| | | timeText.text = Language.Get("OSActivity6"); |
| | | return; |
| | | } |
| | | timeText.text = Language.Get("TimeRush05", TimeUtility.SecondsToShortDHMS(act.GetResetSurplusTime())); |
| | | } |
| | | |
| | | private void CreateTabScroller() |
| | | { |
| | | tabScroller.Refresh(); |
| | | var list = manager.GetTabIDList(); |
| | | if (!list.IsNullOrEmpty()) |
| | | { |
| | | for (int i = 0; i < list.Count; i++) |
| | | { |
| | | tabScroller.AddCell(ScrollerDataType.Header, list[i]); |
| | | } |
| | | } |
| | | tabScroller.Restart(); |
| | | } |
| | | |
| | | |
| | | List<HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianAward> taskList; |
| | | private void CreateTaskScroller(int roundType, int tabType) |
| | | { |
| | | taskList = manager.GetTaskList(roundType, true); |
| | | taskScroller.Refresh(); |
| | | if (!taskList.IsNullOrEmpty()) |
| | | { |
| | | for (int i = 0; i < taskList.Count; i++) |
| | | { |
| | | CellInfo cellInfo = new CellInfo(); |
| | | cellInfo.infoInt1 = roundType; |
| | | cellInfo.infoInt2 = tabType; |
| | | taskScroller.AddCell(ScrollerDataType.Header, i, cellInfo); |
| | | } |
| | | } |
| | | taskScroller.Restart(); |
| | | } |
| | | |
| | | List<TimeRushGiftItem> giftItems; |
| | | private void CreateGiftScroller(int roundType) |
| | | { |
| | | giftItems = manager.GetGiftItemList(roundType, true); |
| | | giftScroller.Refresh(); |
| | | if (!giftItems.IsNullOrEmpty()) |
| | | { |
| | | for (int i = 0; i < giftItems.Count; i++) |
| | | { |
| | | giftScroller.AddCell(ScrollerDataType.Header, i); |
| | | } |
| | | } |
| | | giftScroller.Restart(); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 37423ca15fdd33e45b288c668a3698a5 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | |
| | | public int[] selectCtgIds; |
| | | public int[][] selectGainItemList; |
| | | public int limitPopCnt; |
| | | public int limitShowCnt; |
| | | public int limitPopCd; |
| | | |
| | | public event Action OnSelectCtgIdIndexChangeEvent; |
| | | |
| | | public bool isLogShow = true; |
| | |
| | | DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin; |
| | | DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk; |
| | | GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; |
| | | |
| | | var config = FuncConfigConfig.Get("TimingGift"); |
| | | limitPopCnt = int.Parse(config.Numerical1); |
| | | limitShowCnt = int.Parse(config.Numerical2); |
| | | limitPopCd = int.Parse(config.Numerical3); |
| | | } |
| | | |
| | | public override void Release() |
| | |
| | | return showGiftIdList; |
| | | } |
| | | |
| | | HashSet<int> typeHashSet; |
| | | int GetShowCnt() |
| | | { |
| | | if (typeHashSet == null) |
| | | typeHashSet = new HashSet<int>(); |
| | | |
| | | typeHashSet.Clear(); |
| | | if (showGiftIdList.IsNullOrEmpty()) |
| | | return 0; |
| | | |
| | | for (int i = 0; i < showGiftIdList.Count; i++) |
| | | { |
| | | int id = showGiftIdList[i]; |
| | | if (!TimingGiftConfig.TryGetTimingGiftConfig(id, out var config)) |
| | | continue; |
| | | typeHashSet.Add(config.GiftType); |
| | | } |
| | | return typeHashSet.Count; |
| | | } |
| | | |
| | | int GetPopCnt() |
| | | { |
| | | if (lastTriggerTimeDict.IsNullOrEmpty()) |
| | | return 0; |
| | | int cnt = 0; |
| | | foreach (var item in lastTriggerTimeDict) |
| | | { |
| | | int type = item.Key; |
| | | int time = item.Value; |
| | | var timeData = TimeUtility.GetTime((uint)time); |
| | | DateTime nowTime = TimeUtility.ServerNow; |
| | | if (timeData.Day == nowTime.Day && timeData.Month == nowTime.Month && timeData.Year == nowTime.Year) |
| | | { |
| | | cnt += 1; |
| | | } |
| | | } |
| | | return cnt; |
| | | } |
| | | |
| | | bool IsInLimitCd() |
| | | { |
| | | if (lastTriggerTimeDict.IsNullOrEmpty()) |
| | | return false; |
| | | int lastTime = lastTriggerTimeDict.Values.Max(); |
| | | return TimeUtility.AllSeconds - lastTime <= limitPopCd; |
| | | } |
| | | |
| | | public void TryAdd(int type) |
| | | { |
| | | |
| | | if (NewBieCenter.Instance.inGuiding) |
| | | { |
| | | #if UNITY_EDITOR |
| | |
| | | return; |
| | | } |
| | | |
| | | if (!IsTodayUnlimited(type)) |
| | | { |
| | | #if UNITY_EDITOR |
| | | if (isLogShow) |
| | | { |
| | | int lastTriggerTime = lastTriggerTimeDict[type]; |
| | | DateTime lastTime = TimeUtility.GetTime((uint)lastTriggerTime); |
| | | Debug.Log($"[TimingGift] TryPop:触发Return,今天已弹出过{type}类型的礼包,该类型上次弹出时间为{lastTime:yyyy-MM-dd HH:mm:ss}"); |
| | | } |
| | | #endif |
| | | return; |
| | | } |
| | | |
| | | if (!TimingGiftConfig.TryGetTypeToGiftIdList(type, out List<int> giftIdList)) |
| | | { |
| | | #if UNITY_EDITOR |
| | | if (isLogShow) |
| | | { |
| | | Debug.Log($"[TimingGift] TryPop:触发Return,表格中没有找到{type}类型的礼包ID"); |
| | | } |
| | | #endif |
| | | return; |
| | | } |
| | | int showCnt = GetShowCnt(); |
| | | |
| | | if (limitShowCnt <= showCnt) |
| | | { |
| | | #if UNITY_EDITOR |
| | | if (isLogShow) |
| | | { |
| | | Debug.Log($"[TimingGift] TryPop:触发Return,当前已达到同时展示的礼包类型数量总上限"); |
| | | } |
| | | #endif |
| | | return; |
| | | } |
| | | int popCnt = GetPopCnt(); |
| | | |
| | | if (limitPopCnt <= popCnt) |
| | | { |
| | | #if UNITY_EDITOR |
| | | if (isLogShow) |
| | | { |
| | | Debug.Log($"[TimingGift] TryPop:触发Return,今日已达到礼包类型触发数量总上限"); |
| | | } |
| | | #endif |
| | | return; |
| | | } |
| | | |
| | | bool isInLimitCd = IsInLimitCd(); |
| | | if (isInLimitCd) |
| | | { |
| | | #if UNITY_EDITOR |
| | | if (isLogShow) |
| | | { |
| | | Debug.Log($"[TimingGift] TryPop:触发Return,礼包触发冷却时间中"); |
| | | } |
| | | #endif |
| | | return; |
| | | } |
| | | |
| | | if (!IsTodayUnlimited(type)) |
| | | { |
| | | #if UNITY_EDITOR |
| | | if (isLogShow) |
| | | { |
| | | int lastTriggerTime = lastTriggerTimeDict[type]; |
| | | Debug.Log($"[TimingGift] TryPop:触发Return,今天已弹出过{type}类型的礼包,该类型上次弹出时间为{TimeUtility.GetTime((uint)lastTriggerTime):yyyy-MM-dd HH:mm:ss}"); |
| | | } |
| | | #endif |
| | | return; |
| | |
| | | continue; |
| | | isChange = true; |
| | | showGiftIdList.Add(id); |
| | | lastTriggerTimeDict[id] = TimeUtility.AllSeconds; |
| | | lastTriggerTimeDict[config.GiftType] = TimeUtility.AllSeconds; |
| | | } |
| | | |
| | | if (isChange) |
| | |
| | | |
| | | lastTriggerTimeDict = loadDict; |
| | | InitCurrectTimingGiftIdList(new List<int>(loadDict.Keys)); |
| | | |
| | | |
| | | #if UNITY_EDITOR |
| | | if (isLogShow) |
| | | { |
| | |
| | | using System.Collections.Generic; |
| | | using Cysharp.Threading.Tasks; |
| | | using UnityEngine; |
| | | using UnityEngine.UI; |
| | | |
| | | public class TimingGiftWin : UIBase |
| | | { |
| | |
| | | [SerializeField] TimingGiftCtgIdCell[] ctgIdCells; |
| | | |
| | | [SerializeField] TextEx timeText; |
| | | [SerializeField] ImageEx bgImage; |
| | | [SerializeField] RawImage bgImage; |
| | | [SerializeField] ImageEx IconImage; |
| | | [SerializeField] GradientText giftText; //"礼包" |
| | | [SerializeField] OutlineEx giftTextOutline; |
| | |
| | | leftButton.SetActive(isShowSwitch); |
| | | rightButton.SetActive(isShowSwitch); |
| | | |
| | | bgImage.SetSprite($"TimingGiftBg_{manager.selectTabGiftId}"); |
| | | bgImage.SetTexture2DPNG(IconConfig.Get($"TimingGiftBg_{manager.selectTabGiftId}").sprite); |
| | | bgImage.SetNativeSize(); |
| | | IconImage.SetSprite($"TimingGiftIcon_{manager.selectTabGiftId}"); |
| | | IconImage.SetNativeSize(); |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 9f8b60fd5cb8de143a61b1a3ea0fc728 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| New file |
| | |
| | | using System; |
| | | using UnityEngine; |
| | | using UnityEngine.Video; |
| | | using UnityEngine.UI; |
| | | |
| | | /// <summary> |
| | | /// UI视频播放器组件 - 支持WebM格式透明视频播放 |
| | | /// </summary> |
| | | public class UIVideoPlayer : MonoBehaviour |
| | | { |
| | | [Header("组件引用")] |
| | | public VideoPlayer videoPlayer; |
| | | public RawImage videoImage; |
| | | |
| | | [Header("调试信息")] |
| | | public const string directory = "Video"; |
| | | public string videoName; |
| | | public bool isLoop = false; |
| | | |
| | | [Header("资源管理")] |
| | | [Tooltip("播放完成后是否自动卸载资源(仅当非循环播放时有效)")] |
| | | public bool autoUnloadOnFinish = true; |
| | | |
| | | [Header("回调事件")] |
| | | public Action onComplete; |
| | | public Action onPrepared; |
| | | |
| | | private RenderTexture _renderTexture; |
| | | private VideoClip _loadedClip; |
| | | private bool _isPrepared; |
| | | private bool _isLoading; |
| | | private Action<bool> _onPrepareCallback; |
| | | |
| | | #region Public API |
| | | |
| | | /// <summary> |
| | | /// 加载并播放视频(通过资源系统加载 VideoClip) |
| | | /// </summary> |
| | | /// <param name="_videoName">视频文件名(不含扩展名)</param> |
| | | /// <param name="_loop">是否循环播放</param> |
| | | /// <param name="_onComplete">播放完成回调(仅在非循环播放时调用)</param> |
| | | public async void LoadAndPlayVideo(string _videoName, bool _loop = false, Action _onComplete = null) |
| | | { |
| | | if (!ValidateComponents()) return; |
| | | if (_isLoading) |
| | | { |
| | | Debug.LogWarning($"UIVideoPlayer: Already loading video. Please wait."); |
| | | return; |
| | | } |
| | | |
| | | videoName = _videoName; |
| | | isLoop = _loop; |
| | | onComplete = _onComplete; |
| | | _isPrepared = false; |
| | | _isLoading = true; |
| | | |
| | | // 清理旧资源 |
| | | ReleaseRenderTexture(); |
| | | |
| | | // 隐藏或设置空状态颜色 |
| | | SetEmptyState(); |
| | | |
| | | // 通过 ResManager 加载 VideoClip 资源(支持 AB 打包) |
| | | _loadedClip = await ResManager.Instance.LoadAssetAsync<VideoClip>(directory, videoName, false); |
| | | |
| | | // 检查是否在加载过程中被取消 |
| | | if (!_isLoading) |
| | | { |
| | | _loadedClip = null; |
| | | return; |
| | | } |
| | | |
| | | _isLoading = false; |
| | | |
| | | if (_loadedClip == null) |
| | | { |
| | | Debug.LogError($"UIVideoPlayer: Failed to load VideoClip: {directory}/{videoName}"); |
| | | _isPrepared = false; |
| | | return; |
| | | } |
| | | |
| | | // 创建并绑定 RenderTexture(按视频实际尺寸) |
| | | _renderTexture = new RenderTexture((int)_loadedClip.width, (int)_loadedClip.height, 0); |
| | | videoPlayer.targetTexture = _renderTexture; |
| | | videoImage.texture = _renderTexture; |
| | | videoImage.SetNativeSize(); |
| | | |
| | | |
| | | // 显示视频 |
| | | SetActiveState(); |
| | | |
| | | videoPlayer.source = VideoSource.VideoClip; |
| | | videoPlayer.clip = _loadedClip; |
| | | videoPlayer.isLooping = isLoop; |
| | | videoPlayer.prepareCompleted += OnVideoPrepared; |
| | | |
| | | // 非循环播放时注册完成事件 |
| | | if (!isLoop) |
| | | { |
| | | videoPlayer.loopPointReached += OnVideoFinished; |
| | | } |
| | | |
| | | videoPlayer.Prepare(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 加载并播放指定视频 |
| | | /// </summary> |
| | | public void LoadAndPlay(string videoName, bool loop = false, Action onCompleteCallback = null) |
| | | { |
| | | LoadAndPlayVideo(videoName, loop, onCompleteCallback); |
| | | } |
| | | |
| | | [ContextMenu("播放")] |
| | | public void Play() |
| | | { |
| | | if (!ValidateComponents()) return; |
| | | if (_isPrepared && !videoPlayer.isPlaying) |
| | | { |
| | | videoPlayer.Play(); |
| | | } |
| | | } |
| | | |
| | | [ContextMenu("暂停")] |
| | | public void Pause() |
| | | { |
| | | if (!ValidateComponents()) return; |
| | | if (videoPlayer.isPlaying) |
| | | { |
| | | videoPlayer.Pause(); |
| | | } |
| | | } |
| | | |
| | | [ContextMenu("恢复")] |
| | | public void Resume() |
| | | { |
| | | if (!ValidateComponents()) return; |
| | | if (_isPrepared && !videoPlayer.isPlaying) |
| | | { |
| | | videoPlayer.Play(); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 预加载视频(不自动播放) |
| | | /// </summary> |
| | | /// <param name="_videoName">视频文件名(不含扩展名)</param> |
| | | /// <param name="onPreparedOK">预加载完成回调,参数为是否成功</param> |
| | | public async void Prepare(string _videoName, Action<bool> onPreparedOK) |
| | | { |
| | | if (!ValidateComponents()) |
| | | { |
| | | onPreparedOK?.Invoke(false); |
| | | return; |
| | | } |
| | | |
| | | if (_isLoading) |
| | | { |
| | | Debug.LogWarning($"UIVideoPlayer: Already loading video. Please wait."); |
| | | onPreparedOK?.Invoke(false); |
| | | return; |
| | | } |
| | | |
| | | videoName = _videoName; |
| | | _onPrepareCallback = onPreparedOK; |
| | | _isPrepared = false; |
| | | _isLoading = true; |
| | | |
| | | // 清理旧资源 |
| | | ReleaseRenderTexture(); |
| | | SetEmptyState(); |
| | | |
| | | // 通过 ResManager 加载 VideoClip 资源(支持 AB 打包) |
| | | _loadedClip = await ResManager.Instance.LoadAssetAsync<VideoClip>(directory, videoName, false); |
| | | |
| | | // 检查是否在加载过程中被取消 |
| | | if (!_isLoading) |
| | | { |
| | | _loadedClip = null; |
| | | return; |
| | | } |
| | | |
| | | _isLoading = false; |
| | | |
| | | if (_loadedClip == null) |
| | | { |
| | | Debug.LogError($"UIVideoPlayer: Failed to load VideoClip: {directory}/{videoName}"); |
| | | _isPrepared = false; |
| | | _onPrepareCallback?.Invoke(false); |
| | | _onPrepareCallback = null; |
| | | return; |
| | | } |
| | | |
| | | // 创建并绑定 RenderTexture(按视频实际尺寸) |
| | | _renderTexture = new RenderTexture((int)_loadedClip.width, (int)_loadedClip.height, 0); |
| | | videoPlayer.targetTexture = _renderTexture; |
| | | videoImage.texture = _renderTexture; |
| | | videoImage.SetNativeSize(); |
| | | |
| | | SetActiveState(); |
| | | |
| | | videoPlayer.source = VideoSource.VideoClip; |
| | | videoPlayer.clip = _loadedClip; |
| | | videoPlayer.prepareCompleted += OnVideoPreparedForPreload; |
| | | |
| | | videoPlayer.Prepare(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 通过 URL 加载并播放视频 |
| | | /// </summary> |
| | | /// <param name="url">视频 URL 地址</param> |
| | | /// <param name="_loop">是否循环播放</param> |
| | | /// <param name="_onComplete">播放完成回调(仅在非循环播放时调用)</param> |
| | | public void LoadAndPlayFromURL(string url, bool _loop = false, Action _onComplete = null) |
| | | { |
| | | if (!ValidateComponents()) return; |
| | | if (_isLoading) |
| | | { |
| | | Debug.LogWarning($"UIVideoPlayer: Already loading video. Please wait."); |
| | | return; |
| | | } |
| | | |
| | | videoName = url; |
| | | isLoop = _loop; |
| | | onComplete = _onComplete; |
| | | _isPrepared = false; |
| | | _isLoading = true; |
| | | |
| | | // 清理旧资源 |
| | | ReleaseRenderTexture(); |
| | | SetEmptyState(); |
| | | |
| | | // 根据 URL 视频创建默认尺寸的 RenderTexture(准备完成后会调整) |
| | | _renderTexture = new RenderTexture(1920, 1080, 0); |
| | | videoPlayer.targetTexture = _renderTexture; |
| | | videoImage.texture = _renderTexture; |
| | | |
| | | SetActiveState(); |
| | | |
| | | videoPlayer.source = VideoSource.Url; |
| | | videoPlayer.url = url; |
| | | videoPlayer.isLooping = isLoop; |
| | | videoPlayer.prepareCompleted += OnVideoPreparedForURL; |
| | | |
| | | // 非循环播放时注册完成事件 |
| | | if (!isLoop) |
| | | { |
| | | videoPlayer.loopPointReached += OnVideoFinished; |
| | | } |
| | | |
| | | videoPlayer.Prepare(); |
| | | } |
| | | |
| | | [ContextMenu("停止")] |
| | | public void Stop() |
| | | { |
| | | if (!ValidateComponents()) return; |
| | | videoPlayer.Stop(); |
| | | } |
| | | |
| | | [ContextMenu("重新播放")] |
| | | public void Restart() |
| | | { |
| | | if (!ValidateComponents()) return; |
| | | if (_isPrepared) |
| | | { |
| | | videoPlayer.Stop(); |
| | | videoPlayer.Play(); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 卸载视频资源 |
| | | /// </summary> |
| | | public void Unload() |
| | | { |
| | | if (videoPlayer == null) return; |
| | | |
| | | // 取消所有事件订阅 |
| | | videoPlayer.prepareCompleted -= OnVideoPrepared; |
| | | videoPlayer.prepareCompleted -= OnVideoPreparedForPreload; |
| | | videoPlayer.prepareCompleted -= OnVideoPreparedForURL; |
| | | videoPlayer.loopPointReached -= OnVideoFinished; |
| | | |
| | | videoPlayer.Stop(); |
| | | videoPlayer.clip = null; |
| | | videoPlayer.url = null; |
| | | videoPlayer.targetTexture = null; |
| | | |
| | | if (videoImage != null) |
| | | { |
| | | videoImage.texture = null; |
| | | } |
| | | |
| | | _loadedClip = null; |
| | | ReleaseRenderTexture(); |
| | | |
| | | // 恢复空状态 |
| | | SetEmptyState(); |
| | | |
| | | _isPrepared = false; |
| | | _isLoading = false; |
| | | onComplete = null; |
| | | onPrepared = null; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region Properties |
| | | |
| | | /// <summary> |
| | | /// 视频是否已准备好 |
| | | /// </summary> |
| | | public bool IsPrepared => _isPrepared; |
| | | |
| | | /// <summary> |
| | | /// 视频是否正在播放 |
| | | /// </summary> |
| | | public bool IsPlaying => videoPlayer != null && videoPlayer.isPlaying; |
| | | |
| | | /// <summary> |
| | | /// 视频是否正在加载 |
| | | /// </summary> |
| | | public bool IsLoading => _isLoading; |
| | | |
| | | /// <summary> |
| | | /// 当前播放时间(秒) |
| | | /// </summary> |
| | | public double CurrentTime => videoPlayer != null ? videoPlayer.time : 0; |
| | | |
| | | /// <summary> |
| | | /// 视频总时长(秒) |
| | | /// </summary> |
| | | public double Duration => _loadedClip != null ? _loadedClip.length : 0; |
| | | |
| | | #endregion |
| | | |
| | | #region Private Methods |
| | | |
| | | [ContextMenu("重新加载")] |
| | | private void Reload() |
| | | { |
| | | LoadAndPlayVideo(videoName, isLoop); |
| | | } |
| | | |
| | | private void OnVideoPrepared(VideoPlayer vp) |
| | | { |
| | | vp.prepareCompleted -= OnVideoPrepared; |
| | | _isPrepared = true; |
| | | _isLoading = false; |
| | | onPrepared?.Invoke(); |
| | | vp.Play(); |
| | | } |
| | | |
| | | private void OnVideoPreparedForPreload(VideoPlayer vp) |
| | | { |
| | | vp.prepareCompleted -= OnVideoPreparedForPreload; |
| | | _isPrepared = true; |
| | | _isLoading = false; |
| | | _onPrepareCallback?.Invoke(true); |
| | | _onPrepareCallback = null; |
| | | // 预加载完成后不自动播放 |
| | | } |
| | | |
| | | private void OnVideoPreparedForURL(VideoPlayer vp) |
| | | { |
| | | vp.prepareCompleted -= OnVideoPreparedForURL; |
| | | _isPrepared = true; |
| | | _isLoading = false; |
| | | |
| | | // 调整 RenderTexture 尺寸为实际视频尺寸 |
| | | if (_renderTexture != null && vp.texture != null) |
| | | { |
| | | var newRT = new RenderTexture((int)vp.width, (int)vp.height, 0); |
| | | ReleaseRenderTexture(); |
| | | _renderTexture = newRT; |
| | | vp.targetTexture = _renderTexture; |
| | | videoImage.texture = _renderTexture; |
| | | videoImage.SetNativeSize(); |
| | | } |
| | | |
| | | onPrepared?.Invoke(); |
| | | vp.Play(); |
| | | } |
| | | |
| | | private void OnVideoFinished(VideoPlayer vp) |
| | | { |
| | | onComplete?.Invoke(); |
| | | |
| | | // 根据设置自动清理资源 |
| | | if (autoUnloadOnFinish) |
| | | { |
| | | Unload(); |
| | | } |
| | | } |
| | | |
| | | private void ReleaseRenderTexture() |
| | | { |
| | | if (_renderTexture != null) |
| | | { |
| | | _renderTexture.Release(); |
| | | Destroy(_renderTexture); |
| | | _renderTexture = null; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置空状态(未加载视频时) |
| | | /// </summary> |
| | | private void SetEmptyState() |
| | | { |
| | | if (videoImage != null) |
| | | { |
| | | videoImage.enabled = false; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置激活状态(视频已加载) |
| | | /// </summary> |
| | | private void SetActiveState() |
| | | { |
| | | if (videoImage != null) |
| | | { |
| | | videoImage.enabled = true; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 验证必需组件 |
| | | /// </summary> |
| | | private bool ValidateComponents() |
| | | { |
| | | if (videoPlayer == null) |
| | | { |
| | | Debug.LogError("UIVideoPlayer: VideoPlayer component is not assigned."); |
| | | return false; |
| | | } |
| | | if (videoImage == null) |
| | | { |
| | | Debug.LogError("UIVideoPlayer: RawImage component is not assigned."); |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region Unity Lifecycle |
| | | |
| | | private void Awake() |
| | | { |
| | | // 初始化时设置为空状态 |
| | | SetEmptyState(); |
| | | } |
| | | |
| | | private void OnDestroy() |
| | | { |
| | | Unload(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 取消预加载 |
| | | /// </summary> |
| | | public void CancelPrepare() |
| | | { |
| | | if (videoPlayer == null) return; |
| | | |
| | | // 取消所有准备相关的事件订阅 |
| | | videoPlayer.prepareCompleted -= OnVideoPrepared; |
| | | videoPlayer.prepareCompleted -= OnVideoPreparedForPreload; |
| | | videoPlayer.prepareCompleted -= OnVideoPreparedForURL; |
| | | |
| | | // 停止 VideoPlayer(如果正在加载) |
| | | if (_isLoading) |
| | | { |
| | | videoPlayer.Stop(); |
| | | } |
| | | |
| | | // 清理资源 |
| | | videoPlayer.clip = null; |
| | | videoPlayer.url = null; |
| | | videoPlayer.targetTexture = null; |
| | | |
| | | if (videoImage != null) |
| | | { |
| | | videoImage.texture = null; |
| | | } |
| | | |
| | | _loadedClip = null; |
| | | ReleaseRenderTexture(); |
| | | SetEmptyState(); |
| | | |
| | | // 重置状态 |
| | | _isPrepared = false; |
| | | _isLoading = false; |
| | | |
| | | // 触发失败回调 |
| | | _onPrepareCallback?.Invoke(false); |
| | | _onPrepareCallback = null; |
| | | } |
| | | |
| | | #endregion |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 780579551ee7fe442bc047278c4b96d6 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| New file |
| | |
| | | |
| | | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public class VideoManager : Singleton<VideoManager> |
| | | { |
| | | private GameObjectPoolManager.GameObjectPool uiVideoPool; |
| | | |
| | | private Dictionary<string, UIVideoPlayer> prepareDict = new Dictionary<string, UIVideoPlayer>(); |
| | | |
| | | private Dictionary<string, Action<bool, UIVideoPlayer>> prepareCallbacks = new Dictionary<string, Action<bool, UIVideoPlayer>>(); |
| | | |
| | | public void Init() |
| | | { |
| | | GameObject uiVideoPrefab = UILoader.LoadPrefab("UIVideoPlayer"); |
| | | uiVideoPool = GameObjectPoolManager.Instance.GetPool(uiVideoPrefab); |
| | | } |
| | | |
| | | public void Release() |
| | | { |
| | | if (uiVideoPool != null) |
| | | { |
| | | uiVideoPool.Clear(); |
| | | uiVideoPool = null; |
| | | } |
| | | } |
| | | |
| | | private UIVideoPlayer GetUIVideoPlayer() |
| | | { |
| | | GameObject videoObj = uiVideoPool.Request(); |
| | | if (videoObj != null) |
| | | { |
| | | return videoObj.GetComponent<UIVideoPlayer>(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public UIVideoPlayer PrepareVideo(string videoName, Action<bool, UIVideoPlayer> onPrepared) |
| | | { |
| | | // 如果已经在准备中,直接返回 并给出提示 已经在加载准备中 |
| | | if (prepareDict.TryGetValue(videoName, out UIVideoPlayer existingPlayer)) |
| | | { |
| | | Debug.LogError("Video " + videoName + " is already being prepared."); |
| | | return existingPlayer; |
| | | } |
| | | |
| | | |
| | | UIVideoPlayer uiVideoPlayer = GetUIVideoPlayer(); |
| | | if (uiVideoPlayer != null) |
| | | { |
| | | string _videoName = videoName; // 避免闭包问题 |
| | | prepareDict.Add(_videoName, uiVideoPlayer); |
| | | prepareCallbacks.Add(_videoName, onPrepared); |
| | | uiVideoPlayer.Prepare(videoName, (success) => |
| | | { |
| | | OnPrepareOK(videoName, success, uiVideoPlayer); |
| | | }); |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("Failed to get UIVideoPlayer from pool."); |
| | | onPrepared?.Invoke(false, null); |
| | | } |
| | | return uiVideoPlayer; |
| | | } |
| | | |
| | | |
| | | public void CancelPrepare(UIVideoPlayer uIVideoPlayer) |
| | | { |
| | | if (uIVideoPlayer != null) |
| | | uIVideoPlayer.CancelPrepare(); |
| | | { |
| | | uiVideoPool.Release(uIVideoPlayer.gameObject); |
| | | // 从 prepareDict 移除 |
| | | string keyToRemove = null; |
| | | foreach (var kv in prepareDict) |
| | | { |
| | | if (kv.Value == uIVideoPlayer) |
| | | { |
| | | keyToRemove = kv.Key; |
| | | break; |
| | | } |
| | | } |
| | | if (keyToRemove != null) |
| | | { |
| | | prepareDict.Remove(keyToRemove); |
| | | prepareCallbacks.Remove(keyToRemove); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void OnPrepareOK(string videoName, bool success, UIVideoPlayer uiVideoPlayer) |
| | | { |
| | | // 安全移除和回调 |
| | | if (prepareDict.ContainsKey(videoName)) |
| | | { |
| | | prepareDict.Remove(videoName); |
| | | } |
| | | Action<bool, UIVideoPlayer> callback = null; |
| | | if (prepareCallbacks.TryGetValue(videoName, out callback)) |
| | | { |
| | | callback?.Invoke(success, uiVideoPlayer); |
| | | prepareCallbacks.Remove(videoName); |
| | | } |
| | | } |
| | | |
| | | public void ReleaseVideoPlayer(UIVideoPlayer uIVideoPlayer) |
| | | { |
| | | if (uIVideoPlayer != null) |
| | | { |
| | | CancelPrepare(uIVideoPlayer); |
| | | uiVideoPool.Release(uIVideoPlayer.gameObject); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 14d20be0871f2e24d96b79440816d7cb |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| New file |
| | |
| | | using System; |
| | | using UnityEngine; |
| | | using UnityEngine.Video; |
| | | using UnityEngine.UI; |
| | | |
| | | public class VideoWin : UIBase |
| | | { |
| | | public UIVideoPlayer videoPlayer; |
| | | protected override void OnOpen() |
| | | { |
| | | // 视频准备完成后会自动播放 |
| | | } |
| | | |
| | | protected override void OnPreClose() |
| | | { |
| | | base.OnPreClose(); |
| | | videoPlayer.Unload(); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: cf2a5c5ccb4f22f4c9408bd3b3efed69 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | WarlordPavilion = 55, //定军阁 |
| | | FuncPreset = 56, //流派预设 |
| | | TimingGift = 57, //时机礼包 |
| | | TimeRush = 58, //限时冲刺 |
| | | } |
| | | |
| | | |
| | |
| | | FairyAffinityLoginAct = 214, //仙缘登陆活动 |
| | | FairyAffinityMissionAct = 215, //仙缘任务活动 |
| | | FairyAffinityRechargeGiftAct = 216, //仙缘礼包活动 |
| | | CycleHallAct = 217, //轮回殿活动 |
| | | TimeRushAct = 217, //轮回殿活动 |
| | | YunShiXBAct = 218, //运势寻宝活动 |
| | | YunShiMissionAct = 219, //运势任务活动 |
| | | YunShiRechargeGiftAct = 220, //运势礼包活动 |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using Spine; |
| | | using Spine.Unity; |
| | | |
| | | public static class Extension |
| | | { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static bool IsSpine(this string _resName) |
| | | { |
| | | if (string.IsNullOrEmpty(_resName)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | return _resName.Contains("SkeletonData"); |
| | | } |
| | | |
| | | public static bool IsVideo(this string _resName) |
| | | { |
| | | if (string.IsNullOrEmpty(_resName)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | return _resName.EndsWith(".mp4"); |
| | | } |
| | | |
| | | public static bool ContainsMotion(this Spine.Skeleton skeleton, string motionName) |
| | | { |
| | | if (skeleton == null || string.IsNullOrEmpty(motionName)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | for (int i = 0; i < skeleton.Data.Animations.Count; i++) |
| | | { |
| | | if (skeleton.Data.Animations.Items[i].Name.ToLower() == motionName.ToLower()) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | public static Spine.Animation GetSpineAnimation(this Spine.Skeleton skeleton, string motionName) |
| | | { |
| | | if (skeleton == null || string.IsNullOrEmpty(motionName)) |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | for (int i = 0; i < skeleton.Data.Animations.Count; i++) |
| | | { |
| | | if (skeleton.Data.Animations.Items[i].Name.ToLower() == motionName.ToLower()) |
| | | { |
| | | return skeleton.Data.Animations.Items[i]; |
| | | } |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | } |