Exemple #1
0
        public virtual void OnGUI()
        {
            if (mode == Mode.Idle)
            {
                return;
            }

            PageStyle pageStyle = Game.GetInstance().activePageStyle;

            if (pageStyle == null)
            {
                return;
            }

            GUIStyle boxStyle             = pageStyle.boxStyle;
            GUIStyle headerStyle          = pageStyle.GetScaledHeaderStyle();
            GUIStyle footerStyle          = pageStyle.GetScaledFooterStyle();
            GUIStyle sayStyle             = pageStyle.GetScaledSayStyle();
            GUIStyle optionStyle          = pageStyle.GetScaledOptionStyle();
            GUIStyle optionAlternateStyle = pageStyle.GetScaledOptionAlternateStyle();

            Rect   outerRect;
            Layout tempLayout;

            Game game = Game.GetInstance();

            if (mode == Mode.Choose &&
                game.centerChooseMenu)
            {
                // Position the Choose menu in middle of screen
                // The width is controlled by game.chooseMenuWidth
                // The height is automatically fitted to the text content
                Vector2 pageScale = new Vector2(game.chooseMenuWidth, 0.5f);
                PageController.ScreenRect screenRect = PageController.CalcScreenRect(pageScale, PageController.PagePosition.Middle);
                outerRect  = PageController.CalcPageRect(screenRect);
                tempLayout = PageController.Layout.FitToMiddle;
            }
            else
            {
                outerRect  = pageRect;
                tempLayout = layout;
            }

            Rect originalRect = outerRect;
            Rect innerRect    = CalcInnerRect(outerRect);

            // Calculate height of each section
            float headerHeight  = CalcHeaderHeight(innerRect.width);
            float footerHeight  = CalcFooterHeight(innerRect.width);
            float storyHeight   = CalcStoryHeight(innerRect.width);
            float optionsHeight = CalcOptionsHeight(innerRect.width);
            float contentHeight = headerHeight + footerHeight + storyHeight + optionsHeight;

            // Adjust outer rect position based on alignment settings
            switch (tempLayout)
            {
            case Layout.FullSize:
                outerRect.height = Mathf.Max(outerRect.height, contentHeight + (boxStyle.padding.top + boxStyle.padding.bottom));
                outerRect.y      = Mathf.Min(outerRect.y, Screen.height - outerRect.height);
                break;

            case Layout.FitToTop:
                outerRect.height = contentHeight + (boxStyle.padding.top + boxStyle.padding.bottom);
                outerRect.y      = originalRect.yMin;
                break;

            case Layout.FitToMiddle:
                outerRect.height = contentHeight + (boxStyle.padding.top + boxStyle.padding.bottom);
                outerRect.y      = originalRect.center.y - outerRect.height / 2;
                break;

            case Layout.FitToBottom:
                outerRect.height = contentHeight + (boxStyle.padding.top + boxStyle.padding.bottom);
                outerRect.y      = originalRect.yMax - outerRect.height;
                break;
            }

            innerRect = CalcInnerRect(outerRect);

            // Draw box
            Rect boxRect = outerRect;

            boxRect.height = contentHeight + (boxStyle.padding.top + boxStyle.padding.bottom);
            if (tempLayout == Layout.FullSize)
            {
                boxRect.height = Mathf.Max(boxRect.height, originalRect.height);
            }
            GUI.Box(boxRect, "", boxStyle);

            // Draw header label
            Rect headerRect = innerRect;

            headerRect.height = headerHeight;
            if (headerHeight > 0)
            {
                GUI.Label(headerRect, headerText, headerStyle);
            }

            // Draw say label
            Rect storyRect = innerRect;

            storyRect.y     += headerHeight;
            storyRect.height = storyHeight;
            GUI.Label(storyRect, displayedStoryText, sayStyle);

            // Draw footer label
            Rect footerRect = innerRect;

            footerRect.y     += storyHeight;
            footerRect.height = footerHeight;
            if (footerHeight > 0)
            {
                GUI.Label(footerRect, footerText, footerStyle);
            }

            if (!FinishedWriting())
            {
                return;
            }

            // Input handling

            if (mode == Mode.Say)
            {
                // Player can continue by clicking anywhere
                if (quickContinueTimer == 0 &&
                    (Input.GetMouseButtonUp(0) || Input.anyKeyDown) &&
                    continueAction != null)
                {
                    deferredAction = continueAction;
                }
            }
            else if (mode == Mode.Choose)
            {
                // Draw option buttons
                Rect buttonRect = innerRect;
                buttonRect.y += headerHeight + storyHeight;
                bool alternateRow = false;
                foreach (Option option in options)
                {
                    GUIContent buttonContent = new GUIContent(option.optionText);
                    buttonRect.height = optionStyle.CalcHeight(buttonContent, innerRect.width);

                    // Select style for odd/even colored rows
                    GUIStyle style;
                    if (alternateRow)
                    {
                        style = optionAlternateStyle;
                    }
                    else
                    {
                        style = optionStyle;
                    }
                    alternateRow = !alternateRow;

                    if (GUI.Button(buttonRect, buttonContent, style))
                    {
                        if (option.optionAction != null)
                        {
                            // We can't execute the option action yet because OnGUI
                            // may be called multiple times during a frame, and it's
                            // not permitted to modify GUI elements within a frame.
                            // We defer executing the action until OnGUI has completed.
                            deferredAction = option.optionAction;
                            break;
                        }
                    }

                    buttonRect.y += buttonRect.height;
                }
            }

            if (Event.current.type == EventType.Repaint)
            {
                if (deferredAction != null)
                {
                    Game.GetInstance().PlayButtonClick();

                    Action tempAction = deferredAction;

                    displayedStoryText = "";
                    originalStoryText  = "";
                    deferredAction     = null;

                    if (mode == Mode.Choose)
                    {
                        options.Clear();

                        // Reset to idle, but calling action may set this again
                        mode = Mode.Idle;

                        CommandQueue commandQueue = Game.GetInstance().commandQueue;
                        commandQueue.CallCommandMethod(tempAction);
                    }
                    else if (mode == Mode.Say)
                    {
                        // Reset to idle, but calling action may set this again
                        mode = Mode.Idle;

                        // Execute next command
                        tempAction();
                    }
                }
            }
        }