593 lines
15 KiB
C#
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
|
|
}
|
|
}
|