diff --git a/Assets/Fungus/Editor/ViewEditor.cs b/Assets/Fungus/Editor/ViewEditor.cs index 7dc23bdd..f7903368 100644 --- a/Assets/Fungus/Editor/ViewEditor.cs +++ b/Assets/Fungus/Editor/ViewEditor.cs @@ -8,6 +8,7 @@ using Fungus; [CustomEditor (typeof(View))] public class ViewEditor : Editor { + // Draw Views when they're not selected [DrawGizmo(GizmoType.NotSelected)] static void RenderCustomGizmo(Transform objectTransform, GizmoType gizmoType) { @@ -34,22 +35,19 @@ public class ViewEditor : Editor void EditViewBounds() { - View t = target as View; - - DrawView(t); + View view = target as View; - Vector3 pos = t.transform.position; - float viewSize = t.viewSize; + DrawView(view); - Vector3 newViewPos = Handles.PositionHandle(pos, Quaternion.identity); + Vector3 pos = view.transform.position; - t.transform.position = newViewPos; + float viewSize = CalculateLocalViewSize(view); Vector3[] handles = new Vector3[2]; - handles[0] = pos + new Vector3(0, -viewSize, 0); - handles[1] = pos + new Vector3(0, viewSize, 0); + handles[0] = view.transform.TransformPoint(new Vector3(0, -viewSize, 0)); + handles[1] = view.transform.TransformPoint(new Vector3(0, viewSize, 0)); - Handles.color = t.primaryColor; + Handles.color = view.primaryColor; for (int i = 0; i < 2; ++i) { @@ -60,8 +58,8 @@ public class ViewEditor : Editor Handles.CubeCap); if (newPos != handles[i]) { - Undo.RecordObject(t, "Changed view size"); - t.viewSize = Mathf.Abs(newPos.y - pos.y); + Undo.RecordObject(view, "Changed view size"); + view.viewSize = (newPos - pos).magnitude; break; } } @@ -69,21 +67,17 @@ public class ViewEditor : Editor public static void DrawView(View view) { - Vector3 pos = view.transform.position; - float viewSize = view.viewSize; - - float height = viewSize; + float height = CalculateLocalViewSize(view); float widthA = height * view.primaryAspectRatio; float widthB = height * view.secondaryAspectRatio; // Draw left box { - Vector3[] verts = new Vector3[4]; - verts[0] = pos + new Vector3(-widthB, -height, 0); - verts[1] = pos + new Vector3(-widthB, height, 0); - verts[2] = pos + new Vector3(-widthA, height, 0); - verts[3] = pos + new Vector3(-widthA, -height, 0); + verts[0] = view.transform.TransformPoint(new Vector3(-widthB, -height, 0)); + verts[1] = view.transform.TransformPoint(new Vector3(-widthB, height, 0)); + verts[2] = view.transform.TransformPoint(new Vector3(-widthA, height, 0)); + verts[3] = view.transform.TransformPoint(new Vector3(-widthA, -height, 0)); Handles.DrawSolidRectangleWithOutline(verts, view.secondaryColor, view.primaryColor ); } @@ -91,10 +85,10 @@ public class ViewEditor : Editor // Draw right box { Vector3[] verts = new Vector3[4]; - verts[0] = pos + new Vector3(widthA, -height, 0); - verts[1] = pos + new Vector3(widthA, height, 0); - verts[2] = pos + new Vector3(widthB, height, 0); - verts[3] = pos + new Vector3(widthB, -height, 0); + verts[0] = view.transform.TransformPoint(new Vector3(widthA, -height, 0)); + verts[1] = view.transform.TransformPoint(new Vector3(widthA, height, 0)); + verts[2] = view.transform.TransformPoint(new Vector3(widthB, height, 0)); + verts[3] = view.transform.TransformPoint(new Vector3(widthB, -height, 0)); Handles.DrawSolidRectangleWithOutline(verts, view.secondaryColor, view.primaryColor ); } @@ -102,12 +96,19 @@ public class ViewEditor : Editor // Draw center box { Vector3[] verts = new Vector3[4]; - verts[0] = pos + new Vector3(-widthA, -height, 0); - verts[1] = pos + new Vector3(-widthA, height, 0); - verts[2] = pos + new Vector3(widthA, height, 0); - verts[3] = pos + new Vector3(widthA, -height, 0); - + verts[0] = view.transform.TransformPoint(new Vector3(-widthA, -height, 0)); + verts[1] = view.transform.TransformPoint(new Vector3(-widthA, height, 0)); + verts[2] = view.transform.TransformPoint(new Vector3(widthA, height, 0)); + verts[3] = view.transform.TransformPoint(new Vector3(widthA, -height, 0)); + Handles.DrawSolidRectangleWithOutline(verts, new Color(1,1,1,0f), view.primaryColor ); } } + + // Calculate view size in local coordinates + // Kinda expensive, but accurate and only called in editor. + static float CalculateLocalViewSize(View view) + { + return view.transform.InverseTransformPoint(view.transform.position + new Vector3(0, view.viewSize, 0)).magnitude; + } } diff --git a/Assets/Fungus/Scripts/CameraController.cs b/Assets/Fungus/Scripts/CameraController.cs index 223eaadc..530bdff3 100644 --- a/Assets/Fungus/Scripts/CameraController.cs +++ b/Assets/Fungus/Scripts/CameraController.cs @@ -46,6 +46,7 @@ namespace Fungus class CameraView { public Vector3 cameraPos; + public Quaternion cameraRot; public float cameraSize; }; @@ -84,11 +85,17 @@ namespace Fungus } } + /** + * Perform a fullscreen fade over a duration. + */ public void Fade(float targetAlpha, float fadeDuration, Action fadeAction) { StartCoroutine(FadeInternal(targetAlpha, fadeDuration, fadeAction)); } + /** + * Fade out, move camera to view and then fade back in. + */ public void FadeToView(View view, float fadeDuration, Action fadeAction) { swipePanActive = false; @@ -97,7 +104,7 @@ namespace Fungus Fade(0f, fadeDuration / 2f, delegate { // Snap to new view - PanToPosition(view.transform.position, view.viewSize, 0f, null); + PanToPosition(view.transform.position, view.transform.rotation, view.viewSize, 0f, null); // Fade in Fade(1f, fadeDuration / 2f, delegate { @@ -162,7 +169,7 @@ namespace Fungus /** * 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) + public void PanToPosition(Vector3 targetPosition, Quaternion targetRotation, float targetSize, float duration, Action arriveAction) { swipePanActive = false; @@ -171,6 +178,7 @@ namespace Fungus // Move immediately Camera.main.orthographicSize = targetSize; Camera.main.transform.position = targetPosition; + Camera.main.transform.rotation = targetRotation; SetCameraZ(); if (arriveAction != null) { @@ -179,7 +187,7 @@ namespace Fungus } else { - StartCoroutine(PanInternal(targetPosition, targetSize, duration, arriveAction)); + StartCoroutine(PanInternal(targetPosition, targetRotation, targetSize, duration, arriveAction)); } } @@ -190,6 +198,7 @@ namespace Fungus { CameraView currentView = new CameraView(); currentView.cameraPos = Camera.main.transform.position; + currentView.cameraRot = Camera.main.transform.rotation; currentView.cameraSize = Camera.main.orthographicSize; storedViews[viewName] = currentView; } @@ -215,6 +224,7 @@ namespace Fungus { // Move immediately Camera.main.transform.position = cameraView.cameraPos; + Camera.main.transform.rotation = cameraView.cameraRot; Camera.main.orthographicSize = cameraView.cameraSize; SetCameraZ(); if (arriveAction != null) @@ -224,17 +234,19 @@ namespace Fungus } else { - StartCoroutine(PanInternal(cameraView.cameraPos, cameraView.cameraSize, duration, arriveAction)); + StartCoroutine(PanInternal(cameraView.cameraPos, cameraView.cameraRot, cameraView.cameraSize, duration, arriveAction)); } } - IEnumerator PanInternal(Vector3 targetPos, float targetSize, float duration, Action arriveAction) + IEnumerator PanInternal(Vector3 targetPos, Quaternion targetRot, float targetSize, float duration, Action arriveAction) { float timer = 0; float startSize = Camera.main.orthographicSize; float endSize = targetSize; Vector3 startPos = Camera.main.transform.position; Vector3 endPos = targetPos; + Quaternion startRot = Camera.main.transform.rotation; + Quaternion endRot = targetRot; bool arrived = false; while (!arrived) @@ -250,6 +262,7 @@ namespace Fungus float t = timer / duration; 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)); + Camera.main.transform.rotation = Quaternion.Lerp(startRot, endRot, Mathf.SmoothStep(0f, 1f, t)); SetCameraZ(); if (arrived && @@ -330,7 +343,7 @@ namespace Fungus Vector3 targetPosition = CalcCameraPosition(cameraPos, swipePanViewA, swipePanViewB); float targetSize = CalcCameraSize(cameraPos, swipePanViewA, swipePanViewB); - PanToPosition(targetPosition, targetSize, duration, delegate { + PanToPosition(targetPosition, Quaternion.identity, targetSize, duration, delegate { swipePanActive = true; diff --git a/Assets/Fungus/Scripts/Commands/CameraCommands.cs b/Assets/Fungus/Scripts/Commands/CameraCommands.cs index d98c9f9d..3b932c6f 100644 --- a/Assets/Fungus/Scripts/Commands/CameraCommands.cs +++ b/Assets/Fungus/Scripts/Commands/CameraCommands.cs @@ -31,7 +31,7 @@ namespace Fungus { Game game = Game.GetInstance(); - game.cameraController.PanToPosition(view.transform.position, view.viewSize, 0, null); + game.cameraController.PanToPosition(view.transform.position, view.transform.rotation, view.viewSize, 0, null); if (onComplete != null) { @@ -46,12 +46,14 @@ namespace Fungus public class PanToPosition : CommandQueue.Command { Vector3 targetPosition; + Quaternion targetRotation; float targetSize; float duration; - public PanToPosition(Vector3 _targetPosition, float _targetSize, float _duration) + public PanToPosition(Vector3 _targetPosition, Quaternion _targetRotation, float _targetSize, float _duration) { targetPosition = _targetPosition; + targetRotation = _targetRotation; targetSize = _targetSize; duration = _duration; } @@ -62,7 +64,7 @@ namespace Fungus game.waiting = true; - game.cameraController.PanToPosition(targetPosition, targetSize, duration, delegate { + game.cameraController.PanToPosition(targetPosition, targetRotation, targetSize, duration, delegate { game.waiting = false; diff --git a/Assets/Fungus/Scripts/GameController.cs b/Assets/Fungus/Scripts/GameController.cs index 75927b6c..0a162f42 100644 --- a/Assets/Fungus/Scripts/GameController.cs +++ b/Assets/Fungus/Scripts/GameController.cs @@ -141,7 +141,7 @@ namespace Fungus */ public static void PanToView(View targetView, float duration) { - PanToPosition(targetView.transform.position, targetView.viewSize, duration); + PanToPosition(targetView.transform.position, targetView.transform.rotation, targetView.viewSize, duration); } /** @@ -149,17 +149,20 @@ namespace Fungus * 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 targetPosition The position to pan the camera to. + * @param targetRotation The rotation to pan the camera to. + * @param targetSize The orthographic size 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) + public static void PanToPosition(Vector3 targetPosition, Quaternion targetRotation, float targetSize, float duration) { CommandQueue commandQueue = Game.GetInstance().commandQueue; - commandQueue.AddCommand(new Command.PanToPosition(targetPosition, targetSize, duration)); + commandQueue.AddCommand(new Command.PanToPosition(targetPosition, targetRotation, targetSize, duration)); } /** * Pans the camera through a sequence of target Views over a period of time. + * Note: Does not support camera Rotation. * 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. * If more control is required over the camera path then you should instead use an Animator component to precisely control the Camera path. @@ -167,6 +170,7 @@ namespace Fungus * @param duration The length of time in seconds needed to complete the pan. * @param targetViews A parameter list of views to visit during the pan. */ + [Obsolete("Use a Camera animation instead.")] public static void PanToPath(float duration, params View[] targetViews) { CommandQueue commandQueue = Game.GetInstance().commandQueue; diff --git a/Assets/Fungus/Scripts/Room.cs b/Assets/Fungus/Scripts/Room.cs index c6953858..d07ec1fa 100644 --- a/Assets/Fungus/Scripts/Room.cs +++ b/Assets/Fungus/Scripts/Room.cs @@ -145,7 +145,7 @@ namespace Fungus else { // Snap to new view - cameraController.PanToPosition(view.transform.position, view.viewSize, 0, null); + cameraController.PanToPosition(view.transform.position, view.transform.rotation, view.viewSize, 0, null); } // Hide all buttons in the room before entering diff --git a/Assets/Fungus/Scripts/View.cs b/Assets/Fungus/Scripts/View.cs index 355de855..56f06d4c 100644 --- a/Assets/Fungus/Scripts/View.cs +++ b/Assets/Fungus/Scripts/View.cs @@ -12,7 +12,7 @@ namespace Fungus public class View : MonoBehaviour { /** - * Orthographic size of the camera view. + * Orthographic size of the camera view in world space coordinates. */ public float viewSize = 0.5f; @@ -37,5 +37,11 @@ namespace Fungus * Color of the secondary view rectangle. */ public Color secondaryColor = Color.grey; + + void Update() + { + // Disable scaling to avoid complicating the orthographic size calculations + transform.localScale = new Vector3(1,1,1); + } } } \ No newline at end of file diff --git a/Assets/FungusExample/Scenes/Example.unity b/Assets/FungusExample/Scenes/Example.unity index fe13dda6..e9b38cb6 100644 Binary files a/Assets/FungusExample/Scenes/Example.unity and b/Assets/FungusExample/Scenes/Example.unity differ diff --git a/Assets/FungusExample/Scripts/ViewRoom.cs b/Assets/FungusExample/Scripts/ViewRoom.cs index 4249784c..ec25ed76 100644 --- a/Assets/FungusExample/Scripts/ViewRoom.cs +++ b/Assets/FungusExample/Scripts/ViewRoom.cs @@ -17,7 +17,6 @@ namespace Fungus.Example AddOption("Lets look at the logo", LookLogo); AddOption("That's a nice toadstool over there", LookToadstool); - AddOption ("Give me the full tour", FullTour); AddOption("Back to menu", MoveToMenu); Say("Wanna move the camera?"); @@ -43,13 +42,5 @@ namespace Fungus.Example Say("Hey - let's go look at that logo"); Call(LookLogo); } - - void FullTour() - { - Say("Let's have a look around here"); - PanToPath(10f, logoView, toadstoolView, mainView); - Say("And we're back!"); - Call(OnEnter); - } } } \ No newline at end of file