Files
FutureMen2/Assets/_FutureMen2/Scripts/Weapons/EnemyBullet/EnemyBullet.cs

205 lines
4.8 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using DragonLi.Core;
using UnityEngine;
using DragonLi.Frame;
using System;
using Random = UnityEngine.Random;
public enum EnemyBulletType
{
DropShipBullet1=1,
DropShipBullet2=2,
Enemy1=3,
LeviathanBullet1=4,
LeviathanBullet2=5,
Enemy2=6,
MachineDragonBullet1=7,
MachineDragonBullet2=8,
Enemy3=9,
Boss1=10,
Boss2=11,
Boss3=12,
}
public class EnemyBullet : MonoBehaviour
{
public EnemyBulletType bulletType;
public float hitDesTime = 1f;
public float autoDesTime = 5f;
public GameObject impactPrefab;
public bool isUserGravity = false;
public LayerMask targetHitLayer;
public bool isRangeBoom;
public float explosionRadius = 2;
[NonSerialized]
public bool isHit = false;
[NonSerialized]
public bool isValid = true;
[NonSerialized]
public float despawnTime = 0f;
[NonSerialized]
public RaycastHit handlingHit;
public Rigidbody riy;
public Vector3 targetPos;
private int[] _damages;//伤害
#region
public void InitData()
{
}
public virtual void Awake()
{
riy=gameObject.GetComponent<Rigidbody>();
if (riy)
{
riy.useGravity = isUserGravity;
riy.constraints = (RigidbodyConstraints)112;
}
targetHitLayer=LayerMask.GetMask("Player","Wall","Ground");
}
private void Start()
{
InitData();
}
public void OnEnable()
{
isHit = false;
isValid = true;
despawnTime = Time.time + autoDesTime;
}
public virtual void Update()
{
if (isValid)
{
if (isHit)
{
DespawnSelf();
return;
}
if (despawnTime < Time.time)
{
isValid = false;
Destroy(transform.gameObject);
}
}
}
internal virtual void FixedUpdate()
{
if ( !isHit && HitCheck())
{
isHit = true;
SpawnImpact();
ApplyDamage();
}
OnFixedUpdate();
}
/// <summary>
/// This will be called when fixedupdate called
/// </summary>
protected void OnFixedUpdate()
{
}
#endregion
public void SpawnImpact()
{
if (impactPrefab != null)
{
GameObject impact = Instantiate(impactPrefab);
impact.transform.position = handlingHit.point;
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
Destroy(impact);
}, despawnTime);
// 碰撞点的法线方向
Vector3 normal = handlingHit.normal;
// 在这里处理特效的生成和方向
// 计算特效的旋转方向,使用法线信息
Quaternion rotation = Quaternion.LookRotation(normal);
// 将特效的旋转方向设置为法线方向
impact.transform.rotation = rotation;
}
}
public void DespawnSelf()
{
isValid = false;
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
// 先检查 gameObject 是否还没被销毁
if (this != null && gameObject != null)
{
Destroy(gameObject);
}
}, despawnTime);
}
public bool HitCheck()
{
Vector3 position = transform.position;
Vector3 velocity = riy.velocity * Time.deltaTime;
if (Physics.Raycast(position, velocity, out handlingHit, velocity.magnitude, targetHitLayer))
{
if ( handlingHit.collider.isTrigger)
{
return false;
}
return true;
}
return false;
}
// todo
public void ApplyDamage()
{
if (isRangeBoom)
{
Collider[] victims = Physics.OverlapSphere(transform.position, explosionRadius, targetHitLayer);
foreach (var item in victims)
{
var damagable = item.GetComponent<IDamagable>();
if (damagable!= null)
{
OnApplyDamage(damagable);
}
}
return;
}
IDamagable component = handlingHit.transform.GetComponent<IDamagable>();
if (component != null)
{
OnApplyDamage(component);
}
}
// todo
public virtual void OnApplyDamage(IDamagable damagable) { }
public int GetDamage(out bool isCriticalHit)
{
int randomDamage = Random.Range(_damages[0], _damages[1]);
isCriticalHit=randomDamage > (_damages[1] - (_damages[1] - _damages[0]) * 0.35f);
return randomDamage;
}
}