From 291902b38608dd972c819c7b8dd5ea5ef05341cf Mon Sep 17 00:00:00 2001 From: chrisgregan Date: Wed, 23 Apr 2014 12:32:09 +0100 Subject: [PATCH] Added more properties to control page position - Default page position (reset every time player enters a Room) - Option to auto-center the choose menu - Moved continue and manual pan icons to bottom left - Refactored page rect calculations to avoid redundant code - Added manual pan to example room --- Assets/Fungus/Prefabs/Game.prefab | Bin 7368 -> 7608 bytes .../Fungus/Scripts/Commands/PageCommands.cs | 14 +- Assets/Fungus/Scripts/Game.cs | 27 ++- Assets/Fungus/Scripts/GameController.cs | 62 +++--- Assets/Fungus/Scripts/Page.cs | 176 ++++++++++++++---- Assets/Fungus/Scripts/PageBounds.cs | 11 +- Assets/Fungus/Scripts/Room.cs | 5 +- Assets/FungusExample/Scenes/Example.unity | Bin 61432 -> 61704 bytes Assets/FungusExample/Scripts/MenuRoom.cs | 4 +- Assets/FungusExample/Scripts/PageRoom.cs | 12 +- Assets/FungusExample/Scripts/ParallaxRoom.cs | 24 ++- 11 files changed, 232 insertions(+), 103 deletions(-) diff --git a/Assets/Fungus/Prefabs/Game.prefab b/Assets/Fungus/Prefabs/Game.prefab index 86069123a07a2d2531572a165c8db325ed196d63..1dabbf3e424006218fcdafdb821046d6722632ff 100644 GIT binary patch delta 384 zcmX?Mxx-q3fkB3sfkAc$0|NsmkZmwgz@AZVb0U{Jr-GaZHrNDN zx#whk4n;=O$$=ayjAoM`vZzdM<`kK{jzg8v0xV_;5@WOilEOey_Q@8UYLivC1SThN zh%(xMZBWWKJ$MMl-OCIatO5EYr&+#ArEr0hcbL)#P(r>WtQ#zi~AQ p2rdBH_a6v~fb@d&@2mlnJEd1_c94-_oUAA#KiNQrb@BvR4FDrIEm{Bo diff --git a/Assets/Fungus/Scripts/Commands/PageCommands.cs b/Assets/Fungus/Scripts/Commands/PageCommands.cs index 4fc458da..99946bfa 100644 --- a/Assets/Fungus/Scripts/Commands/PageCommands.cs +++ b/Assets/Fungus/Scripts/Commands/PageCommands.cs @@ -43,25 +43,19 @@ namespace Fungus */ public class SetPageRect : CommandQueue.Command { - float x1; - float y1; - float x2; - float y2; + Page.ScreenRect screenRect; Page.Layout layout; - public SetPageRect(float _x1, float _y1, float _x2, float _y2, Page.Layout _layout) + public SetPageRect(Page.ScreenRect _screenRect, Page.Layout _layout) { - x1 = _x1; - y1 = _y1; - x2 = _x2; - y2 = _y2; + screenRect = _screenRect; layout = _layout; } public override void Execute(CommandQueue commandQueue, Action onComplete) { Page page = Game.GetInstance().activePage; - page.SetPageRect(x1, y1, x2, y2); + page.pageRect = Page.CalcPageRect(screenRect); page.layout = layout; if (onComplete != null) diff --git a/Assets/Fungus/Scripts/Game.cs b/Assets/Fungus/Scripts/Game.cs index dfcc8ade..8067d7af 100644 --- a/Assets/Fungus/Scripts/Game.cs +++ b/Assets/Fungus/Scripts/Game.cs @@ -73,7 +73,26 @@ namespace Fungus */ public float autoHideButtonDuration = 5f; - float autoHideButtonTimer; + /** + * Default screen position for Page when player enters a Room. + */ + public Page.PagePosition defaultPagePosition; + + /** + * Default width and height of Page as a fraction of screen height [0..1] + */ + public Vector2 defaultPageScale = new Vector2(0.75f, 0.25f); + + /** + * Automatically center the Page when player is choosing from multiple options. + */ + public bool centerChooseMenu = true; + + /** + * Width of Page as a fraction of screen width [0..1] when automatically centering a Choose menu. + * This setting only has an effect when centerChooseMenu is enabled. + */ + public float chooseMenuWidth = 0.5f; /** * Global dictionary of integer values for storing game state. @@ -105,6 +124,8 @@ namespace Fungus [HideInInspector] public float fadeAlpha = 0f; + float autoHideButtonTimer; + static Game instance; /** @@ -174,7 +195,7 @@ namespace Fungus if (manualPanTexture) { Rect rect = new Rect(Screen.width - manualPanTexture.width, - 0, + Screen.height - manualPanTexture.height, manualPanTexture.width, manualPanTexture.height); GUI.DrawTexture(rect, manualPanTexture); @@ -188,7 +209,7 @@ namespace Fungus if (continueTexture) { Rect rect = new Rect(Screen.width - continueTexture.width, - 0, + Screen.height - manualPanTexture.height, continueTexture.width, continueTexture.height); GUI.DrawTexture(rect, continueTexture); diff --git a/Assets/Fungus/Scripts/GameController.cs b/Assets/Fungus/Scripts/GameController.cs index 6d5377eb..f2eb5fd5 100644 --- a/Assets/Fungus/Scripts/GameController.cs +++ b/Assets/Fungus/Scripts/GameController.cs @@ -205,6 +205,12 @@ namespace Fungus commandQueue.AddCommand(new Command.SetPageBounds(pageBounds, pageLayout)); } + public static void SetPageRect(Page.ScreenRect screenRect, Page.Layout pageLayout = Page.Layout.FullSize) + { + CommandQueue commandQueue = Game.GetInstance().commandQueue; + commandQueue.AddCommand(new Command.SetPageRect(screenRect, pageLayout)); + } + /** * Sets the screen space rectangle used to display the Page. * The rectangle coordinates are in normalized screen space. e.g. x1 = 0 (Far left), x1 = 1 (Far right). @@ -218,8 +224,12 @@ namespace Fungus */ public static void SetPageRect(float x1, float y1, float x2, float y2, Page.Layout pageLayout = Page.Layout.FullSize) { - CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.SetPageRect(x1, y1, x2, y2, pageLayout)); + Page.ScreenRect screenRect = new Page.ScreenRect(); + screenRect.x1 = x1; + screenRect.y1 = y1; + screenRect.x2 = x2; + screenRect.y2 = y2; + SetPageRect(screenRect, pageLayout); } /** @@ -231,14 +241,8 @@ namespace Fungus */ public static void SetPageTop(float scaleX, float scaleY, Page.Layout pageLayout) { - float halfWidth = Mathf.Clamp01(scaleX) * 0.5f; - - float x1 = 0.5f - halfWidth; - float x2 = 0.5f + halfWidth; - float y1 = 0f; - float y2 = Mathf.Clamp01(scaleY); - - SetPageRect(x1, y1, x2, y2, pageLayout); + Page.ScreenRect screenRect = Page.CalcScreenRect(new Vector2(scaleX, scaleY), Page.PagePosition.Top); + SetPageRect(screenRect, pageLayout); } /** @@ -247,7 +251,8 @@ namespace Fungus */ public static void SetPageTop() { - SetPageTop(0.75f, 0.25f, Page.Layout.FullSize); + Vector2 pageScale = Game.GetInstance().defaultPageScale; + SetPageTop(pageScale.x, pageScale.y, Page.Layout.FullSize); } /** @@ -259,15 +264,8 @@ namespace Fungus */ public static void SetPageMiddle(float scaleX, float scaleY, Page.Layout pageLayout) { - float halfWidth = Mathf.Clamp01(scaleX) * 0.5f; - float halfHeight = Mathf.Clamp01(scaleY) * 0.5f; - - float x1 = 0.5f - halfWidth; - float x2 = 0.5f + halfWidth; - float y1 = 0.5f - halfHeight; - float y2 = 0.5f + halfHeight; - - SetPageRect(x1, y1, x2, y2, pageLayout); + Page.ScreenRect screenRect = Page.CalcScreenRect(new Vector2(scaleX, scaleY), Page.PagePosition.Middle); + SetPageRect(screenRect, pageLayout); } /** @@ -276,7 +274,8 @@ namespace Fungus */ public static void SetPageMiddle() { - SetPageMiddle(0.5f, 0.5f, Page.Layout.FitToMiddle); + Vector2 pageScale = Game.GetInstance().defaultPageScale; + SetPageMiddle(pageScale.x, pageScale.y, Page.Layout.FitToMiddle); } /** @@ -288,14 +287,8 @@ namespace Fungus */ public static void SetPageBottom(float scaleX, float scaleY, Page.Layout pageLayout) { - float halfWidth = Mathf.Clamp01(scaleX) / 2f; - - float x1 = 0.5f - halfWidth; - float x2 = 0.5f + halfWidth; - float y1 = 1f - Mathf.Clamp01(scaleY); - float y2 = 1; - - SetPageRect(x1, y1, x2, y2, pageLayout); + Page.ScreenRect screenRect = Page.CalcScreenRect(new Vector2(scaleX, scaleY), Page.PagePosition.Bottom); + SetPageRect(screenRect, pageLayout); } /** @@ -304,7 +297,8 @@ namespace Fungus */ public static void SetPageBottom() { - SetPageBottom(0.75f, 0.25f, Page.Layout.FullSize); + Vector2 pageScale = Game.GetInstance().defaultPageScale; + SetPageBottom(pageScale.x, pageScale.y, Page.Layout.FullSize); } /** @@ -321,10 +315,10 @@ namespace Fungus /** * Obsolete! Use Header() instead. */ - [System.Obsolete("use Header() instead")] + [System.Obsolete("use SetHeader() instead")] public static void Title(string titleText) { - Header(titleText); + SetHeader(titleText); } /** @@ -333,7 +327,7 @@ namespace Fungus * This method returns immediately but it queues an asynchronous command for later execution. * @param footerText The text to display as the header of the Page. */ - public static void Header(string headerText) + public static void SetHeader(string headerText) { CommandQueue commandQueue = Game.GetInstance().commandQueue; commandQueue.AddCommand(new Command.SetHeader(headerText)); @@ -345,7 +339,7 @@ namespace Fungus * This method returns immediately but it queues an asynchronous command for later execution. * @param footerText The text to display as the footer of the Page. */ - public static void Footer(string footerText) + public static void SetFooter(string footerText) { CommandQueue commandQueue = Game.GetInstance().commandQueue; commandQueue.AddCommand(new Command.SetFooter(footerText)); diff --git a/Assets/Fungus/Scripts/Page.cs b/Assets/Fungus/Scripts/Page.cs index d27dbdf4..ebd9d187 100644 --- a/Assets/Fungus/Scripts/Page.cs +++ b/Assets/Fungus/Scripts/Page.cs @@ -14,7 +14,30 @@ namespace Fungus [ExecuteInEditMode] public class Page : MonoBehaviour { - /// Page alignment options + /// Options for default Page position on screen + public enum PagePosition + { + /// Page appears full-size and horizontally centered at top of screen. + Top, + /// Page appears centered in middle of screen, with height fitted to content. + Middle, + /// Page appears full-size and horizontally centered at bottom of screen. + Bottom + } + + /** + * Defines a rect in normalized screen space coordinates. + * e.g. x1 = 0 means left of screen, x2 = 1 means right of screen. + */ + public class ScreenRect + { + public float x1; + public float y1; + public float x2; + public float y2; + } + + /// Options for controlling page layout public enum Layout { /// Use the full rect to display the page. @@ -27,28 +50,35 @@ namespace Fungus FitToBottom } - /// Page position within bounds when display height is less than bounds height. + /// Controls layout of content within Page rect. public Layout layout = Layout.FullSize; - string headerText = ""; - string footerText = ""; - - string displayedStoryText = ""; - string originalStoryText = ""; - - Action deferredAction; - Action continueAction; - + /// Supported states for Page public enum Mode { + /// No content to be displayed. Idle, + /// Show a single line of text and wait for player input. Say, + /// Show a multiple choice menu and wait for player to select an option. Choose }; - + [HideInInspector] public Mode mode = Mode.Idle; + /// Screen space rect for Page in pixels. + public Rect pageRect; + + string headerText = ""; + string footerText = ""; + + string displayedStoryText = ""; + string originalStoryText = ""; + + Action deferredAction; + Action continueAction; + class Option { public string optionText; @@ -65,27 +95,86 @@ namespace Fungus float quickContinueTimer; - Rect pageRect; // Screen space rect for Page in pixels + /** + * Calculate a screen space rectangle given normalized screen space coords. + * The resulting rect is clamped to always be on-screen. + */ + public static Rect CalcPageRect(ScreenRect screenRect) + { + Rect rect = new Rect(); + + rect.xMin = Screen.width * screenRect.x1; + rect.yMin = Screen.height * screenRect.y1; + rect.xMax = Screen.width * screenRect.x2; + rect.yMax = Screen.height * screenRect.y2; + + // Clamp to be on-screen + rect.xMax = Mathf.Min(rect.xMax, Screen.width); + rect.xMin = Mathf.Max(rect.xMin, 0); + rect.yMax = Mathf.Min(rect.yMax, Screen.height); + rect.yMin = Mathf.Max(rect.yMin, 0); + + return rect; + } /** - * Set the screen rect in normalized screen space coords. - * The origin is at the top left of the screen. + * Calculates a screen rect in normalized screen space coordinates in one of the 'standard' Page positions (top, middle, bottom). */ - public void SetPageRect(float x1, float y1, float x2, float y2) + public static ScreenRect CalcScreenRect(Vector2 pageScale, PagePosition pagePosition) { - pageRect.xMin = Screen.width * x1; - pageRect.yMin = Screen.height * y1; - pageRect.xMax = Screen.width * x2; - pageRect.yMax = Screen.height * y2; + float width = Mathf.Clamp01(pageScale.x); + float height = Mathf.Clamp01(pageScale.y); - // Clamp to be on-screen - pageRect.xMax = Mathf.Min(pageRect.xMax, Screen.width); - pageRect.xMin = Mathf.Max(pageRect.xMin, 0); - pageRect.yMax = Mathf.Min(pageRect.yMax, Screen.height); - pageRect.yMin = Mathf.Max(pageRect.yMin, 0); + ScreenRect screenRect = new ScreenRect(); + + switch (pagePosition) + { + case PagePosition.Top: + screenRect.x1 = 0.5f - width * 0.5f; + screenRect.x2 = 0.5f + width * 0.5f; + screenRect.y1 = 0f; + screenRect.y2 = height; + break; + case PagePosition.Middle: + screenRect.x1 = 0.5f - width * 0.5f; + screenRect.x2 = 0.5f + width * 0.5f; + screenRect.y1 = 0.5f - height * 0.5f; + screenRect.y2 = 0.5f + height * 0.5f; + break; + case PagePosition.Bottom: + screenRect.x1 = 0.5f - width * 0.5f; + screenRect.x2 = 0.5f + width * 0.5f; + screenRect.y1 = 1f - Mathf.Clamp01(height); + screenRect.y2 = 1; + break; + } + + return screenRect; } - public virtual void Update() + /** + * Reset to the default page layout based on properties in Game class. + */ + public void SetDefaultPageLayout() + { + Game game = Game.GetInstance(); + ScreenRect screenRect = CalcScreenRect(game.defaultPageScale, game.defaultPagePosition); + pageRect = CalcPageRect(screenRect); + switch (game.defaultPagePosition) + { + case Page.PagePosition.Top: + game.activePage.layout = Page.Layout.FullSize; + break; + case Page.PagePosition.Middle: + game.activePage.layout = Page.Layout.FitToMiddle; + break; + case Page.PagePosition.Bottom: + game.activePage.layout = Page.Layout.FullSize; + break; + } + } + + void Update() { if (quickContinueTimer > 0) { @@ -227,7 +316,28 @@ namespace Fungus GUIStyle optionStyle = pageStyle.GetScaledOptionStyle(); GUIStyle optionAlternateStyle = pageStyle.GetScaledOptionAlternateStyle(); - Rect outerRect = pageRect; + 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); + Page.ScreenRect screenRect = Page.CalcScreenRect(pageScale, Page.PagePosition.Middle); + outerRect = Page.CalcPageRect(screenRect); + tempLayout = Page.Layout.FitToMiddle; + } + else + { + outerRect = pageRect; + tempLayout = layout; + } + + Rect originalRect = outerRect; Rect innerRect = CalcInnerRect(outerRect); // Calculate height of each section @@ -238,7 +348,7 @@ namespace Fungus float contentHeight = headerHeight + footerHeight + storyHeight + optionsHeight; // Adjust outer rect position based on alignment settings - switch (layout) + switch (tempLayout) { case Layout.FullSize: outerRect.height = Mathf.Max(outerRect.height, contentHeight + (boxStyle.padding.top + boxStyle.padding.bottom)); @@ -246,15 +356,15 @@ namespace Fungus break; case Layout.FitToTop: outerRect.height = contentHeight + (boxStyle.padding.top + boxStyle.padding.bottom); - outerRect.y = pageRect.yMin; + outerRect.y = originalRect.yMin; break; case Layout.FitToMiddle: outerRect.height = contentHeight + (boxStyle.padding.top + boxStyle.padding.bottom); - outerRect.y = pageRect.center.y - outerRect.height / 2; + outerRect.y = originalRect.center.y - outerRect.height / 2; break; case Layout.FitToBottom: outerRect.height = contentHeight + (boxStyle.padding.top + boxStyle.padding.bottom); - outerRect.y = pageRect.yMax - outerRect.height; + outerRect.y = originalRect.yMax - outerRect.height; break; } @@ -263,9 +373,9 @@ namespace Fungus // Draw box Rect boxRect = outerRect; boxRect.height = contentHeight + (boxStyle.padding.top + boxStyle.padding.bottom); - if (layout == Layout.FullSize) + if (tempLayout == Layout.FullSize) { - boxRect.height = Mathf.Max(boxRect.height, pageRect.height); + boxRect.height = Mathf.Max(boxRect.height, originalRect.height); } GUI.Box(boxRect, "", boxStyle); diff --git a/Assets/Fungus/Scripts/PageBounds.cs b/Assets/Fungus/Scripts/PageBounds.cs index 2c651fa5..41802bba 100644 --- a/Assets/Fungus/Scripts/PageBounds.cs +++ b/Assets/Fungus/Scripts/PageBounds.cs @@ -31,13 +31,14 @@ namespace Fungus Vector2 tl = Camera.main.WorldToScreenPoint(topLeft); Vector2 br = Camera.main.WorldToScreenPoint(bottomRight); - float x1 = (tl.x / Screen.width); - float y1 = 1f - (tl.y / Screen.height); - float x2 = (br.x / Screen.width); - float y2 = 1f - (br.y / Screen.height); + Page.ScreenRect screenRect = new Page.ScreenRect(); + screenRect.x1 = (tl.x / Screen.width); + screenRect.y1 = 1f - (tl.y / Screen.height); + screenRect.x2 = (br.x / Screen.width); + screenRect.y2 = 1f - (br.y / Screen.height); Page page = Game.GetInstance().activePage; - page.SetPageRect(x1, y1, x2, y2); + page.pageRect = Page.CalcPageRect(screenRect); page.layout = layout; } } diff --git a/Assets/Fungus/Scripts/Room.cs b/Assets/Fungus/Scripts/Room.cs index 573a834e..e73d7db0 100644 --- a/Assets/Fungus/Scripts/Room.cs +++ b/Assets/Fungus/Scripts/Room.cs @@ -139,9 +139,8 @@ namespace Fungus button.SetAlpha(0f); } - // Default to bottom aligned Page rect - game.activePage.SetPageRect(0.125f, 0.75f, 0.875f, 1f); - game.activePage.layout = Page.Layout.FullSize; + // Reset Page layout to default setting specified in Game object + game.activePage.SetDefaultPageLayout(); // Rooms may have multiple child views and page. // It is the responsibility of the client room script to set the desired active view & page in the OnEnter method. diff --git a/Assets/FungusExample/Scenes/Example.unity b/Assets/FungusExample/Scenes/Example.unity index c1d0782e64df9772239258781cd92a14409a7b08..f92e865425f89e6de730362cbf924663940be27a 100644 GIT binary patch delta 1951 zcmZwIUu;uV90%~Sa-){pb?=fx2(x%ODRb= zoVUqXQWAuk8wU?Q)CUtD(4ZHA_|z9njek&qWE%eYH%b&&5FJLG-*bEKJlA-W)82l1 z&iS45JHOjbUvuQXafn1mdx^>}BC5iD@*Qz*o$!eM_4-d7T48*SezV@~d^i?Q(@rHC z-Zzw%!@CqYu{V~ECF117D8E+rxjXumNIH>fit^q1BHXKe>u% zA11W2Fdrs2R|5ZT26n@a!v?v)9+=o-54->tgk@B8v{Ey2BEO{wyv$|c&{vnX7FvmR zbAexhiK~g)VE4?xhhZ{|-^dYI3C50zl`?Cm?sUCayXN2dRJNP4|P_;cR{t6j%7g8WH{1QNlQ4cU)oko$1V*3RW-a{sQS<&CDv*Cnrhr8lf5v5)*l&MI z=7pT2Nf^4$K4K!QWcIVF|5o1*qYYb7z})8QF@~nc#+HBR59uK-;?UonsB3%>J#Yo^ z=w;glt>)-btuXO`7MOJEt|I<(@+GJC+JvYt`SNVFP^Dk__K2`z0UL1pEpp@i|NcOc Udcv>k?B&p2omiyjzE4*F18CXQ5C8xG delta 1728 zcmY+^TSyd97zglg+O1Z5Xw8ihA6iN)+f~;4m{!}3)N;L*sZ`#w5;9gHSS_0k6AZct z6DiR{Jp?@zC}S!?U=N1TMe_m`Wf3AK<*kcrWcHuk89noGboV#sJKs6q`DW|C=scfv zMxvW;q6rTX`Qh`O7UPQbT(HE2ztV}5kxQlV&_KP|wfKG3*n-~yM`b! z)3T0>_G*k*W4$_H*~G=kD#lw(V&}#Hj)w<|dDc~2f_T~*&TSQMSvPTs;?w*H`l@Tis7{iH%nZ)gWm(x5EL@`SiH{;;@(`=F2&7{Mc zVYygmMokPeL=icCNxV5SVJ;ZE!7N@tFp%BhwZZ(X&Cx`+nZyC1RXN?UL}#&}T7^|G zdz>%vZzXXctO<6CNo;~qyf*P_7!Pv^n5dSf`a#3tX5a^=3Rm6_<~Ae{l{1O2!e}c| z5^PRMd<|xYu?M*h>wwAEBv)A;t-n%_84?%Q6Xer80=j_g#5PzrEE&)LC`sC3Mr37^ z43yOs)Wb5EYE5?W#c#J09Yw5KttlA4Lz`o|ix-OPfrXg(S4lEgnO8gtd&yLxtuO zgs}_0f!&9(mFa_-_xcX^Q`z99x+`UF*uoVHc+I{&=F1EB5fw4z`VQ-cu?vpF?6?p1 znySd;Y=B*6Vyj{16e2S$QyJ%AcE!%ae8c1v3Kcv8lt&FFx?yMV*`$mMut^x3IIf4U zu%|9I5^js)Va+gh9uK4a+Gb6VV_`U)uu%Sw+uABRfNZA^!8RYzF8B%Nf+ZoL+Wnv9 zSQuNalzZ!4wlr-Y1*IQ#Q9ApZg8LsUt*quzCmYkjy5#QaQ`y>H(8ESy?CF-m_=7k( zHdCOCWiTg<-Hg8+3yZ;=A4)Gwyoftz77l4&lS!Z(#wMA9^}-4ftiB~H9r_wu4iR|a z6*I!>Ve&k+`=_%