Displaying Different Portrait Sizes Correctly

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
PandaBOX
Posts: 8
Joined: Fri Aug 23, 2019 1:56 am

Displaying Different Portrait Sizes Correctly

Post by PandaBOX »

Hello there! :D

I'm using the VN dialogue template prefab.
I have a few character portraits that are varying in sizes for different characters. Currently, the portraits squish to the size of the set portrait image for "Subtitle Panel 1". I would like to display the native size for each different character when they appear in dialogue. How would I go about this?
User avatar
Tony Li
Posts: 20647
Joined: Thu Jul 18, 2013 1:27 pm

Re: Displaying Different Portrait Sizes Correctly

Post by Tony Li »

Hi,

You can add this script to the image. Make sure to set the image's pivot point in the Sprite Editor. If you're using the VN template, the pivot point should be the bottom center of the image.

SetNativeSizeOnEnable.cs

Code: Select all

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class SetNativeSizeOnEnable : MonoBehaviour
{
    private void OnEnable()
    {
        StartCoroutine(SetNativeSize());
    }

    IEnumerator SetNativeSize()
    {
        yield return new WaitForEndOfFrame();
        var image = GetComponent<Image>();
        if (image != null) image.SetNativeSize();
    }
}
PandaBOX
Posts: 8
Joined: Fri Aug 23, 2019 1:56 am

Re: Displaying Different Portrait Sizes Correctly

Post by PandaBOX »

Thanks for taking the time to help!

I've attached the script to the Portrait Image, but I can't seem to make it work. The image is still squished to the portrait image size set in the inspector. Let me know if I should send any files or examples.
Attachments
I placed the script here on the portrait image.
I placed the script here on the portrait image.
convo2.PNG (3.12 KiB) Viewed 1240 times
This is what the test convo structure looks like. The blue is the player. The green and pink are the NPC's. Both taking up &quot;Subtitle Panel 0&quot; space when they appear.
This is what the test convo structure looks like. The blue is the player. The green and pink are the NPC's. Both taking up "Subtitle Panel 0" space when they appear.
convo.PNG (34.71 KiB) Viewed 1240 times
User avatar
Tony Li
Posts: 20647
Joined: Thu Jul 18, 2013 1:27 pm

Re: Displaying Different Portrait Sizes Correctly

Post by Tony Li »

Here's an example: PortraitNativeSizeExample_2019-08-23.unitypackage

In the example, I named the script UseNativeSizeOnEnable.cs so it wouldn't conflict if you have SetNativeSizeOnEnable in your project.

Private Hart has a Dialogue Actor component with a large portrait image. When you talk to him, it will set the Portrait Image size to 227 x 256.

If you talk to the Terminal, it will set the Portrait Image to 128 x 128.

The script also logs when it changes the image size:

UseNativeSizeOnEnable: Using native image size on Portrait Image

If you use the script in your own scene, make sure it logs this message. (You can delete the message from the script once you've confirmed that it works.)
PandaBOX
Posts: 8
Joined: Fri Aug 23, 2019 1:56 am

Re: Displaying Different Portrait Sizes Correctly

Post by PandaBOX »

I appreciate the help!
I've added the script to my scene, and the message does go through. But it's still not working in the way I want it to. The portraits still get squished to the set inspector size. Would it be alright to send over an example scene?
User avatar
Tony Li
Posts: 20647
Joined: Thu Jul 18, 2013 1:27 pm

Re: Displaying Different Portrait Sizes Correctly

Post by Tony Li »

Sure! You can send it to tony (at) pixelcrushers.com. If possible, zip up the entire Assets, ProjectSettings, and Packages folders; or export the required files (scene, maybe UI prefab) in a unitypackage and let me know what version of Unity to import it in.
User avatar
Tony Li
Posts: 20647
Joined: Thu Jul 18, 2013 1:27 pm

Re: Displaying Different Portrait Sizes Correctly

Post by Tony Li »

I replied to your email, but for others' reference in the future, this script will set portraits to their native resolution without Unity 2019.1 issues. (In 2019.1, Image.SetNativeResolution() sets the Image's Rect Transform, but it doesn't actually resize the visual representation of the sprite.) Add it to your dialogue UI.

SetNativeSizeOnLine.cs

Code: Select all

using UnityEngine;
using UnityEngine.UI;
using PixelCrushers.DialogueSystem;

// Add this to your Dialogue UI to make portrait images use their native sizes.
public class SetNativeSizeOnLine : MonoBehaviour
{
    private StandardDialogueUI ui;
    private float canvasPPU;


    private void OnConversationStart(Transform actor)
    {
        ui = DialogueManager.dialogueUI as StandardDialogueUI;
        var scaler = ui.GetComponentInParent<CanvasScaler>();
        canvasPPU = (scaler != null) ? scaler.referencePixelsPerUnit : -1; // We use -1 to mean no PPU set.
    }

    private void OnConversationLine(Subtitle subtitle)
    {
        UpdatePortraitImage(subtitle.speakerInfo);
        UpdatePortraitImage(subtitle.listenerInfo);
    }

    private void UpdatePortraitImage(PixelCrushers.DialogueSystem.CharacterInfo characterInfo)
    {
        if (ui == null) return;

        // Assume we use the default subtitle panel for PC or NPC:
        var panel = characterInfo.isNPC ? ui.conversationUIElements.defaultNPCSubtitlePanel : ui.conversationUIElements.defaultPCSubtitlePanel;
        var image = panel.portraitImage;

        // Set the portrait image's size:
        var sprite = characterInfo.portrait;
        if (sprite == null) return;
        var ppuScaleFactor = (canvasPPU <= 0) ? 1 : (canvasPPU / sprite.pixelsPerUnit);
        image.sprite = sprite;
        image.GetComponent<RectTransform>().sizeDelta = ppuScaleFactor * new Vector2(sprite.rect.width, sprite.rect.height);

        // Then clear and reassign the portrait image's sprite. This will force Unity UI to properly resize
        // the visible representation of the sprite within the image component's Rect Transform.
        image.sprite = null;
        image.sprite = sprite;
    }

}
EDIT: Updated to also take image's Pixels Per Unit into account, and to update both speaker and listener.
Post Reply