This commit is contained in:
2026-08-30 19:57:45 +08:00
parent a1a776d830
commit 6b28f6d7bd
9 changed files with 698 additions and 513 deletions
@@ -8,6 +8,26 @@ PrefabInstance:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 79321102250555621, guid: 825a3a493d3f44b409fbd4cc5eeb4e9e,
type: 3}
propertyPath: m_LocalPosition.y
value: -0.024000064
objectReference: {fileID: 0}
- target: {fileID: 799521184525718548, guid: 825a3a493d3f44b409fbd4cc5eeb4e9e,
type: 3}
propertyPath: m_LocalPosition.y
value: 0.16699992
objectReference: {fileID: 0}
- target: {fileID: 1688248704305440693, guid: 825a3a493d3f44b409fbd4cc5eeb4e9e,
type: 3}
propertyPath: m_LocalPosition.y
value: 0.20599996
objectReference: {fileID: 0}
- target: {fileID: 2822261582276405931, guid: 825a3a493d3f44b409fbd4cc5eeb4e9e,
type: 3}
propertyPath: m_LocalPosition.y
value: -0.18699999
objectReference: {fileID: 0}
- target: {fileID: 3446050555171211319, guid: 825a3a493d3f44b409fbd4cc5eeb4e9e,
type: 3}
propertyPath: m_LocalScale.x
@@ -78,6 +98,31 @@ PrefabInstance:
propertyPath: m_ConstrainProportionsScale
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3498336931698703236, guid: 825a3a493d3f44b409fbd4cc5eeb4e9e,
type: 3}
propertyPath: m_LocalPosition.y
value: 0.009999976
objectReference: {fileID: 0}
- target: {fileID: 4189205739631872733, guid: 825a3a493d3f44b409fbd4cc5eeb4e9e,
type: 3}
propertyPath: m_LocalPosition.y
value: -0.149
objectReference: {fileID: 0}
- target: {fileID: 4454072488200771150, guid: 825a3a493d3f44b409fbd4cc5eeb4e9e,
type: 3}
propertyPath: m_LocalPosition.y
value: -1.12
objectReference: {fileID: 0}
- target: {fileID: 5952411848877789633, guid: 825a3a493d3f44b409fbd4cc5eeb4e9e,
type: 3}
propertyPath: m_LocalPosition.y
value: -0.04200007
objectReference: {fileID: 0}
- target: {fileID: 6042158412426053227, guid: 825a3a493d3f44b409fbd4cc5eeb4e9e,
type: 3}
propertyPath: m_LocalPosition.y
value: -1.12
objectReference: {fileID: 0}
- target: {fileID: 6042158412426053227, guid: 825a3a493d3f44b409fbd4cc5eeb4e9e,
type: 3}
propertyPath: m_LocalRotation.w
@@ -108,6 +153,11 @@ PrefabInstance:
propertyPath: m_TagString
value: Fish
objectReference: {fileID: 0}
- target: {fileID: 6543461877805945619, guid: 825a3a493d3f44b409fbd4cc5eeb4e9e,
type: 3}
propertyPath: m_LocalPosition.y
value: -0.39600003
objectReference: {fileID: 0}
- target: {fileID: 7007380091307527199, guid: 825a3a493d3f44b409fbd4cc5eeb4e9e,
type: 3}
propertyPath: m_Name
@@ -92,7 +92,7 @@ MonoBehaviour:
maxBJCount: 15
laserPrefab: {fileID: 1709254077376921, guid: fdbfa7c8291331a4d838237be97893de,
type: 3}
laserLengthCorrect: 1
laserLengthCorrect: 0.15
lightningMaterial: {fileID: 2100000, guid: a023113e8eb8bf245b8ba10c3e9788d1, type: 2}
lightningColor: {r: 1, g: 0.92156863, b: 0.015686275, a: 1}
lightningWidth: 10
@@ -106,7 +106,7 @@ MonoBehaviour:
lightningCount: 5
circleRange: 20
fillRange: 10
lightningWait: 5
lightningWait: 1
killDelay: 0.3
fishLayer:
serializedVersion: 2
File diff suppressed because it is too large Load Diff
@@ -5,29 +5,43 @@ using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 钻头子弹(3D 预制体,按普通子弹的方式创建和移动)。
/// - 创建:位置 = 炮台子弹起点(GetBulletStartWorldPos),旋转 = Quaternion.Euler(0,0,angle);
/// - 移动:沿 _heading(2D 方向向量)直线飞行,模型保持预制体默认姿态、只转世界 Z 轴;
/// - 撞墙(Wall 层):法线反弹,每撞一次 peng--;次数用完仍继续反弹;
/// - 碰鱼(Fish 层):peng>0 → 回调杀这条鱼(钻头继续飞);peng<=0 → 在碰鱼位置最终爆炸炸死一群鱼;
/// - 超时 desTime:同样最终爆炸;
/// - 爆炸:范围杀鱼(没配特效也照常) → 可选特效 → 回调 onExploded → 销毁自身。
/// 钻头子弹(3D 预制体,按普通子弹的方式创建和移动)。三状态:
/// - 状态1(反弹杀鱼):撞墙反弹 peng 次,碰鱼杀小鱼(帧同步);显示 state1Fx 子对象;
/// - 状态2(乱转反弹):状态1反弹完自动切换,再反弹 peng2 次;碰鱼穿过不杀不炸;显示 state2Fx 并驱动它持续自转;
/// - 状态3(收尾):状态2反弹完 → 飞向世界原点(0,0) → 到达后最终爆炸;显示 state3Fx;
/// 爆炸是否炸范围小鱼由 killFishOnFinal 决定(创建方按 bigPrizeFishMode 传入:KillFish=炸,其余=不炸);
/// - 撞墙(Wall 层):法线反弹并刷新兜底计时(持续反弹永不超时);卡住无碰撞超过 desTime 才兜底爆炸;
/// - 爆炸:范围杀鱼(可选) → 可选特效(没配画范围圈圈) → 回调 onExploded → 销毁自身。
/// </summary>
public class SpecialBulletMove : MonoBehaviour
{
[Header("移动")]
[Tooltip("飞行速度(世界单位/秒)")]
public float moveSpeed = 30f;
[Tooltip("最长存活时间(秒),超时爆炸")]
[Tooltip("无碰撞兜底时间(秒):撞墙反弹会刷新计时(反弹次数没打完绝不超时爆炸),只有卡住不反弹超过该时长才兜底爆炸")]
public float desTime = 12f;
[Header("反弹 / 爆炸")]
[Tooltip("撞墙反弹次数,反弹完爆炸")]
[Tooltip("状态1(反弹杀鱼阶段)的撞墙反弹次数")]
public int peng = 7;
[Tooltip("状态2(乱转反弹阶段)的反弹次数;状态1用上面的 peng")]
public int peng2 = 5;
[Tooltip("状态2乱转自转速度(度/秒,绕屏幕Z轴;负值反向)")]
public float spin2Speed = 720f;
[Tooltip("最终爆炸特效预制体(没配也会照常炸范围杀鱼,特效后期补)")]
public GameObject explosionPrefab;
[Tooltip("最终爆炸杀鱼半径(世界单位)")]
public float explosionRadius = 3f;
[Tooltip("最终爆炸是否炸死范围小鱼:创建方按爆奖事件 bigPrizeFishMode 传入(KillFish=炸,其余=不炸)")]
public bool killFishOnFinal = true;
[Header("三状态表现(钻头子对象,Inspector 拖引用)")]
[Tooltip("状态1:反弹杀鱼阶段显示的子对象(不拖=钻头本体默认显示,不做显隐切换)")]
public GameObject state1Fx;
[Tooltip("状态2:乱转反弹阶段显示的子对象(代码驱动持续自转,转速=spin2Speed)")]
public GameObject state2Fx;
[Tooltip("状态3:飞向屏幕中间+爆炸阶段显示的子对象")]
public GameObject state3Fx;
[Header("层级")]
[Tooltip("墙层(默认取 Wall 层,另兼容 Wall 标签)")]
@@ -49,6 +63,11 @@ public class SpecialBulletMove : MonoBehaviour
private bool _exploded;
private float _bounceCooldown = 0f; // 反弹冷却:防一帧/连续多帧内重复触发穿墙
/// <summary>三状态:状态1反弹杀鱼 → 状态2乱转纯反弹 → 状态3飞向屏幕中间爆炸</summary>
private enum Phase { Rebound1, Rebound2, ToCenter }
private Phase _phase; // 当前状态
private Vector3 _centerTarget; // 状态3目标点:世界原点(0,0)
/// <summary>最后一次爆炸生成的范围圈圈(走兜底圈圈时非空,供外部接 onFadeComplete)</summary>
[System.NonSerialized]
public ExplodeRangeCircle lastCircle;
@@ -68,7 +87,18 @@ public class SpecialBulletMove : MonoBehaviour
if (wallLayer.value == 0) wallLayer = LayerMask.GetMask("Wall");
if (fishLayer.value == 0) fishLayer = LayerMask.GetMask("Fish");
_defaultRot = transform.rotation; // 预制体默认姿态(含默认 X 轴)
SetPhase(Phase.Rebound1); // 三状态表现初始化(子对象没配则无可见变化)
SetHeading(heading);
Debug.Log($"[钻头] 发射 pos={transform.position} dir={heading} speed={moveSpeed} 兜底={desTime}s peng={peng} peng2={peng2}");
}
/// <summary>三状态切换:对应子对象显隐(state2Fx 的自转由 Update 驱动,state3Fx 激活即播)</summary>
private void SetPhase(Phase p)
{
_phase = p;
if (state1Fx != null) state1Fx.SetActive(p == Phase.Rebound1);
if (state2Fx != null) state2Fx.SetActive(p == Phase.Rebound2);
if (state3Fx != null) state3Fx.SetActive(p == Phase.ToCenter);
}
/// <summary>设置前进方向:世界 Z 轴旋转叠加在默认姿态上(默认 X/Y 始终保留)</summary>
@@ -85,7 +115,30 @@ public class SpecialBulletMove : MonoBehaviour
_time += Time.deltaTime;
if (_bounceCooldown > 0f) _bounceCooldown -= Time.deltaTime;
if (_time >= desTime) { Explode(); return; }
if (_time >= desTime)
{
Debug.LogWarning($"[钻头] ⚠兜底爆炸:{desTime}s无碰撞,phase={_phase} 剩余peng={peng} peng2={peng2} pos={transform.position}");
Explode();
return;
}
// 状态2:乱转特效持续自转(绕屏幕Z轴平面内打转),钻头同时继续移动反弹(下方通用移动)
if (_phase == Phase.Rebound2 && state2Fx != null)
state2Fx.transform.Rotate(0f, 0f, spin2Speed * Time.deltaTime, Space.World);
// 状态3:转向世界原点(0,0)直线飞行,到达 → 最终爆炸
if (_phase == Phase.ToCenter)
{
Vector3 toCenter = _centerTarget - transform.position;
if (toCenter.magnitude <= moveSpeed * Time.deltaTime + 0.05f)
{
transform.position = _centerTarget;
Debug.Log($"[钻头] ★到达原点(0,0),最终爆炸");
Explode();
return;
}
SetHeading(toCenter);
}
// 直线飞行(沿 _heading,模型只转 Z 轴)
transform.position += (Vector3)(_heading * (moveSpeed * Time.deltaTime));
@@ -94,34 +147,41 @@ public class SpecialBulletMove : MonoBehaviour
private void OnTriggerEnter2D(Collider2D other)
{
if (_exploded) return;
if (_phase == Phase.ToCenter) return; // 状态3收尾:直奔屏幕中间,不响应任何碰撞
// —— 撞墙:反弹 + 计数(次数用完仍继续反弹,等碰鱼才引爆)——
// —— 撞墙:法线反弹 + 按当前状态计数 ——
if (IsWall(other) && _bounceCooldown <= 0f)
{
Bounce(other);
peng--;
_bounceCooldown = 0.05f; // 短冷却:防同一次碰撞连触发/穿墙
_time = 0f; // 反弹发生 → 刷新兜底计时:只要还在反弹就永不超时,次数打完才走正常流程爆炸
if (_phase == Phase.Rebound1)
{
peng--;
if (peng <= 0) SetPhase(Phase.Rebound2); // 状态1反弹完 → 切状态2(乱转纯反弹)
}
else
{
peng2--;
if (peng2 <= 0) EnterFinal(); // 状态2反弹完 → 飞向屏幕中间爆炸
}
Debug.Log($"[钻头] 反弹 phase={_phase} 剩余peng={peng} peng2={peng2} pos={transform.position}");
return;
}
// —— 碰鱼:只杀普通鱼(黄金鱼/特殊鱼/Boss/特殊Boss 不可被钻头击杀,穿过)——
if (!IsWall(other))
// —— 碰鱼:只处理普通鱼(黄金鱼/特殊鱼/Boss/特殊Boss 穿过) ——
var fish = other.GetComponentInParent<MonsterContral>();
if (fish == null || fish.isDead) return;
if (fish.fishenum != FishTypeEnum.普通鱼) return; // ⭐ 只杀小鱼
// 状态1:杀这条鱼,钻头继续飞
if (_phase == Phase.Rebound1)
{
var fish = other.GetComponentInParent<MonsterContral>();
if (fish == null || fish.isDead) return;
if (fish.fishenum != FishTypeEnum.普通鱼) return; // ⭐ 只杀小鱼
// 反弹次数已用完 → 在碰鱼位置最终爆炸:炸死一群鱼 → 钻头消失
if (peng <= 0)
{
Explode();
return;
}
// 还有反弹次数 → 只杀这条鱼,钻头继续飞
if (!_killed.Add(fish.guid)) return; // 同一条鱼只杀一次
onHitFish?.Invoke(fish);
}
// 状态2:纯反弹乱转阶段,穿过鱼不杀不炸
}
private bool IsWall(Collider2D c)
@@ -130,6 +190,14 @@ public class SpecialBulletMove : MonoBehaviour
|| c.CompareTag("Wall");
}
/// <summary>进入状态3:切换表现 → 目标点=世界原点(0,0),Update 里转向飞过去,到达爆炸</summary>
private void EnterFinal()
{
SetPhase(Phase.ToCenter);
_centerTarget = Vector3.zero;
Debug.Log($"[钻头] ★进入状态3:飞向原点(0,0),当前pos={transform.position}");
}
/// <summary>
/// 按墙面法线反弹(ClosestPoint 求近似法线,适配任意方向的墙)。
/// ⭐ 反弹时把钻头沿法线推回墙外(墙最近点 + 钻头半径 + 余量),防止高速下
@@ -168,8 +236,8 @@ public class SpecialBulletMove : MonoBehaviour
if (_exploded) return;
_exploded = true;
// 范围爆炸:炸 explosionRadius 内的普通鱼(⭐ 只杀小鱼,同一条鱼只杀一次)
if (explosionRadius > 0f && onHitFish != null)
// 范围爆炸:killFishOnFinal(创建方按 bigPrizeFishMode 传入)决定炸不炸鱼(⭐ 只杀小鱼,同一条鱼只杀一次)
if (killFishOnFinal && explosionRadius > 0f && onHitFish != null)
{
var hits = Physics2D.OverlapCircleAll((Vector2)transform.position, explosionRadius, fishLayer);
foreach (var h in hits)
@@ -13,9 +13,12 @@ using UnityEngine.InputSystem;
/// 2. 点击屏幕 → 按普通子弹的创建方式发射钻头
/// (位置=GetBulletStartWorldPos,旋转=Euler(0,0,当前瞄准角));
/// 发射后【立刻】恢复普通炮台(turretParent=true)——爆奖与炮台无关;
/// 3. 钻头飞行:撞墙(Wall层)反弹 peng 次、碰到鱼回调杀鱼(Id_DieFish_FX 帧同步);
/// 4. 反弹次数用完后继续反弹,下次碰鱼 -> 最终爆炸(范围炸一群鱼,无特效则画范围圈圈);
/// 圈圈淡出完成(或兜底) -> ShowEndUI:加分 + 显示 BJEndUI -> 结束爆奖回池。
/// 3. 钻头飞行三状态(表现=钻头子对象,Inspector 配在钻头预制体上):
/// 状态1 反弹杀鱼:撞墙反弹 peng 次,碰鱼回调杀小鱼(Id_DieFish_FX 帧同步),显示 state1Fx;
/// 状态2 乱转纯反弹:再反弹 peng2 次,碰鱼穿过不杀,显示 state2Fx 并驱动持续自转(spin2Speed);
/// 状态3 收尾:飞向世界原点(0,0) → 到达后最终爆炸,显示 state3Fx;
/// 最终爆炸炸不炸鱼按 bigPrizeFishMode 判断(KillFish=炸范围小鱼,NoFish/CoinNoFish=只爆不炸);
/// 4. 爆炸后(无特效则画范围圈圈) 圈圈淡出完成(或兜底) -> ShowEndUI:加分 + 显示 BJEndUI -> 结束爆奖回池。
/// </summary>
public class ZuanTouXie_DieEvent : DieEffect_TSY
{
@@ -28,11 +31,15 @@ public class ZuanTouXie_DieEvent : DieEffect_TSY
public GameObject bulletPrefab;
[Tooltip("最终爆炸特效预制体")]
public GameObject explosionPrefab;
[Tooltip("撞墙反弹次数,反弹完爆炸")]
[Tooltip("状态1(反弹杀鱼阶段)的撞墙反弹次数")]
public int peng = 7;
[Tooltip("状态2(乱转反弹阶段)的反弹次数;状态1用 peng")]
public int peng2 = 5;
[Tooltip("状态2乱转自转速度(度/秒,绕屏幕Z轴;负值反向)")]
public float spin2Speed = 720f;
[Tooltip("钻头飞行速度(世界单位/秒)")]
public float bulletSpeed = 30f;
[Tooltip("钻头最长存活时间(秒)")]
[Tooltip("钻头无碰撞兜底时间(秒):持续反弹会刷新计时,反弹次数没打完绝不超时爆炸")]
public float bulletLife = 12f;
[Tooltip("子弹无碰撞体时自动补圆形触发器半径")]
public float bulletTriggerRadius = 0.6f;
@@ -305,6 +312,10 @@ public class ZuanTouXie_DieEvent : DieEffect_TSY
sb.moveSpeed = bulletSpeed;
sb.desTime = bulletLife;
sb.peng = peng;
sb.peng2 = peng2;
sb.spin2Speed = spin2Speed;
// 状态3最终爆炸炸不炸鱼:按爆奖金币模式 bigPrizeFishMode(KillFish=炸一圈小鱼;NoFish/CoinNoFish=只爆不炸)
sb.killFishOnFinal = bigPrizeFishMode == BigPrizeFishMode.KillFish;
sb.explosionPrefab = explosionPrefab;
if (isKiller) sb.onHitFish = KillSmallFish; // 只有击杀者端杀鱼(走帧同步)
@@ -1961,6 +1961,24 @@ PrefabInstance:
insertIndex: -1
addedObject: {fileID: 7824705585925333471}
m_SourcePrefab: {fileID: 100100000, guid: dd617d0fc54f62c40ac12ba4ff5ebd9f, type: 3}
--- !u!1 &6395126940408738618 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 1076349243203591, guid: dd617d0fc54f62c40ac12ba4ff5ebd9f,
type: 3}
m_PrefabInstance: {fileID: 6396198883015021373}
m_PrefabAsset: {fileID: 0}
--- !u!1 &6396680948013903050 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 1776331922407415, guid: dd617d0fc54f62c40ac12ba4ff5ebd9f,
type: 3}
m_PrefabInstance: {fileID: 6396198883015021373}
m_PrefabAsset: {fileID: 0}
--- !u!1 &6396895597388085080 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 1559492111098981, guid: dd617d0fc54f62c40ac12ba4ff5ebd9f,
type: 3}
m_PrefabInstance: {fileID: 6396198883015021373}
m_PrefabAsset: {fileID: 0}
--- !u!1 &6397323561931113521 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 1133717971556108, guid: dd617d0fc54f62c40ac12ba4ff5ebd9f,
@@ -1982,8 +2000,13 @@ MonoBehaviour:
moveSpeed: 30
desTime: 10
peng: 7
peng2: 5
explosionPrefab: {fileID: 0}
explosionRadius: 20
killFishOnFinal: 1
state1Fx: {fileID: 6395126940408738618}
state2Fx: {fileID: 6396680948013903050}
state3Fx: {fileID: 6396895597388085080}
wallLayer:
serializedVersion: 2
m_Bits: 256