1
This commit is contained in:
@@ -86,6 +86,7 @@ namespace Assets.MyGame.Scripts.Net.WebResponses
|
||||
/// <summary>
|
||||
/// 多次死亡 param:星际巡航(最多3次)/ 烈焰风暴(最多2次)。
|
||||
/// JSON: { "isKill": true, "beishu": 155, "fishId": "13009-3-3" }
|
||||
/// 机械蝎(12028/12029)另带 animId:1=不死只播BJEndUI,2/3/4=带死亡的爆奖
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class BossMultiDeathParam
|
||||
@@ -99,6 +100,17 @@ namespace Assets.MyGame.Scripts.Net.WebResponses
|
||||
/// <summary>鱼ID,格式:原ID-总次数-当前次数(如 13009-3-2)</summary>
|
||||
public string fishId = "";
|
||||
|
||||
/// <summary>
|
||||
/// 机械蝎专用:死亡/状态动画 ID。
|
||||
/// 1 = 不死(只显示 BJEndUI,Boss 保留继续打)
|
||||
/// 2/3/4 = 带死亡的爆奖(三种表现,Boss 消失)
|
||||
/// 其他 Boss 无此字段(默认 0)。
|
||||
/// </summary>
|
||||
public int animId;
|
||||
|
||||
/// <summary>是否带死亡的爆奖(animId >= 2;机械蝎判定用,优先于 isKill)</summary>
|
||||
public bool IsDeathAward => animId >= 2;
|
||||
|
||||
/// <summary>从 fishId 解析总死亡次数(解析失败返回 0)</summary>
|
||||
public int TotalCount
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99a2ec58fc6f71746aa937e9a2f67a23
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 机械蝎八连抽配置生成器(编辑器工具)。
|
||||
///
|
||||
/// 用法:菜单 Tools → 机械蝎 → 生成八连抽配置资产
|
||||
/// 1. 自动查找项目中 PW_Effect_FreeDropChip / PW_Effect_Settle_Scorpion 预制体
|
||||
/// 2. 自动查找 PW_FreeItem_DropGemstone* / DropCard* / DropProp* Sprite,按文件名数字排序填入
|
||||
/// 3. 生成 JiXieXieConfig.asset 到 JiXieXie 目录(已存在则覆盖并刷新)
|
||||
/// 4. 选中生成的资产,拖到爆奖预制体的 JiXieXieEvent.config 字段即可
|
||||
/// </summary>
|
||||
public static class JiXieXieConfigAutoFill
|
||||
{
|
||||
private const string ConfigDir = "Assets/MyGame/aa/Game/XJMH/Boss/JiXieXie";
|
||||
private const string ConfigPath = ConfigDir + "/JiXieXieConfig.asset";
|
||||
|
||||
[MenuItem("Tools/机械蝎/生成八连抽配置资产")]
|
||||
public static void GenerateConfig()
|
||||
{
|
||||
// 1. 查找预制体
|
||||
GameObject chipPrefab = FindAsset<GameObject>("PW_Effect_FreeDropChip");
|
||||
GameObject settlePrefab = FindAsset<GameObject>("PW_Effect_Settle_Scorpion");
|
||||
|
||||
// 2. 查找图片(按名字数字排序)
|
||||
Sprite[] gemstones = FindSpritesSorted("PW_FreeItem_DropGemstone");
|
||||
Sprite[] cards = FindSpritesSorted("PW_FreeItem_DropCard");
|
||||
Sprite[] goods = FindSpritesSorted("PW_FreeItem_DropProp");
|
||||
|
||||
if (chipPrefab == null)
|
||||
Debug.LogWarning("[JiXieXie] 未找到 PW_Effect_FreeDropChip 预制体,config.freeDropChipPrefab 为空");
|
||||
if (settlePrefab == null)
|
||||
Debug.LogWarning("[JiXieXie] 未找到 PW_Effect_Settle_Scorpion 预制体,config.settleScorpionPrefab 为空");
|
||||
if (gemstones.Length == 0 || cards.Length == 0 || goods.Length == 0)
|
||||
Debug.LogWarning($"[JiXieXie] 部分图片没找到:宝石={gemstones.Length} 卡牌={cards.Length} 道具={goods.Length}");
|
||||
|
||||
// 3. 生成/覆盖配置资产
|
||||
JiXieXieConfig cfg = AssetDatabase.LoadAssetAtPath<JiXieXieConfig>(ConfigPath);
|
||||
bool isNew = cfg == null;
|
||||
if (isNew)
|
||||
{
|
||||
cfg = ScriptableObject.CreateInstance<JiXieXieConfig>();
|
||||
EnsureDir();
|
||||
AssetDatabase.CreateAsset(cfg, ConfigPath);
|
||||
}
|
||||
|
||||
cfg.freeDropChipPrefab = chipPrefab;
|
||||
cfg.settleScorpionPrefab = settlePrefab;
|
||||
cfg.gemstoneSprites = gemstones;
|
||||
cfg.cardSprites = cards;
|
||||
cfg.goodsSprites = goods;
|
||||
cfg.propNames = BuildPropNames(goods);
|
||||
|
||||
EditorUtility.SetDirty(cfg);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
// 4. 选中并提示
|
||||
Selection.activeObject = cfg;
|
||||
EditorGUIUtility.PingObject(cfg);
|
||||
Debug.Log($"[JiXieXie] 配置资产{(isNew ? "已生成" : "已更新")}:{ConfigPath}\n" +
|
||||
$" 宝石={cfg.gemstoneSprites.Length} 卡牌={cfg.cardSprites.Length} 道具={cfg.goodsSprites.Length}\n" +
|
||||
" 请把该资产拖到爆奖预制体 JiXieXieEvent 的 config 字段");
|
||||
}
|
||||
|
||||
// ==================== 工具方法 ====================
|
||||
|
||||
private static void EnsureDir()
|
||||
{
|
||||
if (!AssetDatabase.IsValidFolder(ConfigDir))
|
||||
{
|
||||
string parent = "Assets/MyGame/aa/Game/XJMH/Boss";
|
||||
if (!AssetDatabase.IsValidFolder(parent))
|
||||
{
|
||||
Debug.LogError($"[JiXieXie] 目录不存在:{parent}");
|
||||
return;
|
||||
}
|
||||
AssetDatabase.CreateFolder(parent, "JiXieXie");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>按名称模糊查找第一个指定类型资产</summary>
|
||||
private static T FindAsset<T>(string nameFilter) where T : UnityEngine.Object
|
||||
{
|
||||
string[] guids = AssetDatabase.FindAssets(nameFilter + " t:" + typeof(T).Name);
|
||||
foreach (string guid in guids)
|
||||
{
|
||||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
T asset = AssetDatabase.LoadAssetAtPath<T>(path);
|
||||
if (asset != null) return asset;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>查找名称带前缀的所有 Sprite,并按文件名末尾数字排序</summary>
|
||||
private static Sprite[] FindSpritesSorted(string namePrefix)
|
||||
{
|
||||
string[] guids = AssetDatabase.FindAssets(namePrefix + " t:Sprite");
|
||||
List<Sprite> list = new List<Sprite>();
|
||||
foreach (string guid in guids)
|
||||
{
|
||||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path);
|
||||
if (sprite != null)
|
||||
list.Add(sprite);
|
||||
}
|
||||
|
||||
// 按文件名末尾数字排序:DropGemstone1 < DropGemstone2 ... < DropGemstone10
|
||||
list.Sort((a, b) => ExtractTrailingNumber(a.name).CompareTo(ExtractTrailingNumber(b.name)));
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>提取文件名末尾的数字(如 "PW_FreeItem_DropProp1000" → 1000)</summary>
|
||||
private static int ExtractTrailingNumber(string name)
|
||||
{
|
||||
Match m = Regex.Match(name, @"(\d+)$");
|
||||
return m.Success ? int.Parse(m.Value) : 0;
|
||||
}
|
||||
|
||||
/// <summary>按 goods 数量生成默认道具名(1000+ 猜测为火箭炮碎片,其余叫 道具{ID})</summary>
|
||||
private static string[] BuildPropNames(Sprite[] goods)
|
||||
{
|
||||
if (goods == null || goods.Length == 0) return new string[0];
|
||||
|
||||
string[] names = new string[goods.Length];
|
||||
for (int i = 0; i < goods.Length; i++)
|
||||
{
|
||||
if (goods[i] == null) { names[i] = ""; continue; }
|
||||
int id = ExtractTrailingNumber(goods[i].name);
|
||||
if (id >= 1000 && id <= 1003)
|
||||
names[i] = "火箭炮碎片";
|
||||
else if (id == 0)
|
||||
names[i] = "金币";
|
||||
else if (id == 1)
|
||||
names[i] = "钻石";
|
||||
else
|
||||
names[i] = $"道具{id}";
|
||||
}
|
||||
return names;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48db2b478c92fa540800e4b020aae0a8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,130 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: a2d6ec45ade76e745a6d9968ae64cf7d, type: 3}
|
||||
m_Name: JiXieXieConfig
|
||||
m_EditorClassIdentifier:
|
||||
freeDropChipPrefab: {fileID: 1590595001857623, guid: 97d0f70681ad02b4cac0becfe91493bc,
|
||||
type: 3}
|
||||
settleScorpionPrefab: {fileID: 1163031175862678, guid: 25cdb6f7f14f7db42920da145d6bef52,
|
||||
type: 3}
|
||||
gemstoneSprites:
|
||||
- {fileID: 21300000, guid: 868f82a2dd136c04da8e7e45fc8a6c6e, type: 3}
|
||||
- {fileID: 21300000, guid: a65fa4d44f55c9247960c881444b61bc, type: 3}
|
||||
- {fileID: 21300000, guid: cc0fcb0add32c2248a492b67fe09b8f6, type: 3}
|
||||
- {fileID: 21300000, guid: 1570bb1c7ca44fd47a7444e1880ef229, type: 3}
|
||||
- {fileID: 21300000, guid: 066cca573daf75747a26fe5ca3863044, type: 2}
|
||||
- {fileID: 21300000, guid: 3e9bba24a8e3d014495c511f46de7d9d, type: 3}
|
||||
- {fileID: 21300000, guid: d544e3e70b0033c48a9c7441afe43eb1, type: 2}
|
||||
- {fileID: 21300000, guid: 70d2129bedf75324687de76ad250565b, type: 2}
|
||||
- {fileID: 21300000, guid: 75ced8e0a1f225c469d14e68ee2b6101, type: 3}
|
||||
- {fileID: 21300000, guid: 7af48f548f150cc40abe33678a193767, type: 2}
|
||||
- {fileID: 21300000, guid: a011b974531fd264d8aa43f6692e986a, type: 2}
|
||||
- {fileID: 21300000, guid: 857189b4242e25349ae006d897dca886, type: 3}
|
||||
- {fileID: 21300000, guid: c72808bde77924645a1514489e7ed08a, type: 2}
|
||||
- {fileID: 21300000, guid: 39db69c70c806e948a3a57e040885592, type: 2}
|
||||
- {fileID: 21300000, guid: c9a3e0e956e616f40b9b4e5e1c0846cf, type: 3}
|
||||
- {fileID: 21300000, guid: 4af8251b0012b8941a702b573e93eb41, type: 2}
|
||||
cardSprites:
|
||||
- {fileID: 21300000, guid: be2a5ae06ece9864aa275124a43909fa, type: 2}
|
||||
- {fileID: 21300000, guid: 2770e075c6c965c4195b0ac231af14b7, type: 3}
|
||||
- {fileID: 21300000, guid: 7686cfd9492ed674a9f00d1394dc1d14, type: 3}
|
||||
- {fileID: 21300000, guid: aa1ae18b88f6c1f4b9ecbb391598d729, type: 3}
|
||||
- {fileID: 21300000, guid: 2a375c86039b7834fa0c6f71b5103519, type: 3}
|
||||
- {fileID: 21300000, guid: 96efd2e67a939dd4299387c50cee7f81, type: 3}
|
||||
- {fileID: 21300000, guid: 9757d6dc8a986b642b232ab48ce1a496, type: 2}
|
||||
- {fileID: 21300000, guid: 9389cbf1ec55df04eb8e3f80d33d49e3, type: 3}
|
||||
- {fileID: 21300000, guid: 3ca1dab2457a37b4cbab75643a53d559, type: 3}
|
||||
- {fileID: 21300000, guid: 164975a33d92b7642838f7f7d3421cdd, type: 2}
|
||||
- {fileID: 21300000, guid: 59f3691a8bee69b4cb15076334e934e1, type: 2}
|
||||
- {fileID: 21300000, guid: 434fa5275dfac224eb9d01552543c37b, type: 2}
|
||||
- {fileID: 21300000, guid: 0e3ec333aac4849438a6a853efe0f7e8, type: 2}
|
||||
- {fileID: 21300000, guid: 85e826c203cdb094ab80e1b0910fa49a, type: 3}
|
||||
- {fileID: 21300000, guid: fb85359958daba44482d29146b966d7b, type: 2}
|
||||
- {fileID: 21300000, guid: ea3d46b8339c0524da4b0f1605ef1740, type: 3}
|
||||
- {fileID: 21300000, guid: d1360d4c0158da7448cf307985a1fcfc, type: 2}
|
||||
- {fileID: 21300000, guid: b72a87db6356ce74c82088037184008a, type: 2}
|
||||
- {fileID: 21300000, guid: 08045d585aafdb44193a389f958c8758, type: 2}
|
||||
- {fileID: 21300000, guid: 37431ec46f3e2ae43a07807382bc3ed6, type: 3}
|
||||
goodsSprites:
|
||||
- {fileID: 21300000, guid: 1d110e0ad258ca54aa93e2c67ce3899a, type: 2}
|
||||
- {fileID: 21300000, guid: 77816851598769b45a94a17b1ba4b451, type: 3}
|
||||
- {fileID: 21300000, guid: 5eeb77c79438df648a6ee596f6f1fc57, type: 3}
|
||||
- {fileID: 21300000, guid: 3edd7884686662c4aadeee78d4a509eb, type: 3}
|
||||
- {fileID: 21300000, guid: 1e42892beb898b8488014d742a800543, type: 3}
|
||||
- {fileID: 21300000, guid: 6568d93439840e04f8a2a19b5da4b745, type: 3}
|
||||
- {fileID: 21300000, guid: 2157d3c04f46e9e49a0b142e7d9b5d9e, type: 3}
|
||||
- {fileID: 21300000, guid: c3e47328e1b853043b567f5253bf2c01, type: 3}
|
||||
- {fileID: 21300000, guid: 59ab4df37fec2d44aac41da3cd8182ea, type: 3}
|
||||
- {fileID: 21300000, guid: 87eec89dcc6d4c743ae362f52211c707, type: 2}
|
||||
- {fileID: 21300000, guid: d7bcc5f862a223141bd9b9e152fcc9b5, type: 3}
|
||||
- {fileID: 21300000, guid: 6ba36d5836348d945baeee493510680c, type: 3}
|
||||
- {fileID: 21300000, guid: e495fb530e5f1b14583f72cd5070c407, type: 2}
|
||||
- {fileID: 21300000, guid: 47d681577cd9d9143b3d9693aee1f478, type: 3}
|
||||
- {fileID: 21300000, guid: 4afde32a750f7664386da86e412ed9f6, type: 2}
|
||||
- {fileID: 21300000, guid: d22e64b9ffc73c14f895161b3e267cd0, type: 2}
|
||||
- {fileID: 21300000, guid: 8c73e3e838617864f8a9e7ab2c22315c, type: 3}
|
||||
- {fileID: 21300000, guid: 02cb9983d722e2647805137415613325, type: 2}
|
||||
- {fileID: 21300000, guid: 33de53e8049594a40ab45a0dc23a0cf3, type: 2}
|
||||
- {fileID: 21300000, guid: 3afba2eeb8beca84a8a17b084b565468, type: 3}
|
||||
- {fileID: 21300000, guid: 3948d8cf3ceede248965a429349cf979, type: 2}
|
||||
- {fileID: 21300000, guid: 6615632243573aa40838936f5c5484df, type: 3}
|
||||
- {fileID: 21300000, guid: d5f773c04375e47438be84443c93668e, type: 2}
|
||||
- {fileID: 21300000, guid: 32fa9bc20939f354c97acafd96493d0e, type: 2}
|
||||
- {fileID: 21300000, guid: 7fb1ca20d9ab46f4283abd89d2723896, type: 2}
|
||||
- {fileID: 21300000, guid: 8ee387e982aff3a44a49845fad212950, type: 2}
|
||||
- {fileID: 21300000, guid: c20a3932beeb4fc44a0956bbd43fd878, type: 3}
|
||||
- {fileID: 21300000, guid: 3b10cc1775548c748af6ab906ceb35d4, type: 2}
|
||||
- {fileID: 21300000, guid: eaa882c43bfdf7e4f994a309ad1dbb4b, type: 3}
|
||||
- {fileID: 21300000, guid: c792a0fb4b1db094287bb535189fbfa8, type: 2}
|
||||
- {fileID: 21300000, guid: ebdf18dcff2b7dd40b0a009d7475db98, type: 2}
|
||||
- {fileID: 21300000, guid: f679323489c932e4dadb2585ad5e9d67, type: 3}
|
||||
- {fileID: 21300000, guid: ef49b80f7470a9945ab4cd51d60ad71e, type: 2}
|
||||
- {fileID: 21300000, guid: a1da9962c55bd3641994604435af772d, type: 2}
|
||||
- {fileID: 21300000, guid: 9418909a747892f40b4c3776b94d53bb, type: 2}
|
||||
- {fileID: 21300000, guid: a93a624c62447f44ebf1bb373efd5fd2, type: 3}
|
||||
propNames:
|
||||
- "\u91D1\u5E01"
|
||||
- "\u91D1\u5E01"
|
||||
- "\u91D1\u5E01"
|
||||
- "\u91D1\u5E01"
|
||||
- "\u91D1\u5E01"
|
||||
- "\u91D1\u5E01"
|
||||
- "\u91D1\u5E01"
|
||||
- "\u91D1\u5E01"
|
||||
- "\u91D1\u5E01"
|
||||
- "\u91D1\u5E01"
|
||||
- "\u91D1\u5E01"
|
||||
- "\u91D1\u5E01"
|
||||
- "\u94BB\u77F3"
|
||||
- "\u94BB\u77F3"
|
||||
- "\u94BB\u77F3"
|
||||
- "\u9053\u51772"
|
||||
- "\u9053\u51772"
|
||||
- "\u9053\u51772"
|
||||
- "\u9053\u51773"
|
||||
- "\u9053\u51773"
|
||||
- "\u9053\u51773"
|
||||
- "\u9053\u51774"
|
||||
- "\u9053\u51774"
|
||||
- "\u9053\u51774"
|
||||
- "\u706B\u7BAD\u70AE\u788E\u7247"
|
||||
- "\u706B\u7BAD\u70AE\u788E\u7247"
|
||||
- "\u706B\u7BAD\u70AE\u788E\u7247"
|
||||
- "\u706B\u7BAD\u70AE\u788E\u7247"
|
||||
- "\u706B\u7BAD\u70AE\u788E\u7247"
|
||||
- "\u706B\u7BAD\u70AE\u788E\u7247"
|
||||
- "\u706B\u7BAD\u70AE\u788E\u7247"
|
||||
- "\u706B\u7BAD\u70AE\u788E\u7247"
|
||||
- "\u706B\u7BAD\u70AE\u788E\u7247"
|
||||
- "\u706B\u7BAD\u70AE\u788E\u7247"
|
||||
- "\u706B\u7BAD\u70AE\u788E\u7247"
|
||||
- "\u706B\u7BAD\u70AE\u788E\u7247"
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4adb4d6d53ad6b74cabd5722c72c2d25
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,40 @@
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 机械蝎八连抽配置资产(ScriptableObject)。
|
||||
///
|
||||
/// ⭐ 把所有散落的资源引用(预制体 + 图片数组 + 道具名称)集中到一个资产里,
|
||||
/// 爆奖预制体的 JiXieXieEvent 只拖这一个 config 字段即可,不用逐个拖十几张图。
|
||||
///
|
||||
/// 生成方式(推荐):
|
||||
/// 菜单 Tools → 机械蝎 → 生成八连抽配置资产
|
||||
/// 自动查找项目中 PW_FreeItem_DropGemstone/DropCard/DropProp 资源并填入,
|
||||
/// 生成 JiXieXieConfig.asset 到 JiXieXie 目录,然后拖到爆奖预制体的 config 字段。
|
||||
///
|
||||
/// 手动方式:
|
||||
/// Assets → Create → XJMH → 机械蝎八连抽配置,再手动拖入(不推荐,图太多)。
|
||||
/// </summary>
|
||||
[CreateAssetMenu(fileName = "JiXieXieConfig", menuName = "XJMH/机械蝎八连抽配置", order = 0)]
|
||||
public class JiXieXieConfig : ScriptableObject
|
||||
{
|
||||
[Header("预制体")]
|
||||
[Tooltip("宝石/卡牌单片预制体(PW_Effect_FreeDropChip)")]
|
||||
public GameObject freeDropChipPrefab;
|
||||
|
||||
[Tooltip("特殊奖励结算特效(PW_Effect_Settle_Scorpion)")]
|
||||
public GameObject settleScorpionPrefab;
|
||||
|
||||
[Header("图片(数组顺序 = 按数字排序自动填充)")]
|
||||
[Tooltip("宝石图片数组(PW_FreeItem_DropGemstone1~4),代码按 type 1~4 取,顺序别乱")]
|
||||
public Sprite[] gemstoneSprites;
|
||||
|
||||
[Tooltip("卡牌底色图片数组(PW_FreeItem_DropCard0~4),代码按 type 取,顺序别乱")]
|
||||
public Sprite[] cardSprites;
|
||||
|
||||
[Tooltip("道具图片数组(PW_FreeItem_DropProp0~4、1000~1003),代码按 rewardID 取")]
|
||||
public Sprite[] goodsSprites;
|
||||
|
||||
[Header("道具名称(顺序与 goodsSprites 一一对应)")]
|
||||
[Tooltip("显示在卡牌 Name 上的道具名,如 金币/钻石/火箭炮碎片...")]
|
||||
public string[] propNames;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a2d6ec45ade76e745a6d9968ae64cf7d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,92 +1,814 @@
|
||||
using Assets.MyGame.Scripts.Net.APIResponses.Enum;
|
||||
using DG.Tweening;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
/// <summary>
|
||||
/// 机械蝎 Boss 爆奖事件(通用爆炸模式)。
|
||||
/// 机械蝎 Boss 爆奖事件(八连抽模式)。
|
||||
///
|
||||
/// 流程:
|
||||
/// Boss 死亡 → Init → 等待 explosionDelay → 范围杀鱼 → 加分滚动
|
||||
/// 爆奖预制体本身就是爆炸特效,在死亡位置创建。
|
||||
/// 对应美术规格(12028 机械蝎)+ Lua 参考(PW_Effect.txt DropTenCardEffect / FreeDropCardEffect):
|
||||
/// 1. 创建 N 个 PW_Effect_FreeDropChip 实例(美术 8 个),宝石图片在 Gemstone 的 Image(Source Image) 上替换
|
||||
/// 2. 翻牌:隐藏 Gemstone 相关子物体,显示卡牌相关子物体 Card,
|
||||
/// Card 和 Goods 的 Image(Source Image) 替换图片,Name/Num 文本填充
|
||||
/// 3. 显示 BJEndUI 面板收尾
|
||||
///
|
||||
/// 奖励数据(本版只发金币):
|
||||
/// 总金币(RoomKillNotice.gold → maxScore)用拆红包随机分成 chipCount 份,
|
||||
/// 8 份之和 == maxScore。宝石颜色与卡牌颜色一一对应。
|
||||
/// 卡牌颜色分级【金币阈值 = 炮倍 × 阈值倍数】:
|
||||
/// num < 炮倍×100 绿,< 炮倍×200 蓝,< 炮倍×500 紫,≥ 炮倍×500 红(金色不用),
|
||||
/// 每张卡下方显示本份金币数量。
|
||||
///
|
||||
/// 流程(用户确认版,全程 UI 层):
|
||||
/// 死亡位置一次出现 8 颗宝石 → 停留1秒 → 飞到屏幕中心两排(每排4个)排好
|
||||
/// → 一张一张翻牌(全是金币)→ 卡牌飞到座位上方 → 显示 BJEndUI + 加分 + 回收
|
||||
///
|
||||
/// ⭐ 资源配置:所有预制体/图片/名称集中在 JiXieXieConfig 资产(ScriptableObject),
|
||||
/// 只需拖一个 config 字段。资产用菜单 Tools → 机械蝎 → 生成八连抽配置资产 一键生成。
|
||||
/// </summary>
|
||||
public class JiXieXieEvent : BJEventBase
|
||||
{
|
||||
[Header("爆炸配置")]
|
||||
[Tooltip("爆炸检测半径(世界单位)")]
|
||||
public float explosionRadius = 5f;
|
||||
[Tooltip("鱼层(Inspector 设 Fish)")]
|
||||
public LayerMask fishLayer;
|
||||
[Tooltip("爆炸延迟(Boss 死亡后到爆炸的等待)")]
|
||||
public float explosionDelay = 0.5f;
|
||||
[Tooltip("爆炸特效持续时间(播完后才进入加分并回收)")]
|
||||
public float explosionDuration = 2f;
|
||||
// ==================== Inspector 字段 ====================
|
||||
|
||||
/// <summary>爆炸中心(世界坐标,由 Boss 传入=死亡位置)</summary>
|
||||
[Header("八连抽 - 配置资产")]
|
||||
[Tooltip("拖入 JiXieXieConfig 资产(Tools→机械蝎→生成八连抽配置资产 一键生成)。\n包含:FreeDropChip 预制体 + 宝石/卡牌/道具图片 + 道具名称")]
|
||||
public JiXieXieConfig config;
|
||||
|
||||
[Header("八连抽 - 配置")]
|
||||
[Tooltip("宝石/卡牌数量(美术 10 个)")]
|
||||
public int chipCount = 10;
|
||||
|
||||
[Tooltip("拆红包每份最少金币(默认 1,保证每张卡都有钱)")]
|
||||
public long minPartAmount = 1;
|
||||
|
||||
[Tooltip("宝石在屏幕靠上位置出现的间隔(秒,越小越像同时出现)")]
|
||||
public float gemAppearInterval = 0.03f;
|
||||
|
||||
[Tooltip("宝石出生点 Y = 屏幕高度 × 该比例(1=顶部,0.5=正中,默认靠上)")]
|
||||
public float spawnYRatio = 0.78f;
|
||||
|
||||
[Tooltip("宝石飞向屏幕中心的时长(秒)")]
|
||||
public float flyToCenterDuration = 0.8f;
|
||||
|
||||
[Tooltip("卡牌放大倍率(chip 根节点最终缩放,1=原始大小)")]
|
||||
public float cardScale = 1.5f;
|
||||
|
||||
[Tooltip("两排整体中心 Y = 屏幕高度 × 该比例(0.5=正中央,调大靠上,调小靠下)")]
|
||||
public float gridCenterYRatio = 0.5f;
|
||||
|
||||
[Tooltip("两排布局:每颗卡水平间距基础值(UI 像素,实际间距 = 该值 × cardScale)")]
|
||||
public float gridSpacingX = 120f;
|
||||
|
||||
[Tooltip("两排布局:上下排间距基础值(UI 像素,实际间距 = 该值 × cardScale)")]
|
||||
public float gridRowGap = 160f;
|
||||
|
||||
[Tooltip("每张卡翻牌间隔(秒)")]
|
||||
public float flipInterval = 0.5f;
|
||||
|
||||
[Tooltip("全部翻完后停留时间(秒),让玩家看清再飞向炮台")]
|
||||
public float flipEndDelay = 1f;
|
||||
|
||||
[Tooltip("卡片飞到座位上方的时长(秒)")]
|
||||
public float flyToSeatDuration = 0.6f;
|
||||
|
||||
[Header("八连抽 - 宝石颜色(与卡牌颜色一一对应)")]
|
||||
[Tooltip("绿色宝石在 gemstoneSprites 数组中的下标(0 = DropGemstone1 绿色)")]
|
||||
public int gemGreenIndex = 0;
|
||||
|
||||
[Tooltip("蓝色宝石在 gemstoneSprites 数组中的下标(1 = DropGemstone2 蓝色)")]
|
||||
public int gemBlueIndex = 1;
|
||||
|
||||
[Tooltip("紫色宝石在 gemstoneSprites 数组中的下标(2 = DropGemstone3 紫色)")]
|
||||
public int gemPurpleIndex = 2;
|
||||
|
||||
[Tooltip("红色宝石在 gemstoneSprites 数组中的下标(3 = DropGemstone4 红色)")]
|
||||
public int gemRedIndex = 3;
|
||||
|
||||
[Header("八连抽 - 卡牌颜色分级(金币阈值 = 炮倍 × 阈值倍数)")]
|
||||
[Tooltip("卡牌背面图在 cardSprites 数组中的下标(PW_FreeItem_DropCard0 是背面)")]
|
||||
public int cardBackIndex = 0;
|
||||
|
||||
[Tooltip("绿卡上限倍数:金币 < 炮倍×该值 → 绿色(100倍)")]
|
||||
public int greenLimitBeishu = 100;
|
||||
|
||||
[Tooltip("蓝卡上限倍数:金币 < 炮倍×该值 → 蓝色(200倍)")]
|
||||
public int blueLimitBeishu = 200;
|
||||
|
||||
[Tooltip("红卡下限倍数:金币 ≥ 炮倍×该值 → 红色(500倍);< 该值 → 紫色(300倍档)")]
|
||||
public int redLimitBeishu = 500;
|
||||
|
||||
[Tooltip("绿色卡在 cardSprites 数组中的下标(1 = DropCard1 绿色)")]
|
||||
public int greenCardIndex = 1;
|
||||
|
||||
[Tooltip("蓝色卡在 cardSprites 数组中的下标(2 = DropCard2 蓝色)")]
|
||||
public int blueCardIndex = 2;
|
||||
|
||||
[Tooltip("紫色卡在 cardSprites 数组中的下标(3 = DropCard3 紫色)")]
|
||||
public int purpleCardIndex = 3;
|
||||
|
||||
[Tooltip("红色卡在 cardSprites 数组中的下标(4 = DropCard4 红色)")]
|
||||
public int redCardIndex = 4;
|
||||
|
||||
[Header("八连抽 - 子物体名称(与预制体保持一致)")]
|
||||
public string gemstoneName = "Gemstone";
|
||||
public string cardObjName = "Card";
|
||||
public string cardImagePath = "Card/Card";
|
||||
public string goodsPath = "Card/Goods";
|
||||
public string namePath = "Card/Name";
|
||||
public string numPath = "Card/Num";
|
||||
public string mulPath = "Card/Num/Mul";
|
||||
public string starEffectName = "Effect_Gemstone_star";
|
||||
public string bombEffectName = "Effect_Gemstone_Bomb";
|
||||
public string orangeEffectName = "Effect_Card_Orange";
|
||||
public string purpleEffectName = "Effect_Card_Purple";
|
||||
public string createEffectName = "Effect_Create";
|
||||
public string tailEffectName = "Effect_Tail";
|
||||
public string arriveEffectName = "Effect_Arrive";
|
||||
|
||||
/// <summary>爆炸/散落中心(世界坐标,由 Boss 传入=死亡位置)</summary>
|
||||
[HideInInspector]
|
||||
public Vector3 explosionCenter = Vector3.zero;
|
||||
|
||||
// ==================== 运行时数据 ====================
|
||||
|
||||
/// <summary>单片掉落数据</summary>
|
||||
private class DropItemInfo
|
||||
{
|
||||
public int rewardType; // 奖励类型(本版恒为 1 金币)
|
||||
public int rewardID; // 道具ID(本版恒为 0 金币图)
|
||||
public long num; // 本份金币数量
|
||||
public int cardColor; // 颜色分级 1=绿 2=蓝 3=紫 4=红(宝石和卡牌共用,一一对应)
|
||||
}
|
||||
|
||||
/// <summary>当前局掉落数据(长度=chipCount)</summary>
|
||||
private List<DropItemInfo> _dropInfos = new List<DropItemInfo>();
|
||||
|
||||
/// <summary>创建出来的 chip 实例列表(die 时统一销毁)</summary>
|
||||
private readonly List<GameObject> _chipInstances = new List<GameObject>();
|
||||
|
||||
/// <summary>UI 层父节点(chip 都挂这里,随 UI 卸载自动清理)</summary>
|
||||
private Transform _uiLayer;
|
||||
|
||||
/// <summary>UI Canvas(世界坐标 → UI 坐标转换用)</summary>
|
||||
private Canvas _uiCanvas;
|
||||
|
||||
/// <summary>累计金币(rewardType==1 的 num 之和,显示在翻牌完成处)</summary>
|
||||
private long _earnTotal = 0;
|
||||
|
||||
// ==================== 初始化 ====================
|
||||
|
||||
public override void Init(long goldCount, int posID, long paobei, long fishScore, int beishu,
|
||||
Action<int> action, Action action1 = null)
|
||||
{
|
||||
base.Init(goldCount, posID, paobei, fishScore, beishu, action, action1);
|
||||
// ApplySeatOffset 会把位置移到屏幕中心,这里恢复到死亡位置
|
||||
transform.position = explosionCenter;
|
||||
StartCoroutine(ExplodeThenScore());
|
||||
|
||||
// 解析服务端数据(失败则随机生成)
|
||||
_dropInfos = ParseDropInfos();
|
||||
|
||||
// 启动八连抽流程
|
||||
StartCoroutine(TenDropFlow());
|
||||
}
|
||||
|
||||
/// <summary>重写:不移动到屏幕中心,但缓存座位引用(供 isSelf 判断使用)</summary>
|
||||
protected override void ApplySeatOffset()
|
||||
{
|
||||
// 不调用 base.ApplySeatOffset(),避免位置被移到屏幕中心 (0,0,-100)
|
||||
// 但需要设置 _targetSit,否则 Init 里 isSelf 判断会失败
|
||||
GetSeatPosition();
|
||||
}
|
||||
|
||||
/// <summary>爆炸 → 杀鱼 → 加分滚动</summary>
|
||||
private IEnumerator ExplodeThenScore()
|
||||
// ============================================================
|
||||
// 数据解析
|
||||
// ============================================================
|
||||
|
||||
/// <summary>
|
||||
/// 八连抽只发金币:用【拆红包算法】把总金币(maxScore)随机拆成 chipCount 份,
|
||||
/// 每份数量随机(二倍均值法),但 8 份之和恒等于 maxScore。
|
||||
/// 卡牌颜色分级【金币阈值 = 炮倍(paoBei) × 阈值倍数】:
|
||||
/// num < 炮倍×100 → 绿;< 炮倍×200 → 蓝;< 炮倍×500 → 紫;≥ 炮倍×500 → 红(金色不用)
|
||||
/// 每张卡 num 不同 → 颜色可能不同。
|
||||
/// </summary>
|
||||
private List<DropItemInfo> ParseDropInfos()
|
||||
{
|
||||
// 等待 Boss 死亡动画结束
|
||||
yield return new WaitForSeconds(explosionDelay);
|
||||
List<DropItemInfo> result = new List<DropItemInfo>();
|
||||
|
||||
// 爆炸中心 = Boss 传入的死亡位置
|
||||
Vector3 center = explosionCenter;
|
||||
Debug.Log($"[JiXieXie] 爆炸 位置={center}");
|
||||
// ⭐ 拆红包:随机拆成 chipCount 份,总和 == maxScore
|
||||
long[] amounts = SplitRedPacket(maxScore, chipCount, minPartAmount);
|
||||
|
||||
// 爆奖预制体本身就是爆炸特效,已在死亡位置创建并激活,这里不再 Instantiate
|
||||
// ⭐ 金币阈值 = 炮倍 × 阈值倍数(用户口径:100/200/300/500 倍档)
|
||||
long greenMax = paoBei * (long)greenLimitBeishu; // 炮倍×100
|
||||
long blueMax = paoBei * (long)blueLimitBeishu; // 炮倍×200
|
||||
long redMin = paoBei * (long)redLimitBeishu; // 炮倍×500
|
||||
|
||||
// 物理圈检测,范围内的普通鱼走死鱼方法
|
||||
Vector3 sitPos = GetSeatPosition();
|
||||
var hits = Physics2D.OverlapCircleAll(center, explosionRadius, fishLayer);
|
||||
int killCount = 0;
|
||||
foreach (var hit in hits)
|
||||
for (int i = 0; i < amounts.Length; i++)
|
||||
{
|
||||
if (!hit.CompareTag("Fish")) continue;
|
||||
var monster = hit.GetComponentInParent<MonsterContral>();
|
||||
if (monster == null) continue;
|
||||
if (monster.fishenum != FishTypeEnum.普通鱼) continue;
|
||||
var info = new DropItemInfo();
|
||||
info.rewardType = 1; // 金币
|
||||
info.rewardID = 0; // 金币图(goodsSprites 里 ID=0 那张)
|
||||
info.num = amounts[i];
|
||||
|
||||
// 每条鱼的金币 = 炮倍 × 鱼底分
|
||||
var coinNum = new RedPacketRecord
|
||||
{
|
||||
Amount = paoBei * monster.monsterData.fishTypeConfig.fishScore
|
||||
};
|
||||
CreateFishManager.Instance.Id_DieFish_FX(monster.guid, coinNum, sitPos, isSelf);
|
||||
killCount++;
|
||||
// ⭐ 每张卡按自己的金币数量 × 阈值判定颜色(num 不同 → 颜色可不同)
|
||||
info.cardColor = info.num < greenMax ? 1
|
||||
: info.num < blueMax ? 2
|
||||
: info.num < redMin ? 3
|
||||
: 4;
|
||||
|
||||
result.Add(info);
|
||||
}
|
||||
Debug.Log($"[JiXieXie] 爆炸炸死 {killCount} 条鱼");
|
||||
|
||||
// 等爆炸特效播完再进入加分滚动 + 回收
|
||||
yield return new WaitForSeconds(explosionDuration);
|
||||
// 如果 chipCount 被改成比 amounts 多(防御),补齐
|
||||
while (result.Count < chipCount)
|
||||
{
|
||||
var info = new DropItemInfo();
|
||||
info.rewardType = 1;
|
||||
info.rewardID = 0;
|
||||
info.num = 0;
|
||||
info.cardColor = 1;
|
||||
result.Add(info);
|
||||
}
|
||||
|
||||
// 进入加分滚动 → MoveToSit → OnScoreEnd → JiaFen → die(回池)
|
||||
StartAddScore();
|
||||
_earnTotal = maxScore;
|
||||
|
||||
// ⭐ 日志打印每份金额 + 颜色,方便确认
|
||||
Debug.Log($"[JiXieXie] 金币拆红包 {result.Count} 份: [{string.Join(",", amounts)}] 总={_earnTotal} paoBei={paoBei} 阈值={greenMax}/{blueMax}/{redMin}");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>回收爆奖预制体到对象池(先清理分数面板,防止泄漏)</summary>
|
||||
/// <summary>
|
||||
/// 拆红包算法(二倍均值法):把 total 随机拆成 count 份,
|
||||
/// 每份 ≥ min,所有份之和恒等于 total。
|
||||
/// </summary>
|
||||
private long[] SplitRedPacket(long total, int count, long min)
|
||||
{
|
||||
if (count <= 0)
|
||||
{
|
||||
return new long[0];
|
||||
}
|
||||
if (count == 1)
|
||||
{
|
||||
return new long[] { total };
|
||||
}
|
||||
|
||||
long[] result = new long[count];
|
||||
|
||||
// 不够分:每份至少 min,直接平均兜底(避免出现 0)
|
||||
if (total < count * min)
|
||||
{
|
||||
long per = count > 0 ? total / count : 0;
|
||||
long rem = count > 0 ? total % count : 0;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
result[i] = per + (i == 0 ? rem : 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
long remain = total;
|
||||
for (int i = 0; i < count - 1; i++)
|
||||
{
|
||||
int left = count - i; // 剩余份数
|
||||
long max = (remain - (left - 1) * min) * 2 / left; // 二倍均值上限
|
||||
if (max < min) max = min;
|
||||
long span = max - min + 1;
|
||||
// ⭐ 用 double 计算避免大金额时 float 精度不足导致数值相同/重复
|
||||
long amt = min + (long)((double)Random.value * span); // [min, max] 随机
|
||||
if (amt > remain) amt = remain;
|
||||
if (amt < min) amt = min;
|
||||
result[i] = amt;
|
||||
remain -= amt;
|
||||
}
|
||||
result[count - 1] = remain; // 最后一份拿剩余
|
||||
if (result[count - 1] < min) result[count - 1] = min; // 防御:最后一份不足 min 时保底(总和会略超,可接受)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 八连抽流程
|
||||
// ============================================================
|
||||
|
||||
/// <summary>
|
||||
/// 完整流程(用户确认版):
|
||||
/// 屏幕靠上位置一次出现 8 颗宝石 → 直接飞到排开两排(每排4个)
|
||||
/// → 一张一张翻牌(全是金币)→ 卡牌飞到炮台座位 → 显示 BJEndUI + 加分 + 回收
|
||||
/// </summary>
|
||||
private IEnumerator TenDropFlow()
|
||||
{
|
||||
// ---------- 阶段1:屏幕靠上位置一次出现 8 颗宝石 ----------
|
||||
yield return StartCoroutine(SpawnGemsAtDiePos());
|
||||
|
||||
// ---------- 阶段2:生成完直接飞到排开位置,两排每排 4 个 ----------
|
||||
yield return StartCoroutine(FlyToCenterGrid());
|
||||
|
||||
// ---------- 阶段3:一张一张翻牌(全是金币) ----------
|
||||
yield return StartCoroutine(FlipCards());
|
||||
|
||||
// ---------- 阶段3.5:翻完停留,让玩家看清全部卡牌再走 ----------
|
||||
yield return new WaitForSeconds(flipEndDelay);
|
||||
|
||||
// ---------- 阶段4:卡牌移动到炮台座位 ----------
|
||||
yield return StartCoroutine(FlyCardsToSeat());
|
||||
|
||||
// ---------- 阶段5:显示 BJEndUI + 加分 + 回收 ----------
|
||||
ShowEndAndFinish();
|
||||
}
|
||||
|
||||
/// <summary>阶段1:8 颗宝石在屏幕靠上位置一次出现(微小偏移 + 逐个快速放大)</summary>
|
||||
private IEnumerator SpawnGemsAtDiePos()
|
||||
{
|
||||
GameObject chipPrefab = config != null ? config.freeDropChipPrefab : null;
|
||||
if (chipPrefab == null)
|
||||
{
|
||||
Debug.LogError("[JiXieXie] config 或 config.freeDropChipPrefab 未赋值(PW_Effect_FreeDropChip)!跳过宝石阶段");
|
||||
yield break;
|
||||
}
|
||||
|
||||
EnsureUiLayer();
|
||||
if (_uiLayer == null || _uiCanvas == null)
|
||||
{
|
||||
Debug.LogError("[JiXieXie] 未找到 UI 层/Canvas(UIManager.uiRoot 或 currGameType.subPanelParent),跳过宝石阶段");
|
||||
yield break;
|
||||
}
|
||||
|
||||
// ⭐ 出生点 = 屏幕靠上位置(y = 屏幕高度 × spawnYRatio),不再用死亡位置
|
||||
Vector2 baseUi = CoordinateTransformation.ScreenPoint_ToCanvas(
|
||||
new Vector2(Screen.width / 2f, Screen.height * spawnYRatio), _uiCanvas);
|
||||
|
||||
_chipInstances.Clear();
|
||||
|
||||
for (int i = 0; i < _dropInfos.Count; i++)
|
||||
{
|
||||
GameObject chip = Instantiate(chipPrefab, _uiLayer);
|
||||
chip.name = $"Chip_{i}";
|
||||
_chipInstances.Add(chip);
|
||||
|
||||
// ⭐ 全部出现在同一点:出生点 + 微小偏移(避免完全重叠,观感像一堆宝石)
|
||||
Vector2 tiny = Random.insideUnitCircle * 8f;
|
||||
var rt = chip.GetComponent<RectTransform>();
|
||||
if (rt != null)
|
||||
rt.anchoredPosition = baseUi + tiny;
|
||||
else
|
||||
chip.transform.position = explosionCenter;
|
||||
chip.transform.localScale = Vector3.zero;
|
||||
|
||||
// ⭐ 宝石颜色 = 卡牌颜色(cardColor 分级,一一对应)
|
||||
Transform gemstone = chip.transform.Find(gemstoneName);
|
||||
if (gemstone != null)
|
||||
{
|
||||
var img = gemstone.GetComponent<Image>();
|
||||
if (img != null)
|
||||
{
|
||||
Sprite sp = GetGemstoneColorSprite(_dropInfos[i].cardColor);
|
||||
if (sp != null) img.sprite = sp;
|
||||
}
|
||||
gemstone.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
// 卡牌默认隐藏
|
||||
Transform cardObj = chip.transform.Find(cardObjName);
|
||||
if (cardObj != null) cardObj.gameObject.SetActive(false);
|
||||
|
||||
// 关闭所有特效子物体
|
||||
SetChildActive(chip.transform, starEffectName, false);
|
||||
SetChildActive(chip.transform, bombEffectName, false);
|
||||
SetChildActive(chip.transform, orangeEffectName, false);
|
||||
SetChildActive(chip.transform, purpleEffectName, false);
|
||||
SetChildActive(chip.transform, tailEffectName, false);
|
||||
SetChildActive(chip.transform, arriveEffectName, false);
|
||||
|
||||
// 第一颗带出场特效
|
||||
if (i == 0)
|
||||
SetChildActive(chip.transform, createEffectName, true);
|
||||
|
||||
chip.SetActive(true);
|
||||
|
||||
// 放大出现(目标 = cardScale,间隔很小 → 观感一次全部出现)
|
||||
Transform star = chip.transform.Find(starEffectName);
|
||||
chip.transform.DOScale(Vector3.one * cardScale, 0.4f).SetEase(Ease.OutElastic)
|
||||
.OnComplete(() =>
|
||||
{
|
||||
if (star != null) star.gameObject.SetActive(true);
|
||||
});
|
||||
|
||||
Debug.Log($"[JiXieXie] 宝石[{i}] 屏幕靠上位置出现 颜色={GetColorName(_dropInfos[i].cardColor)}");
|
||||
yield return new WaitForSeconds(gemAppearInterval);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>阶段3:宝石飞到排开位置(两排每排 4 个,中心 Y 由 gridCenterYRatio 控制)</summary>
|
||||
private IEnumerator FlyToCenterGrid()
|
||||
{
|
||||
if (_uiLayer == null || _uiCanvas == null) yield break;
|
||||
|
||||
// ⭐ 排开位置基准 = 屏幕 (gridCenterYRatio) 处(默认 0.5 屏幕中央,可配上下)
|
||||
Vector2 centerUi = CoordinateTransformation.ScreenPoint_ToCanvas(
|
||||
new Vector2(Screen.width / 2f, Screen.height * gridCenterYRatio), _uiCanvas);
|
||||
|
||||
// 两排布局(动态列数):10 张 = 每排 5 个;8 张 = 每排 4 个
|
||||
// ⭐ 间距跟随卡牌放大:实际间距 = 基础值 × cardScale(卡牌放大了间距也相应放大,比例不挤)
|
||||
int perRow = (_chipInstances.Count + 1) / 2; // 10 → 5,8 → 4
|
||||
float spacingX = gridSpacingX * cardScale;
|
||||
float rowGap = gridRowGap * cardScale;
|
||||
|
||||
for (int i = 0; i < _chipInstances.Count; i++)
|
||||
{
|
||||
GameObject chip = _chipInstances[i];
|
||||
if (chip == null) continue;
|
||||
|
||||
int row = i / perRow; // 0=上排,1=下排
|
||||
int col = i % perRow;
|
||||
float x = (col - (perRow - 1) / 2f) * spacingX; // 居中:-2,-1,0,1,2 倍间距
|
||||
float y = (row == 0 ? 1 : -1) * rowGap * 0.5f;
|
||||
Vector2 target = centerUi + new Vector2(x, y);
|
||||
|
||||
var rt = chip.GetComponent<RectTransform>();
|
||||
if (rt != null)
|
||||
rt.DOAnchorPos(target, flyToCenterDuration).SetEase(Ease.OutCubic);
|
||||
else
|
||||
chip.transform.DOMove(explosionCenter + (Vector3)target, flyToCenterDuration).SetEase(Ease.OutCubic);
|
||||
|
||||
Debug.Log($"[JiXieXie] 宝石[{i}] 飞到 排{row + 1}列{col + 1} 目标={target}");
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(flyToCenterDuration + 0.1f);
|
||||
}
|
||||
|
||||
/// <summary>阶段5:所有卡牌移动到炮台座位(回收点)</summary>
|
||||
private IEnumerator FlyCardsToSeat()
|
||||
{
|
||||
if (_uiCanvas == null) yield break;
|
||||
|
||||
// ⭐ 回收点 = 击杀者炮台座位位置(GetSeatPosition 返回 currentTurret 位置)
|
||||
Vector3 seatWorld = GetSeatPosition();
|
||||
Vector2 seatUi = CoordinateTransformation.WorldPos_ToCanvas(seatWorld, _uiCanvas);
|
||||
|
||||
for (int i = 0; i < _chipInstances.Count; i++)
|
||||
{
|
||||
GameObject chip = _chipInstances[i];
|
||||
if (chip == null) continue;
|
||||
|
||||
// 轻微错开,观感像飞向同一个点
|
||||
Vector2 target = seatUi + new Vector2((i % 3 - 1) * 12f, 0);
|
||||
|
||||
var rt = chip.GetComponent<RectTransform>();
|
||||
if (rt != null)
|
||||
rt.DOAnchorPos(target, flyToSeatDuration).SetEase(Ease.InCubic);
|
||||
else
|
||||
chip.transform.DOMove(seatWorld, flyToSeatDuration).SetEase(Ease.InCubic);
|
||||
|
||||
Debug.Log($"[JiXieXie] 卡牌[{i}] 飞向炮台座位 {target}");
|
||||
yield return new WaitForSeconds(0.05f);
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(flyToSeatDuration + 0.2f);
|
||||
}
|
||||
|
||||
/// <summary>阶段6:显示 BJEndUI 面板 + 加分 + 回收</summary>
|
||||
private void ShowEndAndFinish()
|
||||
{
|
||||
Debug.Log($"[JiXieXie] 八连抽完成,显示 BJEndUI 倍数={bJbeishu} 总分={maxScore} isSelf={isSelf}");
|
||||
|
||||
Vector3 uiPos = GetSeatPosition() + Vector3.up * bjEndUIOffsetY;
|
||||
if (bjEndUI != null)
|
||||
{
|
||||
var endUI = Instantiate(bjEndUI, uiPos, Quaternion.identity,
|
||||
CreateFishManager.Instance != null ? CreateFishManager.Instance.bjEffectRoot : null);
|
||||
endUI.Init(bJbeishu, maxScore, isSelf);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[JiXieXie] bjEndUI 未赋值(BJEventBase 基类字段),跳过结束面板");
|
||||
}
|
||||
|
||||
// 回加金币到玩家
|
||||
JiaFen?.Invoke();
|
||||
|
||||
// 回收爆奖预制体 + 销毁 chip
|
||||
die();
|
||||
}
|
||||
|
||||
/// <summary>阶段2:逐颗翻牌(隐藏 Gemstone,显示 Card,替换 Card/Goods 图片)</summary>
|
||||
private IEnumerator FlipCards()
|
||||
{
|
||||
for (int i = 0; i < _chipInstances.Count; i++)
|
||||
{
|
||||
GameObject chip = _chipInstances[i];
|
||||
if (chip == null) continue;
|
||||
|
||||
DropItemInfo info = _dropInfos[i];
|
||||
if (info == null) continue;
|
||||
|
||||
FlipOneCard(chip, info, i);
|
||||
yield return new WaitForSeconds(flipInterval);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>翻单张卡:隐藏宝石 → 显示卡牌背面 → 翻转显示正面(分级色)→ 特效</summary>
|
||||
private void FlipOneCard(GameObject chip, DropItemInfo info, int index)
|
||||
{
|
||||
// 隐藏宝石相关子物体
|
||||
Transform gemstone = chip.transform.Find(gemstoneName);
|
||||
if (gemstone != null) gemstone.gameObject.SetActive(false);
|
||||
SetChildActive(chip.transform, starEffectName, false);
|
||||
SetChildActive(chip.transform, bombEffectName, false);
|
||||
|
||||
// 显示卡牌容器,缩放 0 → 1
|
||||
Transform cardObj = chip.transform.Find(cardObjName);
|
||||
if (cardObj == null)
|
||||
{
|
||||
Debug.LogWarning($"[JiXieXie] chip 里找不到 {cardObjName},跳过翻牌");
|
||||
return;
|
||||
}
|
||||
cardObj.gameObject.SetActive(true);
|
||||
cardObj.localScale = Vector3.zero;
|
||||
|
||||
// ⭐ 翻牌素材:背面 = cardSprites[cardBackIndex](DropCard0),正面 = 按金币分级的颜色图
|
||||
Sprite backSprite = GetCardBackSprite();
|
||||
Sprite frontSprite = GetCardColorSprite(info.cardColor);
|
||||
|
||||
// Card / Goods 图片(Source Image)
|
||||
Transform cardImage = chip.transform.Find(cardImagePath);
|
||||
Transform goods = chip.transform.Find(goodsPath);
|
||||
if (cardImage != null)
|
||||
{
|
||||
var img = cardImage.GetComponent<Image>();
|
||||
if (img != null)
|
||||
{
|
||||
// 先显示背面,翻转后换成正面
|
||||
img.sprite = backSprite != null ? backSprite : frontSprite;
|
||||
}
|
||||
}
|
||||
|
||||
if (goods != null)
|
||||
{
|
||||
var img = goods.GetComponent<Image>();
|
||||
if (img != null)
|
||||
{
|
||||
Sprite sp = GetGoodsSprite(info.rewardID);
|
||||
if (sp != null) img.sprite = sp;
|
||||
}
|
||||
}
|
||||
|
||||
// 文本:名称 / 数量 / 倍数(正面内容先设好,翻过来就能看到)
|
||||
Transform nameTf = chip.transform.Find(namePath);
|
||||
if (nameTf != null)
|
||||
{
|
||||
var tmp = nameTf.GetComponent<TextMeshProUGUI>();
|
||||
if (tmp != null)
|
||||
tmp.text = GetPropName(info.rewardID);
|
||||
}
|
||||
|
||||
Transform numTf = chip.transform.Find(numPath);
|
||||
if (numTf != null)
|
||||
{
|
||||
var tmp = numTf.GetComponent<TextMeshProUGUI>();
|
||||
if (tmp != null)
|
||||
tmp.text = info.num > 0 ? FormatGold(info.num) : "已达上限";
|
||||
}
|
||||
|
||||
Transform mulTf = chip.transform.Find(mulPath);
|
||||
if (mulTf != null)
|
||||
{
|
||||
var tmp = mulTf.GetComponent<TextMeshProUGUI>();
|
||||
if (tmp != null)
|
||||
tmp.gameObject.SetActive(false); // 倍数:本版不拆多倍数,隐藏
|
||||
}
|
||||
|
||||
// ⭐ 翻牌动画:背面放大出现 → 停顿 → 压扁(scaleX→0) → 换正面 → 弹开(scaleX→1)
|
||||
Sequence flipSeq = DOTween.Sequence();
|
||||
flipSeq.Append(cardObj.DOScale(Vector3.one, 0.12f).SetEase(Ease.OutBack)); // 背面出现
|
||||
flipSeq.AppendInterval(0.1f); // 让玩家看清背面
|
||||
flipSeq.Append(cardObj.DOScaleX(0f, 0.1f).SetEase(Ease.InOutQuad)); // 压扁成一条线
|
||||
flipSeq.AppendCallback(() =>
|
||||
{
|
||||
// 翻到一半换正面(分级色)
|
||||
if (cardImage != null)
|
||||
{
|
||||
var img = cardImage.GetComponent<Image>();
|
||||
if (img != null && frontSprite != null)
|
||||
img.sprite = frontSprite;
|
||||
}
|
||||
});
|
||||
flipSeq.Append(cardObj.DOScaleX(1f, 0.15f).SetEase(Ease.OutBack)); // 弹开露出正面
|
||||
|
||||
// 紫/红卡附加:弹开后放大一下 + 对应特效(紫=Effect_Card_Purple,红=Effect_Card_Orange)
|
||||
if (info.cardColor >= 3)
|
||||
{
|
||||
Transform purple = chip.transform.Find(purpleEffectName);
|
||||
Transform orange = chip.transform.Find(orangeEffectName);
|
||||
flipSeq.Append(cardObj.DOScale(Vector3.one * 1.2f, 0.25f).SetEase(Ease.OutElastic));
|
||||
flipSeq.AppendCallback(() =>
|
||||
{
|
||||
if (info.cardColor == 3)
|
||||
{
|
||||
if (purple != null) purple.gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (orange != null) orange.gameObject.SetActive(true);
|
||||
}
|
||||
});
|
||||
flipSeq.Append(cardObj.DOScale(Vector3.one, 0.15f));
|
||||
}
|
||||
|
||||
Debug.Log($"[JiXieXie] 翻牌[{index}] 背面→正面({GetColorName(info.cardColor)}) num={info.num}");
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 工具方法(全部从 config 读取资源)
|
||||
// ============================================================
|
||||
|
||||
/// <summary>
|
||||
/// 缓存 UI 层父节点 + Canvas:
|
||||
/// 父节点 = currGameType.subPanelParent.parent(与爆奖预制体同层,随 UI 卸载自动清理)
|
||||
/// Canvas = UIManager.uiRoot 上的 Canvas(世界坐标 → UI 坐标转换用)
|
||||
/// </summary>
|
||||
private void EnsureUiLayer()
|
||||
{
|
||||
if (_uiLayer != null && _uiCanvas != null) return;
|
||||
|
||||
if (CreateFishManager.Instance != null && CreateFishManager.Instance.currGameType != null)
|
||||
{
|
||||
var subPanel = CreateFishManager.Instance.currGameType.subPanelParent;
|
||||
if (subPanel != null)
|
||||
_uiLayer = subPanel.parent;
|
||||
}
|
||||
|
||||
if (UIManager.Instance != null && UIManager.Instance.uiRoot != null)
|
||||
_uiCanvas = UIManager.Instance.uiRoot.GetComponent<Canvas>();
|
||||
|
||||
if (_uiCanvas == null && _uiLayer != null)
|
||||
_uiCanvas = _uiLayer.GetComponentInParent<Canvas>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按颜色分级取宝石图(与卡牌颜色一一对应)。
|
||||
/// ⭐ 优先按文件名末尾数字精确匹配:DropGemstone1=绿 2=蓝 3=紫 4=红,
|
||||
/// 不受资产数组顺序影响;匹配不到再回退 gemGreen/Blue/Purple/RedIndex 下标。
|
||||
/// </summary>
|
||||
private Sprite GetGemstoneColorSprite(int cardColor)
|
||||
{
|
||||
if (config == null || config.gemstoneSprites == null || config.gemstoneSprites.Length == 0) return null;
|
||||
|
||||
// 精确匹配:文件名末尾数字 == cardColor(DropGemstone1~4)
|
||||
Sprite hit = FindSpriteByNumber(config.gemstoneSprites, cardColor);
|
||||
if (hit != null) return hit;
|
||||
|
||||
// 兜底:按下标
|
||||
int idx = cardColor == 1 ? gemGreenIndex
|
||||
: cardColor == 2 ? gemBlueIndex
|
||||
: cardColor == 3 ? gemPurpleIndex
|
||||
: gemRedIndex;
|
||||
idx = Mathf.Clamp(idx, 0, config.gemstoneSprites.Length - 1);
|
||||
return config.gemstoneSprites[idx];
|
||||
}
|
||||
|
||||
/// <summary>取卡牌背面图。⭐ 优先精确匹配 DropCard0,回退 cardBackIndex 下标</summary>
|
||||
private Sprite GetCardBackSprite()
|
||||
{
|
||||
if (config == null || config.cardSprites == null || config.cardSprites.Length == 0) return null;
|
||||
|
||||
Sprite hit = FindSpriteByNumber(config.cardSprites, 0); // DropCard0 = 背面
|
||||
if (hit != null) return hit;
|
||||
|
||||
int idx = Mathf.Clamp(cardBackIndex, 0, config.cardSprites.Length - 1);
|
||||
return config.cardSprites[idx];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按卡牌颜色分级取卡牌图。
|
||||
/// ⭐ 优先按文件名末尾数字精确匹配:DropCard1=绿 2=蓝 3=紫 4=红,
|
||||
/// 不受资产数组顺序影响;匹配不到再回退 green/Blue/Purple/RedCardIndex 下标。
|
||||
/// </summary>
|
||||
private Sprite GetCardColorSprite(int cardColor)
|
||||
{
|
||||
if (config == null || config.cardSprites == null || config.cardSprites.Length == 0) return null;
|
||||
|
||||
// 精确匹配:文件名末尾数字 == cardColor(DropCard1~4)
|
||||
Sprite hit = FindSpriteByNumber(config.cardSprites, cardColor);
|
||||
if (hit != null) return hit;
|
||||
|
||||
// 兜底:按下标
|
||||
int idx = cardColor == 1 ? greenCardIndex
|
||||
: cardColor == 2 ? blueCardIndex
|
||||
: cardColor == 3 ? purpleCardIndex
|
||||
: redCardIndex;
|
||||
idx = Mathf.Clamp(idx, 0, config.cardSprites.Length - 1);
|
||||
return config.cardSprites[idx];
|
||||
}
|
||||
|
||||
/// <summary>在 sprite 数组中查找文件名末尾数字 == number 的图(找不到返回 null)</summary>
|
||||
private static Sprite FindSpriteByNumber(Sprite[] sprites, int number)
|
||||
{
|
||||
if (sprites == null || sprites.Length == 0) return null;
|
||||
for (int i = 0; i < sprites.Length; i++)
|
||||
{
|
||||
if (sprites[i] != null && ExtractTrailingNumber(sprites[i].name) == number)
|
||||
return sprites[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>卡牌颜色分级 → 中文名(日志用)</summary>
|
||||
private string GetColorName(int cardColor)
|
||||
{
|
||||
switch (cardColor)
|
||||
{
|
||||
case 1: return "绿";
|
||||
case 2: return "蓝";
|
||||
case 3: return "紫";
|
||||
case 4: return "红";
|
||||
default: return $"未知({cardColor})";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在 goodsSprites 中定位 rewardID 对应下标。
|
||||
/// 优先精确匹配(文件名末尾数字 == rewardID,支持 1000+ 火箭炮),
|
||||
/// 匹配不到再按取模兜底(避免数组长度取模导致错位)。
|
||||
/// </summary>
|
||||
private int FindGoodsIndex(int rewardID)
|
||||
{
|
||||
if (config == null || config.goodsSprites == null || config.goodsSprites.Length == 0) return -1;
|
||||
|
||||
for (int i = 0; i < config.goodsSprites.Length; i++)
|
||||
{
|
||||
if (config.goodsSprites[i] != null
|
||||
&& ExtractTrailingNumber(config.goodsSprites[i].name) == rewardID)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return Mathf.Abs(rewardID) % config.goodsSprites.Length;
|
||||
}
|
||||
|
||||
/// <summary>按 rewardID 取道具图,越界回退 0</summary>
|
||||
private Sprite GetGoodsSprite(int rewardID)
|
||||
{
|
||||
int idx = FindGoodsIndex(rewardID);
|
||||
if (idx < 0 || config.goodsSprites == null) return null;
|
||||
return config.goodsSprites[idx];
|
||||
}
|
||||
|
||||
/// <summary>按 rewardID 取道具名称,未配置则返回默认</summary>
|
||||
private string GetPropName(int rewardID)
|
||||
{
|
||||
int idx = FindGoodsIndex(rewardID);
|
||||
if (config != null && config.propNames != null && config.propNames.Length > 0
|
||||
&& idx >= 0 && idx < config.propNames.Length
|
||||
&& !string.IsNullOrEmpty(config.propNames[idx]))
|
||||
{
|
||||
return config.propNames[idx];
|
||||
}
|
||||
return "奖励";
|
||||
}
|
||||
|
||||
/// <summary>提取文件名末尾数字(如 "PW_FreeItem_DropProp1000" → 1000),无数字返回 0</summary>
|
||||
private static int ExtractTrailingNumber(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name)) return 0;
|
||||
int i = name.Length - 1;
|
||||
while (i >= 0 && char.IsDigit(name[i])) i--;
|
||||
string numStr = name.Substring(i + 1);
|
||||
return int.TryParse(numStr, out int v) ? v : 0;
|
||||
}
|
||||
|
||||
/// <summary>金币千分位格式化</summary>
|
||||
private string FormatGold(long num)
|
||||
{
|
||||
return num.ToString("N0");
|
||||
}
|
||||
|
||||
/// <summary>按名字设置子物体显隐(找不到跳过)</summary>
|
||||
private void SetChildActive(Transform root, string childName, bool active)
|
||||
{
|
||||
if (root == null || string.IsNullOrEmpty(childName)) return;
|
||||
Transform child = root.Find(childName);
|
||||
if (child != null) child.gameObject.SetActive(active);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 收尾
|
||||
// ============================================================
|
||||
|
||||
/// <summary>回收爆奖预制体到对象池(先清理 chip 实例 + 分数面板)</summary>
|
||||
public override void die()
|
||||
{
|
||||
CleanupBeforeDie();
|
||||
|
||||
// 销毁八连抽 chip 实例
|
||||
for (int i = 0; i < _chipInstances.Count; i++)
|
||||
{
|
||||
if (_chipInstances[i] != null)
|
||||
Destroy(_chipInstances[i]);
|
||||
}
|
||||
_chipInstances.Clear();
|
||||
|
||||
EffectPool.Instance.Return(gameObject);
|
||||
}
|
||||
|
||||
|
||||
@@ -300,6 +300,7 @@ MonoBehaviour:
|
||||
bjEndUIOffsetY: 150
|
||||
coinFlyDuration: 0.5
|
||||
coinArrivalInterval: 0.1
|
||||
showAddScoreFX: 1
|
||||
isSelf: 0
|
||||
autoFinishOnScoreFull: 1
|
||||
totalBJCount: 0
|
||||
@@ -308,10 +309,42 @@ MonoBehaviour:
|
||||
isScoreStart: 0
|
||||
isScoreEnd: 0
|
||||
isGoldEffectStart: 0
|
||||
explosionRadius: 5
|
||||
fishLayer:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
explosionDelay: 0.5
|
||||
explosionDuration: 2
|
||||
config: {fileID: 11400000, guid: 4adb4d6d53ad6b74cabd5722c72c2d25, type: 2}
|
||||
chipCount: 10
|
||||
minPartAmount: 1
|
||||
gemAppearInterval: 0.03
|
||||
spawnYRatio: 0.78
|
||||
flyToCenterDuration: 0.8
|
||||
cardScale: 1.5
|
||||
gridCenterYRatio: 0.5
|
||||
gridSpacingX: 120
|
||||
gridRowGap: 160
|
||||
flipInterval: 0.4
|
||||
flyToSeatDuration: 0.6
|
||||
gemGreenIndex: 0
|
||||
gemBlueIndex: 1
|
||||
gemPurpleIndex: 2
|
||||
gemRedIndex: 3
|
||||
cardBackIndex: 0
|
||||
greenLimitBeishu: 100
|
||||
blueLimitBeishu: 200
|
||||
redLimitBeishu: 500
|
||||
greenCardIndex: 1
|
||||
blueCardIndex: 2
|
||||
purpleCardIndex: 3
|
||||
redCardIndex: 4
|
||||
gemstoneName: Gemstone
|
||||
cardObjName: Card
|
||||
cardImagePath: Card/Card
|
||||
goodsPath: Card/Goods
|
||||
namePath: Card/Name
|
||||
numPath: Card/Num
|
||||
mulPath: Card/Num/Mul
|
||||
starEffectName: Effect_Gemstone_star
|
||||
bombEffectName: Effect_Gemstone_Bomb
|
||||
orangeEffectName: Effect_Card_Orange
|
||||
purpleEffectName: Effect_Card_Purple
|
||||
createEffectName: Effect_Create
|
||||
tailEffectName: Effect_Tail
|
||||
arriveEffectName: Effect_Arrive
|
||||
explosionCenter: {x: 0, y: 0, z: 0}
|
||||
|
||||
@@ -59878,6 +59878,7 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 224855352063733292}
|
||||
- component: {fileID: 222892102804854659}
|
||||
- component: {fileID: 5608389863781542425}
|
||||
m_Layer: 0
|
||||
m_Name: Num
|
||||
m_TagString: Untagged
|
||||
@@ -59913,6 +59914,95 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1810759860515733}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &5608389863781542425
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1810759860515733}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_text:
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 0}
|
||||
m_sharedMaterial: {fileID: 0}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_enableVertexGradient: 0
|
||||
m_colorMode: 3
|
||||
m_fontColorGradient:
|
||||
topLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
topRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_fontColorGradientPreset: {fileID: 0}
|
||||
m_spriteAsset: {fileID: 0}
|
||||
m_tintAllSprites: 0
|
||||
m_StyleSheet: {fileID: 0}
|
||||
m_TextStyleHashCode: 0
|
||||
m_overrideHtmlColors: 0
|
||||
m_faceColor:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontSize: 28
|
||||
m_fontSizeBase: 28
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 0
|
||||
m_fontSizeMin: 0
|
||||
m_fontSizeMax: 0
|
||||
m_fontStyle: 0
|
||||
m_HorizontalAlignment: 2
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 0
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 0
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 0
|
||||
m_isCullingEnabled: 0
|
||||
m_horizontalMapping: 0
|
||||
m_verticalMapping: 0
|
||||
m_uvLineOffset: 0
|
||||
m_geometrySortingOrder: 0
|
||||
m_IsTextObjectScaleStatic: 0
|
||||
m_VertexBufferAutoSizeReduction: 0
|
||||
m_useMaxVisibleDescender: 1
|
||||
m_pageToDisplay: 1
|
||||
m_margin: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_isUsingLegacyAnimationComponent: 0
|
||||
m_isVolumetricText: 0
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!1 &1834793653561820
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@@ -12,7 +12,7 @@ using UnityEngine;
|
||||
/// Settle: PW_Effect_Settle_FuJiaTianXia (Node子物体指认Source Image为tj_fcboss_0)
|
||||
///
|
||||
/// 形态二(铁拳 IronFist, weaponID=6):
|
||||
/// 1. FullScreen(PW_Effect_FullScreen_IronFist): 依次激活 tap_tip → knock_tip(Source Image=Prop_Poster_IronFist) → 隐藏Tip
|
||||
/// 1. FullScreen(PW_Effect_FullScreen_Symmetra): 依次激活 tap_tip → knock_tip(Source Image=Prop_Poster_IronFist) → 隐藏Tip
|
||||
/// 2. Prop(PW_Prop_IronFist): 激活Hole子对象 → Hole从死亡位置移动到屏幕左下角 → 隐藏Hole → 激活Hand
|
||||
/// 3. TextCrit: PW_Effect_TextCrit_Other / PW_Effect_TextCrit_Self (满屏暴击)
|
||||
/// 4. AwardFrame: PW_Effect_AwardFrame_IronFist
|
||||
@@ -32,9 +32,8 @@ using UnityEngine;
|
||||
/// 5. AwardFrame: PW_Effect_AwardFrame_GammaStorm
|
||||
/// 6. Settle: PW_Effect_Settle_GammaStorm_Other
|
||||
///
|
||||
/// ⭐ 注意: 美术表格中铁拳写的是"PW_Effect_FullScreen_Symmetra",但根据Lua逻辑
|
||||
/// (PW_EffectMgr.CreateEffect("FullScreen", "PW_Effect_FullScreen_" .. flag))
|
||||
/// 应该是 PW_Effect_FullScreen_IronFist,此处按Lua逻辑处理。
|
||||
/// ⭐ 注意: 铁拳(形态二)的全屏 UI 框按美术规格用 PW_Effect_FullScreen_Symmetra,
|
||||
/// 海报(Source Image) 仍设置 Prop_Poster_IronFist。
|
||||
///
|
||||
/// ==================== 完整流程 ====================
|
||||
///
|
||||
@@ -260,6 +259,23 @@ public class XingJiXunHangEvent : BJEventBase
|
||||
?? root["weapon_id"]?.Value<int>()
|
||||
?? 0;
|
||||
|
||||
// ⭐ 服务端现在用 animId 区分三种带死亡的爆奖(weaponID 可能不再下发):
|
||||
// animId=2 → 形态二 铁拳 IronFist (weaponID=6)
|
||||
// animId=3 → 形态三 光子 Symmetra (weaponID=8)
|
||||
// animId=4 → 形态四 伽马风暴 GammaStorm (weaponID=7)
|
||||
if (_weaponId == 0)
|
||||
{
|
||||
int animId = root["animId"]?.Value<int>() ?? 0;
|
||||
switch (animId)
|
||||
{
|
||||
case 2: _weaponId = 6; break; // 铁拳
|
||||
case 3: _weaponId = 8; break; // 光子
|
||||
case 4: _weaponId = 7; break; // 伽马风暴
|
||||
}
|
||||
if (animId >= 2)
|
||||
Debug.Log($"[XingJiXunHang] 无 weaponID,按 animId={animId} 映射为 weaponID={_weaponId}");
|
||||
}
|
||||
|
||||
Debug.Log($"[XingJiXunHang] 解析武器 ID: weaponID={_weaponId}");
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -288,7 +304,8 @@ public class XingJiXunHangEvent : BJEventBase
|
||||
_weaponTag = "IronFist";
|
||||
_settlePrefab = isSelf ? settleIronFistSelf : settleIronFistOther;
|
||||
_awardFramePrefab = awardFrameIronFist;
|
||||
_fullScreenPrefab = fullScreenIronFist;
|
||||
// ⭐ 美术规格:铁拳的全屏 UI 框用 PW_Effect_FullScreen_Symmetra(海报仍为 Prop_Poster_IronFist)
|
||||
_fullScreenPrefab = fullScreenSymmetra;
|
||||
_propPrefab = propIronFist;
|
||||
_posterSprite = posterIronFist;
|
||||
break;
|
||||
|
||||
@@ -103,6 +103,16 @@ public class XingJiXunHang_BOSS : MonsterControl_BossBase
|
||||
beishu = p.beishu;
|
||||
if (!string.IsNullOrEmpty(p.fishId))
|
||||
_cruiseFishId = p.fishId;
|
||||
|
||||
// ⭐ animId 优先于 isKill(服务端实际以 animId 为准):
|
||||
// animId==1 → 不死(只播 BJEndUI,Boss 保留)
|
||||
// animId>=2 → 带死亡的爆奖(2/3/4 三种表现)
|
||||
// animId==0 → 老消息无 animId,回退用 isKill
|
||||
if (p.animId >= 1)
|
||||
{
|
||||
isKill = p.animId >= 2;
|
||||
Debug.Log($"[XingJiXunHang] animId={p.animId} → isKill={isKill}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user