Forum rules - please read before posting.

Skin Setter script - update change help

So, I have a new script in my game which is in scene called ACSpineExpressions, which I use to control mouth shapes in Spine at random for my player when speaking:

using UnityEngine;
using System.Collections;
using AC;
using Spine.Unity;
using AC.Spine;
using Timers;

public class ACSpineExpressions : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        InvokeRepeating(nameof(UpdateMouth), 0.1f, 0.2f);
    }

    // Update is called once per frame
    void Update()
    {
        if (speakingCharacter)
        {
            //if (speakingCharacter.isTalking)
            //    Debug.Log("Character: " + speakingCharacter + " isTalking");
        }
    }

    void UpdateMouth()
    {
        if (!skeletonAnimation)
            return;

        if (speakingCharacter && speakingCharacter.isTalking)
        {
            if (Random.Range(0, 100) < 70)
            {
                //skeletonAnimation.AnimationState.SetAnimation(0, "asd", true);
                //skeletonAnimation.AnimationState.AddAnimation(0, "idle", true, 0);

                //skeletonAnimation.Skeleton.SetAttachment("mouth shapes", "o");
                var attachment = skeletonAnimation.Skeleton.FindSlot("mouth shapes");

                if (attachment != null)
                {
                    Debug.Log("blah");

                    switch (Utils.RandomInt(1, 6))
                    {
                        case 1: skeletonAnimation.Skeleton.SetAttachment("mouth shapes", "a, i"); break;
                        //case 2: skeletonAnimation.Skeleton.SetAttachment("mouth shapes", "c,-d,-g,-k,-n,-r,-s,-y,-z"); break;
                        case 3: skeletonAnimation.Skeleton.SetAttachment("mouth shapes", "e"); break;
                        //case 3: skeletonAnimation.Skeleton.SetAttachment("mouth shapes", "f,-v"); break;
                        //case 5: skeletonAnimation.Skeleton.SetAttachment("mouth shapes", "l,-th"); break;  
                        //case 6: skeletonAnimation.Skeleton.SetAttachment("mouth shapes", "m,-b,-p"); break;  
                        case 4: skeletonAnimation.Skeleton.SetAttachment("mouth shapes", "o"); break;  
                        //case 5: skeletonAnimation.Skeleton.SetAttachment("mouth shapes", "q,-w"); break;  
                        case 5: skeletonAnimation.Skeleton.SetAttachment("mouth shapes", "u"); break;  
                    }

                    //clear mouth
                    TimersManager.SetTimer(gameObject, 0.15f, 0, delegate
                    {                     
                        skeletonAnimation.Skeleton.SetAttachment("mouth shapes", "mouth");
                    });

                 }
                else
                {
                    Debug.Log("NO MOUTH SHAPES FOR THIS POSE!");
                }

            }
        }
    }

    void OnEnable()
    {
        EventManager.OnStartSpeech += GetSpeech;
        EventManager.OnStopSpeech += OnStopSpeech;
     }
    void OnDisable()
    {
        EventManager.OnStartSpeech -= GetSpeech;
        EventManager.OnStopSpeech -= OnStopSpeech;
    }

    AC.Char speakingCharacter;
    SkeletonAnimation skeletonAnimation;

    void GetSpeech(AC.Char speaker, string speechText, int lineID)
    {
        Debug.Log("Character: " + speaker + ", Text: " + speechText + ", lineID: " + lineID);

        skeletonAnimation = speaker.GetComponentInChildren<SkeletonAnimation>();

        DirectionMapper directionMapper = speaker.GetComponent<DirectionMapper>();

         Debug.Log("skeletonDataAsset: " + directionMapper.skeletonAnimation.skeletonDataAsset);

        speakingCharacter = speaker;
    }
    void OnStopSpeech(AC.Char speaker)
    {
        Debug.Log("Character: " + speaker + " stopped talking");

    }
}

However, my Skin Setter script replaces the skin every frame, and therefore my facial animations won't be set. Arew you able to help me adapt my Skin Setter script to make this work?

using UnityEngine;
using Spine;
using Spine.Unity;

public class SkinSetter : MonoBehaviour
{

    public string[] newSkinNames = new string[0];

    public void LateUpdate ()
    {
        SkeletonAnimation skeletonAnimation = GetComponentInChildren<SkeletonAnimation> ();
        if (skeletonAnimation == null) return;

        Skeleton skeleton = skeletonAnimation.Skeleton;
        Skin newSkin = new Skin ("new-skin"); // 1. Create a new empty skin
        foreach (string newSkinName in newSkinNames)
        {
            Skin existingSkin = skeleton.Data.FindSkin (newSkinName);
            if (existingSkin != null)
            {
                newSkin.AddSkin (existingSkin);
            }
            else
            {
                Debug.LogWarning ("Cannot find Skin with name '" + newSkinName + "'", skeletonAnimation);
            }
        }

        skeleton.SetSkin (newSkin);
        skeleton.SetSlotsToSetupPose ();
    }

}

Comments

  • This isn't an AC issue - AC is only involved insofar as you setting the skeletonAnimation / speakingCharacter variables.

    If you want the second script to be dependent on the first (i.e. don't run if the first is running), make speakingCharacter public and then check its value at the top of the LateUpdate function, i.e.:

    if (GetComponent<ACSpineExpressions> ().speakingCharacter && GetComponent<ACSpineExpressions> ().speakingCharacter.isTalking) return;
    
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.