LookAt
最終更新: 2026年1月8日
概要
LookAtは、任意のパラメータを特定の座標に追従するよう値を操作する機能です。
追従させる座標をユーザ側でカスタマイズすることで、Cubismのモデルを特定のGameObjectなどに追従させることが可能です。
LookAtの使用方法については こちら をご覧ください。
Cubism SDK for Unity におけるLookAtは4種類の要素によって構成されています。
- 追従させるパラメータ指定用のコンポーネント
- 各パラメータに値を適用するコンポーネント
- 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 = GetComponent<ICubismLookCenter>() as Object;
}
// Initialize cache.
Refresh();
}
CubismLookControllerは、毎フレームのLateUpdate()のタイミングで、CubismLookParameterでマーキングされたパラメータに対してCubismLookController.Targetに設定したオブジェクトが返す座標を適用します。
var target = TargetInterface;
Vector3 centerPosition;
var center = CenterInterface;
if (center == null)
{
centerPosition = Vector3.zero;
}
else
{
centerPosition = center.GetCenterPosition();
}
if (target == null || !target.IsActive())
{
GoalPosition = Vector3.zero;
}
else
{
GoalPosition = transform.InverseTransformPoint(target.GetPosition()) - centerPosition;
}
// Update position.
var position = LastPosition;
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
}
}
4. 追従する中心座標指定用のコンポーネント
視線追従の中心座標を指定するためのコンポーネントを追加します。
これはICubismLookCenterインターフェースを実装したもので、ユーザ側で実装していただくことで追従する座標の中心を任意に設定することができます。
using UnityEngine;
namespace Live2D.Cubism.Framework.LookAt
{
/// <summary>
/// Probides the center position for look-at calculations.
/// </summary>
public interface ICubismLookCenter
{
/// <summary>
/// Gets the position of the center.
/// </summary>
Vector3 GetCenterPosition();
}
}
- GetCenterPosition()
追従の中心座標を返します。
SDKにはICubismLookCenterを実装した例として、中心座標にGameObjectの座標を指定するCubismLookCenterTransform、任意のアートメッシュの中心を指定するCubismLookCenterが同梱されています。
using UnityEngine;
namespace Live2D.Cubism.Framework.LookAt
{
/// <summary>
/// Provides the center position for look-at calculations.
/// </summary>
[DisallowMultipleComponent]
public class CubismLookCenterTransform : MonoBehaviour, ICubismLookCenter
{
public Transform CenterReference;
/// <summary>
/// Model root transform.
/// </summary>
private Transform _modelRootTransform;
private void Start()
{
_modelRootTransform = this.transform;
}
/// <summary>
/// Gets the position of the center.
/// </summary>
public Vector3 GetCenterPosition()
{
if (CenterReference == null)
{
return Vector3.zero;
}
var centerInWorld = CenterReference.position;
var centerInModelLocal = _modelRootTransform.InverseTransformPoint(centerInWorld);
return centerInModelLocal;
}
}
}
using Live2D.Cubism.Core;
using Live2D.Cubism.Rendering;
using UnityEngine;
namespace Live2D.Cubism.Framework.LookAt
{
/// <summary>
/// Provides the center position for look-at calculations using an ArtMesh (CubismDrawable).
/// </summary>
[DisallowMultipleComponent]
public class CubismLookCenterArtMesh : MonoBehaviour, ICubismLookCenter
{
/// <summary>
/// Target drawable to calculate the center from.
/// </summary>
[SerializeField]
public CubismDrawable TargetDrawable;
/// <summary>
/// Model root transform.
/// </summary>
private Transform _modelRootTransform;
private void Start()
{
_modelRootTransform = this.transform;
}
/// <summary>
/// Gets the position of the center.
/// </summary>
public Vector3 GetCenterPosition()
{
if (TargetDrawable == null)
{
return Vector3.zero;
}
var cubismRenderer = TargetDrawable.GetComponent<CubismRenderer>();
if (cubismRenderer == null || cubismRenderer.Mesh == null)
{
return _modelRootTransform.InverseTransformPoint(TargetDrawable.transform.position);
}
var centerInMeshLocal = cubismRenderer.Mesh.bounds.center;
var centerInWorld = TargetDrawable.transform.TransformPoint(centerInMeshLocal);
var centerInModelLocal = _modelRootTransform.InverseTransformPoint(centerInWorld);
return centerInModelLocal;
}
}
}