From ed1e48b2e7ef17c0ff4a7b618830a88b7988b62b Mon Sep 17 00:00:00 2001 From: chrisgregan Date: Thu, 26 Jun 2014 16:40:37 +0100 Subject: [PATCH] Added rotation support to Views. --- Assets/Fungus/Editor/ViewEditor.cs | 61 +++++++++--------- Assets/Fungus/Scripts/CameraController.cs | 25 +++++-- .../Fungus/Scripts/Commands/CameraCommands.cs | 8 ++- Assets/Fungus/Scripts/GameController.cs | 12 ++-- Assets/Fungus/Scripts/Room.cs | 2 +- Assets/Fungus/Scripts/View.cs | 8 ++- Assets/FungusExample/Scenes/Example.unity | Bin 96152 -> 96392 bytes Assets/FungusExample/Scripts/ViewRoom.cs | 9 --- 8 files changed, 71 insertions(+), 54 deletions(-) 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 fe13dda6c5f4dee22534d0e43bafa91ab249f69a..e9b38cb6ac2a1ea09d35e8a4f0c631e1c8aa293f 100644 GIT binary patch delta 3959 zcmaKv3s6&68pqEE0iqC+n4lnu#S$b4WkPr)Y>j|rmEr>w*W#lR1T@ZoJjMrVCFyEg z`m)%&or|{4(uY%Lc8j=a4eNBK%x-swneDW6b*F5ntITe+GJ@LiN zxsTsD=llNOh>0cn1#UJM4_u}hVaozjd07HEZn}N5q#-!m`fCH#Or8wXm#9=8X=ek zYSjxlc-}KZBeW!>k|i{o5o-+1%m{{OE+ovN%+Sm?bHg*ep_w?rqsjJPKk{kxtKJyl zj|Yt*T@(6j|3|MyGD+(j(+v??V+F$u1I-HAy<2Up@WPDb`>Kt5HTm974x3DOI5C?o z4{%~O>x2)?)9>#{$eK0jDbccObJLFbY&))HOf9tQ4T7&MNjUrK68+CJ3z!-;?+&(!+oysnK6)klav zGAx{R#7?VkXlQC~>S%3g+S=4n(@@{sBv4k0|8GYgSA`l*+n+SqaFWpd{hB+xP4p+- z+gqqfr9EB8^!E);6AJ&vG3|ZY5Bs(C+Zs2wu4rv-2_^TQ&FDWfuxb%C3WehhR3RK3 zufp})aX&5bAHGpS8LBA8zKsr#nGLxQ4;dJ1L7_+(OM#joPf0~$>=)m2K znGvu~JfD_F{rnjC4#K5y!GsI82>#@YK0tPgA$Y(;2z8M^@J$zp6D zzztc19L~=Yg9hvm%jW*?O0`G(O(9u zUL0BA{b0Rdyunw%bW6elmAK!(R=M5-#vfxJfQ?41!`FBM(6*GZYN%6AwE&n8jCXQ+ z^D}kh65|RJ{EKr#8#eNtbp>n$Oe%~b<|>$Vd1SZU>R7#@+Y9LA3^we$(J)jKS?NZw zQdpB3<%*pCCNLiu?_?v`C;*@SO<=lTMF#TeU(amp29tW(tJL^2K=rEd8KS5jkrsmS z20sTI0^>9DcQEG@j5WewP!{;Zx?7$;Fg`Qaz*udBXfL}CSPSUJX63B8aMIZ_2v!fK z2)qcEhQo(!LidHiazeFaG&h>F%w+{ZRZ+N2Wku3K^qf zrecX&e0m9G1kR+=ej>G)S4pW+g-kq|Lo)+UnW;xZ@c~UX1*FM0w@@Z-uI-d5`l{e< zIEO5-@+9-nI~vgZ}p^YioUVo5e-={4~1NUqJ6XLs833!FuT;sF;KM4O3nM3Wgo ztjxt_&_s=5p9=<)Gs!5rb8rd0_RdvaeQwP57pl>k^}p4sZ^`J z*4^dWZ9IB1@QI6l7lp)imXcK^zEe(VfuV9LCt30AhbVn&J|x@n95!dMI6s@_iaHa; zP01@RC@OH+^NIs)3uzvuqgX7r5EuDRjeF_$@3A=C+d7)0e>%k0DoPTE7a_Oj7Ex(* zxEi*_WO}z^F~x*mtEi)T%gl_=FPx478pbmZHM^TkUmXnnYhnPOWGp31jV zn)HPJKnmmUmMrCTT@5bHHRMOO(pJ*C7;Vmm1+J_U-jYwgtSfoutwrLCtLXqG1k7vb z72-yD2ItoUG-+SvQCooh;nK2M?t})#6Z5zp| F|3B*iFZ}=j delta 3831 zcmb7{e^gWF8OPrT0*2p#gcdZ^kb=glF##mWCM8a)R9k+CRmxDKh(HgP9|eg{4d=8~ zJ9SNaT`%>t-MY4C{814b*K2pq&S9I~_+v-oq?@P5cAU-aFk2zITB#G=_a^tky)$h$ z&Up!Z-uHRF&#(99+=JKR`X=IZj1oR()YHcpOTgcule(SpqzeokI3Jt5v*nqVt`%+F zPj@j5*D+tu*^VS~b%}cJqeGiGcXB+pu_%c<_i7p$xpZ?L*JLzsgR9cHzM}^0rg9sS z(r9jY$8s#ZL%H0^Bs-bI?A`GcE+;9A^1yPriex?Ihq+@Sh4Y=5C3>Ry*vsZVOn!hY z;l0z?gAMmd_;VJwJY`{E-e5VsH+O#w*W0W4=7>+GFAOvtI~)7$Cz0FB=6G)LeJN2> z6E{;^+nU0)JElPK9n%Sa*IrnGWlWlsEo;!5^{}BmCMq~6axP%-X_ma^NrOMgZ zn-^94NY1xuzj0rD+)iY+oC_Xm5c~YHSr;{cRBn$sT8p!}39~+$c);`EYaM}0>HlL7 z#Q93w(fv$I!;03H_Hd!2P1?*H{&yQt>%g*OY4L&EM&yhweX_V8w2V0RPB`k|2kx9$ zzlxfO8ick3{X|zSCgfbe~B3TXKZB6Zm^pB^o;Gmlmds>955}HdrM#9 zF)&sJdh71pyPf#V!A?Jz7k`gPYsFGwk~EShVqAU7V2^tQ^s}N*;5=cGxnMy*1ecq+&3H)J7;E^#f<>^CU?&3(Zrlhf>M@FlCq%U_)TgNSz*?3s;iLv$*9``jSZ(W4jbCDi%Du z+WQ^GYQesc5L!%X&;LGSc$=X1~Z3jR}3|+^VfqPu4ZCX0RC%#;$`6fq9@IU#O|hC%2k>Q2hhy zEO)=*xvv^R)#^@f18c{_!wutWQu!Of2Emjf+rhLo>hd>%xxu`!9g)`A-+j9MG?+Nc zKDo!|0G;qAK11Zu35o~7l>Iyp76MZ`{3BTN6O1*(HY5f3Mg3HB5KMXJZh+a=tAh5i zF98n%dSEP<=JQ`VcZ`8;0h0r~3Rbm2Ej$i342F27gWkmq?WS7BUQpQX1{(x3fuXqJ z^#ibAE&4A)G3&@Ow1=dF^?|3f2pz^!K+56Wx1x#{e5 zV7ey8pglbw*K7W<*9#U52bdhm#{6{hzVfGpm9dne<%2n-;cJtqO!#RM{hWvi!^%)_hQnCc1EGyN@Z!hsen@X#3hs=jFb=;gOHouWRW8Cmyt<0RYq=- z{3jM#3vEt^t)QTgKU+;pl8TEQ#jfHa*HXp=&q`WGsfkdu7TH}6XK{gjDPLiw+5G4# zh+ck*7V#zv#R)m(q>qi{Zd(I|b!+Ihq*zsj|GTOXa71x|w!r2paJmZZqMkL;Zne2w zMRt3!UAR+68N^#^Xc>R8hKziuh6IG)zmDqh${GIYE!}QeTl)M5ha)BAZFSTYm!K+1 zE2W6Q>T(rA#Nptp7ttJkxSo>viz~>)hw7;>9ID2=VlxT;jTDNBgx>2Rn{diQ55__D NVq>J=o+h%S{|AHk`&j@0 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