Exemplo n.º 1
0
    // 离开状态
    public void OnLeave()
    {
        MoveSyncFlag sendSync = MoveSyncFlag.TO_SERVER;

        int curTick = System.Environment.TickCount;

        if (m_pFSM)
        {
            m_pFSM.syncTick = curTick;
            Vector3 sendVelocity = Vector3.zero;
            m_pFSM.syncVelocity = sendVelocity;
            m_pFSM.syncPosition = m_pFSM.transform.position;
            m_pFSM.syncAngle    = m_pFSM.transform.eulerAngles;
        }
        Send_Sync_Position(sendSync);



        bWallWalking       = false;
        m_wallWalkingState = WallWalkingState.none;
        if (m_pFSM)
        {
            m_pFSM.animator.SetBool(hashid_isWallWalking, false);
            m_pFSM.animator.SetBool(hashid_isUpWall, false);
            m_pFSM.animator.SetBool(hashid_isDownWall, false);
            m_pFSM.enableCollider(true);
        }
    }
Exemplo n.º 2
0
    public void Send_Sync_Position(MoveSyncFlag reportToSever)
    {
        // trace
        if (m_pFSM == null)
        {
            Trace.LogError("CreatureState_Jomp.cs Send_Sync_Position m_pFSM == null");
            return;
        }

        //如果上报位置范围不对,则输出至LOG,退出
        if (float.IsNaN(tr.position.x) || float.IsNaN(tr.position.y) || float.IsNaN(tr.position.z) || Math.Abs(tr.position.x) > SceneManager.MAX_SCENE_SIZE || Math.Abs(tr.position.y) > SceneManager.MAX_SCENE_SIZE || Math.Abs(tr.position.z) > SceneManager.MAX_SCENE_SIZE)
        {
            Debug.LogError(m_pFSM.name + " Jumping Send_Sync_Position Position Error " + tr.position);
            return;
        }


        cmd_creature_rigidbody_sync data = new cmd_creature_rigidbody_sync();

        data.nCreatureState = (int)EntityState.Glide;
        data.fPosition_x    = tr.position.x;
        data.fPosition_y    = tr.position.y;
        data.fPosition_z    = tr.position.z;

        // 直接用欧拉角
        data.fRotation_x = tr.rotation.eulerAngles.x;
        data.fRotation_y = tr.rotation.eulerAngles.y;
        data.fRotation_z = tr.rotation.eulerAngles.z;

        data.fVelocity_x = m_pFSM.syncVelocity.x;
        data.fVelocity_y = m_pFSM.syncVelocity.y;
        data.fVelocity_z = m_pFSM.syncVelocity.z;
        data.nSyn2Server = (int)reportToSever;

        EntityEventHelper.Instance.SendCommand <cmd_creature_rigidbody_sync>(m_pFSM.entityID, EntityLogicDef.ENTITY_CMD_SET_POS, ref data);

        // 通知主角位置发生变化
        U3D_Render.EntityLocUpdate.SendActorLocationChange(new Vector3(tr.position.x, tr.position.y, tr.position.z));
        EntityBatchCommunicator.SendEntityPro(m_pFSM.entityID, tr.position, tr.rotation.eulerAngles);
    }
Exemplo n.º 3
0
    private void updateStep()
    {
        if (m_wallWalkSpeed < 0.01f)
        {
            stopWallWalk();
            return;
        }

        Vector3 walkStep   = m_wallWalkTargetPos - m_pFSM.transform.position;
        float   stepLength = m_wallWalkSpeed * Time.deltaTime;

        if (walkStep.magnitude <= stepLength)
        {
            //m_pFSM.controller.Move(walkStep);
            m_pFSM.transform.position += walkStep;
            nextStep();
        }
        else
        {
            walkStep.Normalize();
            walkStep = walkStep * stepLength;
            //m_pFSM.controller.Move(walkStep);
            m_pFSM.transform.position += walkStep;
        }


        int curTick = System.Environment.TickCount;

        if (curTick - m_lastSyncTick > 200)
        {
            m_lastSyncTick = curTick;
            MoveSyncFlag sendSync = MoveSyncFlag.TO_SERVER;
            m_pFSM.syncTick = curTick;
            Vector3 sendVelocity = walkStep.normalized * m_wallWalkSpeed;
            m_pFSM.syncVelocity = sendVelocity;
            m_pFSM.syncPosition = m_pFSM.transform.position;
            m_pFSM.syncAngle    = m_pFSM.transform.eulerAngles;
            Send_Sync_Position(sendSync);
        }
    }
Exemplo n.º 4
0
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 发送一次位置同步
    public void Send_Sync_Position(MoveSyncFlag reportToSever)
    {
        if (m_pFSM == null)
        {
            Trace.LogError("CreatureState_Standing.cs Send_Sync_Position m_pFSM == null");
            return;
        }

        //如果上报位置范围不对,则输出至LOG,退出
        if (float.IsNaN(m_pFSM.syncPosition.x) || float.IsNaN(m_pFSM.syncPosition.y) || float.IsNaN(m_pFSM.syncPosition.z) || Math.Abs(m_pFSM.syncPosition.x) > SceneManager.MAX_SCENE_SIZE || Math.Abs(m_pFSM.syncPosition.y) > SceneManager.MAX_SCENE_SIZE || Math.Abs(m_pFSM.syncPosition.z) > SceneManager.MAX_SCENE_SIZE)
        {
            Debug.LogError(m_pFSM.name + " standing Send_Sync_Position Position Error " + m_pFSM.syncPosition);
            return;
        }


        cmd_creature_rigidbody_sync data = new cmd_creature_rigidbody_sync();

        data.nCreatureState = (int)EntityState.WallWalking;
        data.fPosition_x    = m_pFSM.syncPosition.x;
        data.fPosition_y    = m_pFSM.syncPosition.y;
        data.fPosition_z    = m_pFSM.syncPosition.z;

        // 直接用欧拉角
        data.fRotation_x = m_pFSM.syncAngle.x;
        data.fRotation_y = m_pFSM.syncAngle.y;
        data.fRotation_z = m_pFSM.syncAngle.z;

        data.fVelocity_x = m_pFSM.syncVelocity.x;
        data.fVelocity_y = m_pFSM.syncVelocity.y;
        data.fVelocity_z = m_pFSM.syncVelocity.z;
        data.nSyn2Server = (int)reportToSever;

        EntityEventHelper.Instance.SendCommand <cmd_creature_rigidbody_sync>(m_pFSM.entityID, EntityLogicDef.ENTITY_CMD_SET_POS, ref data);

        if (tr == null)
        {
            Trace.LogError("CreatureState_Standing.cs Send_Sync_Position tr == null");
            return;
        }

        if (tr.position == null)
        {
            Trace.LogError("CreatureState_WallWalking.cs Send_Sync_Position tr.SetPosition== null");
            return;
        }

        if (tr.rotation == null)
        {
            Trace.LogError("CreatureState_WallWalking.cs Send_Sync_Position tr.rotation == null");
            return;
        }

        if (tr.rotation.eulerAngles == null)
        {
            Trace.LogError("CreatureState_WallWalking.cs Send_Sync_Position tr.rotation.eulerAngles == null");
            return;
        }

        EntityBatchCommunicator.SendEntityPro(m_pFSM.entityID, tr.position, tr.rotation.eulerAngles);

        if (m_pFSM.isHero)
        {
            U3D_Render.EntityView ev = EntityFactory.getPlayerViewByID(m_pFSM.entityID);
            MapFinderManager.MoveObject(ref ev, tr.position);
        }
    }
Exemplo n.º 5
0
    private void UpdateFunction()
    {
        if (floatingState == FloatingState.Down && grounded)
        {
            m_pFSM.ChangeState((int)EntityState.Standing, IntPtr.Zero);

            //float landingSpeed = m_lastvelocity.y;
            //float maxFallSpeed = m_pFSM.SkinConfig == null ? -30 : -m_pFSM.SkinConfig.maxFallSpeed * 2.0f;

            float fallHeight = startHeight - m_pFSM.transform.position.y;
            //if (landingSpeed > maxFallSpeed / 2.0f) //着陆大于最大速度的一半,可能需要计算伤害,上报逻辑层
            if (m_pFSM.isHero && fallHeight > 5.0f) //着陆时落差大于5米,则上报逻辑层
            {
                cmd_creature_act_landspeed data = new cmd_creature_act_landspeed();

                data.fValue = fallHeight;
                IntPtrHelper helper  = new IntPtrHelper();
                int          len     = Marshal.SizeOf(data);
                IntPtr       ptr     = helper.toPtr <cmd_creature_act_landspeed>(ref data);
                int          eventID = (int)EntityLogicDef.ENTITY_CMD_LANDING_SPEED;
                GameLogicAPI.onEntityEvent(m_pFSM.entityID, eventID, len, "", ptr, len);

                if (m_pFSM.showLog)
                {
                    Trace.Log("Big Landing! fallHeight=" + fallHeight.ToString());
                }
            }
        }

        uint currentTick = GameLogicAPI.getTickCount();
        int  deltaTick   = (int)(currentTick - lastFrameTick);

        deltaTick     = deltaTick < 1 ? 1 : deltaTick;
        lastFrameTick = currentTick;
        deltaTime     = ((float)deltaTick) / 1000.0f;
        if (m_lastFrameDeltaTime <= 0.01f)
        {
            m_lastFrameDeltaTime = deltaTime;
        }

        if (m_pFSM.moveCtrl.isCharge())
        {
            //Trace.LogWarning("can't move: m_pFSM.bForceMoving=" + m_pFSM.bForceMoving.ToString() + ",m_pFSM.bForceFlighting=" + m_pFSM.bForceFlighting.ToString());
            return;
        }

        sendSync = MoveSyncFlag.NOT_2_SERVER;

        //--------------------------------------------------------
        // 下面算速度
        //--------------------------------------------------------
        //float finalInertiaAcceleration = m_accSpeed; //惯性加速度
        currentvelocity = new Vector3(0.0f, 0.0f, 0.0f);
        bool forceUp = false;

        if (m_pFSM.isHero && !m_pFSM.bControlledBySever) //主角的话下面多折腾下速度
        {
            // Calculate the velocity based on the current and previous position.
            // This means our velocity will only be the amount the character actually moved as a result of collisions.
            //Vector3 oldHVelocity = new Vector3(lastvelocity.x, 0, lastvelocity.z);
            //Vector3 newHVelocity = lastoffset / deltaTime;
            //newHVelocity = new Vector3(newHVelocity.x, 0, newHVelocity.z);

            //// The CharacterController can be moved in unwanted directions when colliding with things.
            //// We want to prevent this from influencing the recorded velocity.
            //if (oldHVelocity == Vector3.zero)
            //{
            //    newHVelocity = new Vector3(0, newHVelocity.y, 0);
            //}
            //else
            //{
            //    float projectedNewVelocity = Vector3.Dot(newHVelocity, oldHVelocity) / oldHVelocity.sqrMagnitude;
            //    newHVelocity = oldHVelocity * Mathf.Clamp01(projectedNewVelocity) + newHVelocity.y * Vector3.up;
            //}


            //if (newHVelocity.y < currentvelocity.y - 0.001)
            //{
            //    if (newHVelocity.y < 0)
            //    {
            //        // Something is forcing the CharacterController down faster than it should.
            //        // Ignore this
            //        newHVelocity.y = lastvelocity.y;
            //    }
            //}

            // Update velocity based on input
            //newHVelocity = ApplyInputVelocityChange(newHVelocity);
            Vector3 newHVelocity = ApplyInputVelocityChange(m_lastvelocity);

            //if (newHVelocity.sqrMagnitude < 0.001f) //如果是停止的,就不计算惯性速度,免得技能僵直之类的效果生效不够及时
            //{
            //    currentvelocity = newHVelocity;
            //}
            //else
            //{
            currentvelocity = newHVelocity;
            //}

            //这里记录的是没经过ApplyYSpeed的Y轴调整的速度
            m_lastvelocity = currentvelocity;



            // 判断本地的模拟坐标和真实坐标的差别, 只有达到一定阀值才需要同步
            // 暂时在行走过程中200ms同步一次
            int curTick = System.Environment.TickCount;


            if (currentvelocity.sqrMagnitude <= 0.001f)
            {
                currentvelocity = Vector3.zero;
            }

            // 启动和站立强制同步一次
            if ((m_pFSM.syncVelocity.sqrMagnitude > 0.001f && currentvelocity.sqrMagnitude <= 0.001f) ||
                (m_pFSM.syncVelocity.sqrMagnitude <= 0.001f && currentvelocity.sqrMagnitude > 0.001f))
            {
                sendSync = MoveSyncFlag.TO_BROADCAST;
            }
            // 每200毫秒根据速度或者移动距离考虑是否同步一次
            else if (curTick >= m_pFSM.syncTick + m_pFSM.syncInterval)
            {
                //速度/位置/旋转分别跟上一次同步的数据比对看是否需要同步
                Vector3 velSub = currentvelocity - m_pFSM.syncVelocity;
                Vector3 posSub = tr.position - m_pFSM.syncPosition;
                Vector3 rotSub = tr.eulerAngles - m_pFSM.syncAngle;
                if (velSub.sqrMagnitude > 0.01f || posSub.sqrMagnitude > 0.01f || rotSub.sqrMagnitude > 0.01f)
                {
                    sendSync = MoveSyncFlag.TO_SERVER;
                }
            }

            if (floatingState == FloatingState.Down && curTick >= m_pFSM.syncTick + m_pFSM.syncInterval / 4)
            {
                sendSync = MoveSyncFlag.TO_SERVER;
            }

            currentvelocity = ApplyYSpeed(currentvelocity, ref forceUp);
        }
        else//不是主角直接用同步的速度
        {
            currentvelocity = m_pFSM.syncVelocity;
            Vector3 deltapos = m_pFSM.syncPosition - tr.position;
            float   dis      = deltapos.magnitude;
            if (m_pFSM.syncVelocity.sqrMagnitude < 0.001f && dis > 0.01f)     //速度为0,但还没到同步的目的地,补偿一下误差
            {
                float alpha = Mathf.Clamp01((dis - 0.01f) / approximatethre); //对速度根据离同步位置误差距离作逼近收敛修正
                float speed = (1.0f - alpha) * 0.0f + alpha * approximatethre * apmtspeedratio;
                currentvelocity = deltapos.normalized * speed;
            }
            else
            {
                //Vector3 newHVelocity = m_pFSM.syncVelocity;
                //Vector3 oldHVelocity = new Vector3(lastvelocity.x, 0, lastvelocity.z);
                //Vector3 HVelocityDelta = newHVelocity - oldHVelocity;
                //float advance = deltaTime * finalInertiaAcceleration;
                //if (advance > HVelocityDelta.magnitude) advance = HVelocityDelta.magnitude;
                //currentvelocity = oldHVelocity + HVelocityDelta.normalized * advance;
                currentvelocity = m_pFSM.syncVelocity;
            }
            currentvelocity = ApplyYSpeed(currentvelocity, ref forceUp);
        }


        //--------------------------------------------------------
        // 下面算位置
        //--------------------------------------------------------
        // We always want the movement to be framerate independent.  Multiplying by Time.deltaTime does this.

        if (deltaTime > m_lastFrameDeltaTime * 2.0f || deltaTime < m_lastFrameDeltaTime / 2.0f) //缓冲帧率突变产生的跳跃
        {
            deltaTime = deltaTime * m_pFSM.frameAccFactor + m_lastFrameDeltaTime * (1 - m_pFSM.frameAccFactor);
        }
        m_lastFrameDeltaTime = deltaTime;


        Vector3 currentOffset = currentvelocity * deltaTime;

        m_pFSM.syncDetalTime += deltaTime;

        // Find out how much we need to push towards the ground to avoid loosing grouning
        // when walking down a step or over a sharp change in slope.
        if (m_pFSM.isHero && !m_pFSM.bControlledBySever)//主角
        {
            if (m_pFSM.ShiftEnable)
            {
                //if (InputManager.GetKey(KeyCode.LeftShift) || InputManager.GetKey(KeyCode.RightShift))//主角暂时添加加速快捷键以便测试
                {
                    currentOffset *= 5.0f;
                }
            }
        }
        else //非主角
        {
            //Vector3 idealPos = tr.position;
            //calSyncOffset(currentvelocity, ref currentOffset, ref idealPos);
            if (/*floatingState != FloatingState.Down &&*/ !forceUp) //下落的时候采用同步位置会上下拉扯,没到规定高度的时候不等同步包强制上升
            {
                if (floatingState == FloatingState.Down)
                {
                    // 下落过程中不用同步位置会在这段不同步 所以还是要使用水平方向的同步位置
                    // 下落时垂直速度要向下 不能因为同步位置还没过来掉一段再往上个同步位置拉
                    Vector3 dirHrz = m_pFSM.syncPosition - tr.position;
                    dirHrz.y = 0;
                    Vector3 dirNormal = dirHrz.normalized;
                    dirNormal.y = -1;
                    dirNormal   = dirNormal.normalized;

                    currentvelocity = dirNormal * currentvelocity.magnitude;
                }
                else
                {
                    Vector3 dir = (m_pFSM.syncPosition - tr.position).normalized;
                    currentvelocity = dir * currentvelocity.magnitude;
                }
            }
            currentOffset = currentvelocity * deltaTime;
            if (currentOffset.sqrMagnitude < 0.001f)
            {
                currentvelocity = Vector3.zero;
            }
        }

        //--------------------------------------------------------
        // 下面更新animator
        //--------------------------------------------------------
        if (m_pFSM.animator != null)
        {
            if (!m_pFSM.isHero || m_pFSM.bControlledBySever)
            {
                //m_lastvelocity是特殊处理飞行时候的移动速度,是它播放合适的动作
                currentvelocity = m_lastvelocity;
            }
            Vector3 planeVel = new Vector3(currentvelocity.x, 0, currentvelocity.z);
            if (planeVel.sqrMagnitude > 0.001f)
            {
                m_pFSM.animator.SetBool("isMoving", true);
                //m_pFSM.animatorCtrl.ana.SetBool("isMoving", true);
                bIsMoving = true;
            }
            else
            {
                m_pFSM.animator.SetBool("isMoving", false);
                //m_pFSM.animatorCtrl.ana.SetBool("isMoving", false);
                bIsMoving = false;
            }

            //取移动速度相对于主角面向的向前和向左的标量
            Vector3 projectVel = Vector3.zero;
            projectVel.x = Vector3.Dot(m_lastvelocity, tr.right); //m_lastvelocity是排除Y方向操作速度的原始速度,可以用来计算方向动作
            projectVel.z = Vector3.Dot(m_lastvelocity, tr.forward);
            float fRight   = 0.0f;
            float fForward = 0.0f;
            if (projectVel.sqrMagnitude > 0.0036f)//同步过来的速度为0之后,点乘还会有误差,造成轻微移动动作
            {
                fForward = projectVel.z / m_maxSpeed;
                fRight   = projectVel.x / m_maxSpeed;
            }

            if (Mathf.Abs(fRight) < 0.06f)
            {
                fRight = 0.0f;
            }
            if (Mathf.Abs(fForward) < 0.06f)
            {
                fForward = 0.0f;
            }

            fForward = Mathf.Min(fForward, 1.0f);
            fForward = Mathf.Max(fForward, -1.0f);
            fRight   = Mathf.Min(fRight, 1.0f);
            fRight   = Mathf.Max(fRight, -1.0f);

            //移动速度考虑了服务器速度和基本速度的比率后,按服务器速度算animator参数值

            //fForward = fForward / m_maxSpeed;
            //fRight = fRight / m_maxSpeed;

            m_pFSM.animator.SetFloat("moveright", fRight);
            m_pFSM.animator.SetFloat("moveforward", fForward);
            m_pFSM.animator.SetFloat("velocity", currentvelocity.magnitude);


            if (wingAnimator)
            {
                wingAnimator.SetFloat("moveright", fRight);
                wingAnimator.SetFloat("moveforward", fForward);
            }

            if (m_pFSM.animatorCtrl.anb != null)
            {
                m_pFSM.animatorCtrl.anb.SetFloat("moveright", fRight);
                m_pFSM.animatorCtrl.anb.SetFloat("moveforward", fForward);
            }
        }


        //--------------------------------------------------------
        // 下面更新transform
        //--------------------------------------------------------
        // Save lastPosition for velocity calculation.
        Vector3 oldPosition = tr.position;
        float   curtime     = Time.time;

        if (m_pFSM.isHero && !m_pFSM.bControlledBySever)//是主角,都用耗时的物理行走方法
        {
            m_pFSM.collisionFlags = m_pFSM.controller.Move(currentOffset);
            ++heroMoveTimes;
        }
        else//非主角
        {
            float pos_dis = (m_pFSM.syncPosition - tr.transform.position).magnitude;
            if (m_pFSM.syncVelocity.sqrMagnitude < 0.01f && m_pFSM.animatorCtrl.bDoingAttackMove)
            {
                pos_dis = 0.0f;                                                                                  //正在利用动作控制位移,就不按同步包移动了
            }
            if ((floatingState == FloatingState.Down) || (physenable && pos_dis > approximatethre) || (forceUp)) //上下落或者跟同步位置差距较大时用耗时的物理行走方法
            {
                m_pFSM.collisionFlags = m_pFSM.controller.Move(currentOffset);
            }
            else if (pos_dis > 0.01f) //否则用较小耗时的渐趋逼近公式
            {
                Vector3 deltapos = m_pFSM.syncPosition - tr.transform.position;
                Vector3 curPos;
                if (deltapos.sqrMagnitude > currentOffset.sqrMagnitude)
                {
                    curPos = tr.transform.position + currentOffset;
                }
                else
                {
                    curPos = tr.transform.position * 0.5f + m_pFSM.syncPosition * 0.5f;
                }
                tr.transform.SetPosition(curPos);
            }


            //特殊处理飞行时候的移动速度,是它播放合适的动作
            Vector3 deltaDis   = m_pFSM.syncPosition - tr.transform.position;
            Vector3 newVectory = Vector3.zero;
            if (deltaDis.sqrMagnitude > 0.01f)
            {
                newVectory   = currentOffset;
                newVectory.y = 0;
                newVectory   = newVectory.normalized * m_maxSpeed;
            }
            m_lastvelocity = m_lastvelocity * 0.3f + newVectory * 0.7f;
        }

        if (m_pFSM.isHero && !m_pFSM.bControlledBySever)//主角不用平滑角度
        {
        }
        else//非主角才平滑角度角度
        {
            float angle_dis = (m_pFSM.syncAngle - tr.transform.eulerAngles).magnitude;
            if (angle_dis > 0.1f) //角度差距较大时采用逼近公式
            {
                Vector3 newangle;
                newangle.x     = Mathf.LerpAngle(tr.eulerAngles.x, m_pFSM.syncAngle.x, 0.2f);
                newangle.y     = Mathf.LerpAngle(tr.eulerAngles.y, m_pFSM.syncAngle.y, 0.2f);
                newangle.z     = Mathf.LerpAngle(tr.eulerAngles.z, m_pFSM.syncAngle.z, 0.2f);
                tr.eulerAngles = newangle;
            }
        }

        lastupdatetime = curtime;
        lastoffset     = currentOffset;

        //最后算完才上报
        if (sendSync != MoveSyncFlag.NOT_2_SERVER && (m_pFSM.isHero && !m_pFSM.bControlledBySever))
        {
            int curTick = System.Environment.TickCount;
            m_pFSM.syncTick = curTick;
            Vector3 sendVelocity = currentvelocity;
            m_pFSM.syncVelocity = sendVelocity;
            m_pFSM.syncPosition = tr.position;
            m_pFSM.syncAngle    = tr.eulerAngles;
            Send_Sync_Position(sendSync);
        }
        else if (heroMoveTimes >= 8)
        {
            Vector3 sendVelocity = new Vector3(currentvelocity.x, 0.0f, currentvelocity.z);
            updatePosWithoutSend(sendVelocity, tr.position, tr.eulerAngles);
            heroMoveTimes = 0;
        }

        //移动完更新地面判断
        grounded = m_pFSM.groundNormal.y > 0.01f;
    }
Exemplo n.º 6
0
 public void Send_Sync_Position(MoveSyncFlag reportToSever)
 {
 }
Exemplo n.º 7
0
    private void UpdateFunction()
    {
        deltaTime = Time.deltaTime;
        if (deltaTime < 0.001f)
        {
#if  UNITY_EDITOR
            Debug.LogError("deltaTime=" + deltaTime);
#else
            Trace.Log("deltaTime=" + deltaTime);
#endif
            return;
        }

        if (m_lastFrameDeltaTime <= 0.01f)
        {
            m_lastFrameDeltaTime = deltaTime;
        }

        if (m_pFSM.moveCtrl.isCharge())
        {
            if (m_pFSM.animator != null)
            {
                //Trace.LogWarning("can't move: m_pFSM.bForceMoving=" + m_pFSM.bForceMoving.ToString() + ",m_pFSM.bForceFlighting=" + m_pFSM.bForceFlighting.ToString());
                m_pFSM.animator.SetFloat(hashid_moveforward, 0);
                m_pFSM.animator.SetFloat(hashid_moveright, 0);
                m_pFSM.animator.SetFloat(hashid_velocity, 0);
                m_pFSM.animator.SetBool(hashid_isMoving, false);
            }
            return;
        }

        sendSync = MoveSyncFlag.NOT_2_SERVER;

        //--------------------------------------------------------
        // 下面算速度
        //--------------------------------------------------------
        if (float.IsNaN(m_pFSM.creaturePropety.runSpeed_Forward))
        {
            Debug.LogError(m_pFSM.name + " Standing m_pFSM.creaturePropety.runSpeed_Forward error:" + m_pFSM.creaturePropety.runSpeed_Forward);
            return;
        }

        float finalInertiaAcceleration = m_pFSM.creaturePropety.InertiaAcceleration *
                                         ((m_pFSM.maxForwardSpeed / m_pFSM.creaturePropety.runSpeed_Forward - 1.0f) * m_pFSM.creaturePropety.InertiaScale + 1.0f); //惯性加速度


        currentvelocity = new Vector3(0.0f, 0.0f, 0.0f);
        if (m_pFSM.isHero && !m_pFSM.bControlledBySever) //主角的话下面多折腾下速度
        {
            // Calculate the velocity based on the current and previous position.
            // This means our velocity will only be the amount the character actually moved as a result of collisions.
            Vector3 oldHVelocity = new Vector3(lastvelocity.x, 0, lastvelocity.z);
            Vector3 newHVelocity = lastoffset / deltaTime;
            newHVelocity = new Vector3(newHVelocity.x, 0, newHVelocity.z);

            // The CharacterController can be moved in unwanted directions when colliding with things.
            // We want to prevent this from influencing the recorded velocity.
            //if (oldHVelocity == Vector3.zero)
            if (oldHVelocity.sqrMagnitude < 0.0001f)
            {
                newHVelocity = new Vector3(0, newHVelocity.y, 0);
            }
            else
            {
                float projectedNewVelocity = Vector3.Dot(newHVelocity, oldHVelocity) / oldHVelocity.sqrMagnitude; //方向不变 夹角为0 点积为|a||b|*1
                newHVelocity = oldHVelocity * Mathf.Clamp01(projectedNewVelocity) + newHVelocity.y * Vector3.up;
            }



            if (newHVelocity.y < currentvelocity.y - 0.001f)
            {
                if (newHVelocity.y < 0)
                {
                    // Something is forcing the CharacterController down faster than it should.
                    // Ignore this
                    newHVelocity.y = lastvelocity.y;
                }
            }

            // Update velocity based on input
            newHVelocity = ApplyInputVelocityChange(newHVelocity);
            if (newHVelocity.sqrMagnitude < 0.0001f) //如果是停止的,就不计算惯性速度,免得技能僵直之类的效果生效不够及时
            {
                if (InputMoveDirectionDelay > 0.2f)
                {
                    currentvelocity = newHVelocity;
                }
                else
                {
                    //短暂的停止按键留有缓冲时间
                    currentvelocity          = oldHVelocity;
                    InputMoveDirectionDelay += deltaTime;
                }
            }
            else
            {
                if (InputMoveDirectionDelay != 0)
                {
                    InputMoveDirectionDelay = 0;
                }
                Vector3 HVelocityDelta = newHVelocity - oldHVelocity;

                float advance = deltaTime * finalInertiaAcceleration;
                if (advance > HVelocityDelta.magnitude)
                {
                    advance = HVelocityDelta.magnitude;
                }
                currentvelocity = oldHVelocity + HVelocityDelta.normalized * advance;
                if (currentvelocity.magnitude <= 0.1f)
                {
                    //按键输入不为0,速度过度时减速最低不能为0,防止上发判断为停止
                    currentvelocity = currentvelocity.normalized * 0.5f;
                }
            }



            // 判断本地的模拟坐标和真实坐标的差别, 只有达到一定阀值才需要同步
            // 暂时在行走过程中200ms同步一次
            int curTick = System.Environment.TickCount;


            //if (currentvelocity.sqrMagnitude <= 0.0001f && currentvelocity != Vector3.zero)
            //{
            //    currentvelocity = Vector3.zero;
            //}
            //if (currentvelocity == Vector3.zero)
            //{
            //    m_pFSM.RunSpeedUpUpdateInfo(0, 0);
            //}
            // 启动和站立强制同步一次
            if ((m_pFSM.syncVelocity.sqrMagnitude > 0.0001f && currentvelocity.sqrMagnitude <= 0.0001f) ||
                (m_pFSM.syncVelocity.sqrMagnitude <= 0.0001f && currentvelocity.sqrMagnitude > 0.001f))
            {
                sendSync = MoveSyncFlag.TO_BROADCAST;
            }
            // 每syncInterval毫秒根据速度或者移动距离考虑是否同步一次
            else if (curTick >= m_pFSM.syncTick + m_pFSM.syncInterval)
            {
                //速度/位置/旋转分别跟上一次同步的数据比对看是否需要同步
                Vector3 velSub = currentvelocity - m_pFSM.syncVelocity;
                Vector3 posSub = tr.position - m_pFSM.syncPosition;
                Vector3 rotSub = tr.eulerAngles - m_pFSM.syncAngle;
                if (velSub.sqrMagnitude > 0.01f || posSub.sqrMagnitude > 0.01f || rotSub.sqrMagnitude > 0.01f)
                {
                    sendSync = MoveSyncFlag.TO_SERVER;
                }
            }

            currentvelocity = ApplyGravity(currentvelocity); //主角的话添加重力到速度
        }
        else//不是主角直接用同步的速度
        {
            currentvelocity = m_pFSM.syncVelocity;
            Vector3 deltapos = m_pFSM.syncPosition - tr.position;
            float   dis      = deltapos.magnitude;
            if (m_pFSM.syncVelocity.sqrMagnitude < 0.001f && dis > 0.01f)     //速度为0,但还没到同步的目的地,补偿一下误差
            {
                float alpha = Mathf.Clamp01((dis - 0.01f) / approximatethre); //对速度根据离同步位置误差距离作逼近收敛修正
                float speed = (1.0f - alpha) * 0.0f + alpha * approximatethre * apmtspeedratio;
                currentvelocity = deltapos.normalized * speed;
            }
            else
            {
                Vector3 newHVelocity   = m_pFSM.syncVelocity;
                Vector3 oldHVelocity   = new Vector3(lastvelocity.x, 0, lastvelocity.z);
                Vector3 HVelocityDelta = newHVelocity - oldHVelocity;
                float   advance        = deltaTime * finalInertiaAcceleration;
                if (advance > HVelocityDelta.magnitude)
                {
                    advance = HVelocityDelta.magnitude;
                }
                currentvelocity = oldHVelocity + HVelocityDelta.normalized * advance;
            }
        }
        lastvelocity = currentvelocity;
        CheckMoveForward();//检查是否向前



        //--------------------------------------------------------
        // 下面算位置
        //--------------------------------------------------------
        // We always want the movement to be framerate independent.  Multiplying by Time.deltaTime does this.
        if (deltaTime > m_lastFrameDeltaTime * 2.0f || deltaTime < m_lastFrameDeltaTime / 2.0f) //缓冲帧率突变产生的跳跃
        {
            deltaTime = deltaTime * m_pFSM.frameAccFactor + m_lastFrameDeltaTime * (1 - m_pFSM.frameAccFactor);
        }
        m_lastFrameDeltaTime = deltaTime;

        Vector3 currentOffset = currentvelocity * deltaTime;
        m_pFSM.syncDetalTime += deltaTime;

        // Find out how much we need to push towards the ground to avoid loosing grouning
        // when walking down a step or over a sharp change in slope.
        if (m_pFSM.isHero && !m_pFSM.bControlledBySever) //主角
        {
            if (grounded)                                //主角贴地
            {
                float pushDownOffset = Mathf.Max(m_pFSM.controller.stepOffset, (new Vector3(currentOffset.x, 0, currentOffset.z)).magnitude);
                if (float.IsNaN(m_pFSM.controller.stepOffset))
                {
                    Debug.LogError(m_pFSM.name + "standing m_pFSM.controller.stepOffset " + m_pFSM.controller.stepOffset);
                    pushDownOffset = (new Vector3(currentOffset.x, 0, currentOffset.z)).magnitude;
                }
                currentOffset -= pushDownOffset * Vector3.up;
            }
            if (m_pFSM.ShiftEnable)
            {
                //if (InputManager.GetKey(KeyCode.LeftShift) || InputManager.GetKey(KeyCode.RightShift))//主角暂时添加加速快捷键以便测试
                {
                    currentOffset *= 5.0f;
                }
            }
        }
        else //非主角
        {
            //Vector3 idealPos = tr.position;
            //calSyncOffset(currentvelocity, ref currentOffset, ref idealPos);
            //currentvelocity =  * m_pFSM.syncVelocity.magnitude;
            Vector3 dir = (m_pFSM.syncPosition - tr.position).normalized;
            currentvelocity = dir * currentvelocity.magnitude;
            currentOffset   = currentvelocity * deltaTime;
            if (currentOffset.sqrMagnitude < 0.001f)
            {
                currentvelocity = Vector3.zero;
            }
        }

        //--------------------------------------------------------
        // 下面更新animator
        //--------------------------------------------------------
        if (m_pFSM.animatorCtrl.ana != null && m_pFSM.animatorCtrl.ana.isInitialized)
        {
            Vector3 planeVel = new Vector3(currentvelocity.x, 0, currentvelocity.z);
            if (planeVel.sqrMagnitude > 0.0001f)
            {
                m_pFSM.animatorCtrl.ana.SetBool("isMoving", true);
                bIsMoving = true;
            }
            else
            {
                m_pFSM.animatorCtrl.ana.SetBool("isMoving", false);
                bIsMoving = false;
            }

            //取移动速度相对于主角面向的向前和向左的标量
            float fRight   = Vector3.Dot(currentvelocity, tr.right);
            float fForward = Vector3.Dot(currentvelocity, tr.forward);
            if (currentvelocity.sqrMagnitude < 0.0036f)
            {
                //同步过来的速度为0之后,点乘还会有误差,造成轻微移动动作
                fRight   = 0.0f;
                fForward = 0.0f;
            }

            if (Mathf.Abs(fRight) < 0.06f)
            {
                fRight = 0.0f;
            }
            if (Mathf.Abs(fForward) < 0.06f)
            {
                fForward = 0.0f;
            }

            //移动速度考虑了服务器速度和基本速度的比率后,按服务器速度算animator参数值

            if (m_pFSM.maxForwardSpeed > 0)
            {
                if (fForward >= 0.0f)
                {
                    fForward = fForward / m_pFSM.maxForwardSpeed;
                }
                else
                {
                    fForward = fForward / m_pFSM.maxRunBackwardSpeed;
                }
            }
            else
            {
                if (fForward > 0.0f)
                {
                    fForward = fForward / m_pFSM.creaturePropety.runSpeed_Forward;
                }
                else
                {
                    fForward = fForward / m_pFSM.creaturePropety.runSpeed_Back;
                }
            }

            if (m_pFSM.maxRunSidewaySpeed > 0)
            {
                fRight = fRight / m_pFSM.maxRunSidewaySpeed;
            }
            else
            {
                fRight = fRight / m_pFSM.creaturePropety.runSpeed_LeftRight;
            }


            //fForward = fForward / m_pFSM.basicForwardSpeed;
            //fRight = fRight / m_pFSM.basicSidewaysSpeed;


            //速度和动作不能成正比,线性的话速度小的时候容易滑步,这里利用开根做了一次非线性变换
            //if (fForward >= 0.0f)
            //{
            //    fForward = Mathf.Sqrt(fForward);
            //}
            //else
            //{
            //    fForward = -Mathf.Sqrt(-fForward);
            //}

            //if (fRight >= 0.0f)
            //{
            //    fRight = Mathf.Sqrt(fRight);
            //}
            //else
            //{
            //    fRight = -Mathf.Sqrt(-fRight);
            //}

            if (m_pFSM.animatorCtrl.ana != null && m_pFSM.animatorCtrl.ana.isInitialized)
            {
                m_pFSM.animatorCtrl.ana.SetFloat(hashid_moveright, fRight);
                m_pFSM.animatorCtrl.ana.SetFloat(hashid_moveforward, fForward);
                m_pFSM.animatorCtrl.ana.SetFloat(hashid_velocity, currentvelocity.magnitude);
            }

            if (m_pFSM.animatorCtrl.anb != null && m_pFSM.animatorCtrl.anb.isInitialized)
            {
                m_pFSM.animatorCtrl.anb.SetFloat(hashid_moveright, fRight);
                m_pFSM.animatorCtrl.anb.SetFloat(hashid_moveforward, fForward);
            }
            //m_pFSM. updateMovingAnimSpeed();
            //动画速率用maxSpeed和basicSpeed比率控制,这里暂时不控制
            //float speedScale = Mathf.Max(Mathf.Abs(fRight), Mathf.Abs(fForward));
            //if (speedScale > 1.0f)
            //{
            //    speedScale = (speedScale - 1.0f) * 0.3f + 1.0f; //张嘉华提供的跑路速度和跑路动画速度关系
            //    m_pFSM.animator.speed = speedScale;
            //}
            //else
            //{
            //    m_pFSM.animator.speed = 1.0f;
            //}
        }


        //--------------------------------------------------------
        // 下面更新transform
        //--------------------------------------------------------
        // Save lastPosition for velocity calculation.
        Vector3 oldPosition = tr.position;

        float curtime = Time.time;

        if (m_pFSM.isHero && !m_pFSM.bControlledBySever)//是主角,都用耗时的物理行走方法
        {
            m_pFSM.collisionFlags = m_pFSM.controller.Move(currentOffset);
            ++heroMoveTimes;
        }
        else//非主角
        {
            float pos_dis = (m_pFSM.syncPosition - tr.transform.position).magnitude;
            if (m_pFSM.syncVelocity.sqrMagnitude < 0.01f && m_pFSM.animatorCtrl.bDoingAttackMove)
            {
                pos_dis = 0.0f;                          //正在利用动作控制位移,就不按同步包移动了
            }
            if (physenable && pos_dis > approximatethre) //跟同步位置差距较大时用耗时的物理行走方法
            {
                m_pFSM.collisionFlags = m_pFSM.controller.Move(currentOffset);
            }
            else if (pos_dis > 0.01f) //否则用较小耗时的渐趋逼近公式
            {
                Vector3 deltapos = m_pFSM.syncPosition - tr.transform.position;
                Vector3 curPos;
                if (deltapos.sqrMagnitude > currentOffset.sqrMagnitude)
                {
                    curPos = tr.transform.position + currentOffset;
                }
                else
                {
                    curPos = tr.transform.position * 0.5f + m_pFSM.syncPosition * 0.5f;
                }
                float GroundedCheckDistance = 5.0f;
                curPos = BaseStateMachine.CorrectPosFromPhysic(curPos, m_pFSM.creaturePropety.CreatureHeightInMeters + 0.1f, GroundedCheckDistance);
                tr.transform.SetPosition(curPos);
            }
            else
            {
            }
        }

        if (m_pFSM.isHero && !m_pFSM.bControlledBySever)//主角不用平滑角度
        {
        }
        else//非主角才平滑角度角度
        {
            float angle_dis = (m_pFSM.syncAngle - tr.transform.eulerAngles).magnitude;
            if (angle_dis > 0.1f) //角度差距较大时采用逼近公式
            {
                Vector3 newangle;
                newangle.x     = Mathf.LerpAngle(tr.eulerAngles.x, m_pFSM.syncAngle.x, 0.2f);
                newangle.y     = Mathf.LerpAngle(tr.eulerAngles.y, m_pFSM.syncAngle.y, 0.2f);
                newangle.z     = Mathf.LerpAngle(tr.eulerAngles.z, m_pFSM.syncAngle.z, 0.2f);
                tr.eulerAngles = newangle;
            }
        }

        lastupdatetime = curtime;

        lastoffset = currentOffset;
        //最后算完才上报
        if (sendSync != MoveSyncFlag.NOT_2_SERVER && (m_pFSM.isHero && !m_pFSM.bControlledBySever))
        {
            int curTick = System.Environment.TickCount;
            m_pFSM.syncTick = curTick;
            Vector3 sendVelocity = new Vector3(currentvelocity.x, 0.0f, currentvelocity.z);
            m_pFSM.syncVelocity = sendVelocity;
            m_pFSM.syncPosition = tr.position;
            m_pFSM.syncAngle    = tr.eulerAngles;

            Send_Sync_Position(sendSync);
        }
        else if (heroMoveTimes >= 4)
        {
            Vector3 sendVelocity = new Vector3(currentvelocity.x, 0.0f, currentvelocity.z);
            updatePosWithoutSend(sendVelocity, tr.position, tr.eulerAngles);
            heroMoveTimes = 0;
        }
    }
Exemplo n.º 8
0
    // 更新状态逻辑
    public void Update()
    {
        deltaTime = Time.deltaTime;
        if (deltaTime < 0.001f)
        {
            Debug.LogError("deltaTime=" + deltaTime);
            return;
        }
        uint tick        = GameLogicAPI.getTickCount();
        bool oldGrounded = isGrounded;

        isGrounded = IsGroundedTest();                                   //测试是否在空中
        float   Vy            = getVelocity().y;
        Vector3 inputVelocity = ApplyInputVelocityChange(getVelocity()); //根据键盘输入调整速度
        Vector3 velocity      = Vector3.zero;

        if (m_pFSM.isHero && !m_pFSM.bControlledBySever)
        {
            velocity = inputVelocity;
        }
        else
        {
            velocity = m_pFSM.syncVelocity;
        }
        velocity.y = Vy;
        //处理在空中的情况
        if (isGrounded && !m_bIsGlideRuning)
        {
            //刚到地面,开始着陆的处理
            if (!m_bIsLanding)
            {
                //切换动作
                if (m_pFSM.animator)
                {
                    m_pFSM.animator.SetBool(hashid_isLanding, true);
                    m_pFSM.animator.SetBool(hashid_isGlide, false);
                    m_pFSM.animator.SetBool(hashid_FlyDown, false);
                }

                m_bIsLanding = true;    //正在着陆
            }
            else  //着陆后的处理
            {
                //结束本状态,切换到新状态
                velocity.y = Mathf.Min(0, velocity.y) - m_pFSM.currentGravity * deltaTime;
                setVelocity(velocity);
                m_pFSM.maxGlideSpeed = oldGlideSpeed;
                m_pFSM.isGlideState  = false;
                m_pFSM.ChangeState((int)EntityState.Standing, IntPtr.Zero);
            }
        }
        else  //这里包含两个状态:起跳 -> 最高点 ->落地
        {
            if (velocity.y <= 0)
            {
                velocity.y = m_Velocity.y - m_pFSM.glideDownSpeedAcceleration * deltaTime;
            }
            else
            {
                velocity.y = m_Velocity.y - m_pFSM.currentGravity * deltaTime;
            }
            // Make sure we don't fall any faster than maxFallSpeed. This gives our character a terminal velocity.
            velocity.y = Mathf.Max(velocity.y, m_pFSM.SkinConfig == null ? -15 : -m_pFSM.SkinConfig.maxFallSpeed);
            setVelocity(velocity);
            //velocity.y = Mathf.Min(velocity.y, m_pFSM.SkinConfig == null ? 15 : m_pFSM.SkinConfig.maxFallSpeed);
        }
        if (m_bIsGlideRuning)
        {
            Vector3 jumpDir = Vector3.up;
            startUpTick = 0;
            velocity.y  = 0;
            m_pFSM.animator.SetBool(hashid_isGlide, true);
            //添加y轴分量的初始速度,以后做自由落体运动
            //velocity += jumpDir * CalculateJumpVerticalSpeed(m_pFSM.glideUpHeight);// m_pFSM.glideUpHeight);
            m_bIsGlideRuning    = false;
            m_bIsJumping        = false;
            isGrounded          = false;
            m_pFSM.groundNormal = Vector3.zero;
            setVelocity(velocity);
        }

        //同步?
        if (m_pFSM.isHero && !m_pFSM.bControlledBySever)
        {
            m_pFSM.syncVelocity = velocity;

            // 判断本地的模拟坐标和真实坐标的差别, 只有达到一定阀值才需要同步
            // 暂时在行走过程中200ms同步一次
            int          curTick  = System.Environment.TickCount;
            MoveSyncFlag sendSync = MoveSyncFlag.NOT_2_SERVER;
            if (curTick >= m_lastSyncTick + 5000) //5秒强制同步一次
            {
                sendSync = MoveSyncFlag.TO_SERVER;
            }
            else if ((m_lastSyncVel.sqrMagnitude > 0.0001f && m_pFSM.syncVelocity.sqrMagnitude < 0.0001f) || (m_lastSyncVel.sqrMagnitude < 0.0001f && m_pFSM.syncVelocity.sqrMagnitude > 0.0001f))//启动和站立强制同步一次
            {
                sendSync = MoveSyncFlag.TO_BROADCAST;
            }
            else //每200毫秒根据速度或者移动距离考虑是否同步一次
            {
                Vector3 velSub = m_lastSyncVel - m_pFSM.syncVelocity;
                Vector3 posSub = tr.position - m_lastSyncPos;
                if ((curTick >= m_lastSyncTick + 200) && (velSub.sqrMagnitude > 0.01f || posSub.sqrMagnitude > 1.0f))
                {
                    sendSync = MoveSyncFlag.TO_SERVER;
                }
            }

            if (sendSync != MoveSyncFlag.NOT_2_SERVER && (m_pFSM.isHero && !m_pFSM.bControlledBySever))
            {
                m_pFSM.syncVelocity.y = 0.0f; // 跳跃的同步包y方向速度都为0,由实际跳跃产生。
                Send_Sync_Position(sendSync);
                m_lastSyncTick = curTick;
                m_lastSyncVel  = m_pFSM.syncVelocity;
                m_lastSyncPos  = tr.position;
            }
        }


        //移动characterController

        Vector3 currentMovementOffset = velocity * deltaTime;

        // Find out how much we need to push towards the ground to avoid loosing grouning
        // when walking down a step or over a sharp change in slope.

        //计算跨步的距离
        float pushDownOffset = Mathf.Max(m_pFSM.controller.stepOffset, (new Vector3(currentMovementOffset.x, 0, currentMovementOffset.z)).magnitude);

        if (float.IsNaN(m_pFSM.controller.stepOffset))
        {
            Debug.LogError(m_pFSM.name + " jumping controller.stepOffset error" + m_pFSM.controller.stepOffset);
            pushDownOffset = (new Vector3(currentMovementOffset.x, 0, currentMovementOffset.z)).magnitude;
        }

        //向下偏移,处理下楼梯?
        if (isGrounded)
        {
            currentMovementOffset -= pushDownOffset * Vector3.up;
        }

        //真正的移动
        m_pFSM.collisionFlags = m_pFSM.controller.Move(currentMovementOffset);

        //处理消息发送
        //....
    }
Exemplo n.º 9
0
    private void UpdateFunction()
    {
        deltaTime = Time.deltaTime;
        if (deltaTime < 0.001f)
        {
            Debug.LogError("deltaTime=" + deltaTime);
            return;
        }

        if (m_pFSM.moveCtrl.isCharge())
        {
            if (m_pFSM.animator != null)
            {
                m_pFSM.animator.SetFloat(hashid_moveforward, 0);
                m_pFSM.animator.SetFloat(hashid_moveright, 0);
                m_pFSM.animator.SetFloat(hashid_velocity, 0);
                m_pFSM.animator.SetBool(hashid_isMoving, false);
            }
            return;
        }

        Vector3 velocity = m_Velocity;

        m_pFSM.syncDetalTime += deltaTime;

        if (!m_pFSM.isHero || m_pFSM.bControlledBySever)
        {
            velocity = m_pFSM.syncVelocity;
            calSyncVel(tr.position, ref velocity);
        }
        if (float.IsNaN(velocity.x) || float.IsNaN(velocity.y) || float.IsNaN(velocity.z))
        {
            Debug.LogError(m_pFSM.name + " jumping (Line226) velocity error " + velocity);
            velocity = Vector3.zero;
        }

        Vector3 inputVelocity = ApplyInputVelocityChange(velocity); //根据键盘输入调整速度,一般在平地才用

        if (float.IsNaN(inputVelocity.x) || float.IsNaN(inputVelocity.y) || float.IsNaN(inputVelocity.z))
        {
            Debug.LogError(m_pFSM.name + "jumping inputVelocity is " + inputVelocity);
            inputVelocity = Vector3.zero;
        }

        if (m_bIsLanding && (m_pFSM.isHero && !m_pFSM.bControlledBySever))
        {
            // Update velocity based on input
            velocity = inputVelocity;
            //Trace.Log("Landing vel="+m_Velocity.ToString()+"-->"+velocity.ToString());
        }
        else if (m_pFSM.dodge)
        {
            if (m_pFSM.isHero && !m_pFSM.bControlledBySever)
            {
                velocity = inputVelocity;
            }
            else
            {
                velocity = m_pFSM.syncVelocity;
            }
        }
        else
        {
            //在空中的时候,只稍微考虑一下,为了撞墙后直接跳跃也能爬墙,而不是垂直跳
            Vector3 inputOffset = inputVelocity;
            inputOffset.y = 0.0f;
            Vector3 jumpOffset = velocity;
            jumpOffset.y = 0.0f;

            if (inputOffset.magnitude / 2 > jumpOffset.magnitude)
            {
                Vector3 combineOffset = jumpOffset * 0.95f + inputOffset * 0.05f;
                velocity.x = combineOffset.x;
                velocity.z = combineOffset.z;
            }
            if (m_pFSM.isGlideState)
            {
                Vector3 pos = m_pFSM.transform.position + new Vector3(0, 0.1f, 0);
                if (Mathf.Abs(pos.y - glideLastHitPoint.y) > 0.5f)
                {
                    RaycastHit hitInfo;
                    Ray        PointToGroundRay = new Ray(pos, new Vector3(0, -1, 0));
                    Physics.Raycast(PointToGroundRay, out hitInfo, 100);
                    if ((pos.y - hitInfo.point.y) > m_pFSM.controller.height + 0.6f)
                    {
                        m_pFSM.ChangeGlideState();
                    }
                    else
                    {
                        glideLastHitPoint = pos;
                    }
                }
            }
        }

        if (m_pFSM.isHero && !m_pFSM.bControlledBySever)
        {
            m_pFSM.syncVelocity = velocity;

            // 判断本地的模拟坐标和真实坐标的差别, 只有达到一定阀值才需要同步
            // 暂时在行走过程中200ms同步一次
            int          curTick  = System.Environment.TickCount;
            MoveSyncFlag sendSync = MoveSyncFlag.NOT_2_SERVER;
            if (curTick >= m_lastSyncTick + 5000) //5秒强制同步一次
            {
                sendSync = MoveSyncFlag.TO_SERVER;
            }
            else if ((m_lastSyncVel.sqrMagnitude > 0.0001f && m_pFSM.syncVelocity.sqrMagnitude < 0.0001f) || (m_lastSyncVel.sqrMagnitude < 0.0001f && m_pFSM.syncVelocity.sqrMagnitude > 0.0001f))//启动和站立强制同步一次
            {
                sendSync = MoveSyncFlag.TO_BROADCAST;
            }
            else //每200毫秒根据速度或者移动距离考虑是否同步一次
            {
                Vector3 velSub = m_lastSyncVel - m_pFSM.syncVelocity;
                Vector3 posSub = tr.position - m_lastSyncPos;
                if ((curTick >= m_lastSyncTick + 200) && (velSub.sqrMagnitude > 0.01f || posSub.sqrMagnitude > 1.0f))
                {
                    sendSync = MoveSyncFlag.TO_SERVER;
                }
            }

            if (sendSync != MoveSyncFlag.NOT_2_SERVER && (m_pFSM.isHero && !m_pFSM.bControlledBySever))
            {
                m_pFSM.syncVelocity.y = 0.0f; // 跳跃的同步包y方向速度都为0,由实际跳跃产生。
                Send_Sync_Position(sendSync);
                m_lastSyncTick = curTick;
                m_lastSyncVel  = m_pFSM.syncVelocity;
                m_lastSyncPos  = tr.position;
            }
        }

        // We copy the actual velocity into a temporary variable that we can manipulate.

        // Apply gravity and jumping force
        velocity = ApplyGravityAndJumping(velocity);

        if (float.IsNaN(velocity.x) || float.IsNaN(velocity.y) || float.IsNaN(velocity.z))
        {
            Debug.LogError(m_pFSM.name + " jumping velocity (line 304) error" + velocity);
            velocity = Vector3.zero;
        }

        if (m_bIsLanding && m_pFSM.animator != null)
        {
            Vector3 planeVel = new Vector3(velocity.x, 0, velocity.z);
            if (planeVel.sqrMagnitude > 0.0f)
            {
                m_pFSM.animator.SetBool(hashid_isMoving, true);
            }
            else
            {
                m_pFSM.animator.SetBool(hashid_isMoving, false);
            }

            //取移动速度相对于主角面向的向前和向左的标量
            float fRight   = Vector3.Dot(velocity, tr.right);
            float fForward = Vector3.Dot(velocity, tr.forward);


            //移动速度考虑了服务器速度和基本速度的比率后,按服务器速度算animator参数值

            if (m_pFSM.maxForwardSpeed > 0)
            {
                fForward = fForward / m_pFSM.maxForwardSpeed;
            }
            else
            {
                fForward = fForward / m_pFSM.creaturePropety.runSpeed_Forward;
            }

            if (m_pFSM.maxRunSidewaySpeed > 0)
            {
                fRight = fRight / m_pFSM.maxRunSidewaySpeed;
            }
            else
            {
                fRight = fRight / m_pFSM.creaturePropety.runSpeed_LeftRight;
            }


            //fRight = fRight / m_pFSM.basicSidewaysSpeed;
            ////速度和动作不能成正比,线性的话速度小的时候容易滑步,这里利用开根做了一次非线性变换
            //if (fForward >= 0.0f)
            //{
            //    fForward = fForward / m_pFSM.basicForwardSpeed;
            //    fForward = Mathf.Sqrt(fForward);
            //}
            //else
            //{
            //    fForward = fForward / m_pFSM.basicBackwardSpeed;
            //    fForward = -Mathf.Sqrt(-fForward);
            //}

            //if (fRight >= 0.0f)
            //{
            //    fRight = Mathf.Sqrt(fRight);
            //}
            //else
            //{
            //    fRight = -Mathf.Sqrt(-fRight);
            //}



            m_pFSM.animator.SetFloat(hashid_moveright, fRight);
            m_pFSM.animator.SetFloat(hashid_moveforward, fForward);
            m_pFSM.animator.SetFloat(hashid_velocity, velocity.magnitude);

            //动画速率用maxSpeed和basicSpeed比率控制,这里暂时不控制
            //float speedScale = Mathf.Max(Mathf.Abs(fRight), Mathf.Abs(fForward));
            //if (speedScale > 1.0f)
            //{
            //    speedScale = (speedScale - 1.0f) * 0.3f + 1.0f; //张嘉华提供的跑路速度和跑路动画速度关系
            //    m_pFSM.animator.speed = speedScale;
            //}
            //else
            //{
            //    m_pFSM.animator.speed = 1.0f;
            //}
        }

        // Moving platform support
        Vector3 moveDistance = Vector3.zero;

        // Save lastPosition for velocity calculation.
        Vector3 lastPosition = tr.position;

        // We always want the movement to be framerate independent.  Multiplying by Time.deltaTime does this.

        Vector3 currentMovementOffset = velocity * deltaTime;

        // Find out how much we need to push towards the ground to avoid loosing grouning
        // when walking down a step or over a sharp change in slope.
        float pushDownOffset = Mathf.Max(m_pFSM.controller.stepOffset, (new Vector3(currentMovementOffset.x, 0, currentMovementOffset.z)).magnitude);

        if (float.IsNaN(m_pFSM.controller.stepOffset))
        {
            Debug.LogError(m_pFSM.name + " jumping controller.stepOffset error" + m_pFSM.controller.stepOffset);
            pushDownOffset = (new Vector3(currentMovementOffset.x, 0, currentMovementOffset.z)).magnitude;
        }


        if (grounded)
        {
            currentMovementOffset -= pushDownOffset * Vector3.up;
        }


        m_pFSM.collisionFlags = m_pFSM.controller.Move(currentMovementOffset);

        //先暂时关闭拉扯位置,保证非主角跳跃平滑
        //if (!m_pFSM.isHero) //前面都是自己算的运动轨迹,非主角考虑同步位置的问题,避免连续跳跃(例如轻功)时位置偏移过大
        //{
        //    Vector3 syncOffset = m_pFSM.syncPosition - tr.position;
        //    syncOffset.y = 0.0f;
        //    if (syncOffset.sqrMagnitude > 0.01f)
        //    {
        //        m_pFSM.controller.Move(syncOffset * 0.8f);
        //    }
        //}


        // Calculate the velocity based on the current and previous position.
        // This means our velocity will only be the amount the character actually moved as a result of collisions.
        Vector3 oldHVelocity = new Vector3(velocity.x, 0, velocity.z);

        m_Velocity = (tr.position - lastPosition) / deltaTime;
        Vector3 newHVelocity = new Vector3(m_Velocity.x, 0, m_Velocity.z);

        // The CharacterController can be moved in unwanted directions when colliding with things.
        // We want to prevent this from influencing the recorded velocity.
        //if (oldHVelocity == Vector3.zero)
        if (oldHVelocity.sqrMagnitude < 0.0001f)
        {
            m_Velocity = new Vector3(0, m_Velocity.y, 0);
        }
        else
        {
            float projectedNewVelocity = Vector3.Dot(newHVelocity, oldHVelocity) / oldHVelocity.sqrMagnitude;
            m_Velocity = oldHVelocity * Mathf.Clamp01(projectedNewVelocity) + m_Velocity.y * Vector3.up;
        }


        if (m_Velocity.y < velocity.y - 0.001)
        {
            if (m_Velocity.y < 0)
            {
                // Something is forcing the CharacterController down faster than it should.
                // Ignore this
                m_Velocity.y = velocity.y;
            }
        }

        // We were grounded but just loosed grounding
        if (grounded && !IsGroundedTest())
        {
            grounded = false;

            //m_pFSM.SendMessage("OnFall", SendMessageOptions.DontRequireReceiver);
            // We pushed the character down to ensure it would stay on the ground if there was any.
            // But there wasn't so now we cancel the downwards offset to make the fall smoother.
            tr.position += pushDownOffset * Vector3.up;
        }
        // We were not grounded but just landed on something
        else if (!grounded && IsGroundedTest())
        {
            grounded = true;
            if (m_pFSM.animator)
            {
                m_pFSM.animator.SetBool("isLanding", true);

                Vector3 moveDir = m_pFSM.inputMoveDirection;

                Vector3 planeVel = new Vector3(moveDir.x, 0, moveDir.z);
                if (planeVel.sqrMagnitude > 0.0f)
                {
                    m_pFSM.animator.SetBool(hashid_isMoving, true);
                }
                else
                {
                    m_pFSM.animator.SetBool(hashid_isMoving, false);
                }
            }



            m_bIsLanding = true;
            m_bIsJumping = false;
            m_bLongJump  = false;

            //float maxFallSpeed = m_pFSM.SkinConfig == null ? 15 : m_pFSM.SkinConfig.maxFallSpeed;
            //int landingSpeed = (int)(-velocity.y);
            float fallHeight = startHeight - m_pFSM.transform.position.y;
            //if (landingSpeed > maxFallSpeed / 2.0f) //着陆大于最大速度的一半,可能需要计算伤害,上报逻辑层
            if (m_pFSM.isHero && fallHeight > 5.0f) //着陆时落差大于5米,则上报逻辑层
            {
                cmd_creature_act_landspeed data = new cmd_creature_act_landspeed();

                //data.fValue = landingSpeed;
                data.fValue = fallHeight;

                IntPtrHelper helper  = new IntPtrHelper();
                int          len     = Marshal.SizeOf(data);
                IntPtr       ptr     = helper.toPtr <cmd_creature_act_landspeed>(ref data);
                int          eventID = (int)EntityLogicDef.ENTITY_CMD_LANDING_SPEED;
                GameLogicAPI.onEntityEvent(m_pFSM.entityID, eventID, len, "", ptr, len);

                if (m_pFSM.showLog)
                {
                    Trace.Log("Big Landing! fallHeight=" + fallHeight.ToString());
                }
            }

            if (m_pFSM.creaturePropety.effectIDForLand > 0)
            {
                m_pFSM.creaturePropety.Master.LightingEffectManager.BindLighting(m_pFSM.creaturePropety.effectIDForLand);
            }


            //m_pFSM.SendMessage("OnLand", SendMessageOptions.DontRequireReceiver);
        }

        if (m_bIsLanding == false)
        {
            m_pFSM.groundNormal = Vector3.zero;
        }
    }