Files
DefendNJ/Assets/_DefendNJ/Scripts/Bullets/Bullet.cs

219 lines
5.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using DragonLi.Core;
using DragonLi.Frame;
using Mirror;
using UnityEngine;
public class Bullet : NetworkBehaviour
{
/// <summary>
/// 子弹类型
/// </summary>
#if UNITY_EDITOR
[DisplayOnly]
#endif
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;
}
}
private bool _isHit = false;
private bool _isValid = true;
private float _despawnTime = 0f;
private RaycastHit _handlingHit;
#region
public void Awake()
{
RigidbodyComponent.useGravity = use_gravity;
RigidbodyComponent.constraints = (RigidbodyConstraints)112;
}
public void OnEnable()
{
_isHit = false;
_isValid = true;
_despawnTime = Time.time + auto_despawn_delay;
}
public void Update()
{
if (isServer)
{
if (_isValid)
{
if (_isHit)
{
DespawnSelf();
return;
}
if (_despawnTime < Time.time)
{
_isValid = false;
NetworkServer.Destroy(transform.gameObject);
}
}
}
}
internal void FixedUpdate()
{
if (isServer && !_isHit && HitCheck())
{
// Debug.Log("撞击");
_isHit = true;
SpawnImpact();
ApplyDamage();
}
OnFixedUpdate();
}
/// <summary>
/// This will be called when fixedupdate called
/// </summary>
protected virtual void OnFixedUpdate() { }
#endregion
[Server]
public virtual void OnSpawn(int curOwnerIndex, Vector3 recoil, float recoilCount)
{
if (curOwnerIndex != -1)
ownerIndex = curOwnerIndex;
rigidbodyComponent.velocity = recoil.normalized * recoilCount;
rigidbodyComponent.rotation = Quaternion.LookRotation(recoil.normalized);
}
[Server]
public virtual void OnSpawn( Vector3 targetPos, float speed)
{
// 计算方向(忽略 Y 轴,让子弹水平飞行)
Vector3 dir = (targetPos - transform.position);
dir.y = 0f; // 固定 Y不让子弹上下飞
dir.Normalize();
// 设置刚体运动
rigidbodyComponent.velocity = dir * speed;
rigidbodyComponent.rotation = Quaternion.LookRotation(dir, Vector3.up);
}
[Server]
public void DespawnSelf()
{
_isValid = false;
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
NetworkServer.Destroy(transform.gameObject);
}, despawn_delay);
}
[Server]
public virtual void SpawnImpact()
{
if (impact_prefab != null)
{
GameObject impact = Instantiate(impact_prefab);
Debug.Log("生成击中点");
impact.transform.position = _handlingHit.point;
NetworkServer.Spawn(impact);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
NetworkServer.Destroy(impact);
}, impact_despawn_time);
// 碰撞点的法线方向
Vector3 normal = _handlingHit.normal;
// 在这里处理特效的生成和方向
// 计算特效的旋转方向,使用法线信息
Quaternion rotation = Quaternion.LookRotation(normal);
// 将特效的旋转方向设置为法线方向
impact.transform.rotation = rotation;
}
}
[Server]
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;
}
[Server]
public virtual void ApplyDamage()
{
// IDamagable component = _handlingHit.transform.GetComponent<IDamagable>();
IDamagable component = _handlingHit.transform.GetComponent<IDamagable>();
if (component != null)
{
OnApplyDamage(component);
}
Player hitPlayer = _handlingHit.transform.GetComponentInParent<Player>();
if (hitPlayer != null)
{
OnHitPlayer(hitPlayer.index);
}
}
[Server]
public virtual void OnApplyDamage(IDamagable damagable) { }
[Server]
public virtual void OnHitPlayer(int index) { }
}