LoginSignup
1
3

More than 3 years have passed since last update.

LeapMotionでLive2Dモデルの指を動かす

Last updated at Posted at 2019-12-22

はじめに

Unity(C#)でLeapMotionから指の角度を取得してLive2Dモデルをリアルタイムに動かす方法

環境

Unity : 2019.2.2f1
Live2D SDK : 4.0-beta.2
LeapMotion SDK : 4.4.0
Live2Dモデル書き出しファイル : 以下画像
qiita1.png
今回使用した腕モデルはLive2Dイラストレーター・モデラーの鳥総帥様から許可を得て使用しています

準備

Live2D

公式チュートリアルページのSDKをインポートの通りにSDKとモデルをインポート

LeapMotion

Unity向けSDKからUnityPackageをインポート
ここからが問題なんですよね
大抵はLeapHandControllerプレハブをヒエラルキーに入れると書いてあるんですが、少なくとも私の環境ではインポートの問題か何回試してもスクリプトがmissingだったため使えませんでした。
image.png
なのでSDK付属のサンプルシーンからコピペします。
参考にしたのは以下の記述です。

Assets/LeapMotion/Core/Examples/Capsule Hands(Desktop)からLeapMotionControllerとHandModelsをコピペして自分のシーンに貼り付けます。
LeapMotion+Unityでグー・チョキ・パーを認識する より引用

実際のコード

このスクリプトをLive2Dモデルにアタッチします

MovingArm.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Leap;
using Live2D.Cubism.Core;
using Live2D.Cubism.Framework;

public class MoveArm : MonoBehaviour
{
    private CubismModel _model;
    private Controller controller;
    private Dictionary<Leap.Finger.FingerType, CubismParameter> modelfingers;

    // Start is called before the first frame update
    void Start()
    {
        controller = new Controller();
        _model = this.FindCubismModel();

        modelfingers = new Dictionary<Leap.Finger.FingerType, CubismParameter>();
        modelfingers.Add(Leap.Finger.FingerType.TYPE_INDEX, _model.Parameters[1]);
        modelfingers.Add(Leap.Finger.FingerType.TYPE_MIDDLE, _model.Parameters[2]);
        modelfingers.Add(Leap.Finger.FingerType.TYPE_RING, _model.Parameters[3]);
        modelfingers.Add(Leap.Finger.FingerType.TYPE_PINKY, _model.Parameters[4]);
        modelfingers.Add(Leap.Finger.FingerType.TYPE_THUMB, _model.Parameters[5]);
    }
    private void LateUpdate()
    {
        Frame frame = controller.Frame();

        if (frame.Hands.Count != 0)
        {
            List<Hand> hand = frame.Hands;
            var fingers = hand[0].Fingers;
            foreach (Finger finger in fingers)
            {
                if (finger.Type == Leap.Finger.FingerType.TYPE_UNKNOWN) continue;

                var angle = Mathf.PI - finger.Direction.AngleTo(hand[0].Direction);
                var param = EditParam(angle, 0f, Mathf.PI, -30, 30);

                if (finger.Type == Leap.Finger.FingerType.TYPE_THUMB)
                {
                    angle = finger.Direction.AngleTo(hand[0].PalmNormal);
                    param = EditParam(angle, 1.0f, 1.27f, -30, 30);
                    Debug.Log("THUMB " + angle + " " + param);
                }

                modelfingers[finger.Type].Value = param;
            }
        }
    }
    private float EditParam(float param,float leapmin,float leapmax, float modelmin,float modelmax)
    {
        return (param - leapmin) * ((modelmax - modelmin) / (leapmax - leapmin)) + modelmin;
    }
}

解説

using

LeapMotionの機能を使いたい→ using Leap;
Live2Dの機能を使いたい→ using Live2D.Cubism.Core;
using Live2D.Cubism.Framework;

modelfingers って辞書はなに

Fingerクラスに取得したFinger型オブジェクトの指の種類(親指・人差し指・中指・薬指・小指・不明)が取得できるFingerTypeがあるので、モデルの各指パラメータの順番に合わせて(例えば今回モデルの人差し指は2番目の位置にあるので0開始で_model.Parameters[1])各指の種類とモデルのパラメータオブジェクトを当てはめてる
image.png

angleってなに

finger.Directionで指の差す角度(Vector)
hand[0].Directionで手先の角度(Vector)
AngleTo()で各ベクトル間の角度を取得
今回モデルの動き(Angleパラメータ最大(30)で指伸ばし最小(-30)で指曲げ)とAngleToで取得できる数値が逆だったため180度(Mathf.PI)で反転してます

EditParam(angle, 1.0f, 1.27f, -30, 30);

すいません取得した値をログでひろってきて値の最大最小を直接入力するゴリ押しをしました
親指だけ曲がる角度が大きく違うので……
ここはもっと方法があると思います

最後

間違い、説明不足な点などありましたらコメントか編集リクエストをお願いします。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3