2025-05-18 01:04:31 +08:00

593 lines
15 KiB
C#

// ***********************************************************************
// Assembly : Game
// Author : Kimch
// Created : 2021-01-09
// Description :
// Last Modified By :
// Last Modified On :
// ***********************************************************************
// <copyright file= "EntityEnemy" company="Kunpo"></copyright>
// <summary></summary>
// ***********************************************************************
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace G
{
/// <summary>
/// 敌人
/// </summary>
public class EntityEnemy : EntityCha
{
#region Field
private float _lifeTime;
/// <summary>
/// 毒药
/// </summary>
protected bool _poison;
protected float _poisonDamage;
protected float _poisonDelay;
protected int _lastPoisonDelay;
/// <summary>
/// 刺
/// </summary>
protected bool _pierce;
/// <summary>
///
/// </summary>
protected bool _risedrop;
protected float _riseFactor;
/// <summary>
/// 狂暴
/// </summary>
protected float _rampage;
/// <summary>
/// 狂暴
/// </summary>
protected float _rampageDelay;
/// <summary>
///
/// </summary>
protected bool _resetTarget;
/// <summary>
/// 固定目标
/// </summary>
protected bool _fixedTarget;
/// <summary>
/// 约束范围
/// </summary>
protected float _restrictArea;
/// <summary>
///
/// </summary>
protected int _behaviour;
protected float _behaviourDelay = 2f;
/// <summary>
///
/// </summary>
protected Vector3 _direction;
protected Vector3 _behitDirection;
protected Vector3 _attackStartDirection;
protected Vector3 _attackStartPosition;
/// <summary>
///
/// </summary>
protected Transform _target;
protected Transform _cha1;
protected EntityMainPlayer _scriptCha;
/// <summary>
///
/// </summary>
protected Renderer _mainRender;
protected Texture _originTex;
//
protected int _attributeStatus;
//
protected bool _showArrow;
/// <summary>
/// 方向箭头
/// </summary>
protected Transform _cloneArrow;
#endregion
#region Property
/// <summary>
///
/// </summary>
public int attack
{
get;
set;
}
/// <summary>
///
/// </summary>
public int defence
{
get;
set;
}
/// <summary>
///
/// </summary>
public int block
{
get;
set;
}
public float moveSpeed
{
get;
set;
}
/// <summary>
///
/// </summary>
public int moveState
{
get;
set;
}
float _timeTimeFactor = 1f;
protected float deltaTime
{
get { return Time.deltaTime * _timeTimeFactor; }
}
#endregion
#region Method
protected override void OnViewInitCompleted()
{
base.OnViewInitCompleted();
_timeTimeFactor = 1f;
var viewGO = entityView.gameObject;
gameObject.layer = viewGO.layer;
gameObject.tag = viewGO.tag;
var viewTr = entityView.transform;
_mainRender = viewTr.GetChild(0).GetComponent<Renderer>();
if (!_mainRender)
_mainRender = viewTr.GetComponentInChildren<SkinnedMeshRenderer>();
_originTex = _mainRender.material.mainTexture;
}
protected void InitRigbody(float mass)
{
var rb = gameObject.AddComponent<Rigidbody>();
rb.mass = mass;
rb.drag = 5f;
rb.angularDrag = 5f;
rb.useGravity = false;
rb.constraints = RigidbodyConstraints.FreezePositionY | RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ;
SetRigidbody(rb);
}
int _shadowIndex = -1;
public override void SetShadowVisible(bool visible)
{
if (visible)
{
if (_shadowIndex == -1)
_shadowIndex = EnemyHelper.Instance.CreateShadow(transform.GetChild(0), 1f);
}
else
{
if (_shadowIndex >= 0)
EnemyHelper.Instance.DestroyShadow(_shadowIndex);
_shadowIndex = -1;
}
}
/// <summary>
///
/// </summary>
/// <param name="pos"></param>
/// <param name="damage"></param>
/// <param name="dir"></param>
/// <param name="crit"></param>
public void SetDamageNumber(Vector3 pos, int damage, Vector3 dir, int crit = 0)
{
var damageBoard = BoardManager.Instance.CreateDamageBoard(crit == 0 ? "DamageBoard2" : "DamageBoard1");
damageBoard.SetValue(damage, DamageBoardType.ENEMY_HP_SUB);
damageBoard.SetPosition(pos);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public Transform GetDefaultTarget()
{
return _cha1;
}
/// <summary>
///
/// </summary>
/// <param name="visible"></param>
public void ShowArrow(bool visible)
{
_showArrow = visible;
if (_cloneArrow)
_cloneArrow.gameObject.SetActive(visible);
}
/// <summary>
///
/// </summary>
public void DestroyArrow()
{
if (_cloneArrow)
Destroy(_cloneArrow.gameObject);
}
/// <summary>
///
/// </summary>
public void UpdateArrow()
{
//显示箭头
if (_showArrow)
{
var arrowDir = Vector3.Normalize(this.position - _cha1.position);
if (arrowDir != Vector3.zero)
{
_cloneArrow.rotation = Quaternion.LookRotation(arrowDir);
}
arrowDir = _cha1.position + Vector3.up * 0.02f + arrowDir * 0.3f;
_cloneArrow.position = Vector3.Lerp(_cloneArrow.position, arrowDir, Time.deltaTime * 4f);
//_cloneArrow.gameObject.SetActive(true);
}
}
public virtual void Dead(int kind)
{
isLife = false;
DestroyArrow();
DestroyHpBar();
DropItems();
EntityManager.Instance.RemoveEntity(this);
}
public virtual void DropItems()
{
if (EntityPet.Instance)
{
Vector3 a = Random.onUnitSphere * Random.Range(0.18f, 0.26f);
EntityPet.Instance.OnEnemyDied(transform.position + a);
}
}
/// <summary>
/// baozou
/// </summary>
public virtual void Rampage()
{
_timeTimeFactor = 3f;
_animator.speed = 3f;
}
/// <summary>
///
/// </summary>
public virtual void Grabed()
{
//无法抓取
}
public virtual void OnDamage(AllyDamage allyDamage, int damageLayer)
{
}
public bool Burn(int damage)
{
if (_attributeStatus != 2)
{
_attributeStatus = 1;
StartCoroutine(BurnCO(damage));
}
return false;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public IEnumerator BurnCO(int damage)
{
SetElementEffect(0);
yield return new WaitForSeconds(0.5f);
for (int i = 0; i < 5; i++)
{
BurnDamage(damage);
yield return new WaitForSeconds(0.5f);
}
yield return null;
_attributeStatus = 0;
RestoreElementEffect();
}
/// <summary>
///
/// </summary>
private void BurnDamage(int damage)
{
int dmg = Mathf.Max(1, damage / 20);
curHp -= dmg;
SetDamageNumber(transform.position, dmg, Vector3.zero);
SetHpBar(curHp, maxHp, -1);
if (curHp <= 0)
{
Dead(0);
}
}
public bool Freeze(int damage)
{
if (_attributeStatus != 1)
{
_attributeStatus = 2;
StartCoroutine(FreezeCO());
return true;
}
return false;
}
public IEnumerator FreezeCO()
{
_animator.enabled = false;
SetElementEffect(1);
yield return new WaitForSeconds(2f);
_attributeStatus = 0;
_animator.enabled = true;
RestoreElementEffect();
}
public bool Shock(int damage)
{
if (_attributeStatus != 3)
{
StartCoroutine(ShockCO(damage));
_attributeStatus = 3;
return true;
}
return false;
}
public IEnumerator ShockCO(int damage)
{
SetElementEffect(2);
yield return new WaitForSeconds(0.5f);
for (int i = 0; i < 7; i++)
{
ShockDamage();
yield return new WaitForSeconds(0.1f);
}
yield return null;
_attributeStatus = 0;
RestoreElementEffect();
}
/// <summary>
///
/// </summary>
private void ShockDamage()
{
PlayAnimation(Hash_Down, 0f);
}
/// <summary>
/// 暗黑
/// </summary>
/// <returns></returns>
public bool Darken(int damage)
{
if (_attributeStatus != 4)
{
StartCoroutine(DarkenCO());
_attributeStatus = 4;
return true;
}
return false;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public IEnumerator DarkenCO()
{
SetElementEffect(3);
yield return new WaitForSeconds(2f);
_attributeStatus = 0;
RestoreElementEffect();
}
/// <summary>
/// 击晕
/// </summary>
/// <param name="damage"></param>
public void Stun(int damage)
{
if (_attributeStatus != 1)
{
StartCoroutine(StunCO());
_attributeStatus = 2;
}
}
public IEnumerator StunCO()
{
_animator.enabled = false;
yield return new WaitForSeconds(2f);
_animator.enabled = true;
_attributeStatus = 0;
}
/// <summary>
/// 石化攻击 有几率直接死亡
/// </summary>
/// <param name="damage"></param>
/// <returns></returns>
public bool Petrify(int damage)
{
StartCoroutine(PetrifyCO(damage));
return true;
}
/// <summary>
/// 石化
/// </summary>
/// <returns></returns>
public IEnumerator PetrifyCO(int rate)
{
isLife = false;
SetHpBar(curHp, maxHp, 2);
this.gameObject.layer = GameLayer.ObjectLayer;
SetElementEffect(1);
yield return new WaitForSeconds(2.5f);
if (rate > 0 && rate > GlobalUtils.RndHundred)
{
Dead(0);
yield break;
}
this.gameObject.layer = GameLayer.UnitLayer;
RestoreElementEffect();
isLife = true;
SetHpBar(curHp, maxHp, 0);
}
/// <summary>
/// 穿刺攻击
/// </summary>
/// <param name="damage"></param>
/// <param name="damageDir"></param>
/// <returns></returns>
public bool Pierced(int damage, Vector3 damageDir)
{
isLife = false;
SetColliderEnabled(false);
SetHpBar(0, maxHp, 9f, 0);
StartCoroutine(PiercedCO(damageDir));
return true;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public IEnumerator PiercedCO(Vector3 damageDir)
{
yield return new WaitForSeconds(1.5f);
if (curHp <= 0)
{
Dead(0);
}
else
{
SetHpBar(curHp, maxHp, 0);
}
CrossFade(Hash_Down_High, 0.1f, 0.49f);
GameCamera.Instance.Hitcam();
EnemyHelper.Instance.CreateBlood_Only(transform.position, damageDir);
//SetMoveSpeed(0f);
EnemyHelper.Instance.SoundOn(1);
SetColliderEnabled(true);
isLife = true;
}
/// <summary>
///
/// </summary>
/// <param name="index"></param>
public void SetElementEffect(int index)
{
_mainRender.material.mainTexture = EnemyHelper.Instance.attribute_tex[index];
//if (!_elementFx)
// _elementFx = Object.Instantiate(EnemyHelper.Instance.attribute_pt[element], this.transform);
}
/// <summary>
///
/// </summary>
public void RestoreElementEffect()
{
_mainRender.material.mainTexture = _originTex;
//if (_elementFx)
// Destroy(_elementFx);
}
public virtual void UpdateState()
{
_lifeTime += Time.deltaTime;
//if (_lifeTime > 60f)
//{
// Rampage();
//}
if (GameLevel.Instance.isRampage)
{
Rampage();
}
}
#endregion
#region Unity
private void FixedUpdate()
{
UpdateState();
}
private void OnTriggerEnter(Collider other)
{
int damageLayer = other.gameObject.layer;
if (damageLayer < GameLayer.PlayerAttack)
return;
var allyDamage = other.gameObject.GetComponent<AllyDamage>();
if (!allyDamage)
return;
OnDamage(allyDamage, damageLayer);
}
public override void Dispose()
{
RestoreElementEffect();
base.Dispose();
}
#endregion
}
}