Skip to content

v2.6.0 has been released!

Compare
Choose a tag to compare
@hecomi hecomi released this 05 Jan 07:26
· 81 commits to main since this release

Update

  • Add 10. Runtime Setup example
  • Add Timeline Setup Helper
  • Add an API to get phoneme names Profile.GetPhonemeNames()

Timeline Setup Helper

Window > uLipSync > Timeline Setup Helper

This tool automatically creates BakedData corresponding to clips registered in AudioTrack and registers them in uLipSync Track.

timeline-setup-helper

Runtime Setup

  1. Attach uLipSyncBlendShape
  2. Register SkinneMeshRenderer there
  3. Bind the phoneme name registered in Profile and the corresponding SkinnedMeshRenderer BlendShape with AddBlendShape(string phoneme, string blendShape)
  4. Attach uLipSync
  5. Register Profile
  6. Register the callback for uLipSyncBlendShape there
using UnityEngine;
using System.Collections.Generic;

public class uLipSyncBlendShapeRuntimeSetupExample : MonoBehaviour
{
    // GameObject to add uLipSync (that has an AudioSource component)
    public GameObject target;

    // Profile to bind
    public uLipSync.Profile profile;

    // SkinnedMeshRenderer containing BlendShapes
    public string skinnedMeshRendererName = "MTH_DEF";

    // Assuming that some arbitrary data exists
    [System.Serializable]
    public class PhonemeBlendShapeInfo
    {
        public string phoneme;
        public string blendShape;
    }
    public List<PhonemeBlendShapeInfo> phonemeBlendShapeTable 
        = new List<PhonemeBlendShapeInfo>();

    uLipSync.uLipSync _lipsync;
    uLipSync.uLipSyncBlendShape _blendShape;

    void Start()
    {
        if (!target) return;

        SetupBlendShpae();
        SetupLipSync();
    }

    void SetupBlendShpae()
    {
        // Search for GameObject with specified name
        var targetTform = uLipSync.Util.FindChildRecursively(
            target.transform, 
            skinnedMeshRendererName);

        if (!targetTform) 
        {
            Debug.LogWarning(
                $"There is no GameObject named \"{skinnedMeshRendererName}\"");
            return;
        }

        // Get SkinnedMeshRenderer
        var smr = targetTform.GetComponent<SkinnedMeshRenderer>();
        if (!smr) 
        {
            Debug.LogWarning(
                $"\"{skinnedMeshRendererName}\" does not have SkinnedMeshRenderer.");
            return;
        }

        // Attach uLipSyncBlendShape
        _blendShape = target.AddComponent<uLipSync.uLipSyncBlendShape>();
        _blendShape.skinnedMeshRenderer = smr;

        // Bind Phoneme and BlendShape name using some data
        foreach (var info in phonemeBlendShapeTable)
        {
            _blendShape.AddBlendShape(info.phoneme, info.blendShape);
        }
    }

    void SetupLipSync()
    {
        if (!_blendShape) return;

        // Attach uLipSync
        _lipsync = target.AddComponent<uLipSync.uLipSync>();

        // Specify Profile
        _lipsync.profile = profile;

        // Register callback for uLipSyncBlendShape
        _lipsync.onLipSyncUpdate.AddListener(_blendShape.OnLipSyncUpdate);
    }
}