特定構成のAnimatorControllerを作るとパラメータを変更しても元に戻ってしまう

【Cubism SDKのバージョン】Cubism SDK for Unity R6
【OS名・バージョン】Windows10
【開発使用ツール】Visual Studio Code Unity 2021.3.17f1
【不具合の状況】

AnimatorControllerが特定の構成のアニメーションクリップを持っているとき、スクリプトからのパラメータ変更を行っても元の値に戻されてしまいます。

そもそもの使い方がおかしいのか、それともどこか作り方が悪いようであれば原因を教えていただけないでしょうか。

検証用に作成したモデル・プロジェクトでも再現したため、以下手順を記載します。

  1. 赤い丸だけのLive2Dモデルがあります。このモデルには「赤丸透明度」「上下移動」というパラメータがあります。
    ・赤丸透明度: 0(デフォルト)~100 を持ち、デフォーマの透明度を操作して赤丸を表示します。
    ・上下移動:は-30~0(デフォルト)~30の値を持ち、デフォーマを操作して赤丸を上下に移動します。

  2. アニメーションで2つのシーンを作成しました。
    ・表示シーン:0フレーム目で「赤丸透明度」を100に設定するシーン
    ・上下移動シーン:100フレームかけて「上下移動」を-30~30変化させるシーン

  3. モデル・アニメーションをそれぞれ組み込み用ファイル書き出しで出力しました。

  4. Unityで新しいプロジェクト(2D)を作成し、Cubism SDK for Unity R6をインポートしました。

  5. Unityにモデルとアニメーションファイルをインポートしました。

  6. 「MyAnimationController」というAnimatorControllerを作成し、表示アニメーションクリップをデフォルト、上下移動アニメーションクリップを配置しました。
    この時、表示と上下移動は繋いでいません。

  7. L2DTestというスクリプトを作成し赤丸モデルにアタッチしました。
    これは左クリックで「上下移動」パラメータを増加、右クリックで減少、ホイールクリックで0にするというスクリプトです。
    以下を参照してください。

using UnityEngine;
using Live2D.Cubism.Core;

public class L2DTest : MonoBehaviour
{

    public CubismModel model;
    public CubismParameter param;

    // Start is called before the first frame update
    void Start()
    {
        param = model.Parameters.FindById("ParamMoveY");
    }

    void LateUpdate()
    {
        if (Input.GetMouseButton(0))
        {
            param.Value = param.Value + 1f;
        }

        if (Input.GetMouseButton(1))
        {
            param.Value = param.Value - 1f;
        }

        if (Input.GetMouseButton(2))
        {
            param.Value = 0f;
        }
    }
}

  1. ゲームを実行し左or右クリックすると一瞬だけ赤丸が上下に移動し中央に戻ってしまいます。
    不思議なことにAnimatorControllerから上下移動のアニメーションクリップを削除すると左or右クリックによって赤丸が移動するようになります。

・どんなモデルを使用したか、サンプルモデルでも発生するか

モデルについては他項を参照願います。
サンプルモデルでは未検証です。

・プロジェクトの最小構成でも発生するか

発生します。
検証に使用したモデル及びUnityプロジェクトを添付します。

モデル.zip:Live2DTest_akamaru.zip (41.8 KB)
Unity.zip:Live2DTest_akamaru_Unity.zip (19.7 KB)

モデル.zipには、モデルとアニメーションのファイルと書き出したファイルが含まれています。

Unity.zipには.unitypackageがあるので、新しいプロジェクトを作成していただき、CubismSDK→Live2DTest_akamaru_Unityの順番でインポートしていただければ環境が再現できるかと思います。(できなかったらすみません…)

【知りたいこと】
・上記のような構成でもパラメータ操作ができるようにするにはどうすればいいのでしょうか。

こちら、自分では解決できなかったので、別の実装方法に変更しました。

マウス操作によるパラメータ操作とAnimation Controller.Animation Clipのパラメータ操作があるとうまくいかないので、Animation Controllerは使わず、すべてスクリプトから制御する形にしました。

お騒がせしました :melting_face:

@monore

いつも弊社製品をご愛顧くださり誠にありがとうございます。
Live2Dスタッフでございます。

Unityは、Animator Controllerに登録されているすべてのAnimationClipが参照しているパラメータの値を管理しており、毎フレーム参照先の値をリセットするという仕様となっております。
これは、Animator Controller内でアニメーションステートが繋がれていないAnimationClipも対象となります。
参考:【Unity】Animatorで動かすオブジェクトをスクリプトでも動かす際の注意 - テラシュールブログ

こちらは、ご提示していただいたスクリプトをCubism SDKの実行順を制御するコンポーネントに登録し、フェード処理よりも後で呼び出すように設定し、値を直接適用せずキャッシュさせるように修正することで意図通りの動作にすることが可能です。
独自のスクリプトの実行順ををCubism SDKに制御させるためには、ICubismUpdatableを実装します。
CubismUpdateControllerについては以下をご覧ください。

以下は、ご提示していただいたスクリプトの実行順を制御させるよう改修したスニペットになります。

using UnityEngine;
using Live2D.Cubism.Core;
using Live2D.Cubism.Framework;
using Live2D.Cubism.Framework.Motion;

public class L2DTest : MonoBehaviour, ICubismUpdatable
{

    public CubismModel model;
    public CubismParameter param;

    private CubismMotionController motionController;

    public int ExecutionOrder
    {
        get { return CubismUpdateExecutionOrder.CubismParameterStoreSaveParameters + 1; }
    }

    public bool NeedsUpdateOnEditing
    {
        get { return false; }
    }

    public bool HasUpdateController { get; set; }

    private float _value;

    // Start is called before the first frame update
    void Start()
    {
        param = model.Parameters.FindById("ParamMoveY");

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

        _value = 0.0f;
    }

    void LateUpdate()
    {
        if (HasUpdateController)
        {
            return;
        }

        OnLateUpdate();
    }

    public void OnLateUpdate()
    {
        if (Input.GetMouseButton(0))
        {
            _value += 1f;
        }

        if (Input.GetMouseButton(1))
        {
            _value -= 1f;
        }

        if (Input.GetMouseButton(2))
        {
            _value = 0f;
        }

        param.Value += _value;
    }
}

以上、よろしくお願いいたします。