public override void Run(RenderWorld context, FixPoint current_time, FixPoint delta_time_fp)
        {
            bool  over       = false;
            float delta_time = (float)delta_time_fp;

            if (delta_time > m_remain_predict_time)
            {
                delta_time            = m_remain_predict_time;
                m_remain_predict_time = -1f;
                over = true;
            }
            else
            {
                m_remain_predict_time -= delta_time;
            }
            LocomotorComponent locomotor_component = m_predict_component.GetLocomotorComponent();

            if (m_predict_component.CanPredictLocomotor && locomotor_component.IsEnable())
            {
                Vector3 offset = m_direction * (float)locomotor_component.MaxSpeed * delta_time;
                m_predict_component.AddPredictOffset(offset);
            }
            if (!over)
            {
                Schedule(current_time, FixPoint.PrecisionFP);
            }
        }
        void OnPick(RaycastHit hit)
        {
            GameObject         go      = hit.transform.gameObject;
            UnityObjectBinding binding = go.GetComponent <UnityObjectBinding>();

            if (binding == null)
            {
                Debug.Log("RenderWorld.OnPick(), YOU CHOOSE A POINT" + hit.point.ToString());
                if (m_current_operate_entityi_id < 0)
                {
                    return;
                }
                RenderEntity render_entity = m_render_entity_manager.GetObject(m_current_operate_entityi_id);
                if (render_entity == null)
                {
                    return;
                }
                LocomotorComponent locomotor_component = render_entity.GetLogicEntity().GetComponent(LocomotorComponent.ID) as LocomotorComponent;
                if (locomotor_component == null || !locomotor_component.IsEnable())
                {
                    return;
                }
                EntityMoveCommand cmd = Command.Create <EntityMoveCommand>();
                cmd.ConstructAsDestination(m_current_operate_entityi_id, Vector3_To_Vector3FP(hit.point));
                PushLocalCommand(cmd);
#if UNITY_EDITOR
                if (m_draw_grid && m_grid_graph != null)
                {
                    PositionComponent position_component = render_entity.GetLogicEntity().GetComponent(PositionComponent.ID) as PositionComponent;
                    if (!m_grid_graph.FindPath(position_component.CurrentPosition, Vector3_To_Vector3FP(hit.point)))
                    {
                        Debug.LogError("FindPath Failed!");
                    }
                    else
                    {
                        List <Vector3FP> path = m_grid_graph.GetPath();
                        m_current_path.Clear();
                        for (int i = 0; i < path.Count; ++i)
                        {
                            m_current_path.Add(Vector3FP_To_Vector3(path[i]));
                        }
                    }
                }
#endif
            }
            else
            {
                RenderEntity render_entity = m_render_entity_manager.GetObject(binding.EntityID);
                if (render_entity == null)
                {
                    return;
                }
                if (m_combat_client.LocalPlayerPstid == m_logic_world.GetPlayerManager().Objectid2Pstid(render_entity.GetOwnerPlayerID()))
                {
                    m_current_operate_entityi_id = binding.EntityID;
                    Debug.Log("RenderWorld.OnPick(), YOU CHOOSE YOUR ENTITY " + hit.transform.parent.name);
                }
                else
                {
                    Debug.Log("RenderWorld.OnPick(), YOU CHOOSE AN ENEMY " + hit.transform.parent.name);
                    if (m_current_operate_entityi_id < 0)
                    {
                        return;
                    }
                    EntityTargetCommand cmd = Command.Create <EntityTargetCommand>();
                    cmd.Construct(m_current_operate_entityi_id, render_entity.ID);
                    PushLocalCommand(cmd);
#if UNITY_EDITOR
                    if (m_draw_grid && m_grid_graph != null)
                    {
                        RenderEntity      self_entity               = m_render_entity_manager.GetObject(m_current_operate_entityi_id);
                        PositionComponent self_position_component   = self_entity.GetLogicEntity().GetComponent(PositionComponent.ID) as PositionComponent;
                        PositionComponent target_position_component = render_entity.GetLogicEntity().GetComponent(PositionComponent.ID) as PositionComponent;
                        if (!m_grid_graph.FindPath(self_position_component.CurrentPosition, target_position_component.CurrentPosition))
                        {
                            Debug.LogError("FindPath Failed!");
                        }
                        else
                        {
                            List <Vector3FP> path = m_grid_graph.GetPath();
                            m_current_path.Clear();
                            for (int i = 0; i < path.Count; ++i)
                            {
                                m_current_path.Add(Vector3FP_To_Vector3(path[i]));
                            }
                        }
                    }
#endif
                }
            }
        }
        public void OnTaskService(FixPoint delta_time)
        {
            PositionComponent     position_cmp  = ParentObject.GetComponent(PositionComponent.ID) as PositionComponent;
            LocomotorComponent    locomotor_cmp = ParentObject.GetComponent(LocomotorComponent.ID) as LocomotorComponent;
            SkillManagerComponent skill_cmp     = ParentObject.GetComponent(SkillManagerComponent.ID) as SkillManagerComponent;
            Skill skill = skill_cmp.GetSkill(m_skill_index);

            if (skill == null)
            {
                StopTargeting();
                return;
            }

            if (!skill.IsReady() && locomotor_cmp != null && locomotor_cmp.IsMoving)
            {
                FixPoint delay = skill.GetNextReadyTime();
                if (delay == FixPoint.Zero)
                {
                    delay = FixPoint.PrecisionFP;
                }
                ScheduleTargeting(delay);
                return;
            }

            bool              move_required       = false;
            FixPoint          max_range           = skill.GetDefinitionComponent().MaxRange;
            PositionComponent target_position_cmp = m_current_target.GetComponent(PositionComponent.ID) as PositionComponent;
            Vector3FP         direction           = target_position_cmp.CurrentPosition - position_cmp.CurrentPosition;

            if (max_range > 0)
            {
                FixPoint distance = direction.FastLength() - target_position_cmp.Radius - position_cmp.Radius;  //ZZWTODO 多处距离计算
                if (distance > max_range)
                {
                    move_required = true;
                    if (locomotor_cmp == null)
                    {
                        //ZZWTODO
                        ScheduleTargeting(TARGETING_UPDATE_MAX_FREQUENCY);
                    }
                    else if (!locomotor_cmp.IsEnable())
                    {
                        ScheduleTargeting(TARGETING_UPDATE_MIN_FREQUENCY);
                    }
                    else
                    {
                        FixPoint delay = (distance - max_range) / locomotor_cmp.MaxSpeed;
                        if (delay > TARGETING_UPDATE_MAX_FREQUENCY)
                        {
                            delay = TARGETING_UPDATE_MAX_FREQUENCY;
                        }
                        else if (delay < TARGETING_UPDATE_MIN_FREQUENCY)
                        {
                            delay = TARGETING_UPDATE_MIN_FREQUENCY;
                        }
                        PathFindingComponent pathfinding_component = ParentObject.GetComponent(PathFindingComponent.ID) as PathFindingComponent;
                        if (pathfinding_component != null)
                        {
                            if (pathfinding_component.FindPath(target_position_cmp.CurrentPosition))
                            {
                                locomotor_cmp.GetMovementProvider().FinishMovementWhenTargetInRange(target_position_cmp, max_range);
                            }
                        }
                        else
                        {
                            List <Vector3FP> path = new List <Vector3FP>();
                            path.Add(position_cmp.CurrentPosition);
                            path.Add(target_position_cmp.CurrentPosition);
                            locomotor_cmp.MoveAlongPath(path, false);
                            locomotor_cmp.GetMovementProvider().FinishMovementWhenTargetInRange(target_position_cmp, max_range);
                        }
                        ScheduleTargeting(delay);
                    }
                }
            }
            if (!move_required)
            {
                if (skill.CanActivate(false))
                {
                    position_cmp.SetFacing(direction);
                    skill.GetDefinitionComponent().ExternalID = m_current_target.ID;
                    skill.Activate(GetCurrentTime());
                    if (m_attack_once)
                    {
                        StopTargeting();
                        return;
                    }
                    FixPoint delay = skill.GetDefinitionComponent().CooldownTime + FixPoint.PrecisionFP;
                    if (delay > TARGETING_UPDATE_MAX_FREQUENCY)
                    {
                        delay = TARGETING_UPDATE_MAX_FREQUENCY;
                    }
                    ScheduleTargeting(delay);
                }
                else
                {
                    FixPoint delay = skill.GetNextReadyTime();
                    if (delay < TARGETING_UPDATE_MIN_FREQUENCY)
                    {
                        delay = TARGETING_UPDATE_MIN_FREQUENCY;
                    }
                    ScheduleTargeting(delay);
                }
            }
        }