This commit is contained in:
wuyanchen 2025-12-14 14:25:11 +08:00
parent 9ca2acac10
commit e88caba51f
7 changed files with 108 additions and 124 deletions

View File

@ -345,7 +345,7 @@ MonoBehaviour:
m_EditorClassIdentifier: m_EditorClassIdentifier:
minHealthPercent: 50 minHealthPercent: 50
maxHealthPercent: 100 maxHealthPercent: 100
health: 150 health: 200
boomClip: {fileID: 0} boomClip: {fileID: 0}
addEulerX: 0 addEulerX: 0
randomColors: randomColors:

View File

@ -643,7 +643,7 @@ MonoBehaviour:
muzzleFlare: {fileID: 4000010921236120, guid: 6a0a0f7a97e0e7747accda091cb14743, muzzleFlare: {fileID: 4000010921236120, guid: 6a0a0f7a97e0e7747accda091cb14743,
type: 3} type: 3}
bullet: {fileID: 4010437552377404, guid: 3e8f90cf5ace53541b8523ce5200cdc5, type: 3} bullet: {fileID: 4010437552377404, guid: 3e8f90cf5ace53541b8523ce5200cdc5, type: 3}
continueShotCount: 0 continueShotCount: 3
turret: {fileID: 1898544591301130533} turret: {fileID: 1898544591301130533}
gun: {fileID: 5342608149001152939} gun: {fileID: 5342608149001152939}
shotAudioClip: {fileID: 8300000, guid: 038911361e37ae84b8fdc585b7b83895, type: 3} shotAudioClip: {fileID: 8300000, guid: 038911361e37ae84b8fdc585b7b83895, type: 3}

View File

@ -844,7 +844,7 @@ Camera:
width: 1 width: 1
height: 1 height: 1
near clip plane: 0.3 near clip plane: 0.3
far clip plane: 1000 far clip plane: 120
field of view: 70 field of view: 70
orthographic: 1 orthographic: 1
orthographic size: 7 orthographic size: 7
@ -1655,11 +1655,11 @@ MonoBehaviour:
shotDuration: 0.35 shotDuration: 0.35
shotNextDuration: 0.1 shotNextDuration: 0.1
shotDistance: 18 shotDistance: 18
shotSpeed: 15 shotSpeed: 12
initBulletCount: 100 initBulletCount: 10
shotOffsetZMul: 0 shotOffsetZMul: 0
shotFixAngleX: 0 shotFixAngleX: 0
lerpSpeed: 10 lerpSpeed: 8
isAutoLock: 0 isAutoLock: 0
pressAction: {fileID: 76562581802851548, guid: 50486e0197319e948b872b25ef15b507, pressAction: {fileID: 76562581802851548, guid: 50486e0197319e948b872b25ef15b507,
type: 3} type: 3}
@ -2333,11 +2333,11 @@ MonoBehaviour:
shotDuration: 0.35 shotDuration: 0.35
shotNextDuration: 0.1 shotNextDuration: 0.1
shotDistance: 18 shotDistance: 18
shotSpeed: 15 shotSpeed: 12
initBulletCount: 100 initBulletCount: 10
shotOffsetZMul: 0 shotOffsetZMul: 0
shotFixAngleX: 0 shotFixAngleX: 0
lerpSpeed: 10 lerpSpeed: 8
isAutoLock: 0 isAutoLock: 0
pressAction: {fileID: 76562581802851548, guid: 50486e0197319e948b872b25ef15b507, pressAction: {fileID: 76562581802851548, guid: 50486e0197319e948b872b25ef15b507,
type: 3} type: 3}
@ -2422,7 +2422,7 @@ RectTransform:
m_GameObject: {fileID: 1138813630} m_GameObject: {fileID: 1138813630}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 3.8472223, y: 3.8472223, z: 1} m_LocalScale: {x: 4.2899303, y: 4.2899303, z: 1}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: [] m_Children: []
m_Father: {fileID: 97192695} m_Father: {fileID: 97192695}
@ -3235,8 +3235,8 @@ MonoBehaviour:
shotDuration: 0.35 shotDuration: 0.35
shotNextDuration: 0.1 shotNextDuration: 0.1
shotDistance: 18 shotDistance: 18
shotSpeed: 15 shotSpeed: 12
initBulletCount: 100 initBulletCount: 10
shotOffsetZMul: 0 shotOffsetZMul: 0
shotFixAngleX: 0 shotFixAngleX: 0
lerpSpeed: 8 lerpSpeed: 8
@ -3456,8 +3456,8 @@ MonoBehaviour:
shotDuration: 0.35 shotDuration: 0.35
shotNextDuration: 0.1 shotNextDuration: 0.1
shotDistance: 18 shotDistance: 18
shotSpeed: 15 shotSpeed: 12
initBulletCount: 100 initBulletCount: 10
shotOffsetZMul: 0 shotOffsetZMul: 0
shotFixAngleX: 0 shotFixAngleX: 0
lerpSpeed: 8 lerpSpeed: 8
@ -3796,8 +3796,8 @@ MonoBehaviour:
shotDuration: 0.35 shotDuration: 0.35
shotNextDuration: 0.1 shotNextDuration: 0.1
shotDistance: 18 shotDistance: 18
shotSpeed: 15 shotSpeed: 12
initBulletCount: 100 initBulletCount: 10
shotOffsetZMul: 0 shotOffsetZMul: 0
shotFixAngleX: 0 shotFixAngleX: 0
lerpSpeed: 8 lerpSpeed: 8
@ -3833,7 +3833,7 @@ RectTransform:
m_GameObject: {fileID: 2083258305} m_GameObject: {fileID: 2083258305}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 3.8472223, y: 3.8472223, z: 1} m_LocalScale: {x: 4.2899303, y: 4.2899303, z: 1}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: [] m_Children: []
m_Father: {fileID: 97192695} m_Father: {fileID: 97192695}

View File

@ -366,6 +366,7 @@ namespace Assets.Scripts
BeforeHitTarget = null; BeforeHitTarget = null;
_shotTargetPosition = Vector3.zero; _shotTargetPosition = Vector3.zero;
transform.localPosition = new Vector3(-100, -100, -100);
//currentShotCount = 0; //currentShotCount = 0;
//if (isDestroyLimit) //if (isDestroyLimit)
//{ //{

View File

@ -67,7 +67,7 @@ public class Shot : MonoBehaviour
private Vector3 turretLerpEuler = Vector3.zero; private Vector3 turretLerpEuler = Vector3.zero;
private float smoothXAngle = 0f; private float smoothXAngle = 0f;
private float targetXAngle = 0f; private float targetXAngle = 0f;
private float hitDistance = 0.3f; // 命中检测距离阈值 private float hitDistance = 0.1f; // 命中检测距离阈值
private bool isCanShot = false; private bool isCanShot = false;
private bool isStartAttack = false; private bool isStartAttack = false;
private ConcurrentQueue<NextShotInfo> nextShotInfos = new(); private ConcurrentQueue<NextShotInfo> nextShotInfos = new();
@ -76,9 +76,9 @@ public class Shot : MonoBehaviour
// 弹仓List避免重复分配对象 // 弹仓List避免重复分配对象
private List<Transform> bulletPool = new(); private ConcurrentQueue<Transform> bulletPool = new();
private List<Transform> muzzlePool = new(); private ConcurrentQueue<Transform> muzzlePool = new();
private List<Transform> impactPool = new(); private ConcurrentQueue<Transform> impactPool = new();
private List<Transform> activeBulletPool = new(); private List<Transform> activeBulletPool = new();
private List<Transform> activeImpactPool = new(); private List<Transform> activeImpactPool = new();
@ -213,25 +213,25 @@ public class Shot : MonoBehaviour
bulletObj.gameObject.SetActive(false); bulletObj.gameObject.SetActive(false);
bulletObj.SetParent(null); // 强制设为世界对象 bulletObj.SetParent(null); // 强制设为世界对象
bulletObj.name = $"Bullet_{i}"; bulletObj.name = $"Bullet_{i}";
this.bulletPool.Add(bulletObj); this.bulletPool.Enqueue(bulletObj);
// 枪口火焰对象 // 枪口火焰对象
var muzzleObj = Instantiate(muzzleFlare); var muzzleObj = Instantiate(muzzleFlare);
muzzleObj.gameObject.SetActive(false); muzzleObj.gameObject.SetActive(false);
muzzleObj.SetParent(null); muzzleObj.SetParent(null);
muzzleObj.name = $"Muzzle_{i}"; muzzleObj.name = $"Muzzle_{i}";
this.muzzlePool.Add(muzzleObj); this.muzzlePool.Enqueue(muzzleObj);
for (int j = 0; j < Mathf.Max(1, continueShotCount / 3); j++) //for (int j = 0; j < Mathf.Max(1, continueShotCount / 3); j++)
{ //{
// 爆炸火焰对象 // 爆炸火焰对象
var impactObj = Instantiate(impact); var impactObj = Instantiate(impact);
impactObj.gameObject.SetActive(false); impactObj.gameObject.SetActive(false);
impactObj.SetParent(null); impactObj.SetParent(null);
impactObj.name = $"Impact_{i}"; impactObj.name = $"Impact_{i}";
impactObj.GetComponent<RecycleImpact>().RecycleAction = this.RecycleImpactToPool; impactObj.GetComponent<RecycleImpact>().RecycleAction = this.RecycleImpactToPool;
this.impactPool.Add(impactObj); this.impactPool.Enqueue(impactObj);
} //}
} }
//for (int i = 0; i < _qiuObjects.Length; i++) //for (int i = 0; i < _qiuObjects.Length; i++)
//{ //{
@ -326,10 +326,8 @@ public class Shot : MonoBehaviour
if (bulletObj != null) if (bulletObj != null)
{ {
// 1. 强制重置所有状态 //// 1. 强制重置所有状态
PoolTool.ResetTransform(bulletObj); //PoolTool.ResetTransform(bulletObj);
// 6. 激活对象
bulletObj.gameObject.SetActive(true);
// 10. 播放音效 // 10. 播放音效
if (!isNextLineShot && shotAudioClip != null) if (!isNextLineShot && shotAudioClip != null)
{ {
@ -343,13 +341,15 @@ public class Shot : MonoBehaviour
// 3. 设置初始位置(强制世界坐标) // 3. 设置初始位置(强制世界坐标)
if (initBulletPos == null) if (initBulletPos == null)
{ {
bulletObj.position = new Vector3(transform.position.x, gun.position.y, transform.position.z); bulletObj.position = gun.position;
} }
else else
{ {
bulletObj.position = initBulletPos.Value; bulletObj.position = initBulletPos.Value;
} }
// 6. 激活对象
bulletObj.gameObject.SetActive(true);
// 5. 计算目标位置沿Y轴正方向 // 5. 计算目标位置沿Y轴正方向
//Vector3 targetPos = Vector3.zero;// new Vector3(firePos.x, firePos.y + shotDistance, 0); //Vector3 targetPos = Vector3.zero;// new Vector3(firePos.x, firePos.y + shotDistance, 0);
// //targetPos.z = 0; // //targetPos.z = 0;
@ -515,10 +515,11 @@ public class Shot : MonoBehaviour
CheckBulletBoom(isBulletHitted, bulletComp, false); CheckBulletBoom(isBulletHitted, bulletComp, false);
bulletComp.ResetEnemyTargets(); bulletComp.ResetEnemyTargets();
SingleShot(nextLockTarget, true, currentShotCount, initBulletPos, null, bulletComp.BeforeHitTarget);//连线射击 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 }); //nextShotInfos.Enqueue(new NextShotInfo { CurrentShotCount = currentShotCount, LockEnemy = nextLockTarget, InitBulletPos = initBulletPos, BulletObj = null, BeforeLockTarget = bulletComp.BeforeHitTarget });
PoolTool.RecycleBulletToPool(bulletObj, this.bulletPool, this.activeBulletPool);
} }
else else
@ -540,52 +541,20 @@ public class Shot : MonoBehaviour
// Debug.Log(currentShotCount); // Debug.Log(currentShotCount);
//} //}
}); });
//// 8. 子弹飞行(使用线性缓动,强制世界坐标)
//yield return bulletObj.DOMove(targetPos, shotSpeed)
// .SetEase(Ease.Linear)
// .OnUpdate(() =>
// {
// if (lockEnemy != null)
// {
// targetPos = lockEnemy.transform.position;
// }
// bulletObj.transform.LookAt(targetPos);//跟踪导弹用
// bulletObj.transform.eulerAngles = euler;
// })
// .SetSpeedBased()
// .OnPlay(() =>
// {
// //0.1秒后)设置 子弹组件状态为发射中
// DOVirtual.DelayedCall(Time.deltaTime, () =>
// {
// if (bulletComp != null)
// {
// bulletComp.isShoting = true;
// }
// });
// })
// //.SetUpdate(true) // 忽略Time.timeScale影响
// .OnComplete(() =>
// {
// // 重置子弹组件状态
// if (bulletComp != null)
// {
// bulletComp.isShoting = false;
// }
// // 回收对象
// RecycleToPool(bulletObj, bulletPool, activeBullets);
// RecycleToPool(muzzleObj, muzzlePool, activeMuzzles);
// });
//// 9. 枪口火焰自动隐藏0.2秒后) // 9. 爆炸火焰自动隐藏0.2秒后)
//DOVirtual.DelayedCall(0.2f, () => DOVirtual.DelayedCall(0.2f, () =>
//{ {
// if (muzzleObj != null) if (muzzleObj != null)
// { {
// RecycleToPool(muzzleObj, muzzlePool, activeMuzzles); PoolTool.RecycleMuzzleToPool(muzzleObj, this.muzzlePool, this.activeImpactPool);
// } }
//}); });
} }
//else
//{
// Debug.Log("No Bullet");
//}
} }
private void CheckBulletBoom(bool isBulletHitted, Bullet bulletComp, bool recycleToPool = true) private void CheckBulletBoom(bool isBulletHitted, Bullet bulletComp, bool recycleToPool = true)
@ -640,22 +609,22 @@ public class Shot : MonoBehaviour
//在摄像机看到的屏幕范围之外,销毁子弹 //在摄像机看到的屏幕范围之外,销毁子弹
isBulletHitted = !VisibilityTool.IsObjectInFrustum(bulletComp.gameObject, _cam); isBulletHitted = !VisibilityTool.IsObjectInFrustum(bulletComp.gameObject, _cam);
} }
if (!isBulletHitted && bulletComp.LockTarget != null) //if (!isBulletHitted && bulletComp.LockTarget != null)
{ //{
if (bulletComp.LockTarget != bulletComp.BeforeHitTarget) // if (bulletComp.LockTarget != bulletComp.BeforeHitTarget)
{ // {
float currentDistance = Vector3.Distance(bulletComp.transform.position, bulletComp.LockTarget.transform.position); // float currentDistance = Vector3.Distance(bulletComp.transform.position, bulletComp.LockTarget.transform.position);
if (currentDistance < hitDistance) // if (currentDistance < hitDistance)
{ // {
isBulletHitted = true; // isBulletHitted = true;
bulletComp.currentHitPosition = bulletComp.LockTarget.transform.position; // bulletComp.currentHitPosition = bulletComp.LockTarget.transform.position;
bulletComp.HitTarget = bulletComp.LockTarget; // bulletComp.HitTarget = bulletComp.LockTarget;
bulletComp.BeforeHitTarget = bulletComp.HitTarget; // bulletComp.BeforeHitTarget = bulletComp.HitTarget;
bulletComp.IsShoting = false; // bulletComp.IsShoting = false;
} // }
} // }
} //}
//if (isDestroyed) //if (isDestroyed)
//{ //{
// bulletComp.Tweener.Kill(true); // bulletComp.Tweener.Kill(true);

View File

@ -12,34 +12,37 @@ public class PoolTool
// 从池中获取对象 // 从池中获取对象
public static Transform GetFromPool(List<Transform> pool, List<Transform> activeBulletPool, List<Transform> activeImpactPool) public static Transform GetFromPool(ConcurrentQueue<Transform> pool, List<Transform> activeBulletPool, List<Transform> activeImpactPool)
{ {
//lock (pool) // 线程安全锁 //lock (pool) // 线程安全锁
//{ //{
//while (pool.Count > 0) //while (pool.Count > 0)
//{ //{
Transform obj = pool.Where(o => !o.gameObject.activeSelf).FirstOrDefault(); if (pool.TryDequeue(out Transform obj))
if (obj != null)
{ {
pool.Remove(obj); if (obj != null)
ResetTransform(obj); // »ñÈ¡Ê±ÖØÖÃ״̬
if (obj.GetComponent<Bullet>() != null)
{ {
activeBulletPool.Add(obj); //pool.Remove(obj);
ResetTransform(obj); // »ñÈ¡Ê±ÖØÖÃ״̬
if (obj.GetComponent<Bullet>() != null)
{
activeBulletPool.Add(obj);
}
else if (obj.GetComponent<RecycleImpact>() != null)
{
activeImpactPool.Add(obj);
}
return obj;
} }
else if (obj.GetComponent<RecycleImpact>() != null)
{ }//.Where(o => !o.gameObject.activeSelf).FirstOrDefault();
activeImpactPool.Add(obj);
}
return obj;
}
//} //}
//} //}
return null; return null;
} }
// 回收对象到池 // 回收对象到池
public static void RecycleToPool(Transform obj, List<Transform> pool) public static void RecycleToPool(Transform obj, ConcurrentQueue<Transform> pool)
{ {
if (obj == null) return; if (obj == null) return;
// 避免重复入队 // 避免重复入队
@ -47,7 +50,7 @@ public class PoolTool
{ {
// 回收时彻底重置 // 回收时彻底重置
ResetTransform(obj); ResetTransform(obj);
pool.Add(obj); pool.Enqueue(obj);
} }
} }
@ -68,7 +71,7 @@ public class PoolTool
// 命中目标后的逻辑(可自定义爆炸、伤害等) // 命中目标后的逻辑(可自定义爆炸、伤害等)
public static void RecycleTarget(Transform bulletObj, Transform muzzleObj, public static void RecycleTarget(Transform bulletObj, Transform muzzleObj,
List<Transform> bulletPool, List<Transform> activeBulletPool, List<Transform> muzzlePool, List<Transform> activeImpactPool) ConcurrentQueue<Transform> bulletPool, List<Transform> activeBulletPool, ConcurrentQueue<Transform> muzzlePool, List<Transform> activeImpactPool)
{ {
if (bulletObj != null) if (bulletObj != null)
{ {
@ -93,7 +96,7 @@ public class PoolTool
RecycleMuzzleToPool(muzzleObj, muzzlePool, activeImpactPool); RecycleMuzzleToPool(muzzleObj, muzzlePool, activeImpactPool);
} }
public static void RecycleBulletToPool(Transform bulletObj, List<Transform> bulletPool, List<Transform> activeBulletPool) public static void RecycleBulletToPool(Transform bulletObj, ConcurrentQueue<Transform> bulletPool, List<Transform> activeBulletPool)
{ {
if (bulletObj != null) if (bulletObj != null)
{ {
@ -118,14 +121,14 @@ public class PoolTool
} }
} }
public static void RecycleMuzzleToPool(Transform muzzleObj, List<Transform> muzzlePool, List<Transform> activeImpactPool) public static void RecycleMuzzleToPool(Transform muzzleObj, ConcurrentQueue<Transform> muzzlePool, List<Transform> activeImpactPool)
{ {
activeImpactPool.Remove(muzzleObj); activeImpactPool.Remove(muzzleObj);
// 回收对象 // 回收对象
RecycleToPool(muzzleObj, muzzlePool); RecycleToPool(muzzleObj, muzzlePool);
} }
public static void RecycleImpactToPool(Transform impactObj, List<Transform> impactPool) public static void RecycleImpactToPool(Transform impactObj, ConcurrentQueue<Transform> impactPool)
{ {
// 回收对象 // 回收对象
RecycleToPool(impactObj, impactPool); RecycleToPool(impactObj, impactPool);

View File

@ -1,6 +1,7 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements;
public class VisibilityTool public class VisibilityTool
{ {
@ -14,12 +15,22 @@ public class VisibilityTool
{ {
if (obj == null || camera == null) return false; if (obj == null || camera == null) return false;
Renderer renderer = obj.GetComponent<Renderer>(); //Renderer renderer = obj.GetComponent<Renderer>();
if (renderer == null) return false; // 没有Renderer则无法获取包围盒 //if (renderer == null) return false; // 没有Renderer则无法获取包围盒
// 获取相机的视锥体平面数组 Vector3 viewportPos = camera.WorldToViewportPoint(obj.transform.position);
Plane[] frustumPlanes = GeometryUtility.CalculateFrustumPlanes(camera); bool isVisible = viewportPos.x >= 0 && viewportPos.x <= 1 &&
// 检测包围盒是否在视锥体内 viewportPos.y >= 0 && viewportPos.y <= 1 &&
return GeometryUtility.TestPlanesAABB(frustumPlanes, renderer.bounds); viewportPos.z > 0;
return isVisible;
//var extents = renderer.bounds.extents;
//if (extents.x < 0.001 && extents.y < 0.001 && extents.z < 0.001)
//{
// renderer.bounds = new Bounds(renderer.bounds.center, Vector3.one);
//}
//// 获取相机的视锥体平面数组
//Plane[] frustumPlanes = GeometryUtility.CalculateFrustumPlanes(camera);
//// 检测包围盒是否在视锥体内
//return GeometryUtility.TestPlanesAABB(frustumPlanes, renderer.bounds);
} }
} }