LookAt (Cocos Creator)

最終更新: 2023年3月14日

このページはCubism 4.2以前の古いバージョン向けです。 最新のページはこちら

概要

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

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

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

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

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

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

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/** Look axis. */
@property({ type: Enum(CubismLookAxis), serializable: true, visible: true })
public axis: CubismLookAxis = CubismLookAxis.X;
/** Factor. */
@property({ type: CCFloat, serializable: true, visible: true })
public factor: number = 0;
/** Look axis. */ @property({ type: Enum(CubismLookAxis), serializable: true, visible: true }) public axis: CubismLookAxis = CubismLookAxis.X; /** Factor. */ @property({ type: CCFloat, serializable: true, visible: true }) public factor: number = 0;
/** Look axis. */
@property({ type: Enum(CubismLookAxis), serializable: true, visible: true })
public axis: CubismLookAxis = CubismLookAxis.X;

/** Factor. */
@property({ type: CCFloat, serializable: true, visible: true })
public factor: number = 0;
  • Axis

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/** Look axis. */
enum CubismLookAxis {
/** X axis. */
X,
/** Y axis. */
Y,
/** Z axis. */
Z,
}
export default CubismLookAxis;
/** Look axis. */ enum CubismLookAxis { /** X axis. */ X, /** Y axis. */ Y, /** Z axis. */ Z, } export default CubismLookAxis;
/** Look axis. */
enum CubismLookAxis {
  /** X axis. */
  X,
  /** Y axis. */
  Y,
  /** Z axis. */
  Z,
}
export default CubismLookAxis;
  • Factor

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public tickAndEvaluate(targetOffset: math.Vec3): number {
const result =
this.axis == CubismLookAxis.X
? targetOffset.x
: this.axis == CubismLookAxis.Z
? targetOffset.z
: targetOffset.y;
return result * this.factor;
}
public tickAndEvaluate(targetOffset: math.Vec3): number { const result = this.axis == CubismLookAxis.X ? targetOffset.x : this.axis == CubismLookAxis.Z ? targetOffset.z : targetOffset.y; return result * this.factor; }
public tickAndEvaluate(targetOffset: math.Vec3): number {
  const result =
    this.axis == CubismLookAxis.X
      ? targetOffset.x
      : this.axis == CubismLookAxis.Z
      ? targetOffset.z
      : targetOffset.y;
  return result * this.factor;
}

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

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

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

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/** Refreshes the controller. Call this method after adding and/or removing {@link CubismLookParameter}s. */
public refresh(): void {
const model = CoreComponentExtensionMethods.findCubismModel(this);
if (model == null) {
return;
}
if (model.parameters == null) {
return;
}
// Catch sources and destinations.
this.sources = ComponentExtensionMethods.getComponentsMany(
model.parameters,
CubismLookParameter
);
this.destinations = new Array<CubismParameter>(this.sources.length);
for (let i = 0; i < this.sources.length; i++) {
this.destinations[i] = this.sources[i].getComponent(CubismParameter);
}
// Get cubism update controller.
this.hasUpdateController = this.getComponent(CubismUpdateController) != null;
}
...
/** Called by Cocos Creator. Makes sure cache is initialized. */
protected start(): void {
// Default center if necessary.
if (this.center == null) {
this.center = this.node;
}
// Initialize cache.
this.refresh();
}
/** Refreshes the controller. Call this method after adding and/or removing {@link CubismLookParameter}s. */ public refresh(): void { const model = CoreComponentExtensionMethods.findCubismModel(this); if (model == null) { return; } if (model.parameters == null) { return; } // Catch sources and destinations. this.sources = ComponentExtensionMethods.getComponentsMany( model.parameters, CubismLookParameter ); this.destinations = new Array<CubismParameter>(this.sources.length); for (let i = 0; i < this.sources.length; i++) { this.destinations[i] = this.sources[i].getComponent(CubismParameter); } // Get cubism update controller. this.hasUpdateController = this.getComponent(CubismUpdateController) != null; } ... /** Called by Cocos Creator. Makes sure cache is initialized. */ protected start(): void { // Default center if necessary. if (this.center == null) { this.center = this.node; } // Initialize cache. this.refresh(); }
/** Refreshes the controller. Call this method after adding and/or removing {@link CubismLookParameter}s. */
public refresh(): void {
  const model = CoreComponentExtensionMethods.findCubismModel(this);
  if (model == null) {
    return;
  }
  if (model.parameters == null) {
    return;
  }

  // Catch sources and destinations.

  this.sources = ComponentExtensionMethods.getComponentsMany(
    model.parameters,
    CubismLookParameter
  );
  this.destinations = new Array<CubismParameter>(this.sources.length);

  for (let i = 0; i < this.sources.length; i++) {
    this.destinations[i] = this.sources[i].getComponent(CubismParameter);
  }

  // Get cubism update controller.
  this.hasUpdateController = this.getComponent(CubismUpdateController) != null;
}

...

/** Called by Cocos Creator. Makes sure cache is initialized. */
protected start(): void {
  // Default center if necessary.
  if (this.center == null) {
    this.center = this.node;
  }

  // Initialize cache.
  this.refresh();
}

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// Update position.
let position = this.lastPosition;
const inverseTransformPoint = this.node.inverseTransformPoint(
new math.Vec3(),
target.getPosition()
);
this.goalPosition = math.Vec3.subtract(
new math.Vec3(),
inverseTransformPoint,
this.center.position
);
if (position != this.goalPosition) {
const temp = MathExtensions.Vec3.smoothDamp(
position,
this.goalPosition,
this.velocityBuffer,
this.damping
);
position = temp[0];
this.velocityBuffer = temp[1];
}
// Update sources and destinations.
for (let i = 0; i < this.destinations.length; i++) {
CubismParameterExtensionMethods.blendToValue(
this.destinations[i],
this.blendMode,
this.sources[i].tickAndEvaluate(position)
);
}
// Store position.
this.lastPosition = position;
// Update position. let position = this.lastPosition; const inverseTransformPoint = this.node.inverseTransformPoint( new math.Vec3(), target.getPosition() ); this.goalPosition = math.Vec3.subtract( new math.Vec3(), inverseTransformPoint, this.center.position ); if (position != this.goalPosition) { const temp = MathExtensions.Vec3.smoothDamp( position, this.goalPosition, this.velocityBuffer, this.damping ); position = temp[0]; this.velocityBuffer = temp[1]; } // Update sources and destinations. for (let i = 0; i < this.destinations.length; i++) { CubismParameterExtensionMethods.blendToValue( this.destinations[i], this.blendMode, this.sources[i].tickAndEvaluate(position) ); } // Store position. this.lastPosition = position;
// Update position.
let position = this.lastPosition;

const inverseTransformPoint = this.node.inverseTransformPoint(
  new math.Vec3(),
  target.getPosition()
);
this.goalPosition = math.Vec3.subtract(
  new math.Vec3(),
  inverseTransformPoint,
  this.center.position
);
if (position != this.goalPosition) {
  const temp = MathExtensions.Vec3.smoothDamp(
    position,
    this.goalPosition,
    this.velocityBuffer,
    this.damping
  );
  position = temp[0];
  this.velocityBuffer = temp[1];
}

// Update sources and destinations.
for (let i = 0; i < this.destinations.length; i++) {
  CubismParameterExtensionMethods.blendToValue(
    this.destinations[i],
    this.blendMode,
    this.sources[i].tickAndEvaluate(position)
  );
}

// Store position.
this.lastPosition = position;

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

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

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/** Target to look at. */
interface ICubismLookTarget {
readonly [ICubismLookTarget.SYMBOL]: typeof ICubismLookTarget.SYMBOL;
/**
* Gets the position of the target.
*
* @returns The position of the target in world space.
*/
getPosition(): math.Vec3;
/**
* Gets whether the target is active.
*
* @returns true if the target is active; false otherwise.
*/
isActive(): boolean;
}
export default ICubismLookTarget;
/** Target to look at. */ interface ICubismLookTarget { readonly [ICubismLookTarget.SYMBOL]: typeof ICubismLookTarget.SYMBOL; /** * Gets the position of the target. * * @returns The position of the target in world space. */ getPosition(): math.Vec3; /** * Gets whether the target is active. * * @returns true if the target is active; false otherwise. */ isActive(): boolean; } export default ICubismLookTarget;
/** Target to look at. */
interface ICubismLookTarget {
  readonly [ICubismLookTarget.SYMBOL]: typeof ICubismLookTarget.SYMBOL;

  /**
   * Gets the position of the target.
   *
   * @returns The position of the target in world space.
   */
  getPosition(): math.Vec3;

  /**
   * Gets whether the target is active.
   *
   * @returns true if the target is active; false otherwise.
   */
  isActive(): boolean;
}
export default ICubismLookTarget;
  • GetPosition()

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

  • IsActive()

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

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/** Straight-forward {@link ICubismLookTarget} {@link Component}. */
@ccclass('CubismLookTargetBehaviour')
export default class CubismLookTargetBehaviour extends Component implements ICubismLookTarget {
readonly [ICubismLookTarget.SYMBOL]: typeof ICubismLookTarget.SYMBOL = ICubismLookTarget.SYMBOL;
//#region Implementation of ICubismLookTarget
/**
* Gets the position of the target.
* @returns The position of the target in world space.
*/
public getPosition(): Readonly<math.Vec3> {
return this.node.worldPosition;
}
/**
* Gets whether the target is active.
* @returns true if the target is active; false otherwise.
*/
public isActive(): boolean {
return this.enabledInHierarchy;
}
//#endregion
}
/** Straight-forward {@link ICubismLookTarget} {@link Component}. */ @ccclass('CubismLookTargetBehaviour') export default class CubismLookTargetBehaviour extends Component implements ICubismLookTarget { readonly [ICubismLookTarget.SYMBOL]: typeof ICubismLookTarget.SYMBOL = ICubismLookTarget.SYMBOL; //#region Implementation of ICubismLookTarget /** * Gets the position of the target. * @returns The position of the target in world space. */ public getPosition(): Readonly<math.Vec3> { return this.node.worldPosition; } /** * Gets whether the target is active. * @returns true if the target is active; false otherwise. */ public isActive(): boolean { return this.enabledInHierarchy; } //#endregion }
/** Straight-forward {@link ICubismLookTarget} {@link Component}. */
@ccclass('CubismLookTargetBehaviour')
export default class CubismLookTargetBehaviour extends Component implements ICubismLookTarget {
  readonly [ICubismLookTarget.SYMBOL]: typeof ICubismLookTarget.SYMBOL = ICubismLookTarget.SYMBOL;

  //#region Implementation of ICubismLookTarget

  /**
   * Gets the position of the target.
   * @returns The position of the target in world space.
   */
  public getPosition(): Readonly<math.Vec3> {
    return this.node.worldPosition;
  }

  /**
   * Gets whether the target is active.
   * @returns true if the target is active; false otherwise.
   */
  public isActive(): boolean {
    return this.enabledInHierarchy;
  }

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