1219 lines
38 KiB
C#
1219 lines
38 KiB
C#
// ***********************************************************************
|
|
// Assembly : Unity
|
|
// Author : Kimch
|
|
// Created : 2018-2-29
|
|
// Description : 游戏小兵
|
|
// Last Modified By :
|
|
// Last Modified On :
|
|
// ***********************************************************************
|
|
// <copyright file= "EntityMinion" company=""></copyright>
|
|
// <summary></summary>
|
|
// ***********************************************************************
|
|
using System.Collections;
|
|
using UnityEngine;
|
|
|
|
namespace G
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public sealed class EntityMinion : EntityEnemy
|
|
{
|
|
#region Field
|
|
|
|
public const float ATTACK_DELAY = 2F;
|
|
|
|
/// <summary>
|
|
/// 子弹
|
|
/// </summary>
|
|
private Transform _bullet => _enemyInfo.ef_weapon;
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private Transform _cloneBullet;
|
|
|
|
private AudioClip _moveSound;
|
|
private AudioClip _attackSound => _enemyInfo.snd_attack;
|
|
|
|
public Transform _directionArrow => _enemyInfo.direction_arrow;
|
|
|
|
/// <summary>
|
|
/// 预警
|
|
/// </summary>
|
|
private Transform _warning => _enemyInfo.line;
|
|
|
|
private bool _lastMon;
|
|
|
|
private Transform _targetOnlyone;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private float _hpBarHeight;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private bool _grabed;
|
|
private int _grabStyle;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private bool _spawning;
|
|
|
|
/// <summary>
|
|
/// 撞击
|
|
/// </summary>
|
|
private bool _impact;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private Quaternion _lookRotation;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private bool _attackStart;
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private float _attackDelay = ATTACK_DELAY;
|
|
/// <summary>
|
|
/// 范围
|
|
/// </summary>
|
|
private float _attackRange = 5f;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private float _idleAnimSpeed;
|
|
|
|
/// <summary>
|
|
/// 游戏
|
|
/// </summary>
|
|
private int _playKind;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
|
|
private ItemMinion _item;
|
|
private EnemyInfo _enemyInfo;
|
|
|
|
#endregion
|
|
|
|
#region Property
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public override EntityType entityType
|
|
{
|
|
get { return EntityType.Minion; }
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private int _kind
|
|
{
|
|
get { return _item.kind; }
|
|
}
|
|
private bool _useTargetPosition => _enemyInfo.useTargetPosition;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private int _sizeKind
|
|
{
|
|
get { return _item.sizeKind; }
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private int _dash
|
|
{
|
|
get { return _item.dash; }
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private bool _attachWeaponEf
|
|
{
|
|
get { return _item.attach_ef != 0; }
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private float _movingAtk
|
|
{
|
|
get { return _item.moving_attack; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// 开火
|
|
/// </summary>
|
|
private float _fireRange
|
|
{
|
|
get { return _item.fireRange; }
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public float attackCd => ATTACK_DELAY;
|
|
|
|
///// <summary>
|
|
/////
|
|
///// </summary>
|
|
//public BehaviorTree behaviorTree
|
|
//{
|
|
// get;
|
|
// private set;
|
|
//}
|
|
|
|
#endregion
|
|
|
|
#region Method
|
|
|
|
/// <summary>
|
|
/// 初始化
|
|
/// </summary>
|
|
/// <param name="info"></param>
|
|
/// <returns></returns>
|
|
public override bool Init(EntityInfo info)
|
|
{
|
|
if (info != null)
|
|
{
|
|
_item = ItemProxy.Instance.GetStaticItem<ItemMinion>(info.itemId);
|
|
SetLevel(info.factorA, info.factorB, 0, true);
|
|
|
|
InitRigbody(_item.mass);
|
|
|
|
_scriptCha = EntityMainPlayer.Instance;
|
|
_cha1 = _scriptCha.transform;
|
|
_target = _cha1;
|
|
if (EntityCart.Instance)
|
|
{
|
|
_target = EntityCart.Instance.transform;
|
|
}
|
|
moveState = 0;
|
|
}
|
|
return base.Init(info);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
protected override void OnViewInitCompleted()
|
|
{
|
|
base.OnViewInitCompleted();
|
|
|
|
var viewGO = entityView.gameObject;
|
|
|
|
_enemyInfo = viewGO.GetComponent<EnemyInfo>();
|
|
|
|
var orb = viewGO.GetComponent<Rigidbody>();
|
|
Destroy(orb);
|
|
|
|
//if (enemy.aiBT)
|
|
//{
|
|
// behaviorTree = this.gameObject.AddComponent<BehaviorTree>();
|
|
// behaviorTree.ExternalBehavior = enemy.aiBT;
|
|
|
|
// var s = behaviorTree.GetVariable("attackCD") as SharedFloat;
|
|
// s.SetValue(5f);
|
|
// s = behaviorTree.GetVariable("attackRange") as SharedFloat;
|
|
// s.SetValue(0.15f);
|
|
// s = behaviorTree.GetVariable("loseTargetRange") as SharedFloat;
|
|
// s.SetValue(1f);
|
|
//}
|
|
|
|
//var osc = view.GetComponent<SphereCollider>();
|
|
//var sc = gameObject.AddComponent<SphereCollider>();
|
|
//sc.isTrigger = osc.isTrigger;
|
|
//sc.center = osc.center;
|
|
//sc.radius = osc.radius;
|
|
//Destroy(osc);
|
|
SetModel(viewGO);
|
|
|
|
SetFloat(Hash_Speed_Move, _item.speed_move);
|
|
SetFloat(Hash_Speed_Attack1, _item.speed_attack);
|
|
SetFloat(Hash_Speed_Attack1_I, _item.speed_attack_i);
|
|
_idleAnimSpeed = _item.speed_idle - 0.05f;
|
|
SetFloat(Hash_Speed_Idle, _idleAnimSpeed);
|
|
|
|
//_moveSound = Monster_efs.Instance.snd_move[Random.Range(0, 3)];
|
|
|
|
CreateHpBar();
|
|
|
|
SetShadowVisible(true);
|
|
|
|
SummonStart();
|
|
StartAI();
|
|
}
|
|
|
|
public override void CreateHpBar()
|
|
{
|
|
_hpBarHeight = 0.09f + _sizeKind * 0.007f;
|
|
_blood = BoardManager.Instance.CreateBloodBoard("BloodBoard2");
|
|
_blood.SetTarget(this.transform, Vector3.up * _hpBarHeight);
|
|
_blood.HideSlider();
|
|
}
|
|
|
|
public override void SetHpBar(int cur, int max, float height, int index)
|
|
{
|
|
base.SetHpBar(cur, max, _hpBarHeight, index);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="a"></param>
|
|
/// <param name="b"></param>
|
|
/// <param name="playkind"></param>
|
|
/// <param name="isSummon"></param>
|
|
public void SetLevel(float[] a, float[] b, int playkind, bool isSummon)
|
|
{
|
|
_playKind = playkind;
|
|
level = 1;
|
|
|
|
attack = (int)(_item.power * a[0] + b[0]);
|
|
|
|
defence = (int)(_item.defence * a[1] + b[1]);
|
|
|
|
maxHp = (int)(_item.hp * a[2] + b[2]);
|
|
curHp = maxHp;
|
|
|
|
block = (int)((_item.block * a[3] + b[3]) * 0.01f);
|
|
|
|
isLife = true;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="speedRate"></param>
|
|
public void SetMoveSpeed(float speedRate)
|
|
{
|
|
moveSpeed = _item.runSpeed * speedRate;
|
|
SetFloat(Hash_Speed_Move, speedRate);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="kind"></param>
|
|
public override void Dead(int kind)
|
|
{
|
|
moveState = -4;
|
|
|
|
_lastMon = false;
|
|
curHp = 0;
|
|
GameLevel.Instance.MinionKill(this.itemId);
|
|
|
|
switch (kind)
|
|
{
|
|
case 2:
|
|
_behitDirection.y = 0f;
|
|
EnemyHelper.Instance.SoundOn(4);
|
|
EnemyHelper.Instance.EnemyDead(_kind, transform.position, this.transform.localScale, _behitDirection, _mainRender.material.mainTexture);
|
|
|
|
break;
|
|
case 1:
|
|
//Destroy(gameObject, 2f);
|
|
//bekicked.wrapMode = WrapMode.ClampForever;
|
|
EnemyHelper.Instance.EnemyDead(0, transform.position, Vector3.zero, Vector3.zero, null);
|
|
SetShadowVisible(false);
|
|
|
|
break;
|
|
case 0:
|
|
EnemyHelper.Instance.SoundOn(4);
|
|
EnemyHelper.Instance.EnemyDead(1, transform.position, Vector3.zero, Vector3.zero, null);
|
|
|
|
break;
|
|
case 3:
|
|
EnemyHelper.Instance.SoundOn(4);
|
|
EnemyHelper.Instance.EnemyDead(3, transform.position, transform.localScale, Vector3.zero, _mainRender.material.mainTexture);
|
|
|
|
break;
|
|
}
|
|
//_script_cha.GainExp(haveExp);
|
|
|
|
if (_cloneBullet)
|
|
{
|
|
Destroy(_cloneBullet.gameObject);
|
|
_cloneBullet = null;
|
|
}
|
|
|
|
base.Dead(kind);
|
|
}
|
|
|
|
public override void DropItems()
|
|
{
|
|
var dropBox = BoxProxy.Instance.GetBoxInfo(_item.boxDrop);
|
|
if (dropBox != null)
|
|
{
|
|
int dropCount = dropBox.item.typeArgs[0];
|
|
for (int i = 0; i < dropCount; i++)
|
|
{
|
|
Vector3 a = Random.onUnitSphere * Random.Range(0.18f, 0.26f);
|
|
var dropItem = dropBox.GetRndItem();
|
|
EnemyHelper.Instance.CreateBox(dropItem.id, dropItem.count, transform.position + a);
|
|
}
|
|
}
|
|
|
|
base.DropItems();
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public override void Grabed()
|
|
{
|
|
if (_attributeStatus <= 0 && !_grabed)
|
|
{
|
|
var myPos = transform.position;
|
|
myPos.y = 0f;
|
|
var chaPos = _cha1.position;
|
|
chaPos.y = 0f;
|
|
|
|
_behitDirection = Vector3.Normalize(myPos - chaPos);
|
|
this.transform.forward = -_behitDirection;
|
|
|
|
_grabStyle = Random.Range(0, 2);
|
|
|
|
if (_sizeKind == 20)
|
|
{
|
|
_grabStyle += 3;
|
|
}
|
|
else if (_kind != 2)
|
|
{
|
|
_grabStyle = 6;
|
|
}
|
|
_collider.enabled = false;
|
|
|
|
switch (_grabStyle)
|
|
{
|
|
case 1:
|
|
PlayAnimation(Hash_Begrab1);
|
|
break;
|
|
case 2:
|
|
PlayAnimation(Hash_Begrab2);
|
|
break;
|
|
case 3:
|
|
PlayAnimation(Hash_Begrab3);
|
|
break;
|
|
case 4:
|
|
PlayAnimation(Hash_Begrab4);
|
|
break;
|
|
case 5:
|
|
PlayAnimation(Hash_Begrab5);
|
|
break;
|
|
default:
|
|
PlayAnimation(Hash_Begrab);
|
|
break;
|
|
}
|
|
|
|
AddForce(_behitDirection * EnemyHelper.Instance.GetGrabForce(_grabStyle));
|
|
_scriptCha.Grab(_grabStyle, transform.position);
|
|
_grabed = true;
|
|
_poisonDelay = -1f;
|
|
}
|
|
}
|
|
|
|
public void CountDown()
|
|
{
|
|
if (isLife)
|
|
{
|
|
_cloneArrow = Instantiate(_directionArrow, _cha1.position, Quaternion.identity);
|
|
_showArrow = true;
|
|
_lastMon = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public void SummonStart()
|
|
{
|
|
float time = 1.5f;
|
|
if (_kind == 2)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
time = 0.4f;
|
|
}
|
|
|
|
_spawning = true;
|
|
this.transform.rotation = Quaternion.Euler(0f, GlobalUtils.RndAngle, 0f);
|
|
PlayAnimation(Hash_Summon);
|
|
Invoke(nameof(SummonFinish), time);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public void SummonFinish()
|
|
{
|
|
_spawning = false;
|
|
}
|
|
|
|
public override void OnDamage(AllyDamage allyDamage, int damageLayer)
|
|
{
|
|
if (!isLife || _grabed)
|
|
return;
|
|
|
|
var sourceCha = allyDamage.source;
|
|
var myPosition = this.position;
|
|
|
|
_behitDirection = myPosition - sourceCha.position;
|
|
_behitDirection.y = 0f;
|
|
_behitDirection = Vector3.Normalize(_behitDirection);
|
|
|
|
bool downHigh = sourceCha.attackRising;
|
|
|
|
float damage = 0f;
|
|
float addDamage = sourceCha.伤害加深百分比 * 0.01f;
|
|
float realDefence = (defence - sourceCha.忽视防御固定值) * (100 - sourceCha.忽视防御百分比) * 0.01f;
|
|
|
|
float damageForce = 0f;
|
|
bool pierce = false;
|
|
|
|
switch (damageLayer)
|
|
{
|
|
case GameLayer.NormalAttack:
|
|
{
|
|
damageForce = 40f;
|
|
|
|
int sourceHitRate = sourceCha.sourceTotalHitRate;
|
|
int blockRate = (int)((block - sourceHitRate) * 1000f / Mathf.Max(block, sourceHitRate, 1) + 50);
|
|
//Debug.Log($"({block} - {sourceHitRate}) *100 /max({block},{sourceHitRate},1)+5 = " + blockRate);
|
|
if (moveState >= 0 && GlobalUtils.RndThousand < blockRate)
|
|
{
|
|
_scriptCha.Blocked(myPosition);
|
|
AddForce(_behitDirection * 10f);
|
|
return;
|
|
}
|
|
|
|
damage = sourceCha.damage;
|
|
_target = _cha1;
|
|
GameCamera.Instance.Hitcam();
|
|
EnemyHelper.Instance.CreateBlood(myPosition, _behitDirection);
|
|
break;
|
|
}
|
|
case GameLayer.PowerAttack:
|
|
{
|
|
damageForce = 30f;
|
|
downHigh = true;
|
|
realDefence *= 0.5f;
|
|
damage = sourceCha.damage;
|
|
_target = _cha1;
|
|
GameCamera.Instance.Hitcam2(1f);
|
|
EnemyHelper.Instance.CreateBlood_Only(myPosition, _behitDirection);
|
|
break;
|
|
}
|
|
case GameLayer.SkillAttack:
|
|
{
|
|
damageForce = 10f;
|
|
downHigh = true;
|
|
damage = allyDamage.physicsDamage;
|
|
_target = _cha1;
|
|
//GameCamera.Instance.Hitcam();
|
|
EnemyHelper.Instance.CreateBlood_Only(myPosition, _behitDirection);
|
|
break;
|
|
}
|
|
case GameLayer.PoisonAttack:
|
|
{
|
|
damageForce = 10f;
|
|
damage = allyDamage.physicsDamage;
|
|
if (damage == 0.1f)
|
|
{
|
|
damage = 0;
|
|
_poison = true;
|
|
_poisonDamage = sourceCha.damage * 0.2f;
|
|
_poisonDelay = 4f;
|
|
downHigh = false;
|
|
_target = _cha1;
|
|
return;
|
|
}
|
|
_poison = true;
|
|
_poisonDamage = damage;
|
|
damage *= 50f;
|
|
_poisonDelay = 5f;
|
|
downHigh = true;
|
|
_target = _cha1;
|
|
|
|
GameCamera.Instance.Hitcam();
|
|
EnemyHelper.Instance.CreateBlood_Only(myPosition, _behitDirection);
|
|
break;
|
|
}
|
|
case GameLayer.DeathAttack:
|
|
{
|
|
damageForce = 0f;
|
|
var petrifyRate = (int)allyDamage.physicsDamage;
|
|
Petrify(petrifyRate);
|
|
_target = _cha1;
|
|
AddForce(_behitDirection * -100);
|
|
GameCamera.Instance.Hitcam();
|
|
break;
|
|
}
|
|
case GameLayer.GeneralAttack:
|
|
{
|
|
damageForce = 60f;
|
|
downHigh = false;
|
|
damage = sourceCha.damage * EntityPet.Instance.bulletDamage;
|
|
_target = _cha1;
|
|
EnemyHelper.Instance.CreateBlood_Only(myPosition, _behitDirection);
|
|
break;
|
|
}
|
|
case GameLayer.PierceAttack:
|
|
{
|
|
damageForce = 0f;
|
|
pierce = true;
|
|
damage = allyDamage.physicsDamage;
|
|
|
|
Pierced((int)damage, _behitDirection);
|
|
curHp -= (int)damage;
|
|
_target = _cha1;
|
|
|
|
SetHpBar(0, maxHp, 9f, 0);
|
|
EnemyHelper.Instance.CreateBlood_Only(myPosition, _behitDirection);
|
|
break;
|
|
}
|
|
case GameLayer.CrowdAttack:
|
|
{
|
|
damageForce = 10f;
|
|
|
|
damage = allyDamage.physicsDamage;
|
|
_target = sourceCha.transform;
|
|
_resetTarget = true;
|
|
EnemyHelper.Instance.CreateBlood_Only(myPosition, _behitDirection);
|
|
break;
|
|
}
|
|
case GameLayer.PushAttack:
|
|
{
|
|
damageForce = 40f;
|
|
damage = sourceCha.damage;
|
|
_target = _cha1;
|
|
GameCamera.Instance.Hitcam();
|
|
EnemyHelper.Instance.CreateBlood(myPosition, _behitDirection);
|
|
break;
|
|
}
|
|
case GameLayer.BurnAttack:
|
|
{
|
|
damageForce = 40f;
|
|
damage = sourceCha.damage;
|
|
if (sourceCha.IsMainPlayer())
|
|
{
|
|
GameCamera.Instance.Hitcam();
|
|
}
|
|
_target = _cha1;
|
|
if (Burn((int)damage))
|
|
EnemyHelper.Instance.CreateBlood(myPosition, _behitDirection);
|
|
break;
|
|
}
|
|
case GameLayer.ColdAttack:
|
|
{
|
|
damageForce = 40f;
|
|
downHigh = false;
|
|
damage = sourceCha.damage;
|
|
if (sourceCha.IsMainPlayer())
|
|
{
|
|
GameCamera.Instance.Hitcam();
|
|
}
|
|
_target = _cha1;
|
|
|
|
var si = _animator.GetCurrentAnimatorStateInfo(0);
|
|
if (si.shortNameHash != Hash_Down_High)
|
|
{
|
|
if (Freeze((int)damage))
|
|
EnemyHelper.Instance.CreateBlood(myPosition, _behitDirection);
|
|
}
|
|
break;
|
|
}
|
|
case GameLayer.StunAttack:
|
|
{
|
|
damageForce = -10f;
|
|
damage = 0f;
|
|
_target = _cha1;
|
|
Stun((int)damage);
|
|
break;
|
|
}
|
|
case GameLayer.ShockAttack:
|
|
{
|
|
damageForce = 40f;
|
|
damage = sourceCha.damage;
|
|
if (sourceCha.IsMainPlayer())
|
|
{
|
|
GameCamera.Instance.Hitcam();
|
|
}
|
|
_target = _cha1;
|
|
if (Shock((int)damage))
|
|
{
|
|
EnemyHelper.Instance.CreateBlood(myPosition, _behitDirection);
|
|
}
|
|
break;
|
|
}
|
|
case GameLayer.DarkAttack:
|
|
{
|
|
damageForce = 40f;
|
|
damage = sourceCha.damage;
|
|
if (sourceCha.IsMainPlayer())
|
|
{
|
|
GameCamera.Instance.Hitcam();
|
|
}
|
|
_target = _cha1;
|
|
if (Darken((int)damage))
|
|
{
|
|
EnemyHelper.Instance.CreateBlood(myPosition, _behitDirection);
|
|
}
|
|
break;
|
|
}
|
|
case GameLayer.RiseupAttack2:
|
|
{
|
|
damageForce = 0f;
|
|
damage = sourceCha.damage * 0.4f;
|
|
if (_risedrop)
|
|
{
|
|
_riseFactor = 0.6f;
|
|
}
|
|
else
|
|
{
|
|
transform.rotation = Random.rotation;
|
|
_riseFactor = 3.4f;
|
|
}
|
|
_risedrop = true;
|
|
_target = _cha1;
|
|
EnemyHelper.Instance.CreateBlood_Only(myPosition, _behitDirection);
|
|
break;
|
|
}
|
|
case GameLayer.RiseupAttack:
|
|
{
|
|
damageForce = 0f;
|
|
damage = sourceCha.damage * 0.4f;
|
|
GameCamera.Instance.Hitcam2(0.08f);
|
|
if (_risedrop)
|
|
{
|
|
_riseFactor = 0.6f;
|
|
}
|
|
else
|
|
{
|
|
transform.rotation = Random.rotation;
|
|
_riseFactor = 1.2f;
|
|
}
|
|
_risedrop = true;
|
|
_target = _cha1;
|
|
EnemyHelper.Instance.CreateBlood(myPosition, _behitDirection);
|
|
break;
|
|
}
|
|
}
|
|
damage -= realDefence;
|
|
damage += damage * addDamage;
|
|
damage = Mathf.Max(1f, damage);
|
|
|
|
SetMoveSpeed(0f);
|
|
|
|
EnemyHelper.Instance.SoundOn(1);
|
|
if (!isLife)
|
|
{
|
|
if (pierce)
|
|
{
|
|
PlayAnimation(Hash_Pierced);
|
|
}
|
|
else
|
|
{
|
|
_animator.enabled = false;
|
|
StopAnimation();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (downHigh)
|
|
{
|
|
transform.Rotate(0f, Random.Range(0, 360), 0f);
|
|
PlayAnimation(Hash_Down_High);
|
|
}
|
|
else
|
|
{
|
|
PlayAnimation(Hash_Down, 0f);
|
|
}
|
|
|
|
if (damageForce > 0f)
|
|
this.AddForce(_behitDirection * damageForce);
|
|
if (_direction == Vector3.zero)
|
|
{
|
|
_direction = -Vector3.forward;
|
|
}
|
|
|
|
if (damage > 0)
|
|
{
|
|
curHp -= (int)damage;
|
|
SetDamageNumber(transform.position, (int)damage, _behitDirection, _scriptCha.critDamage);
|
|
SetHpBar(curHp, maxHp, -1);
|
|
}
|
|
//if (Random.Range(0, 5) == 0)
|
|
//{
|
|
// PlaySound(EnemyHelper.Instance.ScreamSFX());
|
|
//}
|
|
}
|
|
|
|
if (curHp <= 0 && isLife)
|
|
{
|
|
if (!_risedrop)
|
|
{
|
|
Dead(2);
|
|
}
|
|
}
|
|
else if (_fixedTarget)
|
|
{
|
|
_target = _targetOnlyone;
|
|
}
|
|
if (EntityCart.Instance)
|
|
{
|
|
_target = EntityCart.Instance.transform;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public override void UpdateState()
|
|
{
|
|
if (!entityView.initSuccess)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!isLife)
|
|
{
|
|
return;
|
|
}
|
|
|
|
base.UpdateState();
|
|
|
|
//
|
|
UpdateRiseDrop();
|
|
|
|
_behaviourDelay -= deltaTime;
|
|
|
|
var currentStateInfo = _animator.GetCurrentAnimatorStateInfo(0);
|
|
int currStateNameHash = currentStateInfo.shortNameHash;
|
|
int currStateTagHash = currentStateInfo.tagHash;
|
|
|
|
if (_grabed)
|
|
{
|
|
if (currStateTagHash == Hash_Begrab)
|
|
{
|
|
_scriptCha.Grabfinish(transform.position, transform.forward);
|
|
moveState = -2;
|
|
transform.position = _cha1.position;
|
|
}
|
|
else if (currStateTagHash == Hash_Bethrust)
|
|
{
|
|
_scriptCha.Grabfinish(transform.position, transform.forward);
|
|
if (moveState != -3)
|
|
{
|
|
curHp = 0;
|
|
SetHpBar(0);
|
|
var transform2 = _scriptCha.scriptWeapon.main_hand;// GameObject.Find("weapon_dummy");
|
|
if (transform2)
|
|
{
|
|
Quaternion dir = Quaternion.LookRotation(-transform2.forward, new Vector3(0f, -1.3f, 1f));
|
|
EnemyHelper.Instance.CreateGrabBlood(transform2.position + transform2.forward * 0.01f, dir);
|
|
}
|
|
GameCamera.Instance.Hitcam2(1f);
|
|
EnemyHelper.Instance.SoundOn(3);
|
|
}
|
|
moveState = -3;
|
|
}
|
|
else if (currStateTagHash == Hash_Bekicked)
|
|
{
|
|
if (moveState != -4)
|
|
{
|
|
AddForwardForce(EnemyHelper.Instance.GetKickForce(_grabStyle));
|
|
GameCamera.Instance.Hitcam2(1f);
|
|
EnemyHelper.Instance.SoundOn(2);
|
|
if (curHp <= 0)
|
|
{
|
|
Dead(1);
|
|
}
|
|
else
|
|
{
|
|
//if (_grabStyle != 6)
|
|
//{
|
|
// myanimation.AddClip(script_monEf.getup[_grabStyle], "getup");
|
|
//}
|
|
//var getup = myanimation.PlayQueued("getup");
|
|
//getup.speed = script_monEf.speed_getup[_grabStyle];
|
|
}
|
|
}
|
|
moveState = -4;
|
|
_grabed = false;
|
|
}
|
|
}
|
|
else if (currStateTagHash == Hash_Getup)
|
|
{
|
|
moveState = 0;
|
|
}
|
|
else if (currStateNameHash == Hash_Summon)
|
|
{
|
|
moveState = 0;
|
|
}
|
|
else if (currStateNameHash == Hash_Down_High)
|
|
{
|
|
moveState = -1;
|
|
}
|
|
else if (currStateNameHash == Hash_Down)
|
|
{
|
|
moveState = -1;
|
|
}
|
|
else if (currStateNameHash == Hash_Attack1)
|
|
{
|
|
_impact = false;
|
|
moveState = 11;
|
|
var _lookRotation = Quaternion.LookRotation(_attackStartDirection);
|
|
transform.rotation = Quaternion.Lerp(transform.rotation, _lookRotation, deltaTime * 6f);
|
|
transform.position += _attackStartDirection * (deltaTime * _movingAtk);
|
|
}
|
|
else if (currStateNameHash == Hash_Attack1_I)
|
|
{
|
|
moveState = 12;
|
|
if (!_impact)
|
|
{
|
|
_impact = true;
|
|
|
|
if (_dash > 0)
|
|
{
|
|
AddForce(_attackStartDirection * _dash);
|
|
}
|
|
|
|
Vector3 bulletPosition = _attackStartPosition;
|
|
if (!_useTargetPosition)
|
|
bulletPosition = transform.TransformPoint(_bullet.localPosition);
|
|
if (_cloneBullet == null)
|
|
{
|
|
_cloneBullet = Instantiate(_bullet, bulletPosition, transform.rotation);
|
|
_cloneBullet.GetComponent<EnemyDamage>().PressDamage(this.attack);
|
|
if (_attachWeaponEf)
|
|
{
|
|
_cloneBullet.parent = transform;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_cloneBullet.SetPositionAndRotation(bulletPosition, transform.rotation);
|
|
_cloneBullet.gameObject.SetActive(true);
|
|
}
|
|
|
|
PlaySound(_attackSound);
|
|
|
|
Vector3 pos = transform.position;
|
|
pos.y = 0f;
|
|
transform.position = pos;
|
|
}
|
|
}
|
|
else if (currStateNameHash == Hash_Idle || currStateNameHash == Hash_Move)
|
|
{
|
|
_attackDelay -= deltaTime;
|
|
if (_attackDelay <= 0f)
|
|
_attackStart = false;
|
|
_grabed = false;
|
|
moveState = 1;
|
|
}
|
|
else
|
|
{
|
|
moveState = 1;
|
|
}
|
|
|
|
if (moveState == 1)
|
|
{
|
|
this.transform.position += _direction * (moveSpeed * deltaTime);
|
|
if (_animator.enabled)
|
|
{
|
|
this.transform.rotation = Quaternion.Lerp(transform.rotation, _lookRotation, deltaTime * 3f);
|
|
}
|
|
}
|
|
|
|
//
|
|
UpdateArrow();
|
|
|
|
//du
|
|
UpdatePoison();
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private void UpdateRiseDrop()
|
|
{
|
|
if (_risedrop)
|
|
{
|
|
Vector3 position = this.transform.position;
|
|
position += Vector3.up * (_riseFactor * deltaTime);
|
|
_riseFactor -= deltaTime * 5f;
|
|
|
|
if (position.y >= 0f)
|
|
{
|
|
this.transform.position = position;
|
|
return;
|
|
}
|
|
|
|
position.y = 0f;
|
|
this.transform.position = position;
|
|
|
|
PlayAnimation(Hash_Down);
|
|
|
|
_risedrop = false;
|
|
_riseFactor = 0f;
|
|
|
|
var damage = _scriptCha.damage;
|
|
curHp -= damage;
|
|
|
|
if (curHp <= 0)
|
|
{
|
|
Dead(3);
|
|
}
|
|
else if (_behitDirection != Vector3.zero)
|
|
{
|
|
transform.rotation = Quaternion.LookRotation(_behitDirection);
|
|
}
|
|
else
|
|
{
|
|
transform.rotation = Quaternion.identity;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private void UpdatePoison()
|
|
{
|
|
//中毒
|
|
if (_poison)
|
|
{
|
|
_poisonDelay -= deltaTime;
|
|
if (_poisonDelay < 0f)
|
|
{
|
|
_poison = false;
|
|
SetHpBar(curHp, maxHp, 0);
|
|
}
|
|
else if ((int)_poisonDelay != _lastPoisonDelay)
|
|
{
|
|
curHp -= (int)_poisonDamage;
|
|
|
|
SetDamageNumber(transform.position, (int)_poisonDamage, _behitDirection);
|
|
SetHpBar(curHp, maxHp, 1);
|
|
|
|
_lastPoisonDelay = (int)_poisonDelay;
|
|
if (curHp <= 0)
|
|
{
|
|
Dead(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ForAI
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public void SimpleAI()
|
|
{
|
|
if (!isLife || _spawning)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (_target == null)
|
|
{
|
|
_target = GetDefaultTarget();
|
|
}
|
|
|
|
switch (_attributeStatus)
|
|
{
|
|
//dark
|
|
case 4:
|
|
_attackRange = 2f;
|
|
_direction = transform.position - _target.position;
|
|
_direction.y = 0f;
|
|
_direction = Vector3.Normalize(_direction);
|
|
break;
|
|
//shock
|
|
case 3:
|
|
_direction = -transform.forward;
|
|
_attackRange = 2f;
|
|
break;
|
|
//freeze
|
|
case 2:
|
|
_direction = Vector3.zero;
|
|
_attackRange = 2f;
|
|
break;
|
|
default:
|
|
_direction = _target.position - transform.position;
|
|
_attackRange = _direction.magnitude;
|
|
_direction.y = 0f;
|
|
_direction = Vector3.Normalize(_direction);
|
|
break;
|
|
}
|
|
|
|
if (_direction != Vector3.zero)
|
|
{
|
|
_lookRotation = Quaternion.LookRotation(_direction);
|
|
}
|
|
|
|
//几种行为
|
|
if (_behaviourDelay < 0f)
|
|
{
|
|
_behaviour = Random.Range(0, 6);
|
|
if (_behaviour == 0)
|
|
{
|
|
if (_moveSound)
|
|
PlaySound(_moveSound);
|
|
}
|
|
_behaviourDelay = 2f;
|
|
}
|
|
|
|
if (_attackRange < _fireRange)
|
|
{
|
|
if (!_attackStart && moveState >= 0 && _scriptCha.CanSelectAsTarget())
|
|
{
|
|
PlayAnimation(Hash_Attack1);
|
|
|
|
_attackStart = true;
|
|
_attackDelay = attackCd;
|
|
_attackStartDirection = _direction;
|
|
_attackStartPosition = _target.position;
|
|
|
|
//开始攻击
|
|
if (_warning)
|
|
{
|
|
var clone_line = Instantiate(_warning, _useTargetPosition ? _attackStartPosition : transform.position, Quaternion.LookRotation(_attackStartDirection));
|
|
Destroy(clone_line.gameObject, 1f);
|
|
}
|
|
|
|
if (_resetTarget)
|
|
{
|
|
_target = _cha1;
|
|
_resetTarget = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
moveSpeed = _item.backSpeed;
|
|
SetFloat(Hash_Speed_Idle, _idleAnimSpeed * -0.5f);
|
|
|
|
_behaviour = -1;
|
|
_behaviourDelay = 1f;
|
|
}
|
|
}
|
|
else if (_mainRender.isVisible)
|
|
{
|
|
if (_behaviour != -1)
|
|
{
|
|
if (_behaviour >= 3)
|
|
{
|
|
SetFloat(Hash_Speed_Idle, _idleAnimSpeed);
|
|
SetMoveSpeed(0.4f);
|
|
}
|
|
else
|
|
{
|
|
SetMoveSpeed(1f);
|
|
}
|
|
}
|
|
|
|
if (_lastMon)
|
|
{
|
|
ShowArrow(false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetMoveSpeed(Random.Range(0.7f, 1f));
|
|
if (_direction != Vector3.zero)
|
|
{
|
|
transform.rotation = Quaternion.LookRotation(_direction);
|
|
}
|
|
|
|
if (_lastMon)
|
|
{
|
|
ShowArrow(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void StartAI()
|
|
{
|
|
//if (behaviorTree)
|
|
// StartCoroutine(nameof(AICoroutine));
|
|
//else
|
|
InvokeRepeating(nameof(SimpleAI), 0.1f, 0.5f);
|
|
}
|
|
|
|
public override void EndAI(bool pause)
|
|
{
|
|
CancelInvoke(nameof(SimpleAI));
|
|
//StopCoroutine(nameof(AICoroutine));
|
|
}
|
|
|
|
private IEnumerator AICoroutine()
|
|
{
|
|
yield return new WaitForSeconds(0.1f);
|
|
while (true)
|
|
{
|
|
UpdateAI();
|
|
yield return new WaitForSeconds(0.5f);
|
|
}
|
|
}
|
|
|
|
private void UpdateAI()
|
|
{
|
|
if (!isLife | _spawning)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (_target == null)
|
|
{
|
|
_target = _cha1;
|
|
}
|
|
|
|
switch (_attributeStatus)
|
|
{
|
|
case 4:
|
|
_attackRange = 2f;
|
|
_direction = transform.position - _target.position;
|
|
_direction.y = 0f;
|
|
_direction = Vector3.Normalize(_direction);
|
|
break;
|
|
case 3:
|
|
_direction = -transform.forward;
|
|
_attackRange = 2f;
|
|
break;
|
|
case 2:
|
|
_direction = Vector3.zero;
|
|
_attackRange = 2f;
|
|
break;
|
|
default:
|
|
_attackRange = Vector3.Distance(transform.position, _target.position);
|
|
_direction = _target.position - transform.position;
|
|
_direction.y = 0f;
|
|
_direction = Vector3.Normalize(_direction);
|
|
break;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
|