316 lines
11 KiB
C#
316 lines
11 KiB
C#
using Thousandto.Code.Center;
|
||
using Thousandto.Code.Global;
|
||
using Thousandto.Core.Asset;
|
||
using UnityEngine;
|
||
|
||
namespace Thousandto.Code.Logic
|
||
{
|
||
public class MarryChild : Character
|
||
{
|
||
#region//私有变量
|
||
//宠物属性模块
|
||
private MarryChildProperty _propMoudleEx = null;
|
||
private Player _master = null;
|
||
private AIState _aiState = AIState.Count;
|
||
private Vector2 _moveTarget2D = Vector2.zero;
|
||
#endregion
|
||
|
||
#region 属性信息
|
||
//名称
|
||
public new string Name
|
||
{
|
||
get
|
||
{
|
||
var name = PropMoudle.Name;
|
||
if(string.IsNullOrEmpty(name))
|
||
{
|
||
name = PropMoudle.Cfg.ChildName;
|
||
}
|
||
return name;
|
||
}
|
||
}
|
||
public new MarryChildProperty PropMoudle
|
||
{
|
||
get
|
||
{
|
||
if (_propMoudleEx == null)
|
||
{
|
||
_propMoudleEx = base.PropMoudle as MarryChildProperty;
|
||
}
|
||
return _propMoudleEx;
|
||
}
|
||
}
|
||
|
||
//是否显示选中框
|
||
public override bool CanShowSelectUI
|
||
{
|
||
get
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
public override bool CanBeSelect
|
||
{
|
||
get
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
public override bool IsShowModel
|
||
{
|
||
get
|
||
{
|
||
return _isShowModel;
|
||
}
|
||
set
|
||
{
|
||
_isShowModel = value;
|
||
if (_isShowModel != Skin.IsActive())
|
||
{
|
||
Skin.SetActive(_isShowModel);
|
||
}
|
||
}
|
||
}
|
||
public override float MoveSpeed
|
||
{
|
||
get
|
||
{
|
||
if(_master != null)
|
||
{
|
||
return _master.MoveSpeed;
|
||
}
|
||
return base.MoveSpeed;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region//初始化,卸载,加载Skin等处理
|
||
//加载Skin
|
||
protected override FSkinBase OnSetupSkin()
|
||
{
|
||
FSkinModel skin = GameCenter.LuaSystem.Adaptor.CreateFSkinModel(FSkinTypeCode.MarryChild);
|
||
skin.SetLayer(LayerUtils.RemotePlayer);
|
||
skin.SetMipmapLevel(0.5f);
|
||
return skin;
|
||
}
|
||
//初始化
|
||
protected override bool OnInitializeAfter(EntityInitInfo baseInfo)
|
||
{
|
||
var initInfo = baseInfo as MarryChildInitInfo;
|
||
base.OnInitializeAfter(baseInfo);
|
||
SyncInfo(initInfo);
|
||
ShowHUD();
|
||
return true;
|
||
}
|
||
//卸载处理
|
||
protected override void OnUninitializeBefore()
|
||
{
|
||
base.OnUninitializeBefore();
|
||
HideHUD();
|
||
}
|
||
//初始化信息刷新
|
||
public virtual void SyncInfo(MarryChildInitInfo initInfo)
|
||
{
|
||
_propMoudle = _propMoudleEx = new MarryChildProperty(this, initInfo.Cfg, initInfo.Name);
|
||
_propMoudleEx.MasterID = initInfo.Owner.ID;
|
||
_master = initInfo.Owner;
|
||
_propMoudleEx.SetBattleProp(AllBattleProp.MoveSpeed, (long)(_master.MoveSpeed * 100));
|
||
if (Skin.GetSkinPartCfgID(FSkinPartCode.Body) != initInfo.Cfg.Model)
|
||
{
|
||
Skin.SetSkinPartFromCfgID(FSkinPartCode.Body, initInfo.Cfg.Model);
|
||
}
|
||
IsShowModel = GameObjectLimit.IsCanShow(this);
|
||
BodyScale = 1f;
|
||
RayCastToGroundXOZ(Position2d);
|
||
}
|
||
protected override bool OnSetupFSMBefore()
|
||
{
|
||
ResetDirection();
|
||
return base.OnSetupFSMBefore();
|
||
}
|
||
//安装设置FSM状态机
|
||
protected override bool OnSetupFSM()
|
||
{
|
||
Fsm = new EntityFSM(this);
|
||
Fsm.AddState(new Idle());
|
||
Fsm.AddState(new PathMove());
|
||
Fsm.SetDefaultStateId(EntityStateID.Idle);
|
||
Fsm.Init(this);
|
||
return true;
|
||
}
|
||
#endregion
|
||
#region //重写Entity的方法
|
||
//是否是主角仙娃
|
||
public override bool IsLocalMarryChild()
|
||
{
|
||
return PropMoudle.MasterID == GameCenter.GameSceneSystem.GetLocalPlayerID();
|
||
}
|
||
#endregion
|
||
|
||
|
||
//接受到被击时的处理
|
||
#region 受击处理
|
||
public override void OnBeAttackedResponse(Character attacker, HitEffectInfo hitInfo, SkillHitType hitType, MSG_Fight.HitEffectInfo msgInfo)
|
||
{
|
||
//法宝不能被攻击,所以不处理受击效果
|
||
base.OnBeAttackedResponse(attacker, hitInfo, hitType, msgInfo);
|
||
}
|
||
#endregion
|
||
|
||
#region//心跳处理
|
||
//心跳处理
|
||
protected override void OnUpdate(float elapsedTime)
|
||
{
|
||
if (_master == null || _master.Skin == null || _master.ID <= 0)
|
||
{
|
||
//主角已经被删除,删除自己
|
||
Scene.DeleteEntity(ID);
|
||
return;
|
||
}
|
||
UpdateState();
|
||
base.OnUpdate(elapsedTime);
|
||
}
|
||
private void ChangeState(AIState state)
|
||
{
|
||
if (_aiState == state)
|
||
return;
|
||
OnStateLeave(_aiState);
|
||
_aiState = state;
|
||
OnStateEnter(_aiState);
|
||
}
|
||
private void UpdateState()
|
||
{
|
||
switch (_aiState)
|
||
{
|
||
case AIState.Idle:
|
||
{
|
||
if (_master != null)
|
||
{
|
||
if (Vector2.SqrMagnitude(Position2d - _master.Position2d) < 1f)
|
||
{
|
||
//距离太近,走远一点
|
||
var dir = -_master.GetFacingDirection2d();
|
||
_moveTarget2D = _master.Position2d + dir.normalized * 1.5f;
|
||
ChangeState(AIState.Follow);
|
||
break;
|
||
}
|
||
else if (Vector2.SqrMagnitude(Position2d - _master.Position2d) > 9f)
|
||
{
|
||
//距离太远,走近一点
|
||
var dir = -_master.GetFacingDirection2d();
|
||
_moveTarget2D = _master.Position2d + dir.normalized * 1.5f;
|
||
ChangeState(AIState.Follow);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case AIState.Follow:
|
||
{
|
||
if (_master != null)
|
||
{
|
||
if (Vector2.SqrMagnitude(Position2d - _master.Position2d) > 400f)
|
||
{
|
||
//与玩家的距离超过了20米,直接瞬移
|
||
Stop_Action(false);
|
||
var dir = -_master.GetFacingDirection2d();
|
||
var targetPos = _master.Position2d + dir.normalized * 1.5f;
|
||
if (Scene.navigator.IsBlocked(targetPos))
|
||
{
|
||
RayCastToGroundXOZ(_master.Position2d);
|
||
}
|
||
else
|
||
{
|
||
RayCastToGroundXOZ(targetPos);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (!IsMoving())
|
||
{
|
||
if (Vector2.SqrMagnitude(Position2d - _master.Position2d) > 9f)
|
||
{
|
||
//距离太远,走近一点
|
||
var dir = -_master.GetFacingDirection2d();
|
||
_moveTarget2D = _master.Position2d + dir.normalized * 1.5f;
|
||
Action_MoveTo(new Vector3(_moveTarget2D.x, 0f, _moveTarget2D.y), 0.5f);
|
||
}
|
||
else
|
||
{
|
||
ChangeState(AIState.Idle);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//如果快到目标点了计算是否继续移动,主要为了防止宠物行走卡顿
|
||
var moveState = Fsm.CurrentState as PathMove;
|
||
if (moveState != null)
|
||
{
|
||
if (Vector2.SqrMagnitude(Position2d - moveState.CurPathTarget) <= 1f && Vector2.SqrMagnitude(Position2d - _master.Position2d) > 9f)
|
||
{
|
||
//距离太远,走近一点
|
||
var dir = -_master.GetFacingDirection2d();
|
||
_moveTarget2D = _master.Position2d + dir.normalized * 1.5f;
|
||
Action_MoveTo(new Vector3(_moveTarget2D.x, 0f, _moveTarget2D.y), 0.5f);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case AIState.Count:
|
||
{
|
||
ChangeState(AIState.Idle);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
private void OnStateEnter(AIState state)
|
||
{
|
||
switch (state)
|
||
{
|
||
case AIState.Idle:
|
||
{
|
||
|
||
}
|
||
break;
|
||
case AIState.Follow:
|
||
{
|
||
Action_MoveTo(new Vector3(_moveTarget2D.x, 0f, _moveTarget2D.y), 0.5f);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
private void OnStateLeave(AIState state)
|
||
{
|
||
switch (state)
|
||
{
|
||
case AIState.Idle:
|
||
{
|
||
|
||
}
|
||
break;
|
||
case AIState.Follow:
|
||
{
|
||
}
|
||
break;
|
||
case AIState.Count:
|
||
{
|
||
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region//私有类
|
||
private enum AIState
|
||
{
|
||
Idle,
|
||
Follow,
|
||
Count,
|
||
}
|
||
#endregion
|
||
}
|
||
}
|