玩家身上绑定的Entity脚本,
关联所有的动画
public virtual void Start()
{
if (SyncEntity != null && SyncEntity.entityType == EntityType.Player)
{
if (this.GetComponent<Animation>() == null)
{
return;
}
//英雄表
List<string> aniList = ConfigReader.HeroXmlInfoDict[SyncEntity.NpcGUIDType].n32RandomAttack;
foreach(string ani in aniList)
{
if (GetComponent<Animation>().GetClip(ani))
{
AnimationEvent skillEvent = new AnimationEvent();
//动画播放时间
skillEvent.time = getAnimationTime(ani);
//攻击完成后的回调
skillEvent.functionName = "OnAttackEnd";
//给动画添加上skillEvent事件
GetComponent<Animation>().GetClip(ani).AddEvent(skillEvent);
}
}
}
}
每帧都在执行
拖拽
设置遥感移动范围
发送移动信息给服务器
void SendMove()
{
//运动方向
Vector3 direction = GetPointerDirection();
Transform target = GameLogic.Instance.transform;
Entity entity = PlayerManager.Instance.LocalPlayer.RealEntity;
if (entity == null) {
return ;
}
PlayState playState = GameStateManager.Instance.GetCurState() as PlayState;
if (playState == null)
return;
target.position = entity.transform.position;
target.LookAt(entity.transform.position + direction);
//运动正方向
Vector3 dir = new Vector3(0, 0, 0);
//地图已经修改,不需要旋转
//target.transform.Rotate(new Vector3(0.0f, 45f, 0.0f));
//获取当前相机类型
if (playState.mCameraType == 1) //斜45度
{
//转为相机坐标系
if (entity.CampType == EntityCampType.CampTypeA)
{
Quaternion rot = Quaternion.Euler(0, 45f, 0);
dir = rot * target.forward;
}
else if (entity.CampType == EntityCampType.CampTypeB)
{
Quaternion rot = Quaternion.Euler(0, -135f, 0);
dir = rot * target.forward;
}
else
{
Debug.Log("no valid entity camp type!");
}
}
else //水平
{
//转为相机坐标系
if (entity.CampType == EntityCampType.CampTypeA)
{
Quaternion rot = Quaternion.Euler(0, 0f, 0);
dir = rot * target.forward;
}
else if (entity.CampType == EntityCampType.CampTypeB)
{
Quaternion rot = Quaternion.Euler(0, -180f, 0);
dir = rot * target.forward;
}
else
{
Debug.Log("no valid entity camp type!");
}
}
Vector3 dealPos = entity.transform.position + dir * Time.deltaTime * PlayerManager.Instance.LocalPlayer.EntityFSMMoveSpeed;
Vector3 dealPos1 = dealPos + dir * Time.deltaTime * PlayerManager.Instance.LocalPlayer.EntityFSMMoveSpeed * 2;
if(dir != Vector3.zero && Time.time - MoveSendTime >= SendMoveInterVal)
{
MoveSendTime = Time.time;
//告诉服务器主角的运动方向发生变化
CGLCtrl_GameLogin.Instance.EmsgToss_AskMoveDir(dir);
beforeDir = dir ;
//主角移动
PlayerAdMove(dir);
}
}
发送消息
转化成先行状态
同时Update会调用执行方法
IselfPlayer===》IPlayer====》entity
播放移动的动画,先播放动画,服务端返回状态后,进行走动
Entity属性赋值来自 Ientity;类中调用的方法也全部来自Ientity
接受到服务端消息,通知玩家跑
Int32 OnNetMsg_NotifyGameObjectRunState(Stream stream)
{
GSToGC.RunningState pMsg;
if (!ProtoDes(out pMsg, stream))
{
return PROTO_DESERIALIZE_ERROR;
}
if (null == pMsg.dir || null == pMsg.pos)
return 0;
UInt64 sGUID;
sGUID = pMsg.objguid;
Vector3 mvPos = this.ConvertPosToVector3(pMsg.pos);
Vector3 mvDir = this.ConvertDirToVector3(pMsg.dir);
float mvSp = pMsg.movespeed / 100.0f;
Ientity entity = null;
if (EntityManager.AllEntitys.TryGetValue(sGUID, out entity))
{
mvPos.y = entity.RealEntity.transform.position.y;
entity.GOSSI.sServerBeginPos = mvPos;
entity.GOSSI.sServerSyncPos = mvPos;
entity.GOSSI.sServerDir = mvDir;
entity.GOSSI.fServerSpeed = mvSp;
entity.GOSSI.fBeginTime = Time.realtimeSinceStartup;
entity.GOSSI.fLastSyncSecond = Time.realtimeSinceStartup;
entity.EntityFSMChangedata(mvPos, mvDir, mvSp);
entity.OnFSMStateChange(EntityRunFSM.Instance);
}
return (Int32)EErrorCode.eNormal;
}
进入这里,属性绑定
执行
每帧通过Entity 的Update方法调用
主角移动代码
新位置=时间间隔*速度*方向+之间的位置
/// <summary>
/// 执行移动的代码
/// </summary>
public virtual void OnExecuteMove()
{
if (RealEntity == null || this.entityType == EntityType.Building)
{
return;
}
//播放跑的动画
RealEntity.PlayerRunAnimation();
//当前时间
float fThisRealTimeSinceStartup = Time.realtimeSinceStartup;
//当前时间-开始移动时的使时间
float fTimeSpan = fThisRealTimeSinceStartup - m_pcGOSSI.fBeginTime;
//距离上一次计算距离的时间间隔
float fThisFrameTimeSpan = fThisRealTimeSinceStartup - m_pcGOSSI.fLastSyncSecond;
m_pcGOSSI.fLastSyncSecond = fThisRealTimeSinceStartup;
//物体移动的距离
float fMoveDist = fTimeSpan * m_pcGOSSI.fServerSpeed;
//服务端计算的位置
m_pcGOSSI.sServerSyncPos = m_pcGOSSI.sServerBeginPos + m_pcGOSSI.sServerDir * fMoveDist;
//服务端位置
Vector3 serverPos2D = new Vector3(m_pcGOSSI.sServerSyncPos.x, 60, m_pcGOSSI.sServerSyncPos.z);
//客户端位置
Vector3 realPos2D = new Vector3(objTransform.position.x, 60, objTransform.position.z);
//服务端和客户端位置的差
float fDistToSyncPos = Vector3.Distance(serverPos2D, realPos2D);
//相差大于10,以服务端的为准
if (fDistToSyncPos > 10)
{
//位置为服务端
objTransform.position = m_pcGOSSI.sServerSyncPos;
//转向
objTransform.rotation = Quaternion.LookRotation(EntityFSMDirection);
//朝向
m_pcGOSSI.sLocalSyncDir = EntityFSMDirection;
return;
}
//服务端前方五个单位点
Vector3 sCrossPoint = 5 * m_pcGOSSI.sServerDir + m_pcGOSSI.sServerSyncPos;
//朝向
Vector3 sThisSyncDir = sCrossPoint - realPos2D;
sThisSyncDir.y = 0;
sThisSyncDir.Normalize();
//服务端和客户端朝向的夹角
float fAngle = Vector3.Angle(sThisSyncDir, m_pcGOSSI.sLocalSyncDir);
//夹角大于5度,修正角度
if (5 < fAngle)
{
float fLerpVlaue = fAngle / 100;
Vector3 sTempThisSyncDir = Vector3.Lerp(m_pcGOSSI.sLocalSyncDir, sThisSyncDir, fLerpVlaue);
sThisSyncDir = sTempThisSyncDir;
}
float fThisMoveSpeed = m_pcGOSSI.fServerSpeed;
//服务端和客户端的距离差
Vector3 sTempSyncDir = m_pcGOSSI.sServerSyncPos - realPos2D;
sTempSyncDir.y = 0;
sTempSyncDir.Normalize();
//朝向夹角
fAngle = Vector3.Angle(sTempSyncDir, m_pcGOSSI.sLocalSyncDir);
////根据距离和角度的不同调整速度
if (90 < fAngle)
{
if (1 > fDistToSyncPos)
{
fThisMoveSpeed = m_pcGOSSI.fServerSpeed;
}
else if (2 > fDistToSyncPos)
{
fThisMoveSpeed -= m_pcGOSSI.fServerSpeed * 0.01f;
}
else if (5 > fDistToSyncPos)
{
fThisMoveSpeed -= fThisMoveSpeed * 0.05f;
}
else if (6 > fDistToSyncPos)
{
fThisMoveSpeed -= fThisMoveSpeed * 0.10f;
}
fThisMoveSpeed = m_pcGOSSI.fServerSpeed;
}
else
{
if (1 > fDistToSyncPos)
{
fThisMoveSpeed = m_pcGOSSI.fServerSpeed;
}
else if (2 > fDistToSyncPos)
{
fThisMoveSpeed += fThisMoveSpeed * 0.05f;
}
else if (4 > fDistToSyncPos)
{
fThisMoveSpeed += fThisMoveSpeed * 0.10f;
}
else if (6 > fDistToSyncPos)
{
fThisMoveSpeed += fThisMoveSpeed * 0.20f;
}
fThisMoveSpeed = m_pcGOSSI.fServerSpeed;
}
//两个移动速度的差值
float fDistDiff = Mathf.Abs(fThisMoveSpeed - m_pcGOSSI.fServerSpeed);
if (0.1 <= fDistDiff)
{
Debug.Log("GO " + GameObjGUID + " fThisMoveSpeed:" + fThisMoveSpeed);
}
//每一个uptate客户端和服务端距离的差值
float fThisSyncDist = fThisMoveSpeed * fThisFrameTimeSpan;
//新位置=方位乘以距离+当前的位置
Vector3 sNewPos = sThisSyncDir * fThisSyncDist + realPos2D;
if (sNewPos.magnitude > 0)
{
objTransform.position = sNewPos;
}
//最终朝向
m_pcGOSSI.sLocalSyncDir = sThisSyncDir;
Quaternion DestQuaternion = Quaternion.LookRotation(sThisSyncDir);
Quaternion sMidQuater = Quaternion.Lerp(objTransform.rotation, DestQuaternion, 3 * Time.deltaTime);
//最终的旋转角度
objTransform.rotation = sMidQuater;
}