Forum rules - please read before posting.

Blendshapes options for blendshape call via [expression:Name] in "Dialogue:Play speech"

Hi!

Is there any way to have same options for blendshape call via [expression:Name] like in "Object:Blend shape"?

I mean to control "New value" and "Transition time" of the blendshape through tokens in the Line Text.

Beacause when i call blendshape now, it has automatically value 100 and it is very quick and unnatural..

Thanks!
Jakub

Comments

  • You can do this by defining a custom speech event token, which allow you to create custom [key:value] tokens in speech text.

    See the Manual's "Speech event tokens" chapter for more details.

    If you're always setting the same group/key, you can set the token's key to be the new value, and the value to be the transition time.

    These are both strings, so you'll have to convert them in your OnSpeechToken function. Something like this:

    private void OnSpeechToken (AC.Char speakingCharacter, int lineID, string tokenKey, string tokenValue)
    {
        float shapeValue = 0f;
        float transitionTime = 0f;
        if (float.TryParse (tokenKey, out shapeValue) && float.TryParse (tokenValue, out transitionTime))
        {
            int shapeGroupID = 0; // Set group here
            int shapeKeyID = 0; // Set key here
    
            Shapeable shapeable = speakingCharacter.GetComponentInChildren <Shapeable>();
            shapeable.SetActiveKey (shapeGroupID, shapeKeyID, shapeValue, transitionTime, MoveMethod.Smooth, null);
        }
    }
    
  • Thanks for the fast answer and the code, will try it!
    Jakub

  • Do I have to edit AC's function "Call_OnSpeechToken" in EventManager.cs as above?

    But I don't set up always same group\key, I want to set diferent shapes (keys), is it possible?

    Is it possible to set custom speech token similar to this: [Smile01:50:10] which means shape key "Smile01", value 50 (just a half) and 10 seconds transition.

    Thanks,
    Jakub

  • edited April 2020

    Do I have to edit AC's function "Call_OnSpeechToken" in EventManager.cs as above?

    No - this is an event hook, which means you can paste it into a custom script, and hook it up to the event system so that it gets triggered every time that event is fired. In this case, it's the OnSpeechToken event.

    The Manual chapter I mentioned above details how to use such hooks, but a more general tutorial on custom events can be found here.

    But I don't set up always same group\key, I want to set diferent shapes (keys), is it possible?

    The above was just a basic example. You can parse the token value to extract whatever data you want from it.

    For example, using the format [shape:group_key_value_transition], where:

    • shape is the token key (don't change this)
    • group is replaced by the group ID
    • key is replaced by the label of the key within that group
    • value is replaced by the new value
    • transition is replaced by the transition time

    So, your example would have the format [shape:0_Smile01_50_10] (where "0" is the group ID).

    At the moment, it's necessary to refer to groups by their ID number - but I'll look to extend this by allowing referral by label as well.

    Anyway, here's a full script that should process this format:

    using UnityEngine;
    using AC;
    
    public class ShapeableTokens : MonoBehaviour
    {
    
        private void OnEnable () { EventManager.OnSpeechToken += OnSpeechToken; }
    
        private void OnDisable () { EventManager.OnSpeechToken -= OnSpeechToken; }
    
        private void OnSpeechToken (AC.Char speakingCharacter, int lineID, string tokenKey, string tokenValue)
        {
            if (tokenKey == "shape")
            {
                string[] valueArray = tokenValue.Split ("_"[0]);
                if (valueArray.Length == 4)
                {
                    int groupID = 0;
                    string keyName = valueArray[1];
                    float value = 0f;
                    float transition = 0f;
    
                    if (int.TryParse (valueArray[0], out groupID) &&
                        float.TryParse (valueArray[2], out value) &&
                        float.TryParse (valueArray[3], out transition))
                    {
                        Shapeable shapeable = speakingCharacter.GetComponentInChildren <Shapeable>();
                        shapeable.SetActiveKey (groupID, keyName, value, transition, MoveMethod.Smooth, null);
                    }
                }
            }
        }
    
    }
    
  • Thank you very much! Will try it!
    Jakub

  • It doesnt work:-(

    1. On my Player prefab I have shapeable component with group 0:Smiles and one shape key inside it 0:Smile01
    2. On my Player prefab I checked "Use expressions" and "Map to shapeable" in the Player script. Here is also Expression shape group "0:Smiles" and iside it Expression #0 : Smile01
    3. Created C sharp script "ShapeableTokens" with your code above and attached it on GameObject in the scene

    Then, when I run "Dialogue:Play speech" and put inside [shape:0_Smile01_50_10], it doesnt work. When I put inside [expression:0_Smile01_50_10], it doesnt work too.

    When I put inside [wait:1] or [expression:Smile01] it works, so generally tokens are working, but not as we want.

    Am I doing anything wrong please?

    Thanks,
    Jakub

  • You just need to define the speech event token itself.

    using UnityEngine;
    using AC;
    
    public class ShapeableTokens : MonoBehaviour
    {
    
        private void OnEnable ()
        {
            KickStarter.dialog.SpeechEventTokenKeys = new string[1] { "shape" };
            EventManager.OnSpeechToken += OnSpeechToken;
        }
    
        private void OnDisable () { EventManager.OnSpeechToken -= OnSpeechToken; }
    
        private void OnSpeechToken (AC.Char speakingCharacter, int lineID, string tokenKey, string tokenValue)
        {
            if (tokenKey == "shape")
            {
                string[] valueArray = tokenValue.Split ("_"[0]);
                if (valueArray.Length == 4)
                {
                    int groupID = 0;
                    string keyName = valueArray[1];
                    float value = 0f;
                    float transition = 0f;
    
                    if (int.TryParse (valueArray[0], out groupID) &&
                        float.TryParse (valueArray[2], out value) &&
                        float.TryParse (valueArray[3], out transition))
                    {
                        Shapeable shapeable = speakingCharacter.GetComponentInChildren <Shapeable>();
                        shapeable.SetActiveKey (groupID, keyName, value, transition, MoveMethod.Smooth, null);
                    }
                }
            }
        }
    
    }
    
  • It's working now! Thank you again @ChrisIceBox !
    Jakub

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.