fungus

Open full view…

Change SayDialog dynamically based on device orientation

technobabel
Mon, 25 Mar 2019 15:13:00 GMT

I have a script that switches between two SayDialogs depending on the orientation of the player's device. The script works. The SayDialogue does change. However, it will only change when the player taps to move on to the next Narrative Say Command. For example, if the player is reading the text in Landscape, then turns the device to Portrait, the current text will still be displayed in in the Landscape SayDialog. When the player taps to move on, the new text will display in the Portrait SayDialog. Is there a way to force the SayDialog to change immediately upon the player turn the device while still displaying the same text? This is the script: public SayDialog portraitSD; public SayDialog landscapeSD; void Update() { // Detect the orientation of the device to change the SayDialogue display ChangeSD(); } void ChangeSD() { if (Input.deviceOrientation == DeviceOrientation.Portrait) { SayDialog.ActiveSayDialog = portraitSD; } else { SayDialog.ActiveSayDialog = landscapeSD; } }

wolfrug
Tue, 26 Mar 2019 15:22:32 GMT

Yeah, hm. This is more complex. Yikes. Not sure if this is possible without lightly editing the default Say command, or using some other magic. You do know you can make a say dialog that works both vertical and horizontal by messing around wth the canvas, anchors, etc? It probably won't be quite as pretty as a bespoke vertical/horizontal one, but you can get pretty far!

technobabel
Tue, 26 Mar 2019 21:56:14 GMT

Hm... Since I'm not a wizard, I'll look into making a single duel/multipurpose SayDialog. Sounds like that might be the best way to go. Thanks for the advice!

Steve Halliwell
Wed, 27 Mar 2019 05:17:22 GMT

As Wolfrug mentioned, it would be possible to change the way the canvas in the say prefab is setup and then use the existing Unity UI anchors and layout elements to make this workable in both layouts. If you want two separate layouts, I'd look at changing how the saydialogue or the possibly writer operates. Giving it more than 1 panel to target and then enable/disable the panels that don't meet conditions like deviceOrientation. That way you know all panels have the correct information just only 1 of them is every visible.

technobabel
Mon, 13 May 2019 20:26:29 GMT

I thought I'd update this while I'm here... I did as wolfrug suggested and the SayDialog seemed to fit perfectly in portrait and landscape. However, a new iteration on the way text and dialog are presented demanded more from the SayDialog. So, instead of trying to swap between two SDs, my script detects the orientation and adjusts the anchors. This works immediately and is much smoother. --- void Update() { if (Input.deviceOrientation == DeviceOrientation.Portrait) { StartCoroutine(ChangeUIAnchors(0, 0, 1, -0.6f)); } else if (Input.deviceOrientation == DeviceOrientation.LandscapeLeft || Input.deviceOrientation == DeviceOrientation.LandscapeRight) { StartCoroutine(ChangeUIAnchors(0.7f, 0, 1, 0)); } } IEnumerator ChangeUIAnchors(float minX, float minY, float maxX, float maxY) { yield return new WaitForSeconds(0.2f); sdText.anchorMin = new Vector2(minX, minY); sdText.anchorMax = new Vector2(maxX, maxY); yield break; } --- Thanks for all of the suggestions. I learned a lot about Unity UI.