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:
minHealthPercent: 50
maxHealthPercent: 100
health: 150
health: 200
boomClip: {fileID: 0}
addEulerX: 0
randomColors:

View File

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

View File

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

View File

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

View File

@ -67,7 +67,7 @@ public class Shot : MonoBehaviour
private Vector3 turretLerpEuler = Vector3.zero;
private float smoothXAngle = 0f;
private float targetXAngle = 0f;
private float hitDistance = 0.3f; // 命中检测距离阈值
private float hitDistance = 0.1f; // 命中检测距离阈值
private bool isCanShot = false;
private bool isStartAttack = false;
private ConcurrentQueue<NextShotInfo> nextShotInfos = new();
@ -76,9 +76,9 @@ public class Shot : MonoBehaviour
// 弹仓List避免重复分配对象
private List<Transform> bulletPool = new();
private List<Transform> muzzlePool = new();
private List<Transform> impactPool = new();
private ConcurrentQueue<Transform> bulletPool = new();
private ConcurrentQueue<Transform> muzzlePool = new();
private ConcurrentQueue<Transform> impactPool = new();
private List<Transform> activeBulletPool = new();
private List<Transform> activeImpactPool = new();
@ -213,25 +213,25 @@ public class Shot : MonoBehaviour
bulletObj.gameObject.SetActive(false);
bulletObj.SetParent(null); // 强制设为世界对象
bulletObj.name = $"Bullet_{i}";
this.bulletPool.Add(bulletObj);
this.bulletPool.Enqueue(bulletObj);
// 枪口火焰对象
var muzzleObj = Instantiate(muzzleFlare);
muzzleObj.gameObject.SetActive(false);
muzzleObj.SetParent(null);
muzzleObj.name = $"Muzzle_{i}";
this.muzzlePool.Add(muzzleObj);
this.muzzlePool.Enqueue(muzzleObj);
for (int j = 0; j < Mathf.Max(1, continueShotCount / 3); j++)
{
// 爆炸火焰对象
var impactObj = Instantiate(impact);
impactObj.gameObject.SetActive(false);
impactObj.SetParent(null);
impactObj.name = $"Impact_{i}";
impactObj.GetComponent<RecycleImpact>().RecycleAction = this.RecycleImpactToPool;
this.impactPool.Add(impactObj);
}
//for (int j = 0; j < Mathf.Max(1, continueShotCount / 3); j++)
//{
// 爆炸火焰对象
var impactObj = Instantiate(impact);
impactObj.gameObject.SetActive(false);
impactObj.SetParent(null);
impactObj.name = $"Impact_{i}";
impactObj.GetComponent<RecycleImpact>().RecycleAction = this.RecycleImpactToPool;
this.impactPool.Enqueue(impactObj);
//}
}
//for (int i = 0; i < _qiuObjects.Length; i++)
//{
@ -326,10 +326,8 @@ public class Shot : MonoBehaviour
if (bulletObj != null)
{
// 1. 强制重置所有状态
PoolTool.ResetTransform(bulletObj);
// 6. 激活对象
bulletObj.gameObject.SetActive(true);
//// 1. 强制重置所有状态
//PoolTool.ResetTransform(bulletObj);
// 10. 播放音效
if (!isNextLineShot && shotAudioClip != null)
{
@ -343,13 +341,15 @@ public class Shot : MonoBehaviour
// 3. 设置初始位置(强制世界坐标)
if (initBulletPos == null)
{
bulletObj.position = new Vector3(transform.position.x, gun.position.y, transform.position.z);
bulletObj.position = gun.position;
}
else
{
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;
@ -515,10 +515,11 @@ public class Shot : MonoBehaviour
CheckBulletBoom(isBulletHitted, bulletComp, false);
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 });
PoolTool.RecycleBulletToPool(bulletObj, this.bulletPool, this.activeBulletPool);
}
else
@ -540,52 +541,20 @@ public class Shot : MonoBehaviour
// 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秒后)
//DOVirtual.DelayedCall(0.2f, () =>
//{
// if (muzzleObj != null)
// {
// RecycleToPool(muzzleObj, muzzlePool, activeMuzzles);
// }
//});
// 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)
@ -640,22 +609,22 @@ public class Shot : MonoBehaviour
//在摄像机看到的屏幕范围之外,销毁子弹
isBulletHitted = !VisibilityTool.IsObjectInFrustum(bulletComp.gameObject, _cam);
}
if (!isBulletHitted && bulletComp.LockTarget != null)
{
if (bulletComp.LockTarget != bulletComp.BeforeHitTarget)
{
float currentDistance = Vector3.Distance(bulletComp.transform.position, bulletComp.LockTarget.transform.position);
//if (!isBulletHitted && bulletComp.LockTarget != null)
//{
// if (bulletComp.LockTarget != bulletComp.BeforeHitTarget)
// {
// float currentDistance = Vector3.Distance(bulletComp.transform.position, bulletComp.LockTarget.transform.position);
if (currentDistance < hitDistance)
{
isBulletHitted = true;
bulletComp.currentHitPosition = bulletComp.LockTarget.transform.position;
bulletComp.HitTarget = bulletComp.LockTarget;
bulletComp.BeforeHitTarget = bulletComp.HitTarget;
bulletComp.IsShoting = false;
}
}
}
// if (currentDistance < hitDistance)
// {
// isBulletHitted = true;
// bulletComp.currentHitPosition = bulletComp.LockTarget.transform.position;
// bulletComp.HitTarget = bulletComp.LockTarget;
// bulletComp.BeforeHitTarget = bulletComp.HitTarget;
// bulletComp.IsShoting = false;
// }
// }
//}
//if (isDestroyed)
//{
// 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) // 线程安全锁
//{
//while (pool.Count > 0)
//{
Transform obj = pool.Where(o => !o.gameObject.activeSelf).FirstOrDefault();
if (obj != null)
if (pool.TryDequeue(out Transform obj))
{
pool.Remove(obj);
ResetTransform(obj); // »ñÈ¡Ê±ÖØÖÃ״̬
if (obj.GetComponent<Bullet>() != null)
if (obj != 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)
{
activeImpactPool.Add(obj);
}
return obj;
}
}//.Where(o => !o.gameObject.activeSelf).FirstOrDefault();
//}
//}
return null;
}
// 回收对象到池
public static void RecycleToPool(Transform obj, List<Transform> pool)
public static void RecycleToPool(Transform obj, ConcurrentQueue<Transform> pool)
{
if (obj == null) return;
// 避免重复入队
@ -47,7 +50,7 @@ public class PoolTool
{
// 回收时彻底重置
ResetTransform(obj);
pool.Add(obj);
pool.Enqueue(obj);
}
}
@ -68,7 +71,7 @@ public class PoolTool
// 命中目标后的逻辑(可自定义爆炸、伤害等)
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)
{
@ -93,7 +96,7 @@ public class PoolTool
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)
{
@ -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);
// 回收对象
RecycleToPool(muzzleObj, muzzlePool);
}
public static void RecycleImpactToPool(Transform impactObj, List<Transform> impactPool)
public static void RecycleImpactToPool(Transform impactObj, ConcurrentQueue<Transform> impactPool)
{
// 回收对象
RecycleToPool(impactObj, impactPool);

View File

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