protected override void OnRenderUI(GuiRenderer renderer)
        {
            base.OnRenderUI(renderer);

            List <string> lines = new List <string>();

            lines.Add("Unit tasks:");
            foreach (Entity entity in Map.Instance.Children)
            {
                Character character = entity as Character;
                if (character != null)
                {
                    GameCharacterAI ai = character.Intellect as GameCharacterAI;
                    if (ai != null)
                    {
                        if (lines.Count > 1)
                        {
                            lines.Add("");
                        }
                        lines.Add("  " + ai.CurrentTask.ToString());
                        foreach (GameCharacterAI.Task task in ai.Tasks)
                        {
                            lines.Add("  " + task.ToString());
                        }
                    }
                }
            }

            EngineApp.Instance.ScreenGuiRenderer.AddTextLines(lines, new Vec2(.95f, .075f),
                                                              HorizontalAlign.Right, VerticalAlign.Top, 0, new ColorValue(1, 1, 1));
        }
        void UnitAttack(MapObject attackedObject)
        {
            foreach (Entity entity in Map.Instance.Children)
            {
                Character character = entity as Character;
                if (character != null && attackedObject != character)
                {
                    GameCharacterAI ai = character.Intellect as GameCharacterAI;
                    if (ai != null)
                    {
                        string text = string.Format("Unit attack \"{0}\"", entity.ToString());
                        GameEngineApp.Instance.AddScreenMessage(text);

                        bool toQueue = EngineApp.Instance.IsKeyPressed(EKeys.Shift);
                        ai.AutomaticTasks = GameCharacterAI.AutomaticTasksEnum.Disabled;
                        ai.DoTask(new GameCharacterAI.AttackTask(ai, attackedObject), toQueue);
                    }
                }
            }
        }
        void UnitMove(Vec3 position)
        {
            foreach (Entity entity in Map.Instance.Children)
            {
                Character character = entity as Character;
                if (character != null)
                {
                    GameCharacterAI ai = character.Intellect as GameCharacterAI;
                    if (ai != null)
                    {
                        string text = string.Format("Unit move to \"{0}\"", position.ToString(1));
                        GameEngineApp.Instance.AddScreenMessage(text);

                        bool toQueue = EngineApp.Instance.IsKeyPressed(EKeys.Shift);
                        ai.AutomaticTasks = GameCharacterAI.AutomaticTasksEnum.Disabled;
                        ai.DoTask(new GameCharacterAI.MoveTask(ai, position, .5f), toQueue);
                    }
                }
            }
        }
        protected override void OnRender()
        {
            base.OnRender();

            Camera camera = RendererWorld.Instance.DefaultCamera;

            GetNavigationSystem().DebugDrawNavMesh(camera);

            //path test
            {
                Vec3 offset = new Vec3(0, 0, .2f);

                if (pathTest)
                {
                    camera.DebugGeometry.Color = new ColorValue(0, 0, 1);
                    AddArrow(camera, startPosition + new Vec3(0, 0, 4), startPosition + offset, .07f, 1.2f);

                    List <string> lines = new List <string>();

                    if (time < 0.001f)
                    {
                        lines.Add(string.Format("Time: <0.001 seconds"));
                    }
                    else
                    {
                        lines.Add(string.Format("Time: {0} seconds", time.ToString("F3")));
                    }

                    //SodanKerjuu: we check if the path will lead us close enough to where we wanted
                    bool futile = false;
                    if (found)
                    {
                        if ((path[path.Length - 1] - endPosition).Length() > 1f)
                        {
                            futile = true;
                            lines.Add("Path found, but didn't reach close enough to end point.");
                        }
                        else
                        {
                            lines.Add("Path found");
                        }
                    }
                    else
                    {
                        lines.Add("Path not found");
                    }

                    //write out information
                    if (found)
                    {
                        lines.Add(string.Format("Points: {0}", path.Length));

                        camera.DebugGeometry.Color = new ColorValue(0, 1, 0);
                        for (int n = 1; n < path.Length; n++)
                        {
                            Vec3 from = path[n - 1] + offset;
                            Vec3 to   = path[n] + offset;
                            AddThicknessLine(camera, from, to, .07f);
                            camera.DebugGeometry.AddLine(from, to);
                        }

                        camera.DebugGeometry.Color = futile ? new ColorValue(1, 0, 0) : new ColorValue(1, 1, 0);
                        foreach (Vec3 point in path)
                        {
                            AddSphere(camera, new Sphere(point + offset, .15f));
                        }
                    }

                    //show end position and arrow between start and end
                    if (GetPositionByCursor(out endPosition))
                    {
                        camera.DebugGeometry.Color = new ColorValue(1, 0, 0);
                        AddArrow(camera, endPosition + new Vec3(0, 0, 4), endPosition + offset, .07f, 1.2f);
                    }

                    EngineApp.Instance.ScreenGuiRenderer.AddTextLines(lines, new Vec2(.05f, .075f),
                                                                      HorizontalAlign.Left, VerticalAlign.Top, 0, new ColorValue(1, 1, 1));
                }
                else
                {
                    //show end position and arrow between start and end
                    Vec3 pos;
                    if (GetPositionByCursor(out pos))
                    {
                        camera.DebugGeometry.Color = new ColorValue(1, 0, 0);
                        AddArrow(camera, pos + new Vec3(0, 0, 4), pos + offset, .07f, 1.2f);
                    }
                }
            }

            //highlight cursor on object
            {
                MapObject mapObject = GetMapObjectByCursor();
                if (mapObject != null)
                {
                    camera.DebugGeometry.Color = new ColorValue(1, 1, 0);
                    Box box = mapObject.GetBox();
                    box.Expand(.1f);
                    camera.DebugGeometry.AddBox(box);
                }
            }

            //draw paths of units
            foreach (Entity entity in Map.Instance.Children)
            {
                Character character = entity as Character;
                if (character != null)
                {
                    GameCharacterAI ai = character.Intellect as GameCharacterAI;
                    if (ai != null)
                    {
                        ai.DebugDrawTasks(camera);
                        ai.DebugDrawPath(camera);
                    }
                }
            }

            UpdateHUD();
        }