From 20b795771b3575096423fcd2cef9d00191fa9f9b Mon Sep 17 00:00:00 2001 From: chrisgregan Date: Thu, 17 Apr 2014 09:12:51 +0100 Subject: [PATCH] Added simpler Page handling, manual pan mode and more MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - There is now only one Page game object. It is created automatically by the Game class on startup. - To control Page layout, use the new SetPageTop(), SetPageMiddle(), SetPageBottom(), SetPageRect() & SetPageBounds() commands. - You can still specify Page layout in the editor using the new PageBounds script & prefab, using the SetPageBounds() method. - Replaced Game.mainCamera with built-in Camera.main - Added StoreView() and PanToStoredView() - Game class now handles rendering fade texture (instead of CameraController) - Game class handles rendering pan / continue icons - Added new StartManualPan() and StopManualPan() commands to manually pan between 2 views - Removed continueStyle class & prefab (replaced by continue icon rendering) - Removed Game.activeView as it’s not needed - Parallax factor can now be controlled in X & Y - Reorganised command classes - Added PanToPosition() command - Pages now default to display full-size at bottom of screen. - Changed Page.VerticalAlign to Page.Layout and provided better options for controlling how the page automatically resizes. --- Assets/Fungus/Editor/PageEditor.cs | 98 --- Assets/Fungus/Prefabs/ContinueStyle.prefab | Bin 10848 -> 0 bytes .../Fungus/Prefabs/ContinueStyle.prefab.meta | 4 - Assets/Fungus/Prefabs/Game.prefab | Bin 7248 -> 7368 bytes Assets/Fungus/Prefabs/Page.prefab | Bin 25056 -> 0 bytes Assets/Fungus/Prefabs/Page.prefab.meta | 4 - Assets/Fungus/Prefabs/PageStyle1.prefab | Bin 34280 -> 34280 bytes Assets/Fungus/Prefabs/Room.prefab | Bin 11528 -> 9768 bytes Assets/Fungus/Scripts/CameraController.cs | 255 ++++-- Assets/Fungus/Scripts/Commands.cs | 757 ------------------ Assets/Fungus/Scripts/Commands.meta | 5 + .../Fungus/Scripts/Commands/AudioCommands.cs | 113 +++ .../AudioCommands.cs.meta} | 2 +- .../Fungus/Scripts/Commands/CameraCommands.cs | 273 +++++++ .../Commands/CameraCommands.cs.meta} | 2 +- .../Fungus/Scripts/Commands/GameCommands.cs | 168 ++++ .../GameCommands.cs.meta} | 2 +- .../Fungus/Scripts/Commands/PageCommands.cs | 243 ++++++ .../Scripts/Commands/PageCommands.cs.meta | 8 + .../Fungus/Scripts/Commands/SpriteCommands.cs | 119 +++ .../Scripts/Commands/SpriteCommands.cs.meta | 8 + Assets/Fungus/Scripts/ContinueStyle.cs | 48 -- Assets/Fungus/Scripts/Game.cs | 82 +- Assets/Fungus/Scripts/GameController.cs | 234 +++++- Assets/Fungus/Scripts/Page.cs | 168 ++-- Assets/Fungus/Scripts/Parallax.cs | 6 +- Assets/Fungus/Scripts/Room.cs | 18 +- Assets/FungusExample/Scripts/PageRoom.cs | 9 +- 28 files changed, 1474 insertions(+), 1152 deletions(-) delete mode 100644 Assets/Fungus/Editor/PageEditor.cs delete mode 100644 Assets/Fungus/Prefabs/ContinueStyle.prefab delete mode 100644 Assets/Fungus/Prefabs/ContinueStyle.prefab.meta delete mode 100644 Assets/Fungus/Prefabs/Page.prefab delete mode 100644 Assets/Fungus/Prefabs/Page.prefab.meta delete mode 100644 Assets/Fungus/Scripts/Commands.cs create mode 100644 Assets/Fungus/Scripts/Commands.meta create mode 100644 Assets/Fungus/Scripts/Commands/AudioCommands.cs rename Assets/Fungus/Scripts/{ContinueStyle.cs.meta => Commands/AudioCommands.cs.meta} (78%) create mode 100644 Assets/Fungus/Scripts/Commands/CameraCommands.cs rename Assets/Fungus/{Editor/PageEditor.cs.meta => Scripts/Commands/CameraCommands.cs.meta} (78%) create mode 100644 Assets/Fungus/Scripts/Commands/GameCommands.cs rename Assets/Fungus/Scripts/{Commands.cs.meta => Commands/GameCommands.cs.meta} (78%) create mode 100644 Assets/Fungus/Scripts/Commands/PageCommands.cs create mode 100644 Assets/Fungus/Scripts/Commands/PageCommands.cs.meta create mode 100644 Assets/Fungus/Scripts/Commands/SpriteCommands.cs create mode 100644 Assets/Fungus/Scripts/Commands/SpriteCommands.cs.meta delete mode 100644 Assets/Fungus/Scripts/ContinueStyle.cs diff --git a/Assets/Fungus/Editor/PageEditor.cs b/Assets/Fungus/Editor/PageEditor.cs deleted file mode 100644 index 5287d4ca..00000000 --- a/Assets/Fungus/Editor/PageEditor.cs +++ /dev/null @@ -1,98 +0,0 @@ -using UnityEditor; -using UnityEngine; -using System.Collections; -using System.Collections.Generic; - -namespace Fungus -{ - [CanEditMultipleObjects] - [CustomEditor (typeof(Page))] - public class PageEditor : Editor - { - void OnSceneGUI () - { - Page t = target as Page; - - // Render the parent view to help user position the page - Transform parent = t.transform.parent; - if (parent != null) - { - View view = parent.gameObject.GetComponent(); - if (view != null) - { - ViewEditor.DrawView(view); - } - } - - if (t.enabled) - { - EditPageBounds(); - } - - if (GUI.changed) - { - EditorUtility.SetDirty(target); - } - } - - void EditPageBounds() - { - Page t = target as Page; - Vector3 pos = t.transform.position; - - Vector3[] verts = new Vector3[4]; - verts[0] = new Vector3(pos.x + t.pageBounds.min.x, pos.y + t.pageBounds.min.y, 0); - verts[1] = new Vector3(pos.x + t.pageBounds.min.x, pos.y + t.pageBounds.max.y, 0); - verts[2] = new Vector3(pos.x + t.pageBounds.max.x, pos.y + t.pageBounds.max.y, 0); - verts[3] = new Vector3(pos.x + t.pageBounds.max.x, pos.y + t.pageBounds.min.y, 0); - - Handles.DrawSolidRectangleWithOutline(verts, new Color(1,1,1,0.2f), new Color(0,0,0,1)); - - for(int i = 0; i < 4; ++i) - { - Vector3 vert = verts[i]; - Vector3 newPos = Handles.FreeMoveHandle(vert, - Quaternion.identity, - HandleUtility.GetHandleSize(pos) * 0.1f, - Vector3.zero, - Handles.CubeCap); - newPos.z = 0; - verts[i] = newPos; - - if (vert != newPos) - { - switch(i) - { - case 0: - verts[1].x = newPos.x; - verts[3].y = newPos.y; - break; - case 1: - verts[0].x = newPos.x; - verts[2].y = newPos.y; - break; - case 2: - verts[3].x = newPos.x; - verts[1].y = newPos.y; - break; - case 3: - verts[2].x = newPos.x; - verts[0].y = newPos.y; - break; - } - break; - } - } - - Bounds newBounds = new Bounds(verts[0], Vector3.zero); - newBounds.Encapsulate(verts[1]); - newBounds.Encapsulate(verts[2]); - newBounds.Encapsulate(verts[3]); - - t.transform.position = newBounds.center; - newBounds.center = Vector3.zero; - - t.pageBounds = newBounds; - } - } -} diff --git a/Assets/Fungus/Prefabs/ContinueStyle.prefab b/Assets/Fungus/Prefabs/ContinueStyle.prefab deleted file mode 100644 index 691242ff96cac1e27e4cbd85e32b24caea70eff2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10848 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 diff --git a/Assets/Fungus/Prefabs/ContinueStyle.prefab.meta b/Assets/Fungus/Prefabs/ContinueStyle.prefab.meta deleted file mode 100644 index b94aeb25..00000000 --- a/Assets/Fungus/Prefabs/ContinueStyle.prefab.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: dcca71ea1c47741ce882a7c9dea90719 -NativeFormatImporter: - userData: diff --git a/Assets/Fungus/Prefabs/Game.prefab b/Assets/Fungus/Prefabs/Game.prefab index 1cb8dd81a4842aca6762bacd9c6348864a7af708..86069123a07a2d2531572a165c8db325ed196d63 100644 GIT binary patch delta 386 zcmca$al%r7fkE1afkEa30|NsmkR32lz@AZhV}K6Zt=cpIE|>mY9<2m{X9E$iM;=vj)pR)p2aT%vma+ zxBw{j9|($o^ntN}nnG=S`v%n-~rIaA6_P2{xs_bW2q7rNC?ac#JBeG5<$2>$Nf z)b6I|>(*%9aOaqU*!jsTrDP_v$p~!zAjQJS+ptrMffc9FBqppB7%5oj9#qH}4z delta 314 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 diff --git a/Assets/Fungus/Scripts/CameraController.cs b/Assets/Fungus/Scripts/CameraController.cs index 5c66689a..1777f428 100644 --- a/Assets/Fungus/Scripts/CameraController.cs +++ b/Assets/Fungus/Scripts/CameraController.cs @@ -13,40 +13,23 @@ namespace Fungus public class CameraController : MonoBehaviour { Game game; - Camera mainCamera; - float fadeAlpha = 0f; + // Manual panning control + View manualPanViewA; + View manualPanViewB; + Vector3 previousMousePos; - void Start() + class CameraView { - game = Game.GetInstance(); + public Vector3 cameraPos; + public float cameraSize; + }; - GameObject cameraObject = GameObject.FindGameObjectWithTag("MainCamera"); - if (cameraObject == null) - { - Debug.LogError("Failed to find game object with tag 'MainCamera'"); - return; - } - mainCamera = cameraObject.GetComponent(); - if (mainCamera == null) - { - Debug.LogError("Failed to find camera component"); - return; - } - } - - void OnGUI() - { - int drawDepth = -1000; + Dictionary storedViews = new Dictionary(); - if (fadeAlpha < 1f) - { - // 1 = scene fully visible - // 0 = scene fully obscured - GUI.color = new Color(1,1,1, 1f - fadeAlpha); - GUI.depth = drawDepth; - GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), game.fadeTexture); - } + void Start() + { + game = Game.GetInstance(); } public void Fade(float targetAlpha, float fadeDuration, Action fadeAction) @@ -56,11 +39,13 @@ namespace Fungus public void FadeToView(View view, float fadeDuration, Action fadeAction) { + game.manualPanActive = false; + // Fade out Fade(0f, fadeDuration / 2f, delegate { // Snap to new view - PanToView(view, 0f, null); + PanToPosition(view.transform.position, view.viewSize, 0f, null); // Fade in Fade(1f, fadeDuration / 2f, delegate { @@ -74,7 +59,7 @@ namespace Fungus IEnumerator FadeInternal(float targetAlpha, float fadeDuration, Action fadeAction) { - float startAlpha = fadeAlpha; + float startAlpha = Game.GetInstance().fadeAlpha; float timer = 0; while (timer < fadeDuration) @@ -84,11 +69,11 @@ namespace Fungus t = Mathf.Clamp01(t); - fadeAlpha = Mathf.Lerp(startAlpha, targetAlpha, t); + Game.GetInstance().fadeAlpha = Mathf.Lerp(startAlpha, targetAlpha, t); yield return null; } - fadeAlpha = targetAlpha; + Game.GetInstance().fadeAlpha = targetAlpha; if (fadeAction != null) { @@ -102,31 +87,75 @@ namespace Fungus */ public void CenterOnSprite(SpriteRenderer spriteRenderer) { + game.manualPanActive = false; + Sprite sprite = spriteRenderer.sprite; Vector3 extents = sprite.bounds.extents; float localScaleY = spriteRenderer.transform.localScale.y; - mainCamera.orthographicSize = extents.y * localScaleY; + Camera.main.orthographicSize = extents.y * localScaleY; Vector3 pos = spriteRenderer.transform.position; - mainCamera.transform.position = new Vector3(pos.x, pos.y, 0); + Camera.main.transform.position = new Vector3(pos.x, pos.y, 0); SetCameraZ(); } - public void SnapToView(View view) + /** + * Moves camera from current position to a target position over a period of time. + */ + public void PanToPosition(Vector3 targetPosition, float targetSize, float duration, Action arriveAction) + { + game.manualPanActive = false; + + if (duration == 0f) + { + // Move immediately + Camera.main.orthographicSize = targetSize; + Camera.main.transform.position = targetPosition; + SetCameraZ(); + if (arriveAction != null) + { + arriveAction(); + } + } + else + { + StartCoroutine(PanInternal(targetPosition, targetSize, duration, arriveAction)); + } + } + + /** + * Stores the current camera view using a name. + */ + public void StoreView(string viewName) { - PanToView(view, 0, null); + CameraView currentView = new CameraView(); + currentView.cameraPos = Camera.main.transform.position; + currentView.cameraSize = Camera.main.orthographicSize; + storedViews[viewName] = currentView; } /** - * Moves camera from current position to a target View over a period of time. + * Moves the camera to a previously stored camera view over a period of time. */ - public void PanToView(View view, float duration, Action arriveAction) + public void PanToStoredView(string viewName, float duration, Action arriveAction) { + if (!storedViews.ContainsKey(viewName)) + { + // View has not previously been stored + if (arriveAction != null) + { + arriveAction(); + } + return; + } + + CameraView cameraView = storedViews[viewName]; + if (duration == 0f) { // Move immediately - mainCamera.orthographicSize = view.viewSize; - mainCamera.transform.position = view.transform.position; + Camera.main.transform.position = cameraView.cameraPos; + Camera.main.orthographicSize = cameraView.cameraSize; SetCameraZ(); if (arriveAction != null) { @@ -135,17 +164,17 @@ namespace Fungus } else { - StartCoroutine(PanInternal(view, duration, arriveAction)); + StartCoroutine(PanInternal(cameraView.cameraPos, cameraView.cameraSize, duration, arriveAction)); } } - - IEnumerator PanInternal(View view, float duration, Action arriveAction) + + IEnumerator PanInternal(Vector3 targetPos, float targetSize, float duration, Action arriveAction) { float timer = 0; - float startSize = mainCamera.orthographicSize; - float endSize = view.viewSize; - Vector3 startPos = mainCamera.transform.position; - Vector3 endPos = view.transform.position; + float startSize = Camera.main.orthographicSize; + float endSize = targetSize; + Vector3 startPos = Camera.main.transform.position; + Vector3 endPos = targetPos; bool arrived = false; while (!arrived) @@ -159,8 +188,8 @@ namespace Fungus // Apply smoothed lerp to camera position and orthographic size float t = timer / duration; - mainCamera.orthographicSize = Mathf.Lerp(startSize, endSize, Mathf.SmoothStep(0f, 1f, t)); - mainCamera.transform.position = Vector3.Lerp(startPos, endPos, Mathf.SmoothStep(0f, 1f, t)); + Camera.main.orthographicSize = Mathf.Lerp(startSize, endSize, Mathf.SmoothStep(0f, 1f, t)); + Camera.main.transform.position = Vector3.Lerp(startPos, endPos, Mathf.SmoothStep(0f, 1f, t)); SetCameraZ(); if (arrived && @@ -178,13 +207,15 @@ namespace Fungus */ public void PanToPath(View[] viewList, float duration, Action arriveAction) { + game.manualPanActive = false; + List pathList = new List(); // Add current camera position as first point in path // Note: We use the z coord to tween the camera orthographic size - Vector3 startPos = new Vector3(mainCamera.transform.position.x, - mainCamera.transform.position.y, - mainCamera.orthographicSize); + Vector3 startPos = new Vector3(Camera.main.transform.position.x, + Camera.main.transform.position.y, + Camera.main.orthographicSize); pathList.Add(startPos); for (int i = 0; i < viewList.Length; ++i) @@ -212,8 +243,8 @@ namespace Fungus Vector3 point = iTween.PointOnPath(path, percent); - mainCamera.transform.position = new Vector3(point.x, point.y, 0); - mainCamera.orthographicSize = point.z; + Camera.main.transform.position = new Vector3(point.x, point.y, 0); + Camera.main.orthographicSize = point.z; SetCameraZ(); yield return null; @@ -225,17 +256,127 @@ namespace Fungus } } + /** + * Activates manual panning mode. + * The player can pan the camera within the area between viewA & viewB. + */ + public void StartManualPan(View viewA, View viewB, float duration, Action arriveAction) + { + manualPanViewA = viewA; + manualPanViewB = viewB; + + Vector3 cameraPos = Camera.main.transform.position; + + Vector3 targetPosition = CalcCameraPosition(cameraPos, manualPanViewA, manualPanViewB); + float targetSize = CalcCameraSize(cameraPos, manualPanViewA, manualPanViewB); + + PanToPosition(targetPosition, targetSize, duration, delegate { + + game.manualPanActive = true; + + if (arriveAction != null) + { + arriveAction(); + } + }); + } + + /** + * Deactivates manual panning mode. + */ + public void StopManualPan() + { + game.manualPanActive = false; + manualPanViewA = null; + manualPanViewB = null; + } + /** * Returns the current position of the main camera. */ public Vector3 GetCameraPosition() { - return mainCamera.transform.position; + return Camera.main.transform.position; } void SetCameraZ() { - mainCamera.transform.position = new Vector3(mainCamera.transform.position.x, mainCamera.transform.position.y, game.cameraZ); + Camera.main.transform.position = new Vector3(Camera.main.transform.position.x, Camera.main.transform.position.y, game.cameraZ); + } + + void Update() + { + if (!game.manualPanActive) + { + return; + } + + Vector3 delta = Vector3.zero; + + if (Input.touchCount > 0) + { + if (Input.GetTouch(0).phase == TouchPhase.Moved) + { + delta = Input.GetTouch(0).deltaPosition; + } + } + + if (Input.GetMouseButtonDown(0)) + { + previousMousePos = Input.mousePosition; + } + else if (Input.GetMouseButton(0)) + { + delta = Input.mousePosition - previousMousePos; + previousMousePos = Input.mousePosition; + } + + Vector3 cameraDelta = Camera.main.ScreenToViewportPoint(delta); + cameraDelta.x *= -2f; + cameraDelta.y *= -1f; + cameraDelta.z = 0f; + + Vector3 cameraPos = Camera.main.transform.position; + + cameraPos += cameraDelta; + + Camera.main.transform.position = CalcCameraPosition(cameraPos, manualPanViewA, manualPanViewB); + Camera.main.orthographicSize = CalcCameraSize(cameraPos, manualPanViewA, manualPanViewB); + } + + // Clamp camera position to region defined by the two views + Vector3 CalcCameraPosition(Vector3 pos, View viewA, View viewB) + { + Vector3 safePos = pos; + + // Clamp camera position to region defined by the two views + safePos.x = Mathf.Max(safePos.x, Mathf.Min(viewA.transform.position.x, viewB.transform.position.x)); + safePos.x = Mathf.Min(safePos.x, Mathf.Max(viewA.transform.position.x, viewB.transform.position.x)); + safePos.y = Mathf.Max(safePos.y, Mathf.Min(viewA.transform.position.y, viewB.transform.position.y)); + safePos.y = Mathf.Min(safePos.y, Mathf.Max(viewA.transform.position.y, viewB.transform.position.y)); + + return safePos; + } + + // Smoothly interpolate camera orthographic size based on relative position to two views + float CalcCameraSize(Vector3 pos, View viewA, View viewB) + { + // Get ray and point in same space + Vector3 toViewB = viewB.transform.position - viewA.transform.position; + Vector3 localPos = pos - viewA.transform.position; + + // Normalize + float distance = toViewB.magnitude; + toViewB /= distance; + localPos /= distance; + + // Project point onto ray + float t = Vector3.Dot(toViewB, localPos); + t = Mathf.Clamp01(t); // Not really necessary but no harm + + float cameraSize = Mathf.Lerp(viewA.viewSize, viewB.viewSize, t); + + return cameraSize; } } } diff --git a/Assets/Fungus/Scripts/Commands.cs b/Assets/Fungus/Scripts/Commands.cs deleted file mode 100644 index 2bf009a6..00000000 --- a/Assets/Fungus/Scripts/Commands.cs +++ /dev/null @@ -1,757 +0,0 @@ -using UnityEngine; -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Fungus -{ - /** - * Command classes have their own namespace to prevent them popping up in code completion - */ - namespace Command - { - /** - * Call a delegate method on execution. - * This command can be used to schedule arbitrary script code. - */ - public class CallCommand : CommandQueue.Command - { - Action callAction; - - public CallCommand(Action _callAction) - { - if (_callAction == null) - { - Debug.LogError("Action must not be null."); - return; - } - - callAction = _callAction; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - if (callAction != null) - { - callAction(); - } - - // Execute next command - onComplete(); - } - } - - /** - * Wait for a period of time. - */ - public class WaitCommand : CommandQueue.Command - { - float duration; - - public WaitCommand(float _duration) - { - duration = _duration; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Game.GetInstance().waiting = true; - commandQueue.StartCoroutine(WaitCoroutine(duration, onComplete)); - } - - IEnumerator WaitCoroutine(float duration, Action onComplete) - { - yield return new WaitForSeconds(duration); - if (onComplete != null) - { - Game.GetInstance().waiting = false; - onComplete(); - } - } - } - - /** - * Wait for a player tap/click/key press - */ - public class WaitForInputCommand : CommandQueue.Command - { - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Game.GetInstance().waiting = true; - commandQueue.StartCoroutine(WaitCoroutine(onComplete)); - } - - IEnumerator WaitCoroutine(Action onComplete) - { - while (true) - { - if (Input.GetMouseButtonDown(0) || Input.anyKeyDown) - { - break; - } - yield return null; - } - - if (onComplete != null) - { - Game.GetInstance().waiting = false; - onComplete(); - } - } - } - - /** - * Sets the currently active view immediately. - * The main camera snaps to the active view. - */ - public class SetViewCommand : CommandQueue.Command - { - View view; - - public SetViewCommand(View _view) - { - if (_view == null) - { - Debug.LogError("View must not be null"); - } - - view = _view; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Game game = Game.GetInstance(); - - game.cameraController.SnapToView(view); - game.activeView = view; - - // Set the first page component found (if any) as the active page - Page page = view.gameObject.GetComponentInChildren(); - if (page != null) - { - Game.GetInstance().activePage = page; - } - - if (onComplete != null) - { - onComplete(); - } - } - } - - /** - * Sets the currently active page for text rendering. - */ - public class SetPageCommand : CommandQueue.Command - { - Page page; - - public SetPageCommand(Page _page) - { - page = _page; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Game.GetInstance().activePage = page; - if (onComplete != null) - { - onComplete(); - } - } - } - - /** - * Sets the currently active Page Style for rendering Pages. - */ - public class SetPageStyleCommand : CommandQueue.Command - { - PageStyle pageStyle; - - public SetPageStyleCommand(PageStyle _pageStyle) - { - pageStyle = _pageStyle; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Game.GetInstance().activePageStyle = pageStyle; - if (onComplete != null) - { - onComplete(); - } - } - } - - /** - * Sets the header text displayed at the top of the active page. - */ - public class HeaderCommand : CommandQueue.Command - { - string titleText; - - public HeaderCommand(string _titleText) - { - titleText = _titleText; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Page page = Game.GetInstance().activePage; - if (page == null) - { - Debug.LogError("Active page must not be null"); - } - else - { - page.SetHeader(titleText); - } - if (onComplete != null) - { - onComplete(); - } - } - } - - /** - * Sets the footer text displayed at the top of the active page. - */ - public class FooterCommand : CommandQueue.Command - { - string titleText; - - public FooterCommand(string _titleText) - { - titleText = _titleText; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Page page = Game.GetInstance().activePage; - if (page == null) - { - Debug.LogError("Active page must not be null"); - } - else - { - page.SetFooter(titleText); - } - if (onComplete != null) - { - onComplete(); - } - } - } - - /** - * Writes story text to the currently active page. - * A 'continue' button is displayed when the text has fully appeared. - */ - public class SayCommand : CommandQueue.Command - { - string storyText; - - public SayCommand(string _storyText) - { - storyText = _storyText; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Page page = Game.GetInstance().activePage; - if (page == null) - { - Debug.LogError("Active page must not be null"); - } - else - { - page.Say(storyText, onComplete); - } - } - } - - /** - * Adds an option button to the current list of options. - * Use the Choose command to display added options. - */ - public class AddOptionCommand : CommandQueue.Command - { - string optionText; - Action optionAction; - - public AddOptionCommand(string _optionText, Action _optionAction) - { - optionText = _optionText; - optionAction = _optionAction; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Page page = Game.GetInstance().activePage; - if (page == null) - { - Debug.LogError("Active page must not be null"); - } - else - { - page.AddOption(optionText, optionAction); - } - if (onComplete != null) - { - onComplete(); - } - } - } - - /** - * Displays all previously added options. - */ - public class ChooseCommand : CommandQueue.Command - { - string chooseText; - - public ChooseCommand(string _chooseText) - { - chooseText = _chooseText; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Page page = Game.GetInstance().activePage; - if (page == null) - { - Debug.LogError("Active page must not be null"); - } - else - { - page.Choose(chooseText); - } - // Choose always clears commandQueue, so no need to call onComplete() - } - } - - /** - * Changes the active room to a different room - */ - public class MoveToRoomCommand : CommandQueue.Command - { - Room room; - - public MoveToRoomCommand(Room _room) - { - if (_room == null) - { - Debug.LogError("Room must not be null."); - return; - } - - room = _room; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Game game = Game.GetInstance(); - - game.waiting = true; - - // Fade out screen - game.cameraController.Fade(0f, game.roomFadeDuration / 2f, delegate { - - game.activeRoom = room; - - // Notify room script that the Room is being entered - // Calling private method on Room to hide implementation - game.activeRoom.gameObject.SendMessage("Enter"); - - // Fade in screen - game.cameraController.Fade(1f, game.roomFadeDuration / 2f, delegate { - game.waiting = false; - }); - }); - // MoveToRoom always resets the command queue so no need to call onComplete - } - } - - /** - * Sets a globally accessible game value - */ - public class SetValueCommand : CommandQueue.Command - { - string key; - int value; - - public SetValueCommand(string _key, int _value) - { - key = _key; - value = _value; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Game.GetInstance().SetGameValue(key, value); - if (onComplete != null) - { - onComplete(); - } - } - } - - /** - * Fades a sprite to a given alpha value over a period of time - */ - public class FadeSpriteCommand : CommandQueue.Command - { - SpriteRenderer spriteRenderer; - Color targetColor; - float fadeDuration; - Vector2 slideOffset = Vector2.zero; - - public FadeSpriteCommand(SpriteRenderer _spriteRenderer, - Color _targetColor, - float _fadeDuration, - Vector2 _slideOffset) - { - if (_spriteRenderer == null) - { - Debug.LogError("Sprite renderer must not be null."); - return; - } - - spriteRenderer = _spriteRenderer; - targetColor = _targetColor; - fadeDuration = _fadeDuration; - slideOffset = _slideOffset; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - SpriteFader.FadeSprite(spriteRenderer, targetColor, fadeDuration, slideOffset); - - // Fade is asynchronous, but command completes immediately. - // If you need to wait for the fade to complete, just use an additional Wait() command - if (onComplete != null) - { - onComplete(); - } - } - } - - /** - * Sets an animator trigger to change the animator state for an animated sprite - */ - public class SetAnimatorTriggerCommand : CommandQueue.Command - { - Animator animator; - string triggerName; - - public SetAnimatorTriggerCommand(Animator _animator, - string _triggerName) - { - if (_animator == null) - { - Debug.LogError("Animator must not be null."); - return; - } - - animator = _animator; - triggerName = _triggerName; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - animator.SetTrigger(triggerName); - - if (onComplete != null) - { - onComplete(); - } - } - } - - /** - * Display a button and set the method to be called when player clicks. - */ - public class ShowButtonCommand : CommandQueue.Command - { - Button button; - bool visible; - Action buttonAction; - - public ShowButtonCommand(Button _button, - bool _visible, - Action _buttonAction) - { - if (_button == null) - { - Debug.LogError("Button must not be null."); - return; - } - - button = _button; - visible = _visible; - buttonAction = _buttonAction; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - button.Show(visible, buttonAction); - - if (onComplete != null) - { - onComplete(); - } - } - } - - /** - * Pans the camera to a view over a period of time. - */ - public class PanToViewCommand : CommandQueue.Command - { - View view; - float duration; - - public PanToViewCommand(View _view, - float _duration) - { - if (_view == null) - { - Debug.LogError("View must not be null."); - return; - } - - view = _view; - duration = _duration; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Game game = Game.GetInstance(); - - game.waiting = true; - - game.cameraController.PanToView(view, duration, delegate { - - game.activeView = view; - game.waiting = false; - - // Try to find a page that is a child of the active view. - // If there are multiple child pages then it is the client's responsibility - // to set the correct active page in the room script. - Page defaultPage = view.gameObject.GetComponentInChildren(); - if (defaultPage) - { - game.activePage = defaultPage; - } - - if (onComplete != null) - { - onComplete(); - } - }); - } - } - - /** - * Pans the camera through a sequence of views over a period of time. - */ - public class PanToPathCommand : CommandQueue.Command - { - View[] views; - float duration; - - public PanToPathCommand(View[] _views, - float _duration) - { - if (_views.Length == 0) - { - Debug.LogError("View list must not be empty."); - return; - } - - views = _views; - duration = _duration; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Game game = Game.GetInstance(); - - game.waiting = true; - - game.cameraController.PanToPath(views, duration, delegate { - - if (views.Length > 0) - { - game.activeView = views[views.Length - 1]; - game.waiting = false; - - // Try to find a page that is a child of the active view. - // If there are multiple child pages then it is the client's responsibility - // to set the correct active page in the room script. - Page defaultPage = game.activeView.gameObject.GetComponentInChildren(); - if (defaultPage) - { - game.activePage = defaultPage; - } - } - - if (onComplete != null) - { - onComplete(); - } - }); - } - } - - /** - * Fades the camera to a view over a period of time. - */ - public class FadeToViewCommand : CommandQueue.Command - { - View view; - float duration; - - public FadeToViewCommand(View _view, - float _duration) - { - if (_view == null) - { - Debug.LogError("View must not be null."); - return; - } - - view = _view; - duration = _duration; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Game game = Game.GetInstance(); - - game.waiting = true; - - game.cameraController.FadeToView(view, duration, delegate { - - game.activeView = view; - game.waiting = false; - - // Try to find a page that is a child of the active view. - // If there are multiple child pages then it is the client's responsibility - // to set the correct active page in the room script. - Page defaultPage = view.gameObject.GetComponentInChildren(); - if (defaultPage) - { - game.activePage = defaultPage; - } - - if (onComplete != null) - { - onComplete(); - } - }); - } - } - - /** - * Plays a music clip - */ - public class PlayMusicCommand : CommandQueue.Command - { - AudioClip audioClip; - - public PlayMusicCommand(AudioClip _audioClip) - { - if (_audioClip == null) - { - Debug.LogError("Audio clip must not be null."); - return; - } - - audioClip = _audioClip; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Game game = Game.GetInstance(); - - game.audio.clip = audioClip; - game.audio.Play(); - - if (onComplete != null) - { - onComplete(); - } - } - } - - /** - * Stops a music clip - */ - public class StopMusicCommand : CommandQueue.Command - { - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Game game = Game.GetInstance(); - game.audio.Stop(); - - if (onComplete != null) - { - onComplete(); - } - } - } - - /** - * Fades music volume to required level over a period of time - */ - public class SetMusicVolumeCommand : CommandQueue.Command - { - float musicVolume; - float duration; - - public SetMusicVolumeCommand(float _musicVolume, float _duration) - { - musicVolume = _musicVolume; - duration = _duration; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Game game = Game.GetInstance(); - iTween.AudioTo(game.gameObject, musicVolume, 1f, duration); - - if (onComplete != null) - { - onComplete(); - } - } - } - - /** - * Plays a sound effect once - */ - public class PlaySoundCommand : CommandQueue.Command - { - AudioClip audioClip; - float volume; - - public PlaySoundCommand(AudioClip _audioClip, float _volume) - { - audioClip = _audioClip; - volume = _volume; - } - - public override void Execute(CommandQueue commandQueue, Action onComplete) - { - Game game = Game.GetInstance(); - game.audio.PlayOneShot(audioClip, volume); - - if (onComplete != null) - { - onComplete(); - } - } - } - } -} \ No newline at end of file diff --git a/Assets/Fungus/Scripts/Commands.meta b/Assets/Fungus/Scripts/Commands.meta new file mode 100644 index 00000000..e1cc88b9 --- /dev/null +++ b/Assets/Fungus/Scripts/Commands.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: ed31c7843a16b49bb918643ab98b7f67 +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/Fungus/Scripts/Commands/AudioCommands.cs b/Assets/Fungus/Scripts/Commands/AudioCommands.cs new file mode 100644 index 00000000..77021a68 --- /dev/null +++ b/Assets/Fungus/Scripts/Commands/AudioCommands.cs @@ -0,0 +1,113 @@ +using UnityEngine; +using System; +using System.Collections; + +namespace Fungus +{ + /** + * Command classes have their own namespace to prevent them popping up in code completion + */ + namespace Command + { + /** + * Plays a music clip + */ + public class PlayMusic : CommandQueue.Command + { + AudioClip audioClip; + + public PlayMusic(AudioClip _audioClip) + { + if (_audioClip == null) + { + Debug.LogError("Audio clip must not be null."); + return; + } + + audioClip = _audioClip; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game game = Game.GetInstance(); + + game.audio.clip = audioClip; + game.audio.Play(); + + if (onComplete != null) + { + onComplete(); + } + } + } + + /** + * Stops a music clip + */ + public class StopMusic : CommandQueue.Command + { + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game game = Game.GetInstance(); + game.audio.Stop(); + + if (onComplete != null) + { + onComplete(); + } + } + } + + /** + * Fades music volume to required level over a period of time + */ + public class SetMusicVolume : CommandQueue.Command + { + float musicVolume; + float duration; + + public SetMusicVolume(float _musicVolume, float _duration) + { + musicVolume = _musicVolume; + duration = _duration; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game game = Game.GetInstance(); + iTween.AudioTo(game.gameObject, musicVolume, 1f, duration); + + if (onComplete != null) + { + onComplete(); + } + } + } + + /** + * Plays a sound effect once + */ + public class PlaySound : CommandQueue.Command + { + AudioClip audioClip; + float volume; + + public PlaySound(AudioClip _audioClip, float _volume) + { + audioClip = _audioClip; + volume = _volume; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game game = Game.GetInstance(); + game.audio.PlayOneShot(audioClip, volume); + + if (onComplete != null) + { + onComplete(); + } + } + } + } +} \ No newline at end of file diff --git a/Assets/Fungus/Scripts/ContinueStyle.cs.meta b/Assets/Fungus/Scripts/Commands/AudioCommands.cs.meta similarity index 78% rename from Assets/Fungus/Scripts/ContinueStyle.cs.meta rename to Assets/Fungus/Scripts/Commands/AudioCommands.cs.meta index 1f401643..3ee59fd1 100644 --- a/Assets/Fungus/Scripts/ContinueStyle.cs.meta +++ b/Assets/Fungus/Scripts/Commands/AudioCommands.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b5c35620ec53b405a8d00dcb285cd260 +guid: bc443341450b64de790b66416177cca7 MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/Assets/Fungus/Scripts/Commands/CameraCommands.cs b/Assets/Fungus/Scripts/Commands/CameraCommands.cs new file mode 100644 index 00000000..f582b964 --- /dev/null +++ b/Assets/Fungus/Scripts/Commands/CameraCommands.cs @@ -0,0 +1,273 @@ +using UnityEngine; +using System; +using System.Collections; + +namespace Fungus +{ + /** + * Command classes have their own namespace to prevent them popping up in code completion. + */ + namespace Command + { + /** + * Sets the currently active view immediately. + * The main camera snaps to the active view. + */ + public class SetView : CommandQueue.Command + { + View view; + + public SetView(View _view) + { + if (_view == null) + { + Debug.LogError("View must not be null"); + } + + view = _view; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game game = Game.GetInstance(); + + game.cameraController.PanToPosition(view.transform.position, view.viewSize, 0, null); + + if (onComplete != null) + { + onComplete(); + } + } + } + + /** + * Pans the camera to a target position & size over a period of time. + */ + public class PanToPosition : CommandQueue.Command + { + Vector3 targetPosition; + float targetSize; + float duration; + + public PanToPosition(Vector3 _targetPosition, float _targetSize, float _duration) + { + targetPosition = _targetPosition; + targetSize = _targetSize; + duration = _duration; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game game = Game.GetInstance(); + + game.waiting = true; + + game.cameraController.PanToPosition(targetPosition, targetSize, duration, delegate { + + game.waiting = false; + + if (onComplete != null) + { + onComplete(); + } + }); + } + } + + /** + * Pans the camera through a sequence of views over a period of time. + */ + public class PanToPath : CommandQueue.Command + { + View[] views; + float duration; + + public PanToPath(View[] _views, float _duration) + { + if (_views.Length == 0) + { + Debug.LogError("View list must not be empty."); + return; + } + + views = _views; + duration = _duration; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game game = Game.GetInstance(); + + game.waiting = true; + + game.cameraController.PanToPath(views, duration, delegate { + + if (views.Length > 0) + { + game.waiting = false; + } + + if (onComplete != null) + { + onComplete(); + } + }); + } + } + + /** + * Fades the camera to a view over a period of time. + */ + public class FadeToView : CommandQueue.Command + { + View view; + float duration; + + public FadeToView(View _view, float _duration) + { + if (_view == null) + { + Debug.LogError("View must not be null."); + return; + } + + view = _view; + duration = _duration; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game game = Game.GetInstance(); + + game.waiting = true; + + game.cameraController.FadeToView(view, duration, delegate { + + game.waiting = false; + + if (onComplete != null) + { + onComplete(); + } + }); + } + } + + /** + * Switches on manual pan mode. + * This allows the player to swipe the screen to pan around a region defined by 2 views. + */ + public class StartManualPan : CommandQueue.Command + { + View viewA; + View viewB; + float duration; + + public StartManualPan(View _viewA, View _viewB, float _duration) + { + if (_viewA == null || + _viewB == null) + { + Debug.LogError("Views must not be null."); + return; + } + + viewA = _viewA; + viewB = _viewB; + duration = _duration; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game game = Game.GetInstance(); + + game.waiting = true; + + game.cameraController.StartManualPan(viewA, viewB, duration, delegate { + + game.waiting = false; + + if (onComplete != null) + { + onComplete(); + } + }); + } + } + + /** + * Switches off manual pan mode. + */ + public class StopManualPan : CommandQueue.Command + { + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game game = Game.GetInstance(); + + game.cameraController.StopManualPan(); + + if (onComplete != null) + { + onComplete(); + } + } + } + + /** + * Stores the current camera position + */ + public class StoreView : CommandQueue.Command + { + string viewName; + + public StoreView(string _viewName) + { + viewName = _viewName; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game game = Game.GetInstance(); + + game.cameraController.StoreView(viewName); + + if (onComplete != null) + { + onComplete(); + } + } + } + + /** + * Pans the camera to a view over a period of time. + */ + public class PanToStoredView : CommandQueue.Command + { + float duration; + string viewName; + + public PanToStoredView(string _viewName, float _duration) + { + viewName = _viewName; + duration = _duration; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game game = Game.GetInstance(); + + game.waiting = true; + + game.cameraController.PanToStoredView(viewName, duration, delegate { + + game.waiting = false; + + if (onComplete != null) + { + onComplete(); + } + }); + } + } + } +} \ No newline at end of file diff --git a/Assets/Fungus/Editor/PageEditor.cs.meta b/Assets/Fungus/Scripts/Commands/CameraCommands.cs.meta similarity index 78% rename from Assets/Fungus/Editor/PageEditor.cs.meta rename to Assets/Fungus/Scripts/Commands/CameraCommands.cs.meta index 49d26ab2..e78de55a 100644 --- a/Assets/Fungus/Editor/PageEditor.cs.meta +++ b/Assets/Fungus/Scripts/Commands/CameraCommands.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: dce33924cf6804b2c94d17784a6037d1 +guid: 48a11d9857cef47caad512a6e89998d3 MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/Assets/Fungus/Scripts/Commands/GameCommands.cs b/Assets/Fungus/Scripts/Commands/GameCommands.cs new file mode 100644 index 00000000..26bdb891 --- /dev/null +++ b/Assets/Fungus/Scripts/Commands/GameCommands.cs @@ -0,0 +1,168 @@ +using UnityEngine; +using System; +using System.Collections; + +namespace Fungus +{ + /** + * Command classes have their own namespace to prevent them popping up in code completion. + */ + namespace Command + { + /** + * Call a delegate method on execution. + * This command can be used to schedule arbitrary script code. + */ + public class Call : CommandQueue.Command + { + Action callAction; + + public Call(Action _callAction) + { + if (_callAction == null) + { + Debug.LogError("Action must not be null."); + return; + } + + callAction = _callAction; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + if (callAction != null) + { + callAction(); + } + + // Execute next command + onComplete(); + } + } + + /** + * Wait for a period of time. + */ + public class Wait : CommandQueue.Command + { + float duration; + + public Wait(float _duration) + { + duration = _duration; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game.GetInstance().waiting = true; + commandQueue.StartCoroutine(WaitCoroutine(duration, onComplete)); + } + + IEnumerator WaitCoroutine(float duration, Action onComplete) + { + yield return new WaitForSeconds(duration); + if (onComplete != null) + { + Game.GetInstance().waiting = false; + onComplete(); + } + } + } + + /** + * Wait for a player tap/click/key press + */ + public class WaitForInput : CommandQueue.Command + { + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game.GetInstance().waiting = true; + commandQueue.StartCoroutine(WaitCoroutine(onComplete)); + } + + IEnumerator WaitCoroutine(Action onComplete) + { + while (true) + { + if (Input.GetMouseButtonDown(0) || Input.anyKeyDown) + { + break; + } + yield return null; + } + + if (onComplete != null) + { + Game.GetInstance().waiting = false; + onComplete(); + } + } + } + + /** + * Changes the active room to a different room + */ + public class MoveToRoom : CommandQueue.Command + { + Room room; + + public MoveToRoom(Room _room) + { + if (_room == null) + { + Debug.LogError("Room must not be null."); + return; + } + + room = _room; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game game = Game.GetInstance(); + + game.waiting = true; + + // Fade out screen + game.cameraController.Fade(0f, game.roomFadeDuration / 2f, delegate { + + game.activeRoom = room; + + // Notify room script that the Room is being entered + // Calling private method on Room to hide implementation + game.activeRoom.gameObject.SendMessage("Enter"); + + // Fade in screen + game.cameraController.Fade(1f, game.roomFadeDuration / 2f, delegate { + game.waiting = false; + }); + }); + // MoveToRoom always resets the command queue so no need to call onComplete + } + } + + /** + * Sets a globally accessible game value + */ + public class SetValue : CommandQueue.Command + { + string key; + int value; + + public SetValue(string _key, int _value) + { + key = _key; + value = _value; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game.GetInstance().SetGameValue(key, value); + if (onComplete != null) + { + onComplete(); + } + } + } + } +} \ No newline at end of file diff --git a/Assets/Fungus/Scripts/Commands.cs.meta b/Assets/Fungus/Scripts/Commands/GameCommands.cs.meta similarity index 78% rename from Assets/Fungus/Scripts/Commands.cs.meta rename to Assets/Fungus/Scripts/Commands/GameCommands.cs.meta index 865ee986..d7aeee10 100644 --- a/Assets/Fungus/Scripts/Commands.cs.meta +++ b/Assets/Fungus/Scripts/Commands/GameCommands.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c82cac70434cd411b973a4c590386c63 +guid: 83105d98d4aed45f9b25b7ba66e83a29 MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/Assets/Fungus/Scripts/Commands/PageCommands.cs b/Assets/Fungus/Scripts/Commands/PageCommands.cs new file mode 100644 index 00000000..4fc458da --- /dev/null +++ b/Assets/Fungus/Scripts/Commands/PageCommands.cs @@ -0,0 +1,243 @@ +using UnityEngine; +using System; +using System.Collections; + +namespace Fungus +{ + /** + * Command classes have their own namespace to prevent them popping up in code completion. + */ + namespace Command + { + /** + * Sets the display rect for the active Page using a PageBounds object. + */ + public class SetPageBounds : CommandQueue.Command + { + PageBounds pageBounds; + Page.Layout pageLayout; + + public SetPageBounds(PageBounds _pageBounds, Page.Layout _pageLayout) + { + pageBounds = _pageBounds; + pageLayout = _pageLayout; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + if (pageBounds != null) + { + pageBounds.UpdatePageRect(); + Game.GetInstance().activePage.layout = pageLayout; + } + + if (onComplete != null) + { + onComplete(); + } + } + } + + /** + * Sets the display rect for the active Page using normalized screen space coords. + */ + public class SetPageRect : CommandQueue.Command + { + float x1; + float y1; + float x2; + float y2; + Page.Layout layout; + + public SetPageRect(float _x1, float _y1, float _x2, float _y2, Page.Layout _layout) + { + x1 = _x1; + y1 = _y1; + x2 = _x2; + y2 = _y2; + layout = _layout; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Page page = Game.GetInstance().activePage; + page.SetPageRect(x1, y1, x2, y2); + page.layout = layout; + + if (onComplete != null) + { + onComplete(); + } + } + } + + /** + * Sets the currently active Page Style for rendering Pages. + */ + public class SetPageStyle : CommandQueue.Command + { + PageStyle pageStyle; + + public SetPageStyle(PageStyle _pageStyle) + { + pageStyle = _pageStyle; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Game.GetInstance().activePageStyle = pageStyle; + if (onComplete != null) + { + onComplete(); + } + } + } + + /** + * Sets the header text displayed at the top of the active page. + */ + public class SetHeader : CommandQueue.Command + { + string titleText; + + public SetHeader(string _titleText) + { + titleText = _titleText; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Page page = Game.GetInstance().activePage; + if (page == null) + { + Debug.LogError("Active page must not be null"); + } + else + { + page.SetHeader(titleText); + } + if (onComplete != null) + { + onComplete(); + } + } + } + + /** + * Sets the footer text displayed at the top of the active page. + */ + public class SetFooter : CommandQueue.Command + { + string titleText; + + public SetFooter(string _titleText) + { + titleText = _titleText; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Page page = Game.GetInstance().activePage; + if (page == null) + { + Debug.LogError("Active page must not be null"); + } + else + { + page.SetFooter(titleText); + } + if (onComplete != null) + { + onComplete(); + } + } + } + + /** + * Writes story text to the currently active page. + * A 'continue' icon is displayed when the text has fully appeared. + */ + public class Say : CommandQueue.Command + { + string storyText; + + public Say(string _storyText) + { + storyText = _storyText; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Page page = Game.GetInstance().activePage; + if (page == null) + { + Debug.LogError("Active page must not be null"); + } + else + { + page.Say(storyText, onComplete); + } + } + } + + /** + * Adds an option button to the current list of options. + * Use the Choose command to display added options. + */ + public class AddOption : CommandQueue.Command + { + string optionText; + Action optionAction; + + public AddOption(string _optionText, Action _optionAction) + { + optionText = _optionText; + optionAction = _optionAction; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Page page = Game.GetInstance().activePage; + if (page == null) + { + Debug.LogError("Active page must not be null"); + } + else + { + page.AddOption(optionText, optionAction); + } + if (onComplete != null) + { + onComplete(); + } + } + } + + /** + * Displays all previously added options. + */ + public class Choose : CommandQueue.Command + { + string chooseText; + + public Choose(string _chooseText) + { + chooseText = _chooseText; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + Page page = Game.GetInstance().activePage; + if (page == null) + { + Debug.LogError("Active page must not be null"); + } + else + { + page.Choose(chooseText); + } + // Choose always clears commandQueue, so no need to call onComplete() + } + } + } +} diff --git a/Assets/Fungus/Scripts/Commands/PageCommands.cs.meta b/Assets/Fungus/Scripts/Commands/PageCommands.cs.meta new file mode 100644 index 00000000..bb3faa9b --- /dev/null +++ b/Assets/Fungus/Scripts/Commands/PageCommands.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ae90082ad9904474ebe8554e864a0539 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/Fungus/Scripts/Commands/SpriteCommands.cs b/Assets/Fungus/Scripts/Commands/SpriteCommands.cs new file mode 100644 index 00000000..0a71f7f1 --- /dev/null +++ b/Assets/Fungus/Scripts/Commands/SpriteCommands.cs @@ -0,0 +1,119 @@ +using UnityEngine; +using System; +using System.Collections; + +namespace Fungus +{ + /** + * Command classes have their own namespace to prevent them popping up in code completion. + */ + namespace Command + { + /** + * Fades a sprite to a given alpha value over a period of time + */ + public class FadeSprite : CommandQueue.Command + { + SpriteRenderer spriteRenderer; + Color targetColor; + float fadeDuration; + Vector2 slideOffset = Vector2.zero; + + public FadeSprite(SpriteRenderer _spriteRenderer, + Color _targetColor, + float _fadeDuration, + Vector2 _slideOffset) + { + if (_spriteRenderer == null) + { + Debug.LogError("Sprite renderer must not be null."); + return; + } + + spriteRenderer = _spriteRenderer; + targetColor = _targetColor; + fadeDuration = _fadeDuration; + slideOffset = _slideOffset; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + SpriteFader.FadeSprite(spriteRenderer, targetColor, fadeDuration, slideOffset); + + // Fade is asynchronous, but command completes immediately. + // If you need to wait for the fade to complete, just use an additional Wait() command + if (onComplete != null) + { + onComplete(); + } + } + } + + /** + * Sets an animator trigger to change the animator state for an animated sprite + */ + public class SetAnimatorTrigger : CommandQueue.Command + { + Animator animator; + string triggerName; + + public SetAnimatorTrigger(Animator _animator, + string _triggerName) + { + if (_animator == null) + { + Debug.LogError("Animator must not be null."); + return; + } + + animator = _animator; + triggerName = _triggerName; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + animator.SetTrigger(triggerName); + + if (onComplete != null) + { + onComplete(); + } + } + } + + /** + * Display a button and set the method to be called when player clicks. + */ + public class ShowButton : CommandQueue.Command + { + Button button; + bool visible; + Action buttonAction; + + public ShowButton(Button _button, + bool _visible, + Action _buttonAction) + { + if (_button == null) + { + Debug.LogError("Button must not be null."); + return; + } + + button = _button; + visible = _visible; + buttonAction = _buttonAction; + } + + public override void Execute(CommandQueue commandQueue, Action onComplete) + { + button.Show(visible, buttonAction); + + if (onComplete != null) + { + onComplete(); + } + } + } + } +} \ No newline at end of file diff --git a/Assets/Fungus/Scripts/Commands/SpriteCommands.cs.meta b/Assets/Fungus/Scripts/Commands/SpriteCommands.cs.meta new file mode 100644 index 00000000..3a21518c --- /dev/null +++ b/Assets/Fungus/Scripts/Commands/SpriteCommands.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bb89d5e15bc734221b9d8fe9ae8e8153 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/Fungus/Scripts/ContinueStyle.cs b/Assets/Fungus/Scripts/ContinueStyle.cs deleted file mode 100644 index af4f3625..00000000 --- a/Assets/Fungus/Scripts/ContinueStyle.cs +++ /dev/null @@ -1,48 +0,0 @@ -using UnityEngine; -using System.Collections; - -public class ContinueStyle : MonoBehaviour -{ - /** - * Text to use on 'Continue' buttons. - */ - public string continueText = "Continue"; - - /// Continue font size as a fraction of screen height. - public float continueFontScale = 1f / 30f; - - /// Style for continue button - public GUIStyle style; - - /** - * If true, places the continue button on the active page. - * If false, places the continue button on the screen. - */ - public bool onPage; - - /** - * Specifies continue button position in normalized screen coordinates. - * This setting is ignored if onPage == true - * (0,0) is top left of screen. - * (1,1) is bottom right of screen - */ - public Vector2 screenPosition = new Vector2(1,1); - - /** - * Padding distance between button and edge of the screen in pixels. - */ - public Vector2 padding = new Vector2(4,4); - - /** - * Returns the style for the Continue button. - * Overrides the font size to compensate for varying device resolution. - * Font size is calculated as a fraction of the current screen height. - */ - public GUIStyle GetScaledContinueStyle() - { - GUIStyle guiStyle; - guiStyle = new GUIStyle(style); - guiStyle.fontSize = Mathf.RoundToInt((float)Screen.height * continueFontScale); - return guiStyle; - } -} diff --git a/Assets/Fungus/Scripts/Game.cs b/Assets/Fungus/Scripts/Game.cs index 4d642180..dfcc8ade 100644 --- a/Assets/Fungus/Scripts/Game.cs +++ b/Assets/Fungus/Scripts/Game.cs @@ -53,6 +53,16 @@ namespace Fungus */ public Texture2D fadeTexture; + /** + * Icon to display when manual pan mode is active. + */ + public Texture2D manualPanTexture; + + /** + * Icon to display when waiting for player input to continue + */ + public Texture2D continueTexture; + /** * Sound effect to play when buttons are clicked. */ @@ -63,11 +73,6 @@ namespace Fungus */ public float autoHideButtonDuration = 5f; - /** - * References to a style object which controls the appearance & behavior of the continue button. - */ - public ContinueStyle continueStyle; - float autoHideButtonTimer; /** @@ -76,9 +81,6 @@ namespace Fungus [HideInInspector] public Dictionary values = new Dictionary(); - [HideInInspector] - public View activeView; - [HideInInspector] public Page activePage; @@ -90,13 +92,19 @@ namespace Fungus [HideInInspector] public CameraController cameraController; - + /** * True when executing a Wait() or WaitForTap() command */ [HideInInspector] public bool waiting; + [HideInInspector] + public bool manualPanActive; + + [HideInInspector] + public float fadeAlpha = 0f; + static Game instance; /** @@ -136,9 +144,15 @@ namespace Fungus { // Move to the active room commandQueue.Clear(); - commandQueue.AddCommand(new Command.MoveToRoomCommand(activeRoom)); + commandQueue.AddCommand(new Command.MoveToRoom(activeRoom)); commandQueue.Execute(); } + + // Create the Page game object as a child of Game + GameObject pageObject = new GameObject(); + pageObject.name = "Page"; + pageObject.transform.parent = transform; + activePage = pageObject.AddComponent(); } public virtual void Update() @@ -152,6 +166,46 @@ namespace Fungus } } + void OnGUI() + { + if (manualPanActive) + { + // Draw the swipe-to-pan icon + if (manualPanTexture) + { + Rect rect = new Rect(Screen.width - manualPanTexture.width, + 0, + manualPanTexture.width, + manualPanTexture.height); + GUI.DrawTexture(rect, manualPanTexture); + } + } + + if (activePage.mode == Page.Mode.Say && + activePage.FinishedWriting()) + { + // Draw the continue icon + if (continueTexture) + { + Rect rect = new Rect(Screen.width - continueTexture.width, + 0, + continueTexture.width, + continueTexture.height); + GUI.DrawTexture(rect, continueTexture); + } + } + + // Draw full screen fade texture + if (fadeAlpha < 1f) + { + // 1 = scene fully visible + // 0 = scene fully obscured + GUI.color = new Color(1,1,1, 1f - fadeAlpha); + GUI.depth = -1000; + GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), fadeTexture); + } + } + /** * Plays the button clicked sound effect */ @@ -212,10 +266,10 @@ namespace Fungus * Returns a parallax offset vector based on the camera position relative to the active Room. * Higher values for the parallaxFactor yield a larger offset (appears closer to camera). * Suggested range for good parallax effect is [0.1..0.5]. - * @param parallaxFactor Scale factor to apply to camera offset vector. + * @param parallaxFactor Horizontal and vertical scale factors to apply to camera offset vector. * @return A parallax offset vector based on camera positon relative to current room and the parallaxFactor. */ - public Vector3 GetParallaxOffset(float parallaxFactor) + public Vector3 GetParallaxOffset(Vector2 parallaxFactor) { if (activeRoom == null) { @@ -224,7 +278,9 @@ namespace Fungus Vector3 a = activeRoom.transform.position; Vector3 b = cameraController.GetCameraPosition(); - Vector3 offset = (a - b) * parallaxFactor; + Vector3 offset = (a - b); + offset.x *= parallaxFactor.x; + offset.y *= parallaxFactor.y; return offset; } diff --git a/Assets/Fungus/Scripts/GameController.cs b/Assets/Fungus/Scripts/GameController.cs index 8457ce3d..6d5377eb 100644 --- a/Assets/Fungus/Scripts/GameController.cs +++ b/Assets/Fungus/Scripts/GameController.cs @@ -37,7 +37,7 @@ namespace Fungus public static void MoveToRoom(Room room) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.MoveToRoomCommand(room)); + commandQueue.AddCommand(new Command.MoveToRoom(room)); } /** @@ -48,7 +48,7 @@ namespace Fungus public static void Wait(float duration) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.WaitCommand(duration)); + commandQueue.AddCommand(new Command.Wait(duration)); } /** @@ -58,7 +58,7 @@ namespace Fungus public static void WaitForInput() { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.WaitForInputCommand()); + commandQueue.AddCommand(new Command.WaitForInput()); } /** @@ -70,7 +70,7 @@ namespace Fungus public static void Call(Action callAction) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.CallCommand(callAction)); + commandQueue.AddCommand(new Command.Call(callAction)); } #endregion @@ -78,34 +78,46 @@ namespace Fungus /** * Sets the currently active View immediately. - * The main camera snaps to the new active View. If the View contains a Page object, this Page becomes the active Page. + * The main camera snaps to the new active View. * This method returns immediately but it queues an asynchronous command for later execution. * @param view The View object to make active */ public static void SetView(View view) { - CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.SetViewCommand(view)); + PanToView(view, 0); } /** * Pans the camera to the target View over a period of time. * The pan starts at the current camera position and performs a smoothed linear pan to the target View. - * Command execution blocks until the pan completes. When the camera arrives at the target View, this View becomes the active View. + * Command execution blocks until the pan completes. * This method returns immediately but it queues an asynchronous command for later execution. * @param targetView The View to pan the camera to. * @param duration The length of time in seconds needed to complete the pan. */ public static void PanToView(View targetView, float duration) + { + PanToPosition(targetView.transform.position, targetView.viewSize, duration); + } + + /** + * Pans the camera to the target position and size over a period of time. + * The pan starts at the current camera position and performs a smoothed linear pan to the target. + * Command execution blocks until the pan completes. + * This method returns immediately but it queues an asynchronous command for later execution. + * @param targetView The View to pan the camera to. + * @param duration The length of time in seconds needed to complete the pan. + */ + public static void PanToPosition(Vector3 targetPosition, float targetSize, float duration) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.PanToViewCommand(targetView, duration)); + commandQueue.AddCommand(new Command.PanToPosition(targetPosition, targetSize, duration)); } /** * Pans the camera through a sequence of target Views over a period of time. * The pan starts at the current camera position and performs a smooth pan through all Views in the list. - * Command execution blocks until the pan completes. When the camera arrives at the last View in the list, this View becomes the active View. + * Command execution blocks until the pan completes. * If more control is required over the camera path then you should instead use an Animator component to precisely control the Camera path. * This method returns immediately but it queues an asynchronous command for later execution. * @param duration The length of time in seconds needed to complete the pan. @@ -114,12 +126,11 @@ namespace Fungus public static void PanToPath(float duration, params View[] targetViews) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.PanToPathCommand(targetViews, duration)); + commandQueue.AddCommand(new Command.PanToPath(targetViews, duration)); } /** * Fades out the current camera View, and fades in again using the target View. - * If the target View contains a Page object, this Page becomes the active Page. * This method returns immediately but it queues an asynchronous command for later execution. * @param targetView The View object to fade to. * @param duration The length of time in seconds needed to complete the pan. @@ -127,35 +138,184 @@ namespace Fungus public static void FadeToView(View targetView, float duration) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.FadeToViewCommand(targetView, duration)); + commandQueue.AddCommand(new Command.FadeToView(targetView, duration)); + } + + /** + * Activates manual pan mode. + * The camera first pans to the nearest point between the two views over a period of time. + * The player can pan around the rectangular area defined between viewA & viewB. + * Manual panning remains active until a ManualPanOff, SetView, PanToView, FadeToPath or FadeToView command is executed. + * This method returns immediately but it queues an asynchronous command for later execution. + * @param viewA View object which defines one extreme of the pan area. + * @param viewB View object which defines the other extreme of the pan area. + */ + public static void StartManualPan(View viewA, View viewB, float duration = 1f) + { + CommandQueue commandQueue = Game.GetInstance().commandQueue; + commandQueue.AddCommand(new Command.StartManualPan(viewA, viewB, duration)); + } + + /** + * Deactivates manual pan mode. + * This method returns immediately but it queues an asynchronous command for later execution. + */ + public static void StopManualPan() + { + CommandQueue commandQueue = Game.GetInstance().commandQueue; + commandQueue.AddCommand(new Command.StopManualPan()); + } + + /** + * Stores the current camera view using a name. + * You can later use PanToStoredView() to pan back to this stored position by name. + * This method returns immediately but it queues an asynchronous command for later execution. + * @param viewName Name to associate with the stored camera view. + */ + public static void StoreView(string viewName = "") + { + CommandQueue commandQueue = Game.GetInstance().commandQueue; + commandQueue.AddCommand(new Command.StoreView(viewName)); + } + + /** + * Moves camera from the current position to a previously stored view over a period of time. + * @param duration Time needed for pan to complete. + * @param viewName Name of a camera view that was previously stored using StoreView(). + */ + public static void PanToStoredView(float duration, string viewName = "") + { + CommandQueue commandQueue = Game.GetInstance().commandQueue; + commandQueue.AddCommand(new Command.PanToStoredView(viewName, duration)); } #endregion #region Page Methods /** - * Sets the currently active Page for story text display. - * Once this command executes, all story text added using Say(), AddOption(), Choose(), etc. will be displayed on this Page. - * When a Room contains multiple Page objects, this method can be used to control which Page object is active at a given time. + * Sets the display rect for the active Page using a PageBounds object. + * PageBounds objects can be edited visually in the Unity editor which is useful for accurate placement. + * The actual screen space rect used is based on both the PageBounds values and the camera transform at the time the command is executed. + * This method returns immediately but it queues an asynchronous command for later execution. + * @param pageBounds The bounds object to use when calculating the Page display rect. + */ + public static void SetPageBounds(PageBounds pageBounds, Page.Layout pageLayout = Page.Layout.FullSize) + { + CommandQueue commandQueue = Game.GetInstance().commandQueue; + commandQueue.AddCommand(new Command.SetPageBounds(pageBounds, 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). + * The origin is at the top left of the screen. * This method returns immediately but it queues an asynchronous command for later execution. - * @param page The Page object to make active + * @param x1 Page rect left coordinate in normalized screen space coords [0..1] + * @param y1 Page rect top coordinate in normalized screen space coords [0..1 + * @param x2 Page rect right coordinate in normalized screen space coords [0..1] + * @param y2 Page rect bottom coordinate in normalized screen space coords [0..1] + * @param pageLayout Layout mode for positioning page within the rect. */ - public static void SetPage(Page page) + 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.SetPageCommand(page)); + commandQueue.AddCommand(new Command.SetPageRect(x1, y1, x2, y2, pageLayout)); + } + + /** + * Sets the active Page to display at the top of the screen. + * This method returns immediately but it queues an asynchronous command for later execution. + * @param scaleX Scales the width of the Page [0..1]. 1 = full screen width. + * @param scaleY Scales the height of the Page [0..1]. 1 = full screen height. + * @param pageLayout Controls how the Page is positioned and sized based on the displayed content. + */ + 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); + } + + /** + * Sets the currently active Page to display at the top of the screen. + * This method returns immediately but it queues an asynchronous command for later execution. + */ + public static void SetPageTop() + { + SetPageTop(0.75f, 0.25f, Page.Layout.FullSize); + } + + /** + * Sets the active Page to display at the middle of the screen. + * This method returns immediately but it queues an asynchronous command for later execution. + * @param scaleX Scales the width of the Page [0..1]. 1 = full screen width. + * @param scaleY Scales the height of the Page [0..1]. 1 = full screen height. + * @param pageLayout Controls how the Page is positioned and sized based on the displayed content. + */ + 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); + } + + /** + * Sets the currently active Page to display at the middle of the screen. + * This method returns immediately but it queues an asynchronous command for later execution. + */ + public static void SetPageMiddle() + { + SetPageMiddle(0.5f, 0.5f, Page.Layout.FitToMiddle); + } + + /** + * Sets the active Page to display at the bottom of the screen. + * This method returns immediately but it queues an asynchronous command for later execution. + * @param scaleX Scales the width of the Page [0..1]. 1 = full screen width. + * @param scaleY Scales the height of the Page [0..1]. 1 = full screen height. + * @param pageLayout Controls how the Page is positioned and sized based on the displayed content. + */ + 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); + } + + /** + * Sets the currently active Page to display at the bottom of the screen. + * This method returns immediately but it queues an asynchronous command for later execution. + */ + public static void SetPageBottom() + { + SetPageBottom(0.75f, 0.25f, Page.Layout.FullSize); } /** - * Sets the currently active style for displaying Pages. - * Once this command executes, all Pages will display using the new style. + * Sets the active style for displaying the Page. * This method returns immediately but it queues an asynchronous command for later execution. * @param pageStyle The style object to make active */ public static void SetPageStyle(PageStyle pageStyle) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.SetPageStyleCommand(pageStyle)); + commandQueue.AddCommand(new Command.SetPageStyle(pageStyle)); } /** @@ -176,7 +336,7 @@ namespace Fungus public static void Header(string headerText) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.HeaderCommand(headerText)); + commandQueue.AddCommand(new Command.SetHeader(headerText)); } /** @@ -188,7 +348,7 @@ namespace Fungus public static void Footer(string footerText) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.FooterCommand(footerText)); + commandQueue.AddCommand(new Command.SetFooter(footerText)); } /** @@ -201,7 +361,7 @@ namespace Fungus public static void Say(string storyText) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.SayCommand(storyText)); + commandQueue.AddCommand(new Command.Say(storyText)); } /** @@ -214,7 +374,7 @@ namespace Fungus public static void AddOption(string optionText, Action optionAction) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.AddOptionCommand(optionText, optionAction)); + commandQueue.AddCommand(new Command.AddOption(optionText, optionAction)); } /** @@ -226,7 +386,7 @@ namespace Fungus public static void AddOption(string optionText) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.AddOptionCommand(optionText, delegate {})); + commandQueue.AddCommand(new Command.AddOption(optionText, delegate {})); } /** @@ -246,7 +406,7 @@ namespace Fungus public static void Choose(string chooseText) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.ChooseCommand(chooseText)); + commandQueue.AddCommand(new Command.Choose(chooseText)); } #endregion @@ -261,7 +421,7 @@ namespace Fungus public static void SetValue(string key, int value) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.SetValueCommand(key, value)); + commandQueue.AddCommand(new Command.SetValue(key, value)); } /** @@ -376,7 +536,7 @@ namespace Fungus CommandQueue commandQueue = Game.GetInstance().commandQueue; Color color = spriteRenderer.color; color.a = targetAlpha; - commandQueue.AddCommand(new Command.FadeSpriteCommand(spriteRenderer, color, duration, slideOffset)); + commandQueue.AddCommand(new Command.FadeSprite(spriteRenderer, color, duration, slideOffset)); } /** @@ -391,7 +551,7 @@ namespace Fungus public static void ShowButton(Button button, Action buttonAction) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.ShowButtonCommand(button, true, buttonAction)); + commandQueue.AddCommand(new Command.ShowButton(button, true, buttonAction)); } /** @@ -402,7 +562,7 @@ namespace Fungus public static void HideButton(Button button) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.ShowButtonCommand(button, false, null)); + commandQueue.AddCommand(new Command.ShowButton(button, false, null)); } /** @@ -415,7 +575,7 @@ namespace Fungus public static void SetAnimatorTrigger(Animator animator, string triggerName) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.SetAnimatorTriggerCommand(animator, triggerName)); + commandQueue.AddCommand(new Command.SetAnimatorTrigger(animator, triggerName)); } #endregion @@ -429,7 +589,7 @@ namespace Fungus public static void PlayMusic(AudioClip audioClip) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.PlayMusicCommand(audioClip)); + commandQueue.AddCommand(new Command.PlayMusic(audioClip)); } /** @@ -438,7 +598,7 @@ namespace Fungus public static void StopMusic() { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.StopMusicCommand()); + commandQueue.AddCommand(new Command.StopMusic()); } /** @@ -458,7 +618,7 @@ namespace Fungus public static void SetMusicVolume(float musicVolume, float duration) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.SetMusicVolumeCommand(musicVolume, duration)); + commandQueue.AddCommand(new Command.SetMusicVolume(musicVolume, duration)); } /** @@ -480,7 +640,7 @@ namespace Fungus public static void PlaySound(AudioClip audioClip, float volume) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.PlaySoundCommand(audioClip, volume)); + commandQueue.AddCommand(new Command.PlaySound(audioClip, volume)); } #endregion diff --git a/Assets/Fungus/Scripts/Page.cs b/Assets/Fungus/Scripts/Page.cs index e5104067..d27dbdf4 100644 --- a/Assets/Fungus/Scripts/Page.cs +++ b/Assets/Fungus/Scripts/Page.cs @@ -14,18 +14,21 @@ namespace Fungus [ExecuteInEditMode] public class Page : MonoBehaviour { - /// Rectangular bounds used to display page text - public Bounds pageBounds = new Bounds(Vector3.zero, new Vector3(0.25f, 0.25f, 0f)); - - /// Page position within bounds when display height is less than bounds height - public enum VerticalAlign + /// Page alignment options + public enum Layout { - Top, - Middle, - Bottom + /// Use the full rect to display the page. + FullSize, + /// Resize to fit displayed text and snap to top of rect. + FitToTop, + /// Resize to fit displayed text and snap to middle of rect. + FitToMiddle, + /// Resize to fit displayed text and snap to bottom of rect. + FitToBottom } - public VerticalAlign verticalAlign = VerticalAlign.Middle; + /// Page position within bounds when display height is less than bounds height. + public Layout layout = Layout.FullSize; string headerText = ""; string footerText = ""; @@ -62,6 +65,26 @@ namespace Fungus float quickContinueTimer; + Rect pageRect; // Screen space rect for Page in pixels + + /** + * Set the screen rect in normalized screen space coords. + * The origin is at the top left of the screen. + */ + public void SetPageRect(float x1, float y1, float x2, float y2) + { + pageRect.xMin = Screen.width * x1; + pageRect.yMin = Screen.height * y1; + pageRect.xMax = Screen.width * x2; + pageRect.yMax = Screen.height * y2; + + // 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); + } + public virtual void Update() { if (quickContinueTimer > 0) @@ -179,6 +202,11 @@ namespace Fungus } } + public bool FinishedWriting() + { + return (displayedStoryText.Length == originalStoryText.Length); + } + public virtual void OnGUI() { if (mode == Mode.Idle) @@ -199,8 +227,7 @@ namespace Fungus GUIStyle optionStyle = pageStyle.GetScaledOptionStyle(); GUIStyle optionAlternateStyle = pageStyle.GetScaledOptionAlternateStyle(); - Rect pageRect = GetScreenRect(); - Rect outerRect = FitRectToScreen(pageRect); + Rect outerRect = pageRect; Rect innerRect = CalcInnerRect(outerRect); // Calculate height of each section @@ -211,31 +238,35 @@ namespace Fungus float contentHeight = headerHeight + footerHeight + storyHeight + optionsHeight; // Adjust outer rect position based on alignment settings - switch (verticalAlign) + switch (layout) { - case VerticalAlign.Top: + 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 = pageRect.yMin; break; - case VerticalAlign.Middle: + case Layout.FitToMiddle: outerRect.height = contentHeight + (boxStyle.padding.top + boxStyle.padding.bottom); outerRect.y = pageRect.center.y - outerRect.height / 2; break; - case VerticalAlign.Bottom: + case Layout.FitToBottom: outerRect.height = contentHeight + (boxStyle.padding.top + boxStyle.padding.bottom); outerRect.y = pageRect.yMax - outerRect.height; break; } - // Force outer rect to always be on-screen - // If the rect is bigger than the screen, then the top-left corner will always be visible - outerRect = FitRectToScreen(outerRect); - innerRect = CalcInnerRect(outerRect); // Draw box Rect boxRect = outerRect; boxRect.height = contentHeight + (boxStyle.padding.top + boxStyle.padding.bottom); + if (layout == Layout.FullSize) + { + boxRect.height = Mathf.Max(boxRect.height, pageRect.height); + } GUI.Box(boxRect, "", boxStyle); // Draw header label @@ -261,20 +292,15 @@ namespace Fungus GUI.Label(footerRect, footerText, footerStyle); } - bool finishedWriting = (displayedStoryText.Length == originalStoryText.Length); - if (!finishedWriting) + if (!FinishedWriting()) { return; } + // Input handling + if (mode == Mode.Say) { - ContinueStyle continueStyle = Game.GetInstance().continueStyle; - if (continueStyle != null) - { - DrawContinueButton(outerRect); - } - // Player can continue by clicking anywhere if (quickContinueTimer == 0 && (Input.GetMouseButtonUp(0) || Input.anyKeyDown) && @@ -437,19 +463,6 @@ namespace Fungus return totalHeight; } - // Force rect to always be on-screen - Rect FitRectToScreen(Rect rect) - { - Rect fittedRect = new Rect(); - - fittedRect.xMax = Mathf.Min(rect.xMax, Screen.width); - fittedRect.xMin = Mathf.Max(rect.xMin, 0); - fittedRect.yMax = Mathf.Min(rect.yMax, Screen.height); - fittedRect.yMin = Mathf.Max(rect.yMin, 0); - - return fittedRect; - } - // Returns smaller internal box rect with padding style applied Rect CalcInnerRect(Rect outerRect) { @@ -469,80 +482,5 @@ namespace Fungus return innerRect; } - - /** - * Returns the page rect in screen space coords - */ - public Rect GetScreenRect() - { - // Y decreases up the screen in GUI space, so top left is rect origin - - Vector3 topLeft = transform.position + pageBounds.center; - topLeft.x -= pageBounds.extents.x; - topLeft.y += pageBounds.extents.y; - - Vector3 bottomRight = transform.position + pageBounds.center; - bottomRight.x += pageBounds.extents.x; - bottomRight.y -= pageBounds.extents.y; - - Camera mainCamera = GameObject.FindGameObjectWithTag("MainCamera").camera; - Vector2 tl = mainCamera.WorldToScreenPoint(topLeft); - Vector2 br = mainCamera.WorldToScreenPoint(bottomRight); - - Rect pageRect = new Rect(tl.x, Screen.height - tl.y, br.x - tl.x, tl.y - br.y); - - return FitRectToScreen(pageRect); - } - - void DrawContinueButton(Rect containerRect) - { - PageStyle pageStyle = Game.GetInstance().activePageStyle; - ContinueStyle continueStyle = Game.GetInstance().continueStyle; - - if (pageStyle == null || - continueStyle == null) - { - return; - } - - GUIStyle style = continueStyle.style; - if (style == null) - { - return; - } - - GUIContent content = new GUIContent(continueStyle.continueText); - GUIStyle scaledContinueStyle = continueStyle.GetScaledContinueStyle(); - - Rect continueRect; - - if (continueStyle.onPage) - { - float width = scaledContinueStyle.CalcSize(content).x; - float height = scaledContinueStyle.lineHeight; - float x = containerRect.xMin + (containerRect.width) - (width) - pageStyle.boxStyle.padding.right; - float y = containerRect.yMax - height / 2f; - continueRect = new Rect(x, y, width, height); - } - else - { - Vector2 size = scaledContinueStyle.CalcSize(content); - - float x = Screen.width * continueStyle.screenPosition.x; - float y = Screen.height * continueStyle.screenPosition.y; - float width = size.x; - float height = size.y; - - x = Mathf.Max(x, continueStyle.padding.x); - x = Mathf.Min(x, Screen.width - width - continueStyle.padding.x); - - y = Mathf.Max(y, continueStyle.padding.y); - y = Mathf.Min(y, Screen.height - height - continueStyle.padding.y); - - continueRect = new Rect(x, y, width, height); - } - - GUI.Label(continueRect, content, scaledContinueStyle); - } } } \ No newline at end of file diff --git a/Assets/Fungus/Scripts/Parallax.cs b/Assets/Fungus/Scripts/Parallax.cs index c893281e..056f1e0b 100644 --- a/Assets/Fungus/Scripts/Parallax.cs +++ b/Assets/Fungus/Scripts/Parallax.cs @@ -12,7 +12,7 @@ namespace Fungus /** * Scale factor for calculating the parallax offset. */ - public float parallaxFactor; + public Vector2 parallaxScale = new Vector2(0.1f, 0.1f); Vector3 startPosition; @@ -51,8 +51,8 @@ namespace Fungus return; } - Vector3 offset = Game.GetInstance().GetParallaxOffset(parallaxFactor); - + Vector3 offset = Game.GetInstance().GetParallaxOffset(parallaxScale); + // Set new position for sprite transform.position = startPosition + offset; } diff --git a/Assets/Fungus/Scripts/Room.cs b/Assets/Fungus/Scripts/Room.cs index 046589bb..573a834e 100644 --- a/Assets/Fungus/Scripts/Room.cs +++ b/Assets/Fungus/Scripts/Room.cs @@ -108,11 +108,9 @@ namespace Fungus Game game = Game.GetInstance(); CameraController cameraController = game.gameObject.GetComponent(); - // Pick first view found in the room and snap to camera to this view. // It is allowed for a room to not have any views. - // In this case game.activeView will be null, and the camera will attempt - // to snap to the room sprite. + // In this case the camera will attempt to snap to the room sprite. View view = gameObject.GetComponentInChildren(); if (view == null) { @@ -130,14 +128,9 @@ namespace Fungus else { // Snap to new view - cameraController.SnapToView(view); - game.activeView = view; + cameraController.PanToPosition(view.transform.position, view.viewSize, 0, null); } - // Pick first page found in room - // It is allowed for a room to not have any pages. In this case game.activePage will be null - game.activePage = gameObject.GetComponentInChildren(); - // Hide all buttons in the room before entering // Buttons must always be made visible using a ShowButton() command Button[] buttons = game.activeRoom.GetComponentsInChildren