Paper Doll Sprites

Using Naninovel C# APIs: adding custom actor implementations or commands, overriding engine services, integrating with other systems, etc.
Post Reply
Vitriolic_Crux
Posts: 8
Joined: 15 Jul 2022 04:09

Paper Doll Sprites

Post by Vitriolic_Crux »

Hello! I am a RenPy dev who is very new to Unity, and I am trying to implement the mechanisms similar to the ones I created in Python in C# and Unity.

I am trying to implement a paper-doll-styled sprite in Naninovel that is similar to how I had implemented it in RenPy. Essentially, I had an ordered list of sprite assets that would each be shown or hidden based on logical conditions.

I understand that the LayeredCharacter implementation allows for something similar to this, but from my understanding it is not as dynamic as what I need. In my game, a character's outfit is generated and set based on in-game TOD, their current activity, and other various stats. Instead of setting the Character's elements within the Naninovel script, I'm wondering if there is a C# statement equivalent that would allow me to dynamically set their displayed elements based on generated conditions.

In essence, is there a way to do this:

Code: Select all

@char Miho.Body>Uniform

using C# code instead of a Naninovel command?

I'm thinking maybe something like Miho.ApplyComposition("Body>Uniform"), but I thought I should come here for a quick sanity check, or to see if this whole thing is hopeless and I should just come up with a jury-rigged solution.

idaot
support
Posts: 275
Joined: 01 Aug 2020 08:25

Re: Paper Doll Sprites

Post by idaot »

For a non-C# solution, I suggest storing the data in custom variables: https://naninovel.com/guide/custom-vari ... -variables

In terms of C#, it's possible to instantiate any command and manually invoke it, you can see an example in the Integration Options guide where a custom command (@novel, in other words SwitchToNovelMode) is being executed in C#: https://naninovel.com/guide/integration ... hing-modes

Vitriolic_Crux
Posts: 8
Joined: 15 Jul 2022 04:09

Re: Paper Doll Sprites

Post by Vitriolic_Crux »

So I've gone ahead and tried what I proposed. I'm able to control the shown sprite elements from another class, but the changes that I make aren't being reflected after the sprite has already been shown.

Code: Select all

public class NPC_Controller : MonoBehaviour
{
    public string Name;
    public LayeredCharacterBehaviour Sprite;

public bool Hoodie = false;
public bool Shorts = false;

void Update()
{
    Sprite.ApplyComposition("Body>Base");

    if (Hoodie)
    {
        Sprite.ApplyComposition("Body+Hoodie");
    }
    if (Shorts)
    {
        Sprite.ApplyComposition("Body+Shorts");
    }
}
}

Before the sprite is shown and the game is still on the Start menu, I can make any changes I want. Then whatever configuration I have set is reflected when the sprite is shown after the game starts. So if I say Hoodie = true; before the sprite is shown, then when I do show the sprite, the hoodie appears.

But if I make changes after the sprite is already shown, those changes are not reflected. So if I say Hoodie = false; after the sprite is shown, the hoodie remains. And if I say Shorts = true;, the shorts do not appear.

This makes me think there is some method I need to be calling to trigger a re-draw or re-render of the sprite. This is especially confusing to me because I've enabled Animated in the prefab script which is supposed to mean that the sprite gets redrawn every frame. Any idea what I'm doing wrong?

Vitriolic_Crux
Posts: 8
Joined: 15 Jul 2022 04:09

Re: Paper Doll Sprites

Post by Vitriolic_Crux »

Alright, so I found the problem. My NPC_Controller.Sprite was tied to the prefab of the character, not the actual instance.

Code: Select all

public class NPC_Controller : MonoBehaviour
{
    public string Name;
    private LayeredCharacterBehaviour Sprite;

public bool Hoodie = false;
public bool Shorts = false;

void Update()
{
    if (Sprite == null)
    {
        Sprite = GameObject.Find(Name + "LayeredPrefab").GetComponent<LayeredCharacterBehaviour>();
    }
    else
    {
        Sprite.ApplyComposition("Body>Base");

        if (Hoodie)
        {
            Sprite.ApplyComposition("Body+Hoodie");
        }
        if (Shorts)
        {
            Sprite.ApplyComposition("Body+Shorts");
        }
    }
}
}

It throws a bunch of errors before I hit start and the instance is created, but I don't think I should be super worried about that since I'm not particularly concerned about performance on the main menu. But I'd definitely love to hear any thoughts about what's considered best practice in these situations. Is there a way I can pause the calls to Update() temporarily? I might also be able to dig deeper into the main menu button functions and hook the creation of the NPC_Controller GameObject into whatever's creating the Prefab instances.

idaot
support
Posts: 275
Joined: 01 Aug 2020 08:25

Re: Paper Doll Sprites

Post by idaot »

I don't recommend using Update() in these instances. If you plan to change the composition values via C# then consider using a method to trigger the change. I also suggest studying C# concepts like getters and setters.

Post Reply