摇杆控制角色移动

玩家身上绑定的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;
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值