Custom Actor Implementations

Posted: 08 Jul 2020 14:57
by Nysalie

Hi again! This is part of my ongoing chat system project. One of the goals is to be able to send photos in messages as well.

For the messaging I'm using a TextPrinter similar to the Chat printer. Now the problem with using textprinters is that they are, well text printers, they aren't supposed to be used for images.

I must say that I already implemented this in a CustomUI to be used as a kind of message log, the conversation history, however I would also like to send photos in a regular text printer in order to take advantage of the continue conversation by clicking functionality and also have the visual goodies like delayed message with the dots being printed while someone is "typing", etc. Essentially the CustomUI is to check previous messages and the TextPrinter is to advance the story.

In theory, I just need an extra property in the UITextPrinterPanel that stores a PhotoId string passed from a SendMessage Command via PrinterManager.PrintTextAsync() on ExecuteAsync() of an altered PrintText command (this is the reason I need a new actor implementation, to pass the extra argument on PrintTextAsync()). That PhotoId will be referenced by a method when a Message is instantiated and the corresponding photo Sprite will be fetched with a resource provider. I had a look at ITextPrinterActor and followed references until I believe have found all the relevant connections to make it work.

The problem is that I don't want to touch the framework's asset files, so I copied the files I deemed necessary and made my changes to new similar classes. Now that I've implemented them into my printer's panel class, Unity is throwing me an "actor implementation type for ITextPrinterActorPhoto is not found", it comes from the ActorManager.cs:211 class. I followed the calls and it goes into ReflectionUtils cached domains. This is where i'm at a lost. Tried several stuff but I'm still not sure how to fix this. The files are inside the base Naninovel>Runtime>Actor>TextPrinter folder, in a subfolder called "PhotoImplementation" just so I don't mix them up. The namespace is the default from the files they were copied from (either Naninovel or Naninovel.UI).

Just for exposition sake these are the files I've copied/changed:
Runtime > Actor > TextPrinter - ITextPrinterActor, ITextPrinterManager, PrintTextArgs, TextPrinterManager, TextPrinterState, UITextPrinter
Runtime > UI > TextPrinter - UITextPrinterPanel

I'm not sure if this is a general C#, Unity or Naninovel related issue and my searches lead me nowhere so I must resort to the forum to get help. Hopefully this could also be useful in the future for someone trying to achieve similar things.


Re: Custom Actor Implementations

Posted: 08 Jul 2020 15:42
by Elringus

It's hard to tell what's wrong without a repro. I can investigate this, if you share a repro project (https://naninovel.com/support/#reproduction-project) via a PM in Discord.


Re: Custom Actor Implementations

Posted: 08 Jul 2020 15:44
by Elringus

By the way, did you consider injecting attached images ID to the text messages, similar to how TMPro handles embed sprites? This way you won't have to make any custom actors.


Re: Custom Actor Implementations

Posted: 08 Jul 2020 16:25
by Nysalie

I know it's complicated to debug stuff in the dark like this but i don't feel it's necessary to bother you (even more) with a repro and I think i've found a plausible explanation to this problem.

It's because i'm trying to call a text printer with a custom UITextPrinterPanel (i appended "Photo" to all the files/classes I changed so it's now called UITextPrinterPanelPhoto), the problem is that we can only assign UITextPrinterPanel's in the TextPrinter resources. This means that my Messaging text printer prefab was removed and can't be added to the TextPrinter settings resource panel. I probably need to tweak TextPrinterSettings class in the Editor assembly and add my own UITextPrinterPanel, just need to figure out how to do it without breaking even more stuff.

Do you mean using the images as TMPro sprites? I've done that with emojis and it works but I would like to be able to manage the resources via a "Phone" configuration and use the resource provider to grab the sprite, like i'm doing on the log thing. I'll do some research into inline sprites for text, that might be a simpler solution.


Re: Custom Actor Implementations

Posted: 08 Jul 2020 18:09
by Elringus

Not exactly, I mean include references to the photo resources you need in the text messages and extract them when parsing the message. Eg, you may have the following message with a photo in a naninovel script:

Code: Select all

Here is my photo! <photo>PhotoResourceId</photo>

In the printer you then extract all the photo tags and replace them with sprites.


Re: Custom Actor Implementations

Posted: 08 Jul 2020 18:32
by Nysalie

Ah I see, I was actually looking at making custom rich text tags with TMP but that approach is more intuitive and probably easier to implement.
A bit of regex should do the trick.

I've also ditched the custom actor idea, I would end up needing to essentially create a new TextPrinter category in the settings to support the new metadata and whatnot, that was just asking for trouble in the future I'm sure, plus I'm not comfortable messing with the framework at that level yet.