Browse Source

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
master
chrisgregan 11 years ago
parent
commit
291902b386
  1. BIN
      Assets/Fungus/Prefabs/Game.prefab
  2. 14
      Assets/Fungus/Scripts/Commands/PageCommands.cs
  3. 27
      Assets/Fungus/Scripts/Game.cs
  4. 62
      Assets/Fungus/Scripts/GameController.cs
  5. 176
      Assets/Fungus/Scripts/Page.cs
  6. 11
      Assets/Fungus/Scripts/PageBounds.cs
  7. 5
      Assets/Fungus/Scripts/Room.cs
  8. BIN
      Assets/FungusExample/Scenes/Example.unity
  9. 4
      Assets/FungusExample/Scripts/MenuRoom.cs
  10. 12
      Assets/FungusExample/Scripts/PageRoom.cs
  11. 24
      Assets/FungusExample/Scripts/ParallaxRoom.cs

BIN
Assets/Fungus/Prefabs/Game.prefab

Binary file not shown.

14
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)

27
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);

62
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));

176
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);

11
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;
}
}

5
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.

BIN
Assets/FungusExample/Scenes/Example.unity

Binary file not shown.

4
Assets/FungusExample/Scripts/MenuRoom.cs

@ -13,10 +13,12 @@ public class MenuRoom : Room
void OnEnter()
{
SetPageMiddle();
AddOption("Writing a story with Pages", MoveToWritingRoom);
AddOption("Controlling the camera with Views", MoveToViewRoom);
AddOption("Sprites and Animations", MoveToSpriteRoom);
AddOption("Parallax scrolling effects", MoveToParallaxRoom);
AddOption("Manual pan and parallax", MoveToParallaxRoom);
AddOption("Using Buttons", MoveToButtonsRoom);
AddOption("Playing music and sound effects", MoveToAudioRoom);
Choose("Choose an example");

12
Assets/FungusExample/Scripts/PageRoom.cs

@ -17,24 +17,22 @@ public class PageRoom : Room
void OnEnter()
{
// Sets the header text on the page
Header("The Mushroom");
SetHeader("The Mushroom");
// Each Say() command writes one line of text, followed by a continue button
SetPageTop();
Say("One day in the forest, a mushroom grew.");
SetPageMiddle();
Say("What am I doing here he wondered?");
SetPageBottom();
SetPageTop();
Say("I think I will wait for a while and see if something happens.");
// Wait for a few seconds
Wait(3);
// Set the header text to the empty string to remove the page title
Header("");
SetHeader("");
SetPageBottom();
Say("...");
Say("Hmmm. Nothing seems to be happening.");
@ -81,7 +79,7 @@ public class PageRoom : Room
// Set the default style with background box texture
SetPageStyle(defaultStyle);
// Sets a game flag which we check above in GoToSleep
// Sets a global value flag which we check above in GoToSleep
SetValue("spawned");
AddOption("So tired. I sleep now.", GoToSleep);

24
Assets/FungusExample/Scripts/ParallaxRoom.cs

@ -8,21 +8,31 @@ using Fungus;
public class ParallaxRoom : Room
{
public View mainView;
public View zoomView;
public View viewA;
public View viewB;
public Button menuButton;
public Room menuRoom;
void OnEnter()
{
SetView(mainView);
SetView(viewA);
Say("Let's zoom in!");
PanToView(zoomView, 2);
PanToView(viewB, 2);
Say("Oooh! Nice parallax!");
PanToView(mainView, 2);
Say("Mmmm... purdy!");
PanToView(viewA, 2);
Say("Now you have a go!");
Say("Swipe the screen to pan around.");
ShowButton(menuButton, OnHomeButtonClicked);
StartManualPan(viewA, viewB, 0f);
}
void OnHomeButtonClicked()
{
MoveToRoom(menuRoom);
}
}
}
Loading…
Cancel
Save