From a5864cc7e4a0e85af1dcfde8802f98488da43354 Mon Sep 17 00:00:00 2001 From: wuyanchen <307378529@qq.com> Date: Tue, 16 Dec 2025 13:48:26 +0800 Subject: [PATCH] =?UTF-8?q?=C2=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AirPlane/Enemy/Nightingale Binder.prefab | 2 +- .../AirPlane/Enemy/Orca Defender.prefab | 4 +- .../Mine/WingMan/Tackle Veil WingMan.prefab | 8 +- Assets/Game1/Scenes/Game1_Level1.unity | 180 ++++++++- Assets/Game1/Scripts/RingManager.cs | 46 ++- Assets/Scripts/Bullet.cs | 2 +- Assets/Scripts/Shot.cs | 349 ++++++++---------- Assets/Scripts/Tools/AudioTool.cs | 1 - Assets/Scripts/Tools/PoolTool.cs | 9 + 9 files changed, 383 insertions(+), 218 deletions(-) diff --git a/Assets/Game1/Prefabs/AirPlane/Enemy/Nightingale Binder.prefab b/Assets/Game1/Prefabs/AirPlane/Enemy/Nightingale Binder.prefab index b67066b..3e0f3ac 100644 --- a/Assets/Game1/Prefabs/AirPlane/Enemy/Nightingale Binder.prefab +++ b/Assets/Game1/Prefabs/AirPlane/Enemy/Nightingale Binder.prefab @@ -131,7 +131,7 @@ NavMeshAgent: m_GameObject: {fileID: 3945929085796339777} m_Enabled: 1 m_AgentTypeID: 0 - m_Radius: 0.75 + m_Radius: 0.6 m_Speed: 3.5 m_Acceleration: 8 avoidancePriority: 50 diff --git a/Assets/Game1/Prefabs/AirPlane/Enemy/Orca Defender.prefab b/Assets/Game1/Prefabs/AirPlane/Enemy/Orca Defender.prefab index ee3cc08..4ef62b6 100644 --- a/Assets/Game1/Prefabs/AirPlane/Enemy/Orca Defender.prefab +++ b/Assets/Game1/Prefabs/AirPlane/Enemy/Orca Defender.prefab @@ -143,7 +143,7 @@ NavMeshAgent: m_GameObject: {fileID: 9123038881270525164} m_Enabled: 1 m_AgentTypeID: 0 - m_Radius: 0.82 + m_Radius: 0.7 m_Speed: 3.5 m_Acceleration: 8 avoidancePriority: 50 @@ -152,7 +152,7 @@ NavMeshAgent: m_AutoTraverseOffMeshLink: 1 m_AutoBraking: 1 m_AutoRepath: 1 - m_Height: 0.82 + m_Height: 0.7 m_BaseOffset: 2.2626367 m_WalkableMask: 4294967295 m_ObstacleAvoidanceType: 4 diff --git a/Assets/Game1/Prefabs/AirPlane/Mine/WingMan/Tackle Veil WingMan.prefab b/Assets/Game1/Prefabs/AirPlane/Mine/WingMan/Tackle Veil WingMan.prefab index 4ceec14..3dff07f 100644 --- a/Assets/Game1/Prefabs/AirPlane/Mine/WingMan/Tackle Veil WingMan.prefab +++ b/Assets/Game1/Prefabs/AirPlane/Mine/WingMan/Tackle Veil WingMan.prefab @@ -28,7 +28,7 @@ Transform: m_GameObject: {fileID: 366104515495152937} serializedVersion: 2 m_LocalRotation: {x: -0, y: -1, z: -0, w: 0} - m_LocalPosition: {x: 0, y: 0, z: -16.300001} + m_LocalPosition: {x: 0, y: 0, z: -22} m_LocalScale: {x: 1.7142857, y: 1.7142857, z: 1.7142857} m_ConstrainProportionsScale: 0 m_Children: [] @@ -47,10 +47,10 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: ringManager: {fileID: 0} - impact: {fileID: 4541196389373984, guid: b2123df6038fb164faef17d57b22aab8, type: 3} - muzzleFlare: {fileID: 4000010921236120, guid: 6a0a0f7a97e0e7747accda091cb14743, + impact: {fileID: 4541196389373984, guid: af3f3fa832ef8314bb22c5462402c60c, type: 3} + muzzleFlare: {fileID: 4000010921236120, guid: 66ce0f27574363a4dabe7162e2636e3f, type: 3} - bullet: {fileID: 4010437552377404, guid: 3e8f90cf5ace53541b8523ce5200cdc5, type: 3} + bullet: {fileID: 4638688750665566, guid: 1b81ed6643072854688c442ec72032d6, type: 3} continueShotCount: 3 turret: {fileID: 0} gun: {fileID: 0} diff --git a/Assets/Game1/Scenes/Game1_Level1.unity b/Assets/Game1/Scenes/Game1_Level1.unity index 688de5c..9fadd70 100644 --- a/Assets/Game1/Scenes/Game1_Level1.unity +++ b/Assets/Game1/Scenes/Game1_Level1.unity @@ -251,7 +251,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!4 &46038311 Transform: m_ObjectHideFlags: 0 @@ -280,11 +280,11 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: initCount: 2 - radius: 2 + radius: 1.8 splitAngle: 0 isAlwaysForward: 1 qiu: {fileID: 1083892317890881295, guid: 83c0dc6728f2e3a4ab110648310fc920, type: 3} - rotationalSpeed: 1 + rotationalSpeed: 5 --- !u!1 &49123918 GameObject: m_ObjectHideFlags: 0 @@ -1655,6 +1655,29 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 514426894} m_Modifications: + - target: {fileID: 279031484294811146, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: bullet + value: + objectReference: {fileID: 4836675779974994, guid: a2700d7f89910434081c7dc7c92e22ca, + type: 3} + - target: {fileID: 279031484294811146, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: impact + value: + objectReference: {fileID: 4541196389373984, guid: e3f361eacdeb09440850ac7397930cba, + type: 3} + - target: {fileID: 279031484294811146, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: shotSpeed + value: 15 + objectReference: {fileID: 0} + - target: {fileID: 279031484294811146, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: muzzleFlare + value: + objectReference: {fileID: 4000010921236120, guid: 2cc07ac0b88fafc40b730713b6dac672, + type: 3} - target: {fileID: 1083892317890881295, guid: 435ba18295a2b0240b1511cd4d5a7bc3, type: 3} propertyPath: m_LocalPosition.x @@ -1710,15 +1733,136 @@ PrefabInstance: propertyPath: m_Name value: Tackle Veil objectReference: {fileID: 0} + - target: {fileID: 2521485966335614540, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: bullet + value: + objectReference: {fileID: 4836675779974994, guid: a2700d7f89910434081c7dc7c92e22ca, + type: 3} + - target: {fileID: 2521485966335614540, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: impact + value: + objectReference: {fileID: 4541196389373984, guid: e3f361eacdeb09440850ac7397930cba, + type: 3} + - target: {fileID: 2521485966335614540, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: shotSpeed + value: 15 + objectReference: {fileID: 0} + - target: {fileID: 2521485966335614540, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: muzzleFlare + value: + objectReference: {fileID: 4000010921236120, guid: 2cc07ac0b88fafc40b730713b6dac672, + type: 3} + - target: {fileID: 4123303403043117342, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: m_LocalPosition.z + value: -18.7 + objectReference: {fileID: 0} + - target: {fileID: 5445074278298902311, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: bullet + value: + objectReference: {fileID: 4836675779974994, guid: a2700d7f89910434081c7dc7c92e22ca, + type: 3} + - target: {fileID: 5445074278298902311, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: impact + value: + objectReference: {fileID: 4541196389373984, guid: e3f361eacdeb09440850ac7397930cba, + type: 3} + - target: {fileID: 5445074278298902311, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: shotSpeed + value: 15 + objectReference: {fileID: 0} + - target: {fileID: 5445074278298902311, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: muzzleFlare + value: + objectReference: {fileID: 4000010921236120, guid: 2cc07ac0b88fafc40b730713b6dac672, + type: 3} + - target: {fileID: 5684374028056023295, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: bullet + value: + objectReference: {fileID: 4836675779974994, guid: a2700d7f89910434081c7dc7c92e22ca, + type: 3} + - target: {fileID: 5684374028056023295, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: impact + value: + objectReference: {fileID: 4541196389373984, guid: e3f361eacdeb09440850ac7397930cba, + type: 3} + - target: {fileID: 5684374028056023295, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: shotSpeed + value: 15 + objectReference: {fileID: 0} + - target: {fileID: 5684374028056023295, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: muzzleFlare + value: + objectReference: {fileID: 4000010921236120, guid: 2cc07ac0b88fafc40b730713b6dac672, + type: 3} + - target: {fileID: 7381137082989080464, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: m_LocalPosition.z + value: -27.5 + objectReference: {fileID: 0} - target: {fileID: 7552060864384203727, guid: 435ba18295a2b0240b1511cd4d5a7bc3, type: 3} propertyPath: flipAngle value: 35 objectReference: {fileID: 0} + - target: {fileID: 7563879847434839099, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: m_LocalPosition.z + value: -18.7 + objectReference: {fileID: 0} + - target: {fileID: 8294881102992473182, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: m_LocalPosition.z + value: -23 + objectReference: {fileID: 0} + - target: {fileID: 8361625887681834942, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: bullet + value: + objectReference: {fileID: 4836675779974994, guid: a2700d7f89910434081c7dc7c92e22ca, + type: 3} + - target: {fileID: 8361625887681834942, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: impact + value: + objectReference: {fileID: 4541196389373984, guid: e3f361eacdeb09440850ac7397930cba, + type: 3} + - target: {fileID: 8361625887681834942, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: shotSpeed + value: 15 + objectReference: {fileID: 0} + - target: {fileID: 8361625887681834942, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: muzzleFlare + value: + objectReference: {fileID: 4000010921236120, guid: 2cc07ac0b88fafc40b730713b6dac672, + type: 3} + - target: {fileID: 8610239330163254585, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + propertyPath: m_LocalPosition.z + value: -23 + objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] - m_AddedComponents: [] + m_AddedComponents: + - targetCorrespondingSourceObject: {fileID: 1083892317891246895, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + insertIndex: -1 + addedObject: {fileID: 1557737275} m_SourcePrefab: {fileID: 100100000, guid: 435ba18295a2b0240b1511cd4d5a7bc3, type: 3} --- !u!4 &837546816 stripped Transform: @@ -2395,7 +2539,7 @@ RectTransform: m_GameObject: {fileID: 1138813630} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 4.2899303, y: 4.2899303, z: 1} + m_LocalScale: {x: 4.064236, y: 4.064236, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 97192695} @@ -2950,6 +3094,30 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1557737273 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 1083892317891246895, guid: 435ba18295a2b0240b1511cd4d5a7bc3, + type: 3} + m_PrefabInstance: {fileID: 837546815} + m_PrefabAsset: {fileID: 0} +--- !u!114 &1557737275 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1557737273} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 18e44bc2064cb1c46b4422845bd22c3c, type: 3} + m_Name: + m_EditorClassIdentifier: + initCount: 2 + radius: 1.8 + splitAngle: 0 + isAlwaysForward: 1 + qiu: {fileID: 1083892317890881295, guid: 83c0dc6728f2e3a4ab110648310fc920, type: 3} + rotationalSpeed: 2.5 --- !u!1 &1581003589 GameObject: m_ObjectHideFlags: 0 @@ -3496,7 +3664,7 @@ RectTransform: m_GameObject: {fileID: 2083258305} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 4.2899303, y: 4.2899303, z: 1} + m_LocalScale: {x: 4.064236, y: 4.064236, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 97192695} diff --git a/Assets/Game1/Scripts/RingManager.cs b/Assets/Game1/Scripts/RingManager.cs index f30d55f..32e5b0e 100644 --- a/Assets/Game1/Scripts/RingManager.cs +++ b/Assets/Game1/Scripts/RingManager.cs @@ -13,12 +13,17 @@ public class RingManager : MonoBehaviour [Tooltip("是否一直朝前")] public bool isAlwaysForward = true; public Transform qiu; + public float rotationalSpeed = 5f; // 改为角速度(弧度/秒),更直观 // 旋转力大小(可在Inspector面板调整) //public float rotationalForce = 5f; private List qiuList = new List(); - public float rotationalSpeed = 5f; // 改为角速度(弧度/秒),更直观 + + private float beforePositionX = 0; + private float targetRotationalSpeed = 0; + private bool isToLeftRotation = false; + private bool isCanRotation = false; void Awake() { var qiuCollider = qiu.GetComponentInChildren(); @@ -60,6 +65,8 @@ public class RingManager : MonoBehaviour qiuList.Add(qiuInst); } + //targetRotationalSpeed = rotationalSpeed; + beforePositionX = transform.position.x; // 初始施加旋转力 //ApplyRotationalForce(); } @@ -92,10 +99,45 @@ public class RingManager : MonoBehaviour // 可选:在FixedUpdate中持续施加力(会让小球加速旋转) void FixedUpdate() { + isCanRotation = true; + + if (Mathf.Abs(beforePositionX - transform.position.x) < 0.05f) + { + isCanRotation = false; + } + + if (isCanRotation) + { + if (transform.position.x < beforePositionX) + { + isToLeftRotation = true; + } + else + { + isToLeftRotation = false; + } + } + + beforePositionX = transform.position.x; + if (isCanRotation) + { + targetRotationalSpeed = Mathf.Lerp(targetRotationalSpeed, rotationalSpeed, Time.deltaTime * 5); + } + else + { + targetRotationalSpeed = Mathf.Lerp(targetRotationalSpeed, 0, Time.deltaTime * 5); + } // 或逐个旋转小球(如果需要独立控制) foreach (var ball in qiuList) { - ball.RotateAround(transform.position, Vector3.up, rotationalSpeed * Time.deltaTime * Mathf.Rad2Deg); + if (isToLeftRotation) + { + ball.RotateAround(transform.position, Vector3.up, -targetRotationalSpeed * Time.deltaTime * Mathf.Rad2Deg); + } + else + { + ball.RotateAround(transform.position, Vector3.up, targetRotationalSpeed * Time.deltaTime * Mathf.Rad2Deg); + } if (isAlwaysForward) { ball.eulerAngles = Vector3.zero; diff --git a/Assets/Scripts/Bullet.cs b/Assets/Scripts/Bullet.cs index 5e5a512..340284d 100644 --- a/Assets/Scripts/Bullet.cs +++ b/Assets/Scripts/Bullet.cs @@ -214,7 +214,7 @@ namespace Assets.Scripts //{ // return;//绌胯繃 //} - if (hit.collider.gameObject != gameObject && hit.collider.gameObject.GetComponent() != null) + if (hit.collider.gameObject != gameObject && hit.collider.gameObject.GetComponentInParent() != null) { return;//绌胯繃 } diff --git a/Assets/Scripts/Shot.cs b/Assets/Scripts/Shot.cs index eb7307e..83f6652 100644 --- a/Assets/Scripts/Shot.cs +++ b/Assets/Scripts/Shot.cs @@ -1,20 +1,16 @@ using Assets.Scripts; using DG.Tweening; -using DG.Tweening.Core; -using DG.Tweening.Plugins.Options; -using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Data; -using System.Linq; using Unity.VisualScripting; using UnityEngine; using UnityEngine.InputSystem; -using UnityEngine.InputSystem.EnhancedTouch; -using UnityEngine.UIElements; -using static UnityEngine.GraphicsBuffer; + +/// +/// 炮弹,子弹发射类 +/// public class Shot : MonoBehaviour { public RingManager ringManager; @@ -188,6 +184,7 @@ public class Shot : MonoBehaviour // Destroy(muzzle.gameObject); // } //} + // 清空旧数据 this.activeImpactPool.Clear(); this.activeBulletPool.Clear(); @@ -238,10 +235,6 @@ public class Shot : MonoBehaviour this.impactPool.Enqueue(impactObj); //} } - //for (int i = 0; i < _qiuObjects.Length; i++) - //{ - // _qiuObjects[i].impactPrefab = impact; - //} } private void OnDestroy() @@ -271,6 +264,10 @@ public class Shot : MonoBehaviour isShoting = false; } + /// + /// 连续发射炮弹的协程 + /// + /// private IEnumerator ContinueShot() { //float duration = shotDistance / shotSpeed; // 正确的飞行时间计算:距离/速度 @@ -279,7 +276,7 @@ public class Shot : MonoBehaviour { if (isCanShot) { - SingleShot(lockEnemy, false); + SingleShot(GetBullet(), lockEnemy, false); //isCanShot = !isAutoLock; } @@ -287,6 +284,10 @@ public class Shot : MonoBehaviour } } + /// + /// 弹射炮弹的协程 + /// + /// private IEnumerator QueueNextShot() { //float duration = shotDistance / shotSpeed; // 正确的飞行时间计算:距离/速度 @@ -303,11 +304,107 @@ public class Shot : MonoBehaviour } if (nextShotInfos.TryDequeue(out NextShotInfo info)) { - SingleShot(info.LockEnemy, true, info.CurrentShotCount, info.InitBulletPos, info.BulletObj, info.BeforeLockTarget); + SingleShot(info.BulletObj, info.LockEnemy, true, info.CurrentShotCount, info.InitBulletPos, info.BeforeLockTarget); } } } + /// + /// 从炮弹池中会去对象 + /// + /// + private Transform GetBullet() + { + Transform bulletObj = null; + if (bulletObj == null || bulletObj.IsDestroyed()) + { + // 从池中获取对象 + bulletObj = PoolTool.GetFromPool(this.bulletPool, this.activeBulletPool, this.activeImpactPool); + // 激活对象 + bulletObj.gameObject.SetActive(true); + } + return bulletObj; + } + + /// + /// 更新炮弹对象状态 + /// + /// 炮弹对象 + /// 之前集中的目标,可为空 + private void BulletUpdate(Bullet bulletComp, Transform beforeHitTargetTransform) + { + if (isAutoLock) + { + if (bulletComp.LockTarget == null) + { + bulletComp.LockTarget = GetNearestEnemyFromTransform(bulletComp.transform, beforeHitTargetTransform); + //bulletComp.IsLockedTarget = true; + } + } + + // 修正弹体朝向(对准目标,更真实) + if (bulletComp.LockTarget != null && bulletComp.transform != null) + { + bulletComp.ShotTargetPosition = bulletComp.LockTarget.transform.position; + bulletComp.transform.LookAt(bulletComp.ShotTargetPosition); + } + if (CalcBulletBoom(bulletComp)) + { + bulletComp.transform.DOComplete(true); + bulletComp.transform.DOKill(); + } + } + + private void ShotBulletComplete(Bullet bulletComp, int currentShotCount, Transform muzzleObj) + { + bool isBulletHitted = CalcBulletBoom(bulletComp); + + if (bulletComp.HitTarget != null) + { + if (hitAudioClip != null) + { + AudioTool.AudioSource.PlayOneShot(hitAudioClip, 0.5f); + } + + currentShotCount++; + if (currentShotCount <= continueShotCount) + { + PoolTool.RecycleMuzzleToPool(muzzleObj, this.muzzlePool, this.activeImpactPool); + var nextLockTarget = GetNearestEnemyFromTransform(bulletComp.transform, bulletComp.HitTarget == null ? bulletComp.transform : bulletComp.HitTarget.transform); + if (nextLockTarget != null) + { + Vector3 initBulletPos = bulletComp.transform.position; + Transform hitTransform = null; + if (bulletComp.HitTarget != null) + { + hitTransform = bulletComp.HitTarget.transform; + initBulletPos = hitTransform.position; + } + + CheckBulletBoom(isBulletHitted, bulletComp, false); + bulletComp.ResetEnemyTargets(); + + var beforeTarget = bulletComp.BeforeHitTarget; + PoolTool.RecycleBulletToPool(bulletComp.transform, this.bulletPool, this.activeBulletPool); + SingleShot(GetBullet(), nextLockTarget, true, currentShotCount, initBulletPos, beforeTarget);//连线射击 + //nextShotInfos.Enqueue(new NextShotInfo { CurrentShotCount = currentShotCount, LockEnemy = nextLockTarget, InitBulletPos = initBulletPos, BulletObj = null, BeforeLockTarget = bulletComp.BeforeHitTarget }); + } + else + { + CheckBulletBoom(isBulletHitted, bulletComp); + } + } + else + { + CheckBulletBoom(isBulletHitted, bulletComp); + } + } + else + { + CheckBulletBoom(isBulletHitted, bulletComp); + } + } + /// /// 单次发射方法 /// @@ -315,34 +412,24 @@ public class Shot : MonoBehaviour /// 是否弹射 /// /// - private void SingleShot(Enemy lockEnemy, bool isNextLineShot, int currentShotCount = 0, Vector3? initBulletPos = null, Transform bulletObj = null, Enemy beforeLockTarget = null) + private void SingleShot(Transform bulletObj, Enemy lockEnemy, bool isNextLineShot, int currentShotCount = 0, Vector3? initBulletPos = null, Enemy beforeLockTarget = null) { - //Debug.Log(currentShotCount + ":" + initBulletPos); Transform muzzleObj = null; - if (bulletObj == null || bulletObj.IsDestroyed()) + if (isShowMuzzle && !isNextLineShot) { - // 从池中获取对象(确保线程安全) - bulletObj = PoolTool.GetFromPool(this.bulletPool, this.activeBulletPool, this.activeImpactPool); - if (isShowMuzzle && !isNextLineShot) - { - muzzleObj = PoolTool.GetFromPool(this.muzzlePool, this.activeBulletPool, this.activeImpactPool); - } + muzzleObj = PoolTool.GetFromPool(this.muzzlePool, this.activeBulletPool, this.activeImpactPool); } - if (bulletObj != null) { - //// 1. 强制重置所有状态 - //PoolTool.ResetTransform(bulletObj); - // 10. 播放音效 + // 1. 播放音效 if (!isNextLineShot && shotAudioClip != null) { - AudioTool.AudioSource.PlayOneShot(shotAudioClip); + AudioTool.AudioSource.PlayOneShot(shotAudioClip, 0.5f); } - //PoolTool.ResetTransform(muzzleObj); - // 2. 计算发射位置(确保使用世界坐标) Vector3 firePos = gun.position + gun.forward * shotOffsetZMul; + // 3. 设置初始位置(强制世界坐标) if (initBulletPos == null) { @@ -353,24 +440,19 @@ public class Shot : MonoBehaviour bulletObj.position = initBulletPos.Value; } - // 6. 激活对象 - bulletObj.gameObject.SetActive(true); - // 5. 计算目标位置(沿Y轴正方向) - //Vector3 targetPos = Vector3.zero;// new Vector3(firePos.x, firePos.y + shotDistance, 0); - // //targetPos.z = 0; - - // 7. 获取子弹组件并重置状态 + // 4. 获取子弹组件并重置状态 var bulletComp = bulletObj.GetComponent(); bulletComp.BeforeHitTarget = beforeLockTarget; bulletComp.IsAutoLock = isAutoLock; bulletComp.IsShoting = true; var beforeHitTargetTransform = bulletComp.BeforeHitTarget == null ? null : bulletComp.BeforeHitTarget.transform; + + // 5. 设置炮弹发射方向 if (isNextLineShot) { bulletComp.LockTarget = GetNearestEnemyFromTransform(bulletObj, beforeHitTargetTransform); if (bulletComp.LockTarget != null) { - //Debug.Log((bulletComp.BeforeHitTarget == null ? null : bulletComp.BeforeHitTarget.name) + ":" + bulletComp.LockTarget.name); bulletComp.ShotTargetPosition = bulletComp.LockTarget.transform.position; } else @@ -391,33 +473,30 @@ public class Shot : MonoBehaviour pos.y = gun.position.y; bulletComp.ShotTargetPosition = pos; } - //var tmpTargetPos = bulletComp.ShotTargetPosition; - //bulletObj.LookAt(bulletComp.ShotTargetPosition); + + // 6. 设置炮弹角度 bulletObj.transform.eulerAngles = Vector3.zero; - + // 7. 击中爆炸效果对象不为空,则设置相关参数 if (muzzleObj != null) { + //设置炮口火焰父对象(可选) muzzleObj.position = firePos; - // 4. 设置枪口火焰父对象(可选) muzzleObj.SetParent(gun); muzzleObj.gameObject.SetActive(true); muzzleObj.transform.LookAt(bulletComp.ShotTargetPosition); } - - //每次创建前 Kill 旧 Tween - //bulletComp.Tweener?.Kill(false); - //var worldTop = _cam.ScreenToWorldPoint(new Vector3(0, Screen.height, _cam.nearClipPlane)); - //var yDistance = worldTop.z - transform.position.z; - //float shotDuration = 1f / shotSpeed; - // DOTween.To:动态更新弹体位置(每帧计算目标位置) - bulletComp.Tweener = DOTween.To( + // 8. 延迟一帧,等待下一帧状态更新后,开始炮弹动画和相关逻辑执行 + DOVirtual.DelayedCall(Time.deltaTime, () => + { + bulletComp.Tweener = DOTween.To( () => { return bulletObj == null ? transform.position : bulletObj.position; // 当前位置(Getter) - }, (Vector3 pos) => + }, + (Vector3 pos) => { if (bulletObj != null) { @@ -426,140 +505,31 @@ public class Shot : MonoBehaviour }, bulletComp.ShotTargetPosition,//目标位置 shotSpeed - ) - .SetSpeedBased() - .SetEase(Ease.Linear) - //.OnPlay(() => - //{ - // Debug.Log("Play"); - //}) - .OnUpdate(() => - { - //// 每帧修正朝向(对准目标) - //if (lockTarget != null) - //{ - // targetPos = lockTarget.transform.position; - //} - //bulletObj.transform.LookAt(targetPos);//跟踪导弹用 - //if (bulletObj == null || bulletObj.IsDestroyed()) - //{ - // return; - //} - - //if (bulletComp.IsLockedTarget) - //{ - // if (bulletComp.LockTarget == null) - // { - // bulletObj.DOKill(true); - // return; - // } - //} - - - if (isAutoLock) + ) + .SetSpeedBased() + .SetEase(Ease.Linear) + .OnUpdate(() => { - if (bulletComp.LockTarget == null) + //每帧更新炮弹状态参数 + BulletUpdate(bulletComp, beforeHitTargetTransform); + }) + .OnComplete(() => + { + //动画完成处理(超出视距范围外,或者击中爆炸) + ShotBulletComplete(bulletComp, currentShotCount, muzzleObj); + }); + + // 9. 爆炸火焰自动隐藏(0.2秒后) + DOVirtual.DelayedCall(0.2f, () => + { + if (muzzleObj != null) { - bulletComp.LockTarget = GetNearestEnemyFromTransform(bulletObj, beforeHitTargetTransform); - //bulletComp.IsLockedTarget = true; - } - } - - // 修正弹体朝向(对准目标,更真实) - if (bulletComp.LockTarget != null && bulletObj != null) - { - //var targetDir = (bulletComp.LockTarget.transform.position - bulletObj.transform.position).normalized; - bulletComp.ShotTargetPosition = bulletComp.LockTarget.transform.position; - bulletObj.LookAt(bulletComp.ShotTargetPosition); - //bulletObj.forward = Vector3.Lerp( - // bulletObj.forward, - // targetDir, - // Time.deltaTime * lerpSpeed // 转向灵敏度 - //); - } - //if (isNextLineShot) - //{ - //非自动锁定状态,在轨迹更新过程中也判断是否击中 - - if (CalcBulletBoom(bulletComp)) - { - bulletObj.DOComplete(true); - bulletObj.DOKill(); - } - - //} - }) - .OnComplete(() => - { - bool isBulletHitted = CalcBulletBoom(bulletComp); - - if (bulletComp.HitTarget != null) - { - if (hitAudioClip != null) - { - AudioTool.AudioSource.PlayOneShot(hitAudioClip); - } - - currentShotCount++; - if (currentShotCount <= continueShotCount) - { - //bulletComp.currentShotCount = currentShotCount; - PoolTool.RecycleMuzzleToPool(muzzleObj, this.muzzlePool, this.activeImpactPool); - var nextLockTarget = GetNearestEnemyFromTransform(bulletObj, bulletComp.HitTarget == null ? bulletObj : bulletComp.HitTarget.transform); - if (nextLockTarget != null) - { - Vector3 initBulletPos = bulletObj.position; - Transform hitTransform = null; - if (bulletComp.HitTarget != null) - { - hitTransform = bulletComp.HitTarget.transform; - initBulletPos = hitTransform.position; - } - - CheckBulletBoom(isBulletHitted, bulletComp, false); - bulletComp.ResetEnemyTargets(); - - var beforeTarget = bulletComp.BeforeHitTarget; - PoolTool.RecycleBulletToPool(bulletObj, this.bulletPool, this.activeBulletPool); - SingleShot(nextLockTarget, true, currentShotCount, initBulletPos, null, beforeTarget);//连线射击 - //nextShotInfos.Enqueue(new NextShotInfo { CurrentShotCount = currentShotCount, LockEnemy = nextLockTarget, InitBulletPos = initBulletPos, BulletObj = null, BeforeLockTarget = bulletComp.BeforeHitTarget }); - - - } - else - { - CheckBulletBoom(isBulletHitted, bulletComp); - } } - else - { - CheckBulletBoom(isBulletHitted, bulletComp); - } - } - else - { - CheckBulletBoom(isBulletHitted, bulletComp); - } - //if (currentShotCount > 0) - //{ - // Debug.Log(currentShotCount); - //} - }); + }); - // 9. 爆炸火焰自动隐藏(0.2秒后) - DOVirtual.DelayedCall(0.2f, () => - { - if (muzzleObj != null) - { - PoolTool.RecycleMuzzleToPool(muzzleObj, this.muzzlePool, this.activeImpactPool); - } }); } - //else - //{ - // Debug.Log("No Bullet"); - //} } private void CheckBulletBoom(bool isBulletHitted, Bullet bulletComp, bool recycleToPool = true) @@ -674,13 +644,6 @@ public class Shot : MonoBehaviour { if (lockEnemy == null || lockEnemy.IsDestroyed()) { - //if (lockEnemy != null) - //{ - // Debug.Log("aa:" + lockEnemy.GetHashCode()); - // Global.LockedEnemies.Remove(lockEnemy.GetHashCode()); - // lockEnemy = null; - // Debug.Log("cc:" + Global.LockedEnemies.Count); - //} isStartAttack = false; lockEnemy = GetNearestEnemyFromTransform(transform); } @@ -711,10 +674,6 @@ public class Shot : MonoBehaviour } } } - //if (result == null) - //{ - // result = Global.Enemies.FirstOrDefault(m => !m.IsDestroyed()); - //} return result; } @@ -740,7 +699,6 @@ public class Shot : MonoBehaviour Vector3 enemyPos = lockEnemy.transform.position; turretLerpEuler.Set(turret.eulerAngles.x, turret.eulerAngles.y, turret.eulerAngles.z); speed = this.lerpSpeed; - //turret.LookAt(enemyPos); // 1. 计算炮塔到敌人的方向向量(仅考虑水平平面,忽略y轴高度差) @@ -753,17 +711,6 @@ public class Shot : MonoBehaviour // 3. 赋值给turretLerpEuler的y轴 turretLerpEuler.y = targetYAngle; turretLerpEuler.y = CalcTool.FixEulerAngle(turretLerpEuler.y, turret.eulerAngles.y); - - //turretLerpEuler = new Vector3(turretBeforeEuler.x + shotFixAngleX, CalcTool.FixEulerAngle(tu - - //if (!isCanShot) - //{ - // isCanShot = Vector3.Distance(turret.eulerAngles, turretLerpEuler) < 3f; - // if (isCanShot) - // { - // isStartAttack = true; - // } - //} } turret.eulerAngles = Vector3.Lerp(turret.eulerAngles, turretLerpEuler, Time.deltaTime * speed); } diff --git a/Assets/Scripts/Tools/AudioTool.cs b/Assets/Scripts/Tools/AudioTool.cs index c96a7d5..62c2c42 100644 --- a/Assets/Scripts/Tools/AudioTool.cs +++ b/Assets/Scripts/Tools/AudioTool.cs @@ -17,7 +17,6 @@ public class AudioTool { var audioGameObject = new GameObject("GlobalAudioSource"); _audioSource = audioGameObject.AddComponent(); - _audioSource.volume = 0.2f; Object.DontDestroyOnLoad(audioGameObject); } return _audioSource; diff --git a/Assets/Scripts/Tools/PoolTool.cs b/Assets/Scripts/Tools/PoolTool.cs index e355b73..d6cdcdb 100644 --- a/Assets/Scripts/Tools/PoolTool.cs +++ b/Assets/Scripts/Tools/PoolTool.cs @@ -32,6 +32,15 @@ public class PoolTool { activeImpactPool.Add(obj); } + //var particles = obj.GetComponentsInChildren(); + //foreach (var particle in particles) + //{ + // if (particle != null) + // { + // particle.time = 0; + // particle.Play(); + // } + //} return obj; }