LookAt

最終更新: 2020年1月30日

概要

LookAtは、任意のパラメータを特定の座標に追従するよう値を操作する機能です。
追従させる座標をユーザ側でカスタマイズすることで、Cubismのモデルを特定のGameObjectなどに追従させることが可能です。
LookAtの使用方法については こちら をご覧ください。

Cubism SDK for Unity におけるLookAtは3種類の要素によって構成されています。

  1. 追従させるパラメータ指定用のコンポーネント
  2. 各パラメータに値を適用するコンポーネント
  3. 2で適用する値の操作

1. 追従させるパラメータ指定用のコンポーネント

LookAtで追従させるパラメータを指定するには、CubismLookParameterを使用します。

CubismLookParameterは[Prefabのルート]/Parameters/ 以下に配置されたGameObjectにアタッチして使用します。
これがアタッチされたGameObjectと同じIDのパラメータを視線追従用のパラメータとして扱います。

CubismLookParameterには、Axis , Factor の2つの設定項目があります。

        /// <summary>
        /// Look axis.
        /// </summary>
        [SerializeField]
        public CubismLookAxis Axis;


        /// <summary>
        /// Factor.
        /// </summary>
        [SerializeField]
        public float Factor;
  • Axis

入力された座標のどの軸の値を使用するかを設定します。
設定できる項目は、X, Y, Zの3つです。

namespace Live2D.Cubism.Framework.LookAt
{
    /// <summary>
    /// Look axis.
    /// </summary>
    public enum CubismLookAxis
    {
        /// <summary>
        /// X axis.
        /// </summary>
        X,

        /// <summary>
        /// Y axis.
        /// </summary>
        Y,

        /// <summary>
        /// Z axis.
        /// </summary>
        Z
    }
}
  • Factor

適用される値への補正値を設定します。
入力される座標は、適用される際には-1.0fから1.0fの範囲に加工された値になります。
Factorに設定する値は、入力された値を各パラメータの最小値と最大値に合うように乗算する倍率になります。

        /// <summary>
        /// Updates and evaluates the instance.
        /// </summary>
        /// <param name="targetOffset">Delta to target.</param>
        /// <returns>Evaluation result.</returns>
        internal float TickAndEvaluate(Vector3 targetOffset)
        {
            var result = (Axis == CubismLookAxis.X)
                ? targetOffset.x
                : targetOffset.y;


            if (Axis == CubismLookAxis.Z)
            {
                result = targetOffset.z;
            }


            return result * Factor;
        }

また、CubismLookParameterは、CubismLookControllerが参照先を取得するためのマーカーとしても使用しています。

2. 各パラメータに値を適用するコンポーネント

各パラメータに視線追従を適用するには、CubismLookControllerを使用します。
CubismLookControllerを使用する際はCubismのPrefabのルートにアタッチします。

CubismLookControllerの初期化時に、PrefabにアタッチされたすべてのCubismLookParameterの参照を取得します。
実行中に視線追従用のパラメータを追加/削除した際にはCubismLookController.Refresh()を呼んで参照を取得し直します。

        /// <summary>
        /// Refreshes the controller. Call this method after adding and/or removing <see cref="CubismLookParameter"/>s.
        /// </summary>
        public void Refresh()
        {
            var model = this.FindCubismModel();


            // Catch sources and destinations.
            Sources = model
                .Parameters
                .GetComponentsMany<CubismLookParameter>();
            Destinations = new CubismParameter[Sources.Length];


            for (var i = 0; i < Sources.Length; ++i)
            {
                Destinations[i] = Sources[i].GetComponent<CubismParameter>();
            }

            // Get cubism update controller.
            HasUpdateController = (GetComponent<CubismUpdateController>() != null);
        }

        ...
        
        /// <summary>
        /// Called by Unity. Makes sure cache is initialized.
        /// </summary>
        private void Start()
        {
            // Default center if necessary.
            if (Center == null)
            {
                Center = transform;
            }


            // Initialize cache.
            Refresh();
        }

CubismLookControllerは、毎フレームのLateUpdate()のタイミングで、CubismLookParameterでマーキングされたパラメータに対してCubismLookController.Targetに設定したオブジェクトが返す座標を適用します。

            // Update position.
            var position = LastPosition;
            GoalPosition = transform.InverseTransformPoint(target.GetPosition()) - Center.localPosition;


            if (position != GoalPosition)
            {
                position = Vector3.SmoothDamp(
                    position,
                    GoalPosition,
                    ref VelocityBuffer,
                    Damping);
            }


            // Update sources and destinations.
            for (var i = 0; i < Destinations.Length; ++i)
            {
                Destinations[i].BlendToValue(BlendMode, Sources[i].TickAndEvaluate(position));
            }


            // Store position.
            LastPosition = position;

3. 2で適用する値の操作

「2. 各パラメータに値を適用するコンポーネント」で説明した通り、CubismLookControllerが視線追従用のパラメータに適用する座標はCubismLookController.Targetに設定したオブジェクトが返ります。

これはICubismLookTargetインターフェースを実装したもので、ユーザ側でこちらを実装していただくことでモデルを任意の座標に追従させることができます。

using UnityEngine;


namespace Live2D.Cubism.Framework.LookAt
{
    /// <summary>
    /// Target to look at.
    /// </summary>
    public interface ICubismLookTarget
    {
        /// <summary>
        /// Gets the position of the target.
        /// </summary>
        /// <returns>The position of the target in world space.</returns>
        Vector3 GetPosition();


        /// <summary>
        /// Gets whether the target is active.
        /// </summary>
        /// <returns><see langword="true"/> if the target is active; <see langword="false"/> otherwise.</returns>
        bool IsActive();
    }
}
  • GetPosition()

追従する座標を返します。
ここで返す座標はワールド座標として扱われます。

  • IsActive()

追従が有効かどうかを返します。
trueが返されているときだけ追従します。

SDKにはICubismLookTargetを実装した例としてCubismLookTargetBehaviourが同梱されています。
CubismLookTargetBehaviourは、それがアタッチされたGameObjectの座標を返すサンプルになります。

using UnityEngine;


namespace Live2D.Cubism.Framework.LookAt
{
    /// <summary>
    /// Straight-forward <see cref="ICubismLookTarget"/> <see cref="MonoBehaviour"/>.
    /// </summary>
    public class CubismLookTargetBehaviour : MonoBehaviour, ICubismLookTarget
    {
        #region Implementation of ICubismLookTarget

        /// <summary>
        /// Gets the position of the target.
        /// </summary>
        /// <returns>The position of the target in world space.</returns>
        Vector3 ICubismLookTarget.GetPosition()
        {
            return transform.position;
        }

        /// <summary>
        /// Gets whether the target is active.
        /// </summary>
        /// <returns><see langword="true"/> if the target is active; <see langword="false"/> otherwise.</returns>
        bool ICubismLookTarget.IsActive()
        {
            return isActiveAndEnabled;
        }

        #endregion
    }
}
この記事はお役に立ちましたか?
はいいいえ
この記事に関するご意見・
ご要望をお聞かせください。