Files
Loong/Assets/_Loong/Scripts/Bullet/Bullet.cs

237 lines
5.8 KiB
C#

using System;
using DragonLi.Core;
using DragonLi.Frame;
using Mirror;
using UnityEngine;
public class Bullet : MonoBehaviour
{
/// <summary>
/// 子弹类型
/// </summary>
public BulletType type;
[Header("伤害")]
#if UNITY_EDITOR
[DisplayOnly]
#endif
public float damage = 0;
[Header("破韧")]
#if UNITY_EDITOR
[DisplayOnly]
#endif
public float deToughness = 0;
[Header("击中删除时间")]
public float despawn_delay = 0.1f;
[Header("自动删除时间")]
public float auto_despawn_delay = 5f;
[Header("撞击预制体")]
public GameObject impact_prefab;
[Header("撞击删除时间")]
public float impact_despawn_time = 1f;
[Header("是否使用重力")]
public bool use_gravity = false;
public bool hit_trigger = false;
[Header("目标图层")]
public LayerMask HitLayer;
#if UNITY_EDITOR
[DisplayOnly]
#endif
public int ownerIndex;
private Rigidbody rigidbodyComponent;
/// <summary>
/// 刚体组件
/// </summary>
public Rigidbody RigidbodyComponent
{
get
{
if (rigidbodyComponent == null)
{
rigidbodyComponent = GetComponentInChildren<Rigidbody>();
}
return rigidbodyComponent;
}
}
[NonSerialized]
public bool _isHit = false;
[NonSerialized]
public bool _isValid = true;
[NonSerialized]
public float _despawnTime = 0f;
public RaycastHit handlingHit;
public TrailRenderer trailRenderer;
private bool trailDetached = false;
#region
public void Awake()
{
RigidbodyComponent.useGravity = use_gravity;
RigidbodyComponent.constraints = (RigidbodyConstraints)112;
}
protected virtual void Start()
{
//获取拖尾组件
trailRenderer = GetComponentInChildren<TrailRenderer>();
if (trailRenderer != null)
{
trailRenderer.emitting = true;
}
}
public void OnEnable()
{
_isHit = false;
_isValid = true;
_despawnTime = Time.time + auto_despawn_delay;
}
public virtual void Update()
{
if (_isValid)
{
if (_isHit)
{
DespawnSelf();
return;
}
if (_despawnTime < Time.time)
{
_isValid = false;
Destroy(gameObject);
}
}
}
internal void FixedUpdate()
{
if (!_isHit && HitCheck())
{
_isHit = true;
SpawnImpact();
ApplyDamage();
}
OnFixedUpdate();
}
public virtual void OnFixedUpdate() { }
#endregion
public virtual void OnSpawn(Vector3 recoil, float recoilCount)
{
rigidbodyComponent.velocity = recoil.normalized * recoilCount;
rigidbodyComponent.rotation = Quaternion.LookRotation(recoil.normalized);
}
public virtual void DespawnSelf()
{
_isValid = false;
//处理拖尾效果
if(trailRenderer != null && !trailDetached)
{
DetachTrail();
}
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
Destroy(gameObject);
}, despawn_delay);
}
public virtual void SpawnImpact()
{
if (impact_prefab != null)
{
GameObject impact = Instantiate(impact_prefab);
impact.transform.position = handlingHit.point;
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
Destroy(impact);
}, impact_despawn_time);
// 碰撞点的法线方向
Vector3 normal = handlingHit.normal;
// 在这里处理特效的生成和方向
// 计算特效的旋转方向,使用法线信息
Quaternion rotation = Quaternion.LookRotation(normal);
// 将特效的旋转方向设置为法线方向
impact.transform.rotation = rotation;
}
}
public virtual bool HitCheck()
{
Vector3 position = transform.position;
Vector3 velocity = RigidbodyComponent.velocity * Time.deltaTime;
if (Physics.Raycast(position, velocity, out handlingHit, velocity.magnitude, HitLayer))
{
if (hit_trigger && handlingHit.collider.isTrigger)
{
return false;
}
return true;
}
return false;
}
public virtual void ApplyDamage()
{
Damagable component = handlingHit.transform.GetComponent<Damagable>();
if (component != null)
{
OnApplyDamage(component);
}
Player hitPlayer = handlingHit.transform.GetComponentInParent<Player>();
if (hitPlayer != null)
{
// OnHitPlayer(hitPlayer.index);
}
//处理拖尾效果
HandleTrailEffect();
}
private void HandleTrailEffect()
{
if (trailRenderer == null || trailDetached)
return;
//分离拖尾效果
DetachTrail();
}
private void DetachTrail()
{
if (trailRenderer == null)
return;
//创建新的游戏对象来承载拖尾效果
GameObject trailHolder = new GameObject("TrailHolder");
trailHolder.transform.position = transform.position;
trailHolder.transform.rotation = transform.rotation;
//移动拖尾到新对象
trailRenderer.transform.SetParent(trailHolder.transform);
trailRenderer.emitting = false;
//设置自动销毁
Destroy(trailHolder, trailRenderer.time);
trailDetached = true;
}
public virtual void OnApplyDamage(Damagable damagable) { }
public virtual void OnApplyDamage(IDamagable damagable) { }
public virtual void OnHitPlayer(int index) { }
}