205 lines
4.8 KiB
C#
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;
|
|
}
|
|
|
|
}
|