1010 lines
32 KiB
C#
1010 lines
32 KiB
C#
// ***********************************************************************
|
|
// Assembly : Unity
|
|
// Author : Kimch
|
|
// Created : 2018-2-29
|
|
// Description : 游戏Boss
|
|
// Last Modified By :
|
|
// Last Modified On :
|
|
// ***********************************************************************
|
|
// <copyright file= "EntityBoss" company=""></copyright>
|
|
// <summary></summary>
|
|
// ***********************************************************************
|
|
using System.Collections;
|
|
using UnityEngine;
|
|
|
|
namespace G
|
|
{
|
|
/// <summary>
|
|
/// 游戏Boss
|
|
/// </summary>
|
|
public sealed class EntityBoss : EntityEnemy
|
|
{
|
|
private const int MAX_SKILL_COUNT = 3;
|
|
|
|
class SkillWrapper
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public BossInfo.SkillInfo skillInfo;
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public int power;
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public float fireRange;
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public Vector2 movingAttack;
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public Transform skillClone;
|
|
}
|
|
|
|
#region Field
|
|
|
|
private bool _attackStart;
|
|
private float _attackDelay;
|
|
|
|
private int _attackKind;
|
|
private bool _setAttackKind;
|
|
|
|
private Transform _transform;
|
|
|
|
private bool _bossCutin;
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private float _movingAttackDelay;
|
|
|
|
private bool _jump;
|
|
|
|
private ItemBoss _item;
|
|
|
|
private BossInfo _bossInfo;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private readonly SkillWrapper[] _skillWrappers = new SkillWrapper[MAX_SKILL_COUNT];
|
|
|
|
#endregion
|
|
|
|
#region Property
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public override EntityType entityType
|
|
{
|
|
get { return EntityType.Boss; }
|
|
}
|
|
|
|
private Transform _secondSkill => _bossInfo.weapon_ef;
|
|
|
|
#endregion
|
|
|
|
#region Method
|
|
|
|
public override bool Init(EntityInfo info)
|
|
{
|
|
if (info != null)
|
|
{
|
|
_item = ItemProxy.Instance.GetStaticItem<ItemBoss>(info.itemId);
|
|
|
|
for (int i = 0; i < _skillWrappers.Length; i++)
|
|
{
|
|
_skillWrappers[i] = new SkillWrapper();
|
|
_skillWrappers[i].movingAttack = GlobalUtils.GetVector2(_item.moving_attack[i]);
|
|
_skillWrappers[i].fireRange = _item.fireRange[i];
|
|
}
|
|
|
|
SetLevel(info.factorA, info.factorB);
|
|
|
|
_scriptCha = EntityMainPlayer.Instance;
|
|
_cha1 = _scriptCha.transform;
|
|
_target = _cha1;
|
|
|
|
InitRigbody(_item.mass);
|
|
|
|
moveState = 0;
|
|
}
|
|
return base.Init(info);
|
|
}
|
|
|
|
protected override void OnViewInitCompleted()
|
|
{
|
|
base.OnViewInitCompleted();
|
|
|
|
var viewGO = entityView.gameObject;
|
|
|
|
_bossInfo = viewGO.GetComponent<BossInfo>();
|
|
|
|
var orb = viewGO.GetComponent<Rigidbody>();
|
|
Destroy(orb);
|
|
|
|
_transform = this.transform;
|
|
EnemyHelper.Instance.CreateShadow(_transform, 2.2f);
|
|
|
|
SetModel(viewGO);
|
|
|
|
SetFloat(Hash_Speed_Attack1, _item.speed_attack[0]);
|
|
SetFloat(Hash_Speed_Attack1_I, _item.speed_attack_i[0]);
|
|
SetFloat(Hash_Speed_Attack2, _item.speed_attack[1]);
|
|
SetFloat(Hash_Speed_Attack2_I, _item.speed_attack_i[1]);
|
|
SetFloat(Hash_Speed_Attack3, _item.speed_attack[2]);
|
|
SetFloat(Hash_Speed_Attack3_I, _item.speed_attack_i[2]);
|
|
|
|
//
|
|
CreateHpBar();
|
|
//
|
|
_cloneArrow = Object.Instantiate(_bossInfo.direction_arrow);
|
|
_cloneArrow.gameObject.SetActive(false);
|
|
|
|
StartAI();
|
|
|
|
UI_Ingame.Instance.ShowEffect("UI_fx_Boss01");
|
|
//GlobalNotifier.PostNotification(GlobalDefine.EVENT_SHOW_EFFECT, "21539_", "");
|
|
}
|
|
|
|
public override void CreateHpBar()
|
|
{
|
|
_blood = BoardManager.Instance.CreateBloodBoard("BloodBoard1");
|
|
_blood.SetFixedPosition();
|
|
_blood.SetName(_item.name);
|
|
SetHpBar();
|
|
}
|
|
|
|
public override void DestroyHpBar()
|
|
{
|
|
if (_blood)
|
|
{
|
|
_blood.ReleaseWaitFinish();
|
|
_blood = null;
|
|
}
|
|
}
|
|
|
|
public override void SetHpBar(int cur, int max, float height, int index)
|
|
{
|
|
_blood.SetMultiHp(cur, max, 100);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="kind"></param>
|
|
public override void Dead(int kind)
|
|
{
|
|
moveState = -4;
|
|
|
|
EnemyHelper.Instance.SoundOn(4);
|
|
|
|
if (_bossInfo.weapon)
|
|
{
|
|
var dropWeapon = Object.Instantiate(_bossInfo.weapon);
|
|
dropWeapon.parent = null;
|
|
dropWeapon.GetComponent<WeaponDrop>().Drop(true);
|
|
}
|
|
|
|
for (int i = 0; i < _skillWrappers.Length; i++)
|
|
{
|
|
if (_skillWrappers[i].skillClone)
|
|
Object.Destroy(_skillWrappers[i].skillClone.gameObject);
|
|
}
|
|
|
|
if (_secondSkill != null)
|
|
{
|
|
Object.Destroy(_secondSkill.gameObject);
|
|
}
|
|
|
|
EnemyHelper.Instance.EnemyDead(kind, transform.position, Vector3.one * 2.5f, -_transform.forward, _originTex);
|
|
GameLevel.Instance.BossKill(itemId);
|
|
|
|
base.Dead(kind);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="speedRate"></param>
|
|
public void SetMoveSpeed(float speedRate)
|
|
{
|
|
moveSpeed = _item.runSpeed * speedRate;
|
|
SetFloat(Hash_Speed_Move, speedRate);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
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>
|
|
/// <param name="level"></param>
|
|
/// <param name="restrictArea"></param>
|
|
public void SetLevel(float[] a, float[] b)
|
|
{
|
|
for (int i = 0; i < _skillWrappers.Length; i++)
|
|
{
|
|
_skillWrappers[i].power = (int)(_item.power[i] * 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);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <returns></returns>
|
|
public float GetFireRange(int index)
|
|
{
|
|
return _skillWrappers[index].fireRange;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <returns></returns>
|
|
public int GetDamage(int index)
|
|
{
|
|
return _skillWrappers[index].power;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <returns></returns>
|
|
public Vector2 GetMovingAttack(int index)
|
|
{
|
|
return _skillWrappers[index].movingAttack;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 撞击
|
|
/// </summary>
|
|
public void Impact()
|
|
{
|
|
_secondSkill?.GetComponent<EnemyDamage>()?.PressDamage(GetDamage(_attackKind));
|
|
_secondSkill?.gameObject.SetActive(true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 撞击
|
|
/// </summary>
|
|
public void Impact2()
|
|
{
|
|
_secondSkill?.GetComponent<EnemyDamage>()?.PressDamage(GetDamage(_attackKind));
|
|
_secondSkill?.gameObject.SetActive(true);
|
|
GameCamera.Instance.Hitcam();
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private void TurnNormal()
|
|
{
|
|
this.invincible = false;
|
|
InvokeRepeating(nameof(SimpleAI), 0.3f, 0.5f);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 显示预警
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
public void ShowSkillWarningIndex(int index)
|
|
{
|
|
var skillInfo = _bossInfo.skillInfos[index];
|
|
//显示预警
|
|
if (skillInfo.warning != null)
|
|
{
|
|
var clone_decal = Instantiate(skillInfo.warning).transform;
|
|
var ef_tr = skillInfo.skill;
|
|
|
|
if (skillInfo.useTargetPosition)
|
|
{
|
|
clone_decal.position = _attackStartPosition;
|
|
clone_decal.rotation = Quaternion.LookRotation(_attackStartDirection);
|
|
}
|
|
else
|
|
{
|
|
Quaternion oldRotation = _transform.rotation;
|
|
_transform.rotation = Quaternion.LookRotation(_attackStartDirection);
|
|
|
|
clone_decal.parent = _transform;
|
|
var ef_position = ef_tr.transform.localPosition;
|
|
ef_position.y = 0f;
|
|
clone_decal.localPosition = ef_position;
|
|
clone_decal.localRotation = Quaternion.identity;
|
|
clone_decal.parent = null;
|
|
|
|
_transform.rotation = oldRotation;
|
|
}
|
|
|
|
var ef_col = ef_tr.GetComponent<Collider>();
|
|
|
|
//Vector3 atk_mov = Vector3.zero;
|
|
//if (_movingAttack[_attackKind] != Vector2.zero)
|
|
//{
|
|
// atk_mov = _attackStartDirection * _movingAttack[_attackKind].x * _movingAttack[_attackKind].y;
|
|
//}
|
|
|
|
//clone_decal.forward = _attackDirection;
|
|
|
|
if (ef_col is SphereCollider sc)
|
|
{
|
|
clone_decal.localScale = Vector3.one * sc.radius;
|
|
}
|
|
else if (ef_col is BoxCollider bc)
|
|
{
|
|
clone_decal.localScale = bc.size;// new Vector3(bc.size.x, 1f, bc.size.z);
|
|
}
|
|
Destroy(clone_decal.gameObject, 1f);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 发动技能
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
public void LaunchSkill(int index)
|
|
{
|
|
var skillInfo = _bossInfo.skillInfos[index];
|
|
|
|
var ef_position = skillInfo.skill.transform.localPosition;
|
|
var ef_rotation = Quaternion.LookRotation(_attackStartDirection);
|
|
|
|
if (skillInfo.useTargetPosition)
|
|
{
|
|
ef_position += _attackStartPosition;
|
|
}
|
|
else
|
|
{
|
|
ef_position = _transform.TransformPoint(ef_position);
|
|
}
|
|
|
|
var skillWrapper = _skillWrappers[_attackKind];
|
|
if (!skillWrapper.skillClone)
|
|
{
|
|
if (!skillInfo.instance)
|
|
{
|
|
var skillClone = Instantiate(skillInfo.skill, ef_position, ef_rotation);
|
|
skillClone.SetActive(true);
|
|
skillWrapper.skillClone = skillClone.transform;
|
|
|
|
var attach_weaponEf = _item.attach_ef;
|
|
if (attach_weaponEf != null && attach_weaponEf[_attackKind] >= 1)
|
|
{
|
|
skillWrapper.skillClone.parent = _transform;
|
|
if (_secondSkill && attach_weaponEf[_attackKind] == 2)
|
|
{
|
|
Impact();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var skillClone = skillInfo.skill;
|
|
skillClone.SetActive(true);
|
|
skillWrapper.skillClone = skillClone.transform;
|
|
}
|
|
|
|
var mainDamageComp = skillWrapper.skillClone.GetComponent<EnemyDamage>();
|
|
if (mainDamageComp)
|
|
mainDamageComp.SetDamage(GetDamage(_attackKind), 50);
|
|
else
|
|
Debug.Log("mainDamageComp = null" + this.itemId);
|
|
}
|
|
else
|
|
{
|
|
skillWrapper.skillClone.position = ef_position;
|
|
skillWrapper.skillClone.rotation = ef_rotation;
|
|
skillWrapper.skillClone.gameObject.SetActive(true);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="allyDamage"></param>
|
|
/// <param name="damageLayer"></param>
|
|
public override void OnDamage(AllyDamage allyDamage, int damageLayer)
|
|
{
|
|
if (this.invincible)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var sourceCha = allyDamage.source;
|
|
var myPosition = this.position;
|
|
_setAttackKind = true;
|
|
|
|
float damage = 0f;
|
|
float addDamage = sourceCha.伤害加深百分比 * 0.01f;
|
|
float realDefence = (defence - sourceCha.忽视防御固定值) * (100 - sourceCha.忽视防御百分比) * 0.01f;
|
|
float damageForce = 0f;
|
|
|
|
var damageDir = Vector3.zero;
|
|
if (damageLayer == GameLayer.PushAttack)
|
|
{
|
|
damageDir = myPosition - sourceCha.position;
|
|
damageDir.y = 0f;
|
|
damageDir = Vector3.Normalize(damageDir);
|
|
}
|
|
else
|
|
{
|
|
damageDir = myPosition - allyDamage.transform.position;
|
|
damageDir.y = 0f;
|
|
damageDir = Vector3.Normalize(damageDir);
|
|
}
|
|
if (damageDir == Vector3.zero)
|
|
{
|
|
damageDir = -Vector3.forward;
|
|
}
|
|
|
|
switch (damageLayer)
|
|
{
|
|
case GameLayer.NormalAttack:
|
|
//other.transform.root.GetComponent<Rigidbody>().AddForce(-_attackDirection * 80f);
|
|
GameCamera.Instance.Hitcam();
|
|
damageForce = 60f;
|
|
|
|
var sourceHitRate = sourceCha.sourceTotalHitRate;
|
|
int blockRate = (int)((block - sourceHitRate) * 1000f / Mathf.Max(block, sourceHitRate, 1) + 100);
|
|
if (moveState >= 0 && GlobalUtils.RndThousand < blockRate)
|
|
{
|
|
this.AddForce(damageDir * 10f);
|
|
sourceCha.Blocked(myPosition);
|
|
return;
|
|
}
|
|
damage = sourceCha.damage;
|
|
_target = _cha1;
|
|
EnemyHelper.Instance.CreateBlood(myPosition, damageDir);
|
|
break;
|
|
case GameLayer.PowerAttack:
|
|
damageForce = 100f;
|
|
realDefence *= 0.5f;
|
|
damage = sourceCha.damage;
|
|
_target = _cha1;
|
|
GameCamera.Instance.Hitcam2(1f);
|
|
EnemyHelper.Instance.CreateBlood_Only(myPosition, damageDir);
|
|
break;
|
|
case GameLayer.SkillAttack:
|
|
GameCamera.Instance.Hitcam();
|
|
damageForce = 50f;
|
|
damage = allyDamage.physicsDamage;
|
|
_target = _cha1;
|
|
EnemyHelper.Instance.CreateBlood(myPosition, damageDir);
|
|
break;
|
|
case GameLayer.PoisonAttack:
|
|
{
|
|
damage = allyDamage.physicsDamage;
|
|
if (damage == 0.1f)
|
|
{
|
|
damage = 0f;
|
|
_poison = true;
|
|
_poisonDamage = sourceCha.damage * 0.6f;
|
|
_poisonDelay = 4f;
|
|
_target = _cha1;
|
|
return;
|
|
}
|
|
|
|
damageForce = 100f;
|
|
_poisonDamage = damage;
|
|
_poison = true;
|
|
_poisonDelay = 12f;
|
|
damage *= 2f;
|
|
_target = _cha1;
|
|
GameCamera.Instance.Hitcam();
|
|
EnemyHelper.Instance.CreateBlood(myPosition, damageDir);
|
|
break;
|
|
}
|
|
case GameLayer.DeathAttack:
|
|
damageForce = 100f;
|
|
|
|
//var petrifyRate = (int)(allyDamage.physicsDamage * 0.01f);
|
|
Petrify(0);
|
|
_target = _cha1;
|
|
GameCamera.Instance.Hitcam();
|
|
break;
|
|
case GameLayer.GeneralAttack:
|
|
damageForce = 60f;
|
|
damage = sourceCha.damage * EntityPet.Instance.bulletDamage;
|
|
_target = _cha1;
|
|
EnemyHelper.Instance.CreateBlood_Only(myPosition, damageDir);
|
|
break;
|
|
case GameLayer.PierceAttack:
|
|
damageForce = 10f;
|
|
damage = allyDamage.physicsDamage;
|
|
curHp -= (int)damage;
|
|
SetHpBar(0, maxHp);
|
|
|
|
_target = _cha1;
|
|
EnemyHelper.Instance.CreateBlood_Only(myPosition, damageDir);
|
|
PlayAnimation(Hash_Down, 0f);
|
|
break;
|
|
case GameLayer.PushAttack://
|
|
damageForce = 100f;
|
|
damage = sourceCha.damage;
|
|
_target = _cha1;
|
|
GameCamera.Instance.Hitcam();
|
|
EnemyHelper.Instance.CreateBlood(myPosition, damageDir);
|
|
break;
|
|
case GameLayer.RiseupAttack2:
|
|
damageForce = 50f;
|
|
damage = sourceCha.damage * 0.4f;
|
|
_target = _cha1;
|
|
EnemyHelper.Instance.CreateBlood(myPosition, damageDir);
|
|
break;
|
|
case GameLayer.BurnAttack:
|
|
damageForce = 100f;
|
|
damage = sourceCha.damage;
|
|
_target = _cha1;
|
|
GameCamera.Instance.Hitcam();
|
|
EnemyHelper.Instance.CreateBlood(myPosition, damageDir);
|
|
break;
|
|
case GameLayer.ColdAttack:
|
|
damageForce = 100f;
|
|
damage = sourceCha.damage;
|
|
_target = _cha1;
|
|
GameCamera.Instance.Hitcam();
|
|
EnemyHelper.Instance.CreateBlood(myPosition, damageDir);
|
|
break;
|
|
case GameLayer.StunAttack:
|
|
damageForce = -50f;
|
|
damage = 0f;
|
|
_target = _cha1;
|
|
Stun((int)damage);
|
|
break;
|
|
case GameLayer.RiseupAttack:
|
|
damageForce = 40f;
|
|
damage = allyDamage.physicsDamage;
|
|
_target = _cha1;
|
|
GameCamera.Instance.Hitcam2(0.2f);
|
|
EnemyHelper.Instance.CreateBlood(myPosition, damageDir);
|
|
break;
|
|
case GameLayer.ShockAttack:
|
|
damageForce = 100f;
|
|
damage = sourceCha.damage;
|
|
_target = _cha1;
|
|
GameCamera.Instance.Hitcam();
|
|
EnemyHelper.Instance.CreateBlood(myPosition, damageDir);
|
|
break;
|
|
case GameLayer.DarkAttack:
|
|
damageForce = 100f;
|
|
damage = sourceCha.damage;
|
|
_target = _cha1;
|
|
GameCamera.Instance.Hitcam();
|
|
EnemyHelper.Instance.CreateBlood(myPosition, damageDir);
|
|
break;
|
|
}
|
|
|
|
if (!isLife)
|
|
{
|
|
EnemyHelper.Instance.SoundOn(1);
|
|
//myanimation.Stop();
|
|
return;
|
|
}
|
|
EnemyHelper.Instance.SoundOn(1);
|
|
|
|
damage -= realDefence;
|
|
damage += damage * addDamage;
|
|
damage = Mathf.Max(1, damage);
|
|
|
|
int num = Mathf.Max(1, (int)(maxHp * 0.3f));
|
|
int num2 = curHp / num;
|
|
if (curHp == maxHp)
|
|
{
|
|
num2--;
|
|
}
|
|
|
|
curHp -= (int)damage;
|
|
SetDamageNumber(_transform.position, (int)damage, damageDir, _scriptCha.critDamage);
|
|
SetHpBar();
|
|
|
|
if (curHp <= 0 && isLife)
|
|
{
|
|
Dead(2);
|
|
}
|
|
else if (curHp < num * num2)
|
|
{
|
|
GameLevel.Instance.Summon(4, transform.position);
|
|
damageForce = 300f;
|
|
PlayAnimation(Hash_Down);
|
|
|
|
var skillWrapper = _skillWrappers[_attackKind];
|
|
if (skillWrapper.skillClone)
|
|
{
|
|
skillWrapper.skillClone.gameObject.SetActive(false);
|
|
skillWrapper.skillClone.position = Vector3.one * 8f;
|
|
}
|
|
|
|
if (_secondSkill != null)
|
|
{
|
|
_secondSkill.gameObject.SetActive(false);
|
|
}
|
|
PlaySound(_bossInfo.snd_scream);
|
|
}
|
|
AddForce(damageDir * damageForce);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public override void UpdateState()
|
|
{
|
|
if (!entityView.initSuccess)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!isLife)
|
|
{
|
|
return;
|
|
}
|
|
|
|
base.UpdateState();
|
|
|
|
_behaviourDelay -= deltaTime;
|
|
|
|
UpdateAnim();
|
|
|
|
//显示箭头
|
|
UpdateArrow();
|
|
|
|
//中毒
|
|
UpdatePoison();
|
|
|
|
//限制范围
|
|
UpdateRestrictArea();
|
|
}
|
|
|
|
private bool _isSkilling = false;
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private void UpdateAnim()
|
|
{
|
|
if (_isSkilling)
|
|
{
|
|
var skillWrapper = _skillWrappers[_attackKind];
|
|
var director = skillWrapper.skillClone.GetComponent<UnityEngine.Playables.PlayableDirector>();
|
|
if (director.state != UnityEngine.Playables.PlayState.Playing)
|
|
{
|
|
_isSkilling = false;
|
|
_attackDelay = _item.attackCd;
|
|
skillWrapper.skillClone.gameObject.SetActive(false);
|
|
}
|
|
return;
|
|
}
|
|
|
|
var currentStateInfo = _animator.GetCurrentAnimatorStateInfo(0);
|
|
int stateNameHash = currentStateInfo.shortNameHash;
|
|
int stateTagHash = currentStateInfo.tagHash;
|
|
|
|
if (stateNameHash == Hash_Idle)
|
|
{
|
|
_attackDelay -= deltaTime;
|
|
if (_attackDelay < 0f)
|
|
{
|
|
_attackStart = false;
|
|
}
|
|
|
|
moveState = 1;
|
|
_transform.position += _direction * (deltaTime * moveSpeed);
|
|
if (_direction != Vector3.zero)
|
|
{
|
|
var lookrotation = Quaternion.LookRotation(_direction);
|
|
_transform.rotation = Quaternion.Lerp(_transform.rotation, lookrotation, deltaTime * 5f);
|
|
}
|
|
}
|
|
else if (stateTagHash == Hash_Attack)
|
|
{
|
|
if (_attackStartDirection != Vector3.zero)
|
|
{
|
|
var lookrotation = Quaternion.LookRotation(_attackStartDirection);
|
|
_transform.rotation = Quaternion.Lerp(_transform.rotation, lookrotation, deltaTime * _item.turnSpeed);
|
|
}
|
|
|
|
if (moveState != 11)
|
|
{
|
|
if (_item.colliderOff[_attackKind] != 0 && !_jump)
|
|
{
|
|
SetColliderEnabled(false);
|
|
_jump = true;
|
|
}
|
|
|
|
if (_secondSkill && _item.attach_ef[_attackKind] == 2)
|
|
{
|
|
_secondSkill.gameObject.SetActive(true);
|
|
}
|
|
|
|
ShowSkillWarningIndex(_attackKind);
|
|
}
|
|
|
|
//攻击动作带位移
|
|
var movingAttack = GetMovingAttack(_attackKind);
|
|
if (movingAttack != Vector2.zero)
|
|
{
|
|
if (_movingAttackDelay > movingAttack.x)
|
|
{
|
|
_transform.position += _direction * (deltaTime * movingAttack.y);
|
|
}
|
|
else
|
|
{
|
|
_movingAttackDelay += deltaTime;
|
|
}
|
|
}
|
|
moveState = 11;
|
|
}
|
|
else if (stateTagHash == Hash_Attack_I)
|
|
{
|
|
//冲击
|
|
if (moveState == 11)
|
|
{
|
|
if (_attackStartDirection != Vector3.zero)
|
|
{
|
|
var lookrotation = Quaternion.LookRotation(_attackStartDirection);
|
|
_transform.rotation = lookrotation;
|
|
}
|
|
|
|
if (_jump)
|
|
{
|
|
SetColliderEnabled(true);
|
|
_jump = false;
|
|
}
|
|
|
|
this.AddForwardForce(_item.dash[_attackKind]);
|
|
|
|
LaunchSkill(_attackKind);
|
|
|
|
_movingAttackDelay = 0f;
|
|
var position = _transform.position;
|
|
position.y = 0f;
|
|
_transform.position = position;
|
|
_attackDelay = _item.attackCd;
|
|
}
|
|
moveState = 12;
|
|
}
|
|
else if (stateNameHash == Hash_Down)
|
|
{
|
|
moveState = -1;
|
|
}
|
|
else
|
|
{
|
|
moveState = 1;
|
|
_attackDelay -= deltaTime;
|
|
if (_attackDelay < 0f)
|
|
{
|
|
_attackStart = false;
|
|
}
|
|
|
|
if (_direction != Vector3.zero)
|
|
{
|
|
var lookrotation = Quaternion.LookRotation(_direction);
|
|
_transform.rotation = Quaternion.Lerp(_transform.rotation, lookrotation, deltaTime * 5f);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private void UpdatePoison()
|
|
{
|
|
//中毒
|
|
if (_poison)
|
|
{
|
|
_poisonDelay -= deltaTime;
|
|
if (_poisonDelay < 0f)
|
|
{
|
|
_poison = false;
|
|
SetHpBar();
|
|
}
|
|
else if ((int)_poisonDelay != _lastPoisonDelay)
|
|
{
|
|
curHp -= (int)_poisonDamage;
|
|
SetHpBar();
|
|
_lastPoisonDelay = (int)_poisonDelay;
|
|
if (curHp <= 0)
|
|
{
|
|
Dead(1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private void UpdateRestrictArea()
|
|
{
|
|
//if (Vector3.SqrMagnitude(transform.position) > _restrictArea)
|
|
//{
|
|
// AddForce(-transform.position * 20f);
|
|
//}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region For AI
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public void SimpleAI()
|
|
{
|
|
if (!isLife)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!_target)
|
|
{
|
|
_target = _cha1;
|
|
}
|
|
|
|
if (_bossCutin)
|
|
{
|
|
if (_behaviourDelay < 0f)
|
|
{
|
|
_behaviour = Random.Range(0, 6);
|
|
if (_behaviour == 0)
|
|
{
|
|
PlaySound(_bossInfo.snd_move);
|
|
}
|
|
_behaviourDelay = 1f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GameLevel.Instance.BossCutin(itemId - 1);
|
|
_bossCutin = true;
|
|
|
|
_attackDelay = 2f;
|
|
_attackStart = true;
|
|
//_scriptCam.LookTarget(mytransform, 30, 0f);
|
|
}
|
|
|
|
//
|
|
Vector3 targetPosition = _target.position;
|
|
if (targetPosition.y > 2f)
|
|
{
|
|
//更换目标
|
|
_target = _cha1;
|
|
}
|
|
|
|
Vector3 myselfPosition = _transform.position;
|
|
|
|
var distance = 0f;
|
|
//
|
|
if (_attributeStatus == 2)
|
|
{
|
|
_direction = Vector3.zero;
|
|
distance = 2f;
|
|
}
|
|
else
|
|
{
|
|
_direction = targetPosition - myselfPosition;
|
|
distance = _direction.magnitude;
|
|
_direction.y = 0f;
|
|
_direction = Vector3.Normalize(_direction);
|
|
}
|
|
|
|
if (distance < GetFireRange(2))
|
|
{
|
|
ShowArrow(false);
|
|
|
|
if (_attackStart)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (moveState >= 0 && _scriptCha.moveState < MoveState.state50)
|
|
{
|
|
if (_setAttackKind)
|
|
{
|
|
_attackKind = Random.Range(0, _bossInfo.skillInfos.Length);
|
|
_setAttackKind = false;
|
|
}
|
|
|
|
var skillInfo = _bossInfo.skillInfos[_attackKind];
|
|
if (distance < GetFireRange(_attackKind))
|
|
{
|
|
if (!skillInfo.instance)
|
|
{
|
|
if (_attackKind == 0)
|
|
{
|
|
PlayAnimation(Hash_Attack1);
|
|
}
|
|
else if (_attackKind == 1)
|
|
{
|
|
PlayAnimation(Hash_Attack2);
|
|
}
|
|
else
|
|
{
|
|
PlayAnimation(Hash_Attack3);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_isSkilling = true;
|
|
LaunchSkill(_attackKind);
|
|
|
|
}
|
|
|
|
_attackStartDirection = _direction;
|
|
_attackStartPosition = targetPosition;
|
|
_setAttackKind = true;
|
|
_attackStart = true;
|
|
}
|
|
else
|
|
{
|
|
//move
|
|
|
|
SetMoveSpeed(1f);
|
|
//PlayAnim(Hash_Boss_Move);
|
|
}
|
|
}
|
|
else if (!_attackStart)
|
|
{
|
|
//PlayAnim(Hash_Boss_Idle);
|
|
SetMoveSpeed(0f);
|
|
|
|
_behaviour = 4;
|
|
_behaviourDelay = 1f;
|
|
}
|
|
}
|
|
else if (!_attackStart)
|
|
{
|
|
SetMoveSpeed(_behaviour < 5 ? 1f : 0f);
|
|
|
|
ShowArrow(true);
|
|
}
|
|
}
|
|
|
|
public override void StartAI()
|
|
{
|
|
//if (behaviorTree)
|
|
// StartCoroutine(nameof(AICoroutine));
|
|
//else
|
|
InvokeRepeating(nameof(SimpleAI), 0.3f, 0.5f);
|
|
}
|
|
|
|
public override void EndAI(bool pause)
|
|
{
|
|
CancelInvoke(nameof(SimpleAI));
|
|
//StopCoroutine(nameof(AICoroutine));
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |