LookAt
最終更新: 2020年1月30日
概述
LookAt是操作任意参数追随特定座标的值的功能。
通过自定义用户侧要追随的座标,可以使Cubism模型追随特定的GameObject等。
关于如何使用LookAt,请参考 此处 。
Cubism SDK for Unity中的LookAt包含三种类型的元素。
- 用于指定要追随的参数的组件
- 将值应用于各参数的组件
- 操作2中应用的值
1. 指定要追随的参数的组件
使用CubismLookParameter指定通过LookAt追随的参数。
CubismLookParameter通过附加到置入[Prefab根]/Parameters/下的GameObject来使用。
这会将与附加的GameObject具有相同ID的参数被视为眼动追踪的参数。
CubismLookParameter有两个设置项目,Axis和Factor。
/// <summary>
/// Look axis.
/// </summary>
[SerializeField]
public CubismLookAxis Axis;
/// <summary>
/// Factor.
/// </summary>
[SerializeField]
public float Factor;
- Axis
设置要使用的输入座标的轴值。
可以设置三个项目:X、Y、Z。
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的所有CubismLookParameters的参考。
在执行过程中追加/删除跟踪视线的参数时,会调用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()时,将CubismLookController.Target中设置的物体返回的座标应用到CubismLookParameter标记的参数上。
// 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中实装CubismLookTargetBehaviour的示例,附带ICubismLookTarget。
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
}
}