using Adon.Game.Data.StructData;
using Adon.Game.Helper;
using Adon.Game.Manager;
using AdonGameKit;
using BehaviorDesigner.Runtime;
using Chronos;
using Cinemachine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using WarReport;
namespace Adon.Game.BO
{
///
/// 基础怪
///
public class BaseMonsterAdon : BaseCharacterAdon
{
///
/// 血条类
///
public MonHpBarAdon m_HpBar;
protected NavMeshAgent m_NavMeshAgent;
///
/// 时间器刚体
///
public RigidbodyTimeline3D m_RigidbodyTimeline3D;
///
/// 推力方向
///
public Vector3 m_ForceDirection;
///
/// 推力
///
public float m_Force;
///
/// 暂停时间
///
private float pauseTime = 0;
private bool isPause = false;
//protected BehaviorTreeManager m_BehaviorTreeManager;//行为树管理器
public Behavior CurrentBehaviorTree;
public float m_damageFlashScale;//损伤材质闪光强度
public BaseHero m_TargetHero;
public GameObject m_Lock;//锁定标识
BaseHero _hero;
Dictionary buffnum = new Dictionary();//buff计数
//buff效果对象列表
private GameObject[] buffs = new GameObject[20];
///
/// 是否被击
///
public bool isAttacked;
public BaseHero m_Hero
{
get
{
if (_hero == null)
{
_hero = RoleManager.Instance.GetPlayer() as BaseHero;
}
else if (_hero.gameObject.activeSelf == false)
{
_hero = RoleManager.Instance.GetPlayer() as BaseHero;
}
return _hero;
}
}
private Clock m_Clock;
private bool IsDieEff;//是否在播放特效
//动作参数字符哈希值
protected static readonly int hashMoveX = Animator.StringToHash("MoveX");
protected static readonly int hashMoveZ = Animator.StringToHash("MoveZ");
protected static readonly int hashHit = Animator.StringToHash("Hit");//受击击
//protected static readonly int hashHitX = Animator.StringToHash("HitX");//打击
//protected static readonly int hashHitZ = Animator.StringToHash("HitZ");//打击
protected static readonly int hashHitAngle = Animator.StringToHash("HitAngle");//受击方向
protected static readonly int hashHitDown = Animator.StringToHash("HitDown");//击倒
protected static readonly int hashDie = Animator.StringToHash("Die");//死亡
protected static readonly int hashDieDown = Animator.StringToHash("DieDown");//击飞死亡
private static readonly int hashFind = Animator.StringToHash("Find");//发现目标
protected override void Awake()
{
base.Awake();
m_WeaponCol = transform.Find("WeaponCollider").GetComponent();
m_WeaponCol.gameObject.AddComponent().SetMonster(this); ;//添加武器碰撞器脚本
CurrentBehaviorTree = GetComponent();
m_Lock = transform.Find("FBX/Effect_ZhongXin/Lock").gameObject;
m_FxManagerAdon = GetComponent();
m_CinemachineImpulseSource = GetComponent();
//Name = "Mob01";
//ObjectManagerAdon.AddMobObject(Name, this.gameObject);
m_CurState = eState.Idle;
}
protected virtual void Start()
{
//m_Hero = RoleManager.Instance.GetPlayer(0) as BaseHero;
m_fbx.gameObject.GetComponent().SetOwner(this.gameObject);
m_Clock = Timekeeper.instance.Clock("Enemy");
m_NavMeshAgent = time.navMeshAgent.component;
m_RigidbodyTimeline3D = time.rigidbody;
m_NavMeshAgent.radius = 0;//去掉怪物寻路组件的碰撞范围
m_CapsuleCollider.isTrigger = true;//去掉物理碰撞启用触发方式
}
// Update is called once per frame
protected virtual void Update()
{
if (isPause)
{
pauseTime -= Time.deltaTime;
if (pauseTime <= 0)
{
isPause = false;
CurrentBehaviorTree.EnableBehavior();
if (m_NavMeshAgent && isDie == false)
{
m_NavMeshAgent.isStopped = false;
}
}
}
//受击闪光效果
if (isAttacked)
{
m_damageFlashScale -= time.deltaTime * 20;
if (m_damageFlashScale <= 0)
{
m_damageFlash.gameObject.SetActive(false);
m_damageFlashScale = 0;
isAttacked = false;
}
else
{
m_damageFlash.gameObject.SetActive(true);
}
for (int l = 0; l < m_damageFlashMaterial.Length; l++)
{
m_damageFlashMaterial[l].SetFloat("_Scale", m_damageFlashScale);
}
}
}
///
/// 行为树暂停
///
/// 暂停时间
///
public void BehaviorTreePause(float _pauseTime)
{
isPause = true;
pauseTime = _pauseTime;
m_NavMeshAgent.isStopped = true;
CurrentBehaviorTree.DisableBehavior(true);
}
#region ============================================ 消息触发 MSG ======================================================
///
/// 受击消息接收
///
///
public override void OnMsg_Attacked(Attacked_MsgData data)
{
//Debug.Log("怪物受击消息");
if (m_CurState == eState.Die)
{
return;
}
m_TargetHero = data.sender.GetComponent();
m_ForceDirection = data.forceDirection;
Vector3 hitDir = data.forceDirection;
//计算怪角度偏移
//float HitAngle = PlayerHelperAdon.Angle_360(transform.forward, hitDir);
float HitAngle = data.HitAngle;
HpbarManager.Instance.CreateHpTip(this, data.dmg, data.isCR, data.weakness);//血条及数字显示
if (data.resultHp <= 0)//死亡
{
OnMsg_Die(data.attackedEffType);//发送死亡消息
}
else
{
if (data.attackedEffType == EnumDefine.AttackedEffT.DWN)//击倒击飞
{
// 只有普通怪 才播放播放受击动画
if (roleType == RoleType.Common)
{
BehaviorTreePause(2.5f);
m_Animator.SetTrigger(hashHitDown);//播放击倒动作
SetCameraShake(transform.position, 3f, 0.1f, 0.4f);//震屏
//转向玩家
transform.LookAt(data.sender.transform);
}
}
else if (data.attackedEffType == EnumDefine.AttackedEffT.STF)
{
//SetCameraShake(transform.position, 1f, 0.1f, 0.2f);//震屏
}
else if (data.attackedEffType == EnumDefine.AttackedEffT.INHALE)
{
//SetCameraShake(transform.position, 1f, 0.1f, 0.2f);//震屏
m_Animator.SetFloat(hashMoveZ, 1);//更新移动动作
}
else
{
// 只有普通怪 才播放播放受击动画
if (roleType == RoleType.Common)
{
BehaviorTreePause(1.0f);
m_Animator.Play("HitTree");
m_Animator.SetFloat(hashHitAngle, HitAngle);//根据受击方向播受击动作
}
}
}
//实例化克隆被击光效
if (data.AttackedEff && m_HitObj != null)
{
GameObject effobj = Instantiate(data.AttackedEff);
if (!effobj.GetComponent()) effobj.gameObject.AddComponent();//添加延迟销毁脚本
effobj.transform.position = m_HitObj.position;
effobj.transform.rotation = m_TargetHero.transform.rotation;
effobj.SetActive(true);
}
if (data.SkillId == "6010221")//冰冻技
{
m_freezeFlashs.gameObject.SetActive(true);//冰冻效果
//for (int l = 0; l < m_freezeFlashMaterial.Length; l++)
//{
// m_freezeFlashMaterial[l].SetFloat("_Power", 2.5f);
//}
}
else
{
m_damageFlash.gameObject.SetActive(true);//受击高亮材质显示
m_damageFlashScale = 3f;
for (int l = 0; l < m_damageFlashMaterial.Length; l++)
{
m_damageFlashMaterial[l].SetFloat("_Scale", m_damageFlashScale);
}
}
isAttacked = true;
}
///
/// 执行死亡指令
///
///
public void OnMsg_Die(EnumDefine.AttackedEffT attackedEffType, bool isImmDie = false)
{
//Debug.Log("播放死亡销毁光效");
//m_FxManagerAdon.PlayDieEff(0, false, this.m_HitObj);
//RoleManager.Instance.DeleteRole(this);
print("死亡");
//播放死亡特效和音效
if (isImmDie)
{
//RoleManager.Instance.DeleteRole(this);
}
else if (attackedEffType == EnumDefine.AttackedEffT.DWN)//击倒
{
m_Animator.SetTrigger(hashDieDown);//播放击倒死亡动作
SetCameraShake(transform.position, 2f, 0.1f, 0.3f);//震屏
}
else if (attackedEffType == EnumDefine.AttackedEffT.NOR)
{
//m_Animator.SetTrigger(hashDieDown);//播放击倒死亡动作
//SetCameraShake(transform.position, 2f, 0.1f, 0.3f);//震屏
}
else
{
//死亡动作
m_Animator.SetTrigger(hashDie);
m_NavMeshAgent.baseOffset = 0;
SetCameraShake(transform.position, 0.8f, 0.1f, 0.2f);//震屏
}
//禁用碰撞盒,寻路组件
m_CapsuleCollider.enabled = false;
m_NavMeshAgent.enabled = false;
//CurrentBehaviorTree.SendEvent("DieEvent");
m_CurState = eState.Die;
Invoke("OnDieEnd", 2);
}
///
/// 发现目标消息
///
///
public override void OnMsgFindTarget()
{
m_Animator.SetTrigger(hashFind);
}
///
/// 普通打击
///
///
///
public virtual void OnMsgAttackHit(ReportDataAdon report)
{
//foreach (WarReportUnit heroData in report.UnitDataTarget)//遍历目标者列表
//{
m_TargetHero = RoleManager.Instance.GetRole(report.TargetId) as BaseHero;
//targetHero = hero.gameObject;
Attacked_MsgData data = new Attacked_MsgData();//受击消息数据
data.SkillId = report.SkillId;
data.sender = this.gameObject;
Vector3 force = m_Hero.transform.position - transform.position;//推力方向
force.Normalize();
data.attackedEffType = EnumDefine.AttackedEffT.STF;
data.forceDirection = force;//推力方向
//计算敌人剩余血量
data.resultHp = report.resultHP;
data.dmg = report.dmg;
data.isCR = report.isCR;//是否暴击
data.weakness = report.weakness;
if (m_FxManagerAdon.m_AttackedEff != null && m_FxManagerAdon.m_AttackedEff.Length > 0) data.AttackedEff = m_FxManagerAdon.m_AttackedEff[0].gameObject;//被击特效
m_Hero.OnMsg_Attacked(data);
//if (data.resultHp <= 0)//目标死亡
//{
// //释放目标
// ReleaseTarget();
//}
//}
}
///
/// 打击发动Debuff
///
///
///
public void FireMsgDebuffNew(ReportDataAdon report)
{
Debug.Log("新Debuff战报触发");
Attacked_MsgData data = new Attacked_MsgData();//受击消息数据
data.buffType = report.buffType;
//data.valueMove = report.BuffDataInfo.mo.moveSpeed;
data.dmg = report.dmg;
data.resultHp = report.resultHP;
data.sender = this.gameObject;
//data.AttackedEff = part.GetAttackedEff().gameObject;
//data.DieEff = part.GetDieEff().gameObject;
BaseHero hero = RoleManager.Instance.GetRole(report.TargetId) as BaseHero;
hero.OnMsgDebuff(data);
}
float buffPower = 1;
///
/// 执行debuff
///
///
public void OnMsgDebuff(Attacked_MsgData data)
{
int damage;
//debuff计数
if (buffnum.ContainsKey(data.buffType))
{
int num = buffnum[data.buffType];
num++;
buffnum[data.buffType] = num;
}
else
{
buffnum[data.buffType] = 1;
}
//处理buff特效资源挂载
if(buffs[data.buffType] == null)
{
ResourceHelper.Instance.LoadAssetBundle(data.buffResStr, ab =>
{
if (ab != null)
{
GameObject model = (GameObject)Instantiate(ab.LoadAsset(data.buffResStr));
model.transform.SetParent(transform);
switch(data.buffPoi)
{
case 0:
model.transform.position = m_TopObj.position;
break;
case 1:
model.transform.position = m_HitObj.position;
break;
case 2:
model.transform.position = m_HitObj.position;
break;
case 3:
model.transform.position = m_FootObj.position;
break;
}
buffs[data.buffType] = model;
}
});
}
//1眩晕 2静止 3护盾 4沉默 5麻痹 6灼烧 7冰冻 8中毒
switch (data.buffType)
{
case 6://灼烧
damage = data.dmg;
///灼烧
HpbarManager.Instance.CreateHpTip(this, -damage, false, 1.0f);//血条及数字显示
break;
case 7:
if (data.resultHp <= 0)
{
///死亡
Debug.Log("冰冻死亡");
//播放死亡光效
if(data.DieEff)
{
GameObject difeff = Instantiate(data.DieEff);
difeff.SetActive(true);
difeff.transform.position = m_HitObj.position;
}
OnMsg_Die(data.attackedEffType, true);//发送死亡消息
}
else
{
damage = data.dmg;
buffPower = buffPower - 0.2f;
if (buffPower <= 0)
{
buffPower = 0;
CurrentBehaviorTree.DisableBehavior(true);
}
//float targetATK = report.BuffDataInfo.target.GetProperty(YLBattle.EBattleProperty.ATTACKSPEED);
//float targetMove = report.BuffDataInfo.target.GetProperty(YLBattle.EBattleProperty.MOVESPEED);
///执行debuff
///缓速
///冻结效果
SetLocalClockTimeScale(buffPower);
//开启冻结网格材质
//根据冻结强度设置材质参数
float _PowerMin = 0.3f;
float _PowerMax = 2.5f;
float _PowerDiff = _PowerMax - _PowerMin;
float materialPower = _PowerMin + _PowerDiff * buffPower;
m_freezeFlashs.gameObject.SetActive(true);
//m_freezeFlashPower = 5;
for (int l = 0; l < m_freezeFlashMaterial.Length; l++)
{
m_freezeFlashMaterial[l].SetFloat("_Power", materialPower);
}
HpbarManager.Instance.CreateHpTip(this, -damage, false, 1.0f);//血条及数字显示
}
break;
case 8://中毒
damage = data.dmg;
HpbarManager.Instance.CreateHpTip(this, -damage, false, 1.0f);//血条及数字显示
break;
}
}
///
/// 关闭debuff
///
///
public void OffMsgDebuff(ReportDataAdon reportData)
{
//debuff计数减
if (buffnum.ContainsKey(reportData.buffType))
{
int num = buffnum[reportData.buffType];
num--;
buffnum[reportData.buffType] = num;
}
if (buffnum[reportData.buffType] > 0) return;
//1眩晕 2静止 3护盾 4沉默 5麻痹 6灼烧 7冰冻 8黯
switch (reportData.buffType)
{
case 6:
break;
case 7:
buffPower = 1;
SetLocalClockTimeScale(buffPower);
for (int l = 0; l < m_freezeFlashMaterial.Length; l++)
{
m_freezeFlashMaterial[l].SetFloat("_Power", 2.5f);
}
m_freezeFlashs.gameObject.SetActive(false);
CurrentBehaviorTree.EnableBehavior();
break;
}
buffs[reportData.buffType] = null;//销毁光效对象
}
#endregion
#region ============================================ 动作事件 MSB ======================================================
///
/// 移动进入
///
public void MSB_Move_Enter()
{
m_CurState = eState.Move;
m_WeaponCol.enabled = false;
//SendBehaviorVariable("IsAttacked", false);
//m_RigidbodyTimeline3D.velocity = Vector3.zero;
}
Vector3 LastPosition;
public void MSB_Move_Update(AnimatorStateInfo stateInfo)
{
Vector3 direction = transform.localPosition - LastPosition;//方向
float angle = PlayerHelperAdon.Angle_360(direction, transform.forward);
//float angle = Vector3.Angle(direction, transform.forward);
Vector3 cc = Vector3.zero;
cc.x = -Mathf.Sin(angle * Mathf.Deg2Rad);
cc.z = Mathf.Cos(angle * Mathf.Deg2Rad);
//cc.Normalize();
m_Animator.SetFloat(hashMoveX, cc.x * m_NavMeshAgent.velocity.magnitude / m_Clock.localTimeScale * 0.5f);//更新移动动作
m_Animator.SetFloat(hashMoveZ, cc.z * m_NavMeshAgent.velocity.magnitude / m_Clock.localTimeScale * 0.5f);//更新移动动作
LastPosition = transform.localPosition;
}
public void MSB_Move_Exit()
{
m_damageFlash.gameObject.SetActive(false);
m_RigidbodyTimeline3D.velocity = Vector3.zero;
}
///
/// 受击进入
///
public void MSB_Hit_Enter()
{
m_CurState = eState.Attacked;
m_WeaponCol.enabled = false;
}
public void MSB_Hit_Update(AnimatorStateInfo stateInfo)
{
m_RigidbodyTimeline3D.velocity = GetForce();
//Debug.Log("推力" + m_RigidbodyTimeline3D.velocity);
}
public void MSB_Hit_Exit()
{
m_ForceDirection = Vector3.zero;
m_RigidbodyTimeline3D.velocity = GetForce();
}
///
/// 击飞倒进入
///
public void MSB_Down_Enter()
{
m_CurState = eState.Down;
m_WeaponCol.enabled = false;
}
///
/// 击倒更新
///
///
public void MSB_Down_Update(AnimatorStateInfo stateInfo)
{
m_damageFlashScale -= time.deltaTime * 5;
if (m_damageFlashScale <= 0)
{
m_damageFlash.gameObject.SetActive(false);
m_damageFlashScale = 0;
}
for (int l = 0; l < m_damageFlashMaterial.Length; l++)
{
m_damageFlashMaterial[l].SetFloat("_Scale", m_damageFlashScale);
}
m_RigidbodyTimeline3D.velocity = GetForce();
//Debug.Log("推力" + m_RigidbodyTimeline3D.velocity);
}
public void MSB_Down_Exit()
{
m_ForceDirection = Vector3.zero;
m_RigidbodyTimeline3D.velocity = GetForce();
}
///
/// 死亡状态更新
///
///
public void MSB_Die_Enter()
{
m_CurState = eState.Die;
m_WeaponCol.enabled = false;
}
///
/// 死亡状态更新
///
///
public void MSB_Die_Update(AnimatorStateInfo stateInfo)
{
m_damageFlashScale -= time.deltaTime * 5;
if (m_damageFlashScale <= 0)
{
m_damageFlash.gameObject.SetActive(false);
m_damageFlashScale = 0;
}
for (int l = 0; l < m_damageFlashMaterial.Length; l++)
{
m_damageFlashMaterial[l].SetFloat("_Scale", m_damageFlashScale);
}
if (stateInfo.normalizedTime > 0.9f)
{
GetComponent().enabled = false;
}
m_RigidbodyTimeline3D.velocity = GetForce();
//死亡效果
if (stateInfo.normalizedTime >= 1 && IsDieEff == false)
{
IsDieEff = true;
//GetComponent().enabled = false;
//GetComponent().enabled = false;
//Destroy(GetComponent());//移除刚体
//m_RigidbodyTimeline3D.velocity = Vector3.zero;
////播放死亡光效
//m_FxManagerAdon.PlayDieEff();
////闪红
//m_damageFlash.gameObject.SetActive(true);//受击高亮材质显示
//m_damageFlashScale = 2.5f;
//for (int l = 0; l < m_damageFlashMaterial.Length; l++)
//{
// m_damageFlashMaterial[l].SetFloat("_Scale", m_damageFlashScale);
//}
////销毁
//Destroy(this.gameObject, 0.3f);
}
}
///
/// 死亡状态离开
///
///
public void MSB_Die_Exit()
{
}
public void MSB_Attack_Enter()
{
m_CurState = eState.Attack;
transform.LookAt(new Vector3(m_Hero.transform.position.x, 0, m_Hero.transform.position.z));//看向目标
}
public void MSB_Attack_Update(AnimatorStateInfo stateInfo)
{
//受击闪光逐渐消失
m_damageFlashScale -= time.deltaTime * 10;
if (m_damageFlashScale <= 0)
{
m_damageFlash.gameObject.SetActive(false);
m_damageFlashScale = 0;
}
for (int l = 0; l < m_damageFlashMaterial.Length; l++)
{
m_damageFlashMaterial[l].SetFloat("_Scale", m_damageFlashScale);
}
m_RigidbodyTimeline3D.velocity = GetForce();
}
public void MSB_Attack_Exit()
{
}
///
/// 发现目标进入
///
public void MSB_Find_Enter()
{
m_CurState = eState.Find;
m_WeaponCol.enabled = false;
}
public void MSB_Find_Update(AnimatorStateInfo stateInfo)
{
}
public void MSB_Find_Exit()
{
}
#endregion
#region Animation Event
///
/// 普通攻击开始
///
public virtual void OnAttackStart(int attackId) { }
///
/// 普通攻击触发
///
/// 技能id
/// 子连击id
public virtual void OnAttackOn(string attackId)
{
List list = new List(attackId.Split(','));
m_SkillId = int.Parse(list[0]);
if (list.Count > 1)
{
m_CurAttackIdx = int.Parse(list[1]);
}
else
{
m_CurAttackIdx = 1;
}
m_WeaponCol.transform.localEulerAngles = Vector3.zero;
m_WeaponCol.enabled = true;
}
///
/// 普通攻击结束
///
public virtual void OnAttackOff()
{
this.m_WeaponCol.enabled = false;//关闭武器碰撞
}
///
/// 攻击移动触发
///
public virtual void OnAttackMoveStart(float num)
{
Debug.Log("执行OnAttackMoveStart.SendMessage");
Vector3 velocity = transform.forward.normalized * num;
time.rigidbody.velocity = velocity;
}
///
/// 攻击移动触发
///
public virtual void OnAttackMoveEnd()
{
time.rigidbody.velocity = Vector3.zero;
}
///
/// 打击移动结束
///
public void OnHitMoveEnd()
{
m_RigidbodyTimeline3D.velocity = Vector3.zero;
}
///
/// 可进入极限闪避
///
public void OnExtremeDodge(float _time)
{
//播放可极限闪避光效
m_FxManagerAdon.PlayExtermePointEff();
//设置可进入极限闪避
m_Hero.SetExtermeTimeZone(_time);
}
///
/// 死亡结束,开始销毁
///
public void OnDieEnd()
{
Debug.Log("播放死亡销毁光效");
if (m_FxManagerAdon != null)
{
m_FxManagerAdon.PlayDieEff(0, false, this.transform);
}
RoleManager.Instance.DeleteRole(this);
}
#endregion
/////
///// 发送行为树参数
/////
/////
/////
//private void SendBehaviorVariable(string VariabelName,object value)
//{
// if(m_BehaviorTreeManager.CurrentBehaviorTree)
// //m_BehaviorTreeManager.CurrentBehaviorTree.SetVariableValue(VariabelName, value);
//}
///
/// 震屏
///
public void OnShake(float _velocity = 1)
{
//判断震屏等级
Vector3 velocity = Vector3.one * _velocity;
//发送震屏消息
m_CinemachineImpulseSource.GenerateImpulseAt(this.transform.position, velocity);
}
//设置刚力
public void SetForce(float _Force)
{
m_Force = _Force;
}
///
/// 获取推力
///
///
public Vector3 GetForce()
{
Vector3 force = m_ForceDirection * m_Force;
return force;
}
///
/// 被锁定效果
///
public void Lock()
{
m_Lock.SetActive(true);
}
///
/// 解除被锁定效果
///
public void ReleaseLock()
{
m_Lock.SetActive(false);
if( BattleCanvas.Instance != null)
{
BattleCanvas.Instance.HideLockMonsterHP();
}
}
}
}