204 lines
5.1 KiB
C#
204 lines
5.1 KiB
C#
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 ownerIndex, Vector3 recoil, float recoilCount)
|
|
{
|
|
this.ownerIndex = ownerIndex;
|
|
rigidbodyComponent.velocity = recoil.normalized * recoilCount;
|
|
rigidbodyComponent.rotation = Quaternion.LookRotation(recoil.normalized);
|
|
}
|
|
|
|
[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) { }
|
|
} |