How to Make DIalogue Manager NOT Load All Portraits

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
RX-310
Posts: 22
Joined: Tue Jan 21, 2020 7:50 pm

How to Make DIalogue Manager NOT Load All Portraits

Post by RX-310 »

I noticed that the Dialogue Manager loads every single portrait set on the database on start, and since the portraits I'm using are in high-ish resolution they take a lot of memory. How to make Dialogue Manager load only certain portraits (i.e the ones that are used on current level) instead of all of them?
User avatar
Tony Li
Posts: 21925
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to Make DIalogue Manager NOT Load All Portraits

Post by Tony Li »

Hi,

You can either use multiple databases or put the portraits in assetbundles and use SetPortrait() to set them. If you want to test SetPortrait() first, you can put the portraits in a Resources folder.

In a future version (not 2.2.5, which is wrapping up testing, but I think 2.2.6), you'll be able to use addressables. Without addressables, the way Unity works is that if a scene or asset references any other assets, Unity loads those referenced assets, too.

EDIT: Or use Dialogue Actor components, and assign the portrait to the Dialogue Actor instead of the database.
RX-310
Posts: 22
Joined: Tue Jan 21, 2020 7:50 pm

Re: How to Make DIalogue Manager NOT Load All Portraits

Post by RX-310 »

When 2.2.6 coming out? We're using addressable with our project. And will it be compatible with database created from 2.1.4?
User avatar
Tony Li
Posts: 21925
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to Make DIalogue Manager NOT Load All Portraits

Post by Tony Li »

Version 2.2.5 will be out very soon. I'll try to keep you updated when when 2.2.6 is coming out. You may need to reassign your actors' portraits to be able to use addressables, but otherwise your database will be compatible with 2.1.4.

However, I completely forgot to mention that there's a way you can handle this right now:

Add a Dialogue Actor component to each of your actors. (You can use empty GameObjects if your actors don't already have GameObjects.) Assign the actor's portrait to the Dialogue Actor's Sprite Portrait field. Then unassign the portraits in the dialogue database. Unity will only load portrait images for actors that are in the scene.
RX-310
Posts: 22
Joined: Tue Jan 21, 2020 7:50 pm

Re: How to Make DIalogue Manager NOT Load All Portraits

Post by RX-310 »

I tried to use Dialogue Actor, but i see that it replaced our current actor in entry (instead of validating if the dialogue actor has the same name with current entry actor, then change portrait to dialogue).

For example, let's say i have Anne and John talking.
Previously, the default case should be like this :
(Every portraits registered in Database)
First entry Anne talk to John. Portrait still Anne.
Second entry John talk to Anne. Portrait changed to John.
Third entry Anne talk back to John. Portrait changed to Anne.

Then i removed John and Anne's portraits from Database,
When i put Dialogue Actor to Anne GameObject, set string Actor to "Anne" and Anne's Portrait, every entries become Anne's name and Anne's Portrait.
I saw that it supposed to replace the Actor in the entry, but is there anyway to replace portraits only for corresponding Actor(s) in the dialogue entry?

My expected case is if I put Dialogue Actor to John GameObject later, set string Actor to "John" and John's Portrait, so it would back to the default case.
User avatar
Tony Li
Posts: 21925
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to Make DIalogue Manager NOT Load All Portraits

Post by Tony Li »

This was addressed in a patch shortly after version 2.2.4 came out. Here's a copy of the patch:

DS_ActorPatch_2020-01-02.unitypackage

It added the ability to use Dialogue Actor portraits on additional actors (not just those assigned as the conversation's primary participants), and lets you assign Sprites or Texture2Ds, since version 2.2.4 and earlier only let you assign Texture2Ds.

Here's a test scene:

DS_TestDialogueActorPortraits_2020-03-05.unitypackage

This is also in version 2.2.5, of course, which completed QA and should be available on the Asset Store by early next week.
RX-310
Posts: 22
Joined: Tue Jan 21, 2020 7:50 pm

Re: How to Make DIalogue Manager NOT Load All Portraits

Post by RX-310 »

Thanks for the update, but now I'm having a problem with NGUI integration. I got an error that the NGUI Subtitle Controls uses UITexture type for the portrait, but now that the database's speaker type has been changed to sprite - is there any workaround to fix this?

Also for the AbstractConverterWindow, I see prefs.conversationName has been removed, is it safe to bring it back? Since I'm using it to set the conversation name on my custom csv import tool.
User avatar
Tony Li
Posts: 21925
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to Make DIalogue Manager NOT Load All Portraits

Post by Tony Li »

RX-310 wrote: Fri Mar 06, 2020 4:39 amThanks for the update, but now I'm having a problem with NGUI integration. I got an error that the NGUI Subtitle Controls uses UITexture type for the portrait, but now that the database's speaker type has been changed to sprite - is there any workaround to fix this?
Can you please post the error? I just tested this and it seems to work fine. I added a UITexture to the example dialogue UI's NPC Subtitle Panel and assigned it to the dialogue UI's Dialogue > Npc Subtitle > Portrait Image field. Then I added a Dialogue Actor to Private Hart, selected his Actor from the dropdown, and assigned a sprite to the Portrait(Sprite) field.
RX-310 wrote: Fri Mar 06, 2020 4:39 amAlso for the AbstractConverterWindow, I see prefs.conversationName has been removed, is it safe to bring it back? Since I'm using it to set the conversation name on my custom csv import tool.
Yes. It's just a starter. You can define conversationName in your own subclass. Then override the LoadPrefs() and SavePrefs() methods to save additional information. For example:

Code: Select all

protected override void SavePrefs()
{
    base.SavePrefs();
    EditorPrefs.SaveString("convName"Key, conversationName);
}
BTW, the NGUIDialogueUI gets the sprite's texture by calling sprite.texture. If this isn't available for some reason, you can use a method like this to make a texture from the sprite:

Code: Select all

public static Texture2D textureFromSprite(Sprite sprite)
{
    if (sprite.rect.width == sprite.texture.width)
    {
        return sprite.texture;
    }
    else
    {
        Texture2D texture = new Texture2D((int)sprite.rect.width,(int)sprite.rect.height);
        Color[] colors = sprite.texture.GetPixels((int)sprite.textureRect.x, (int)sprite.textureRect.y, (int)sprite.textureRect.width, (int)sprite.textureRect.height);
        texture.SetPixels(newColors);
        texture.Apply();
        return texture;
    }
 }
RX-310
Posts: 22
Joined: Tue Jan 21, 2020 7:50 pm

Re: How to Make DIalogue Manager NOT Load All Portraits

Post by RX-310 »

Got the portrait UITexture to work but I ran into another problem:

I'm getting weird case using this condition. I saw on your Test Scene and it worked perfectly.
But not on my scene.
Here's my Case :
I put Dialogue Actor in Anne with Anne's Portrait and Anne's Name.
Also put Dialogue Actor in John with John's Portrait and John's Name.
I have Dialogue :
[Case 1] Anne to John : Anne - Hi I'm Anne.
[Case 2] John to Anne : John - Hello Anne, I'm John.
[Case 3] Anne to John : Anne - Nice to meet you, John.
In my Condition, Every Anne's Portrait, become John's. So Case 1 and Case 3, shows John's Portrait instead of Anne.
And In Case 2, It showed Anne's Portrait.
[Case 1] Anne to John : John - Hi I'm Anne.
[Case 2] John to Anne : Anne - Hello Anne, I'm John.
[Case 3] Anne to John : John - Nice to meet you, John.
I did 2 tests to see what happened,
First, i changed John's Dialogue Actor to someone else, let's say Paul (runtime).
Now Every Anne become Paul Portrait, and the name also Changed to Paul. But not for John.
No matter what, it will change Anne, eventhough i tested Dialogue Actor's name with everyone, it changed Anne to Everyone.
Second, i changed Paul to the conversation, and changed John GameObject Dialogue Actor name a Paul,
the conversation is correct as expected, All Paul changed to John's Portrait.
[Case 1] Anne to Paul : Anne - Hi I'm Anne.
[Case 2] Paul to Anne : Paul - Hello Anne, I'm John.
[Case 3] Anne to Paul : Anne - Nice to meet you, John.
I changed to other Actor beside of Anne and John, and also using Dialogue Actor Gameobject to set their portraits,
everyone works perfectly, except for those two. In my Actors, Anne's ID is 2, John's ID is 3.
Why John keep changing Anne's Actor in Dialogue instead of John, or Anne keep changing John. It just happened between both of them.
Here's some of my settings :
- John is instantiated from prefab, so Dialogue Actor in John is set from prefab. (I changed the dialogue actor runtime anyway, it's still the same)
- I'm not ticking Don't destroy on load
- I instantiated Database (Duplicate Database), so i can modify Actor later without modifying my original database (but i don't change the entry for anne and john in the test)
User avatar
Tony Li
Posts: 21925
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to Make DIalogue Manager NOT Load All Portraits

Post by Tony Li »

Hi,

Would it be possible for you to send a reproduction project to tony (at) pixelcrushers.com?

You can zip up the Assets, ProjectSettings, and Packages folder. I won't need any other files or folders.
Post Reply