动画组建
英雄配置表,对应英雄动画 技能编号对应技能表中技能
先理一下结构
角色身上绑定的 Entity 实物脚本
public enum EntityType
{
Monster = 1,
Soldier,
Building,
Player,
AltarSoldier,
}
Awake的时候找到技能释放触发点位置
Start的时候 添加上所有的动画
Update的时候更新 状态以及每次发生变化的所有属性
Ientity 为实物的接口类 ,人物的属性以及调用的方法都调用这个类里面的
每一帧都会调用状态机中的 Execute 函数
然后根据对应的状态再去调用 Iselfplayer 和Iplayer 中对应的方法
技能面板为 SkillWindow
选中目标按下普攻
请求自动战斗
释放技能通知OnNetMsg_NotifyReleaseSkill,
释放的普通技能
//释放技能
public virtual void OnEntityReleaseSkill()
{
SkillManagerConfig skillManagerConfig = ConfigReader.GetSkillManagerCfg(EntitySkillID);
if (skillManagerConfig == null)
{
return;
}
//吸附技能
if (skillManagerConfig.isAbsorb == 1)
{
//删除已有的相同特效
foreach (Transform child in RealEntity.objAttackPoint)
{
if (child.name.Contains(skillManagerConfig.absorbRes))
{
int offset = child.name.IndexOf('_');
if (offset != 0)
{
string name = child.name.Substring(offset + 1);
int id = Convert.ToInt32(name);
EffectManager.Instance.DestroyEffect(id);
}
}
}
//创建吸附技能效果
string absortActPath = "effect/soul_act/" + skillManagerConfig.absorbRes;
NormalEffect absortSkillEffect = EffectManager.Instance.CreateNormalEffect(absortActPath, RealEntity.objAttackPoint.gameObject);
if (absortSkillEffect != null)
{
Quaternion rt = Quaternion.LookRotation(EntityFSMDirection);
//absortSkillEffect.obj.transform.rotation = rt;
}
objTransform.rotation = Quaternion.LookRotation(EntityFSMDirection);
}
else
{
//普通技能
if (skillManagerConfig.isNormalAttack == 1)
{
//播放攻击动画动画
RealEntity.PlayeAttackAnimation();
}
else
{
{
//释放技能动画
RealEntity.PlayerAnimation(skillManagerConfig.rAnimation);
if (RealEntity.GetComponent<Animation>()[skillManagerConfig.rAnimation] != null && RealEntity.GetComponent<Animation>()[skillManagerConfig.rAnimation].wrapMode != WrapMode.Loop)
{
//动画融合
RealEntity.CrossFadeSqu("free");
}
//播放特效
Game.Effect.EffectManager.playSkillReleaseSound(this, EntitySkillID);
}
}
float distance = GetDistanceToPos(EntityFSMPosition);
if (entityType != EntityType.Building)
{
objTransform.rotation = Quaternion.LookRotation(EntityFSMDirection);
}
}
}
技能信息通知OnNetMsg_NotifySkillInfo冷却,
public override void OnSkillInfoChange(int skillID, float time, float maxTime, int slot)
{
SkillType skillType = SkillType.SKILL_NULL;
if (skillID == SkillIdDic[SkillType.SKILL_TYPE1])
{
skillType = SkillType.SKILL_TYPE1;
}
else if (skillID == SkillIdDic[SkillType.SKILL_TYPE3])
{
skillType = SkillType.SKILL_TYPE3;
}
else if (skillID == SkillIdDic[SkillType.SKILL_TYPE2])
{
skillType = SkillType.SKILL_TYPE2;
}
else if (skillID == SkillIdDic[SkillType.SKILL_TYPE4])
{
skillType = SkillType.SKILL_TYPE4;
}
else if (skillID == SkillIdDic[SkillType.SKILL_TYPEABSORB1])
{
skillType = SkillType.SKILL_TYPEABSORB1;
}
else if (skillID == SkillIdDic[SkillType.SKILL_TYPEABSORB2])
{
skillType = SkillType.SKILL_TYPEABSORB2;
}
else
{
return;
}
SetBaseSkillType(skillType, skillID);
if (time > 0)
{
bPlaySkill = false;
}
EventCenter.Broadcast<SkillType, float, float>(EGameEvent.eGameEvent_LocalPlayerSkillCD, skillType, maxTime, time);
}
普通技能return回去了;
通知释放技能,怪物释放技能OnNetMsg_NotifyReleaseSkill 执行上面逻辑
死亡通知OnNetMsg_NotifyGameObjectDeadState
Int32 OnNetMsg_NotifyGameObjectDeadState(Stream stream)
{
GSToGC.DeadState pMsg;
if (!ProtoDes(out pMsg, stream))
{
return PROTO_DESERIALIZE_ERROR;
}
UInt64 deadID;
deadID = pMsg.objguid;
Vector3 pos = this.ConvertPosToVector3(pMsg.pos);
Vector3 dir = this.ConvertDirToVector3(pMsg.dir);
Ientity entity;
if (EntityManager.AllEntitys.TryGetValue(deadID, out entity))
{
pos.y = entity.realObject.transform.position.y;
entity.deadSpot = pMsg.spot;
entity.EntityFSMChangeDataOnDead(pos, dir);
//主基地延时处理
if (entity.NPCCateChild != ENPCCateChild.eNPCChild_BUILD_Base)
{
entity.OnFSMStateChange(EntityDeadFSM.Instance);
}
}
return (Int32)EErrorCode.eNormal;
}
/// <summary>
/// Entity死亡
/// </summary>
public virtual void OnEnterDead()
{
//目标死亡主角相关处理
Iselfplayer player = PlayerManager.Instance.LocalPlayer;
if (player != null && player.SyncLockTarget != null && GameObjGUID == player.SyncLockTarget.GameObjGUID)
{
player.SetSyncLockTarget(null);
}
//播放死亡声音
Vector3 pos = PlayerManager.Instance.LocalPlayer.RealEntity.transform.position;
if (GetDistanceToPos(pos) <= 30)
{
this.PlayDeadSound();
}
//建筑物更换模型和播表现特效
if (this.entityType == EntityType.Building && this.NPCCateChild != ENPCCateChild.eNPCChild_BUILD_Base)
{
if (!EntityManager.GetHomeBaseList().Contains(this))
{
GameMethod.SetLoadJianTaBaoZha(this);
int ret = EntityManager.HandleDelectEntity(this.GameObjGUID);
if (ret != 0)
{
Debug.LogError("OnEnterDead HandleDelectEntity:" + GameObjGUID + "failed");
}
}
EventCenter.Broadcast<Ientity>(EGameEvent.eGameEvent_NotifyBuildingDes, this);
return;
}
//非建筑物播死亡动画和清理血条等状态
this.DoEntityDead();
RealEntity.PlayerDeadAnimation();
}
//播放死亡动画
技能攻击
上面为注册的事件
按下技能OnSkillBtnFunc
private void OnSkillBtnFunc(int ie, bool isDown)
{
if (mIsShowDes)
{
mIsShowDes = false;
return;
}
mIsShowDes = false;
GamePlayCtrl.Instance.showaudiotimeold = System.DateTime.Now;
if (PlayerManager.Instance.LocalPlayer.FSM == null ||
PlayerManager.Instance.LocalPlayer.FSM.State == Game.FSM.FsmState.FSM_STATE_DEAD ||
Game.Skill.BuffManager.Instance.isSelfHaveBuffType(1017))
{
return;
}
//发送技能
SendSkill(ie);
}
SendPreparePlaySkill
释放技能通知释
//释放技能
Int32 OnNetMsg_NotifyReleaseSkill(Stream stream)
{
GSToGC.ReleasingSkillState pMsg;
if (!ProtoDes(out pMsg, stream))
{
return PROTO_DESERIALIZE_ERROR;
}
Vector3 pos = this.ConvertPosToVector3(pMsg.pos);
Vector3 dir = this.ConvertDirToVector3(pMsg.dir);
dir.y = 0.0f;
UInt64 targetID;
targetID = pMsg.targuid;
UInt64 sGUID;
sGUID = pMsg.objguid;
Ientity target;
EntityManager.AllEntitys.TryGetValue(targetID, out target);
Ientity entity;
if (EntityManager.AllEntitys.TryGetValue(sGUID, out entity))
{
pos.y = entity.realObject.transform.position.y;
//准备技能
entity.EntityFSMChangeDataOnPrepareSkill(pos, dir, pMsg.skillid, target);
//有限状态机去改变
entity.OnFSMStateChange(EntityReleaseSkillFSM.Instance);
}
return (Int32)EErrorCode.eNormal;
}
//释放技能
public virtual void OnEntityReleaseSkill()
{
SkillManagerConfig skillManagerConfig = ConfigReader.GetSkillManagerCfg(EntitySkillID);
if (skillManagerConfig == null)
{
return;
}
//吸附技能
if (skillManagerConfig.isAbsorb == 1)
{
//删除已有的相同特效
foreach (Transform child in RealEntity.objAttackPoint)
{
if (child.name.Contains(skillManagerConfig.absorbRes))
{
int offset = child.name.IndexOf('_');
if (offset != 0)
{
string name = child.name.Substring(offset + 1);
int id = Convert.ToInt32(name);
EffectManager.Instance.DestroyEffect(id);
}
}
}
//创建吸附技能效果
string absortActPath = "effect/soul_act/" + skillManagerConfig.absorbRes;
NormalEffect absortSkillEffect = EffectManager.Instance.CreateNormalEffect(absortActPath, RealEntity.objAttackPoint.gameObject);
if (absortSkillEffect != null)
{
Quaternion rt = Quaternion.LookRotation(EntityFSMDirection);
//absortSkillEffect.obj.transform.rotation = rt;
}
objTransform.rotation = Quaternion.LookRotation(EntityFSMDirection);
}
else
{
//普通技能
if (skillManagerConfig.isNormalAttack == 1)
{
//播放攻击动画动画
RealEntity.PlayeAttackAnimation();
}
else
{
{
//释放技能动画
RealEntity.PlayerAnimation(skillManagerConfig.rAnimation);
if (RealEntity.GetComponent<Animation>()[skillManagerConfig.rAnimation] != null && RealEntity.GetComponent<Animation>()[skillManagerConfig.rAnimation].wrapMode != WrapMode.Loop)
{
//动画融合
RealEntity.CrossFadeSqu("free");
}
//播放特效
Game.Effect.EffectManager.playSkillReleaseSound(this, EntitySkillID);
}
}
float distance = GetDistanceToPos(EntityFSMPosition);
if (entityType != EntityType.Building)
{
objTransform.rotation = Quaternion.LookRotation(EntityFSMDirection);
}
}
}
放技能动画 RealEntity.PlayerAnimatio,
通知技能信息
OnNetMsg_NotifySkillInfo技能冷却
OnSkillInfoChange
public override void OnSkillInfoChange(int skillID, float time, float maxTime, int slot)
{
SkillType skillType = SkillType.SKILL_NULL;
if (skillID == SkillIdDic[SkillType.SKILL_TYPE1])
{
skillType = SkillType.SKILL_TYPE1;
}
else if (skillID == SkillIdDic[SkillType.SKILL_TYPE3])
{
skillType = SkillType.SKILL_TYPE3;
}
else if (skillID == SkillIdDic[SkillType.SKILL_TYPE2])
{
skillType = SkillType.SKILL_TYPE2;
}
else if (skillID == SkillIdDic[SkillType.SKILL_TYPE4])
{
skillType = SkillType.SKILL_TYPE4;
}
else if (skillID == SkillIdDic[SkillType.SKILL_TYPEABSORB1])
{
skillType = SkillType.SKILL_TYPEABSORB1;
}
else if (skillID == SkillIdDic[SkillType.SKILL_TYPEABSORB2])
{
skillType = SkillType.SKILL_TYPEABSORB2;
}
else
{
return;
}
SetBaseSkillType(skillType, skillID);
if (time > 0)
{
bPlaySkill = false;
}
EventCenter.Broadcast<SkillType, float, float>(EGameEvent.eGameEvent_LocalPlayerSkillCD, skillType, maxTime, time);
}
收到通知
//显示有效的可以在使用中的技能
public void ShowValideUseSkillBtn(ShortCutBarBtn btnType, bool visiable)
{
Iselfplayer player = PlayerManager.Instance.LocalPlayer;
if (null == player)
{
return;
}
int index = (int)btnType;
int skillId = 0;
SkillManagerConfig info = null;
switch (btnType)
{
case ShortCutBarBtn.BTN_SKILL_1:
case ShortCutBarBtn.BTN_SKILL_2:
case ShortCutBarBtn.BTN_SKILL_3:
case ShortCutBarBtn.BTN_SKILL_4:
break;
case ShortCutBarBtn.BTN_SKILL_5:
if (player != null && player.BaseSkillIdDic.ContainsKey(SkillType.SKILL_TYPEABSORB1))
{
skillId = player.BaseSkillIdDic[SkillType.SKILL_TYPEABSORB1];
}
info = ConfigReader.GetSkillManagerCfg(skillId);
if (skillId == 0 || info == null)
{
visiable = false;
}
break;
case ShortCutBarBtn.BTN_SKILL_6:
if (player != null && player.BaseSkillIdDic.ContainsKey(SkillType.SKILL_TYPEABSORB2))
{
skillId = player.BaseSkillIdDic[SkillType.SKILL_TYPEABSORB2];
}
info = ConfigReader.GetSkillManagerCfg(skillId);
if (skillId == 0 || info == null)
{
visiable = false;
}
break;
default:
return;
}
if (!visiable)
{
ShowCdEndEffect(btnType, false);
}
}
//显示按下技能特效
public void ShowPressEffect(ShortCutBarBtn btnType)
{
if (IsSkillInCd(btnType) || mPressBtnEffect.ContainsKey(btnType))
{
return;
}
ResourceUnit objUnit = ResourcesManager.Instance.loadImmediate(GameConstDefine.PressBtnEffect, ResourceType.PREFAB);
GameObject obj = GameObject.Instantiate(objUnit.Asset) as GameObject;
int index = (int)btnType;
obj.transform.parent = mBtnArray[index].transform;
obj.transform.localPosition = Vector3.zero;
obj.transform.localScale = Vector3.one;
mPressBtnEffect.Add(btnType, obj);
mPressBtnEffectTime.Add(btnType, 1.5f);
}
public void StartCdCountDown(float time, float last)
{
if (canCountCd)
return;
timeLimit = time;
start = time - last;
SetCdShow(true);
StartCountTime = DateTime.Now;
canCountCd = true;
}
接受 OnNetMsg_NotifyLastingSkill
Int32 OnNetMsg_NotifyLastingSkill(Stream stream)
{
GSToGC.LastingSkillState pMsg;
if (!ProtoDes(out pMsg, stream))
{
return PROTO_DESERIALIZE_ERROR;
}
Vector3 pos = this.ConvertPosToVector3(pMsg.pos);
Vector3 dir = this.ConvertDirToVector3(pMsg.dir);
dir.y = 0.0f;
UInt64 targetID;
targetID = pMsg.targuid;
UInt64 sGUID;
sGUID = pMsg.objguid;
Ientity target;
EntityManager.AllEntitys.TryGetValue(targetID, out target);
Ientity entity;
if (EntityManager.AllEntitys.TryGetValue(sGUID, out entity))
{
pos.y = entity.realObject.transform.position.y;
entity.EntityFSMChangeDataOnPrepareSkill(pos, dir, pMsg.skillid, target);
entity.OnFSMStateChange(EntityLastingFSM.Instance);
}
return (Int32)EErrorCode.eNormal;
}
怪物 OnNetMsg_NotifyReleaseSkill 释放技能
OnNetMsg_NotifyGameObjectDeadState
OnNetMsg_NotifySkillInfo return
玩家技能信息,冷却结束