Custom action using enum when playing a dialog entry
-
- Posts: 7
- Joined: Wed Jan 13, 2021 6:28 am
Custom action using enum when playing a dialog entry
Hello !
I'm currently experimenting with the Dialogue system and I'm trying to play an animation when hitting a specifig dialog entry in my dialog. Problem : I can't use the AnimatorPlay lua sequence command because we're using a third party animation system (Animancer). We also use an enum EPlayerAnimation that our LDs use to select animations from a specific list. For example, in my timeline I have an animation clip that look like this :
I wonder what would be the best way to allow that kind of edition when editing a dialog entry. I thought about creating my own lua sequence command but if I understand correctly I can't have an enum as a parameter. I tried using an OnExecute event too but I have the same problem, I can't use an enum (I'm pretty new to Unity, maybe there's a trick I don't know)
How would you do this ?
Thanks
I'm currently experimenting with the Dialogue system and I'm trying to play an animation when hitting a specifig dialog entry in my dialog. Problem : I can't use the AnimatorPlay lua sequence command because we're using a third party animation system (Animancer). We also use an enum EPlayerAnimation that our LDs use to select animations from a specific list. For example, in my timeline I have an animation clip that look like this :
I wonder what would be the best way to allow that kind of edition when editing a dialog entry. I thought about creating my own lua sequence command but if I understand correctly I can't have an enum as a parameter. I tried using an OnExecute event too but I have the same problem, I can't use an enum (I'm pretty new to Unity, maybe there's a trick I don't know)
How would you do this ?
Thanks
Re: Custom action using enum when playing a dialog entry
Hi,
Thanks for checking out the Dialogue System!
I'll outline some different approaches. If one of them sounds interesting to you, I can describe it in more detail.
1. Write a custom sequencer command that uses a string. For example, the dialogue entry's Sequence field might look like:
The sequencer command would roughly look like:
This is the quickest to implement, but the downside is that it depends on string names instead of the actual enum values.
2. Or you can add a custom field to the dialogue entry template. Custom fields can have their owner drawers, which can use a dropdown:
Then you can add an OnConversationLine that checks this field and, if set, plays the corresponding animation through Animancer.
3. Or you can change your PlayerPuppeteerAnimationClip script to use ScriptableObjects as extensible enums instead of using a C# enum. For example, your ScriptableObject might look like:
with ScriptableObject assets in your project named Crouch, Idle, Walk, etc.
The relevant code in your PlayerPuppeteerAnimationClip script might be changed to:
Then you can use dialogue entry nodes' OnExecute() UnityEvents, and assign the desired ScriptableObject asset.
Thanks for checking out the Dialogue System!
I'll outline some different approaches. If one of them sounds interesting to you, I can describe it in more detail.
1. Write a custom sequencer command that uses a string. For example, the dialogue entry's Sequence field might look like:
The sequencer command would roughly look like:
Sequencer command
Code: Select all
public class SequencerCommandPlayAnimancer : SequencerCommand
{
void Awake()
{
var enumStringName = GetParameter(0); // First parameter is text name of enum.
var playerPuppeteerAnimationClip = GetSubject(1, speaker); // Second param is object with PlayerPuppeteeerAnimationClip (defaults to node's speaker).
foreach (var enumValue in Enum.GetValues(typeof(AnimEnum)))
{
if (enumStringName == enumValue.ToString())
{
playerPuppeteerAnimationClip.Play(enumValue);
break;
}
}
Stop();
}
}
2. Or you can add a custom field to the dialogue entry template. Custom fields can have their owner drawers, which can use a dropdown:
Then you can add an OnConversationLine that checks this field and, if set, plays the corresponding animation through Animancer.
3. Or you can change your PlayerPuppeteerAnimationClip script to use ScriptableObjects as extensible enums instead of using a C# enum. For example, your ScriptableObject might look like:
Code: Select all
[CreateAssetMenu] public class AnimancerClip : ScriptableObject
{
public AnimationClip animationClip;
}
The relevant code in your PlayerPuppeteerAnimationClip script might be changed to:
Code: Select all
public void Play(AnimancerClip animancerClip)
{
_Animancer.Play(animancerClip.animcationClip);
}
-
- Posts: 7
- Joined: Wed Jan 13, 2021 6:28 am
Re: Custom action using enum when playing a dialog entry
Wow, thanks for your time.
I think I will explore the solution 2, In order to avoid to create too many scriptable objects. I will keep you in touch when it will work.
Thanks a lot !
I think I will explore the solution 2, In order to avoid to create too many scriptable objects. I will keep you in touch when it will work.
Thanks a lot !
Re: Custom action using enum when playing a dialog entry
Glad to help! Option 2 is the most complex to write, but it's the "nicest" solution since you can show a dropdown for the exact enum that your script uses. Look at the example custom field type scripts in Plugins / Pixel Crushers / Dialogue System / Templates / Scripts / Editor and in Plugins / Pixel Crushers / Dialogue System / Scripts / Editor / Fields / Examples. (The one in Scripts / Editor / Fields / Examples might be the closest to your needs.)
-
- Posts: 7
- Joined: Wed Jan 13, 2021 6:28 am
Re: Custom action using enum when playing a dialog entry
I didn't saw your answer but I did used The TypeScene example, it was indeed quite close to my need
When you're talking about using a "OnConversationLine", is that in a script I would need to add to the GameObject holding my dialogue (let's name it the Dialogue Provider) ? To a script attached to the GameObject "speaking" to my dialogue provider ? Or is that a field I don't find on the conversation ?
Sorry if I'm a bit lost ^^
When you're talking about using a "OnConversationLine", is that in a script I would need to add to the GameObject holding my dialogue (let's name it the Dialogue Provider) ? To a script attached to the GameObject "speaking" to my dialogue provider ? Or is that a field I don't find on the conversation ?
Sorry if I'm a bit lost ^^
Re: Custom action using enum when playing a dialog entry
I forgot to provide a link. Here it is: Script Messages
You can add it to the "speaker" or to the Dialogue Manager GameObject. An example on the Dialogue Manager GameObject:
You can add it to the "speaker" or to the Dialogue Manager GameObject. An example on the Dialogue Manager GameObject:
Code: Select all
// This method is called when a dialogue entry is shown:
void OnConversationLine(Subtitle subtitle)
{
// Check if the entry has an Animancer field value:
string fieldValue = Field.LookupValue(subtitle.dialogueEntry.fields, "Animancer");
if (!string.IsNullOrEmpty(fieldValue))
{
// If so, convert it to an enum value and play it:
AnimationEnum enumValue = (AnimationEnum)SafeConvert.ToInt(enumValue);
PlayerPuppeteerAnimationClip ppac = subtitle.speakerInfo.transform.GetComponent<PlayerPuppeteerAnimationClip>();
ppac.Play(enumValue);
}
}
-
- Posts: 7
- Joined: Wed Jan 13, 2021 6:28 am
Re: Custom action using enum when playing a dialog entry
Thanks a lot
I'm amazed by your work and your reactivity, keep up the good work !
I'm amazed by your work and your reactivity, keep up the good work !
Re: Custom action using enum when playing a dialog entry
Thanks! Glad to help.
-
- Posts: 7
- Joined: Wed Jan 13, 2021 6:28 am
Re: Custom action using enum when playing a dialog entry
Hello.
Just for your information I finally decided to make it work by mixing solution 1 and 2 : I have a custom field with my animation enum and then a sequencer command that uses this field. That way I avoid to create a new script and LDs can play the animation whenever they want.
Just for your information I finally decided to make it work by mixing solution 1 and 2 : I have a custom field with my animation enum and then a sequencer command that uses this field. That way I avoid to create a new script and LDs can play the animation whenever they want.
Re: Custom action using enum when playing a dialog entry
Sounds good! BTW, I don't know if this will be any additional help, but you can also use shortcuts in sequences.