from2001 / VRM_VisualScriptingNodes

Unity Visual Scripting node library for VRM
MIT License
4 stars 2 forks source link

Main VRM Node development (Basic features) #1

Closed from2001 closed 9 months ago

from2001 commented 10 months ago

Topic about VRM node.

from2001 commented 10 months ago

UniVRMを使ってVRMモデルをランタイムロードする方法 #C# - Qiita https://qiita.com/sh_akira/items/8155e4b69107c2a7ede6

        // VRMのメタデータを取得
        var meta = context.ReadMeta(false); //引数をTrueに変えるとサムネイルも読み込みます

        //読み込めたかどうかログにモデル名を出力してみる
        Debug.LogFormat("meta: title:{0}", meta.Title);

UniVRM Programming ドキュメント https://vrm-c.github.io/UniVRM/ja/index.html

from2001 commented 10 months ago

VRM Load with async

async Task<Vrm10Instance> LoadVrm(string URL)
{
    byte[] VrmBytes;
    using (UnityWebRequest www = UnityWebRequest.Post(URL, new WWWForm()))
    {
        await www.SendWebRequest();
        VrmBytes = www.downloadHandler.data;
    }
    //var VrmInstance = await Vrm10.LoadBytesAsync(VrmBytes, canLoadVrm0X: true);
    var VrmInstance = await Vrm10.LoadBytesAsync(VrmBytes, canLoadVrm0X: true, materialGenerator: new UrpVrm10MaterialDescriptorGenerator());
    return VrmInstance;
}

UnityWebRequest async wrapper

    public class UnityWebRequestAwaiter : INotifyCompletion
    {
        private UnityWebRequestAsyncOperation asyncOp;
        private Action continuation;
        public UnityWebRequestAwaiter(UnityWebRequestAsyncOperation asyncOp)
        {
            this.asyncOp = asyncOp;
            asyncOp.completed += OnRequestCompleted;
        }
        public bool IsCompleted { get { return asyncOp.isDone; } }
        public void GetResult() { }
        public void OnCompleted(Action continuation)
        {
            this.continuation = continuation;
        }
        private void OnRequestCompleted(AsyncOperation obj)
        {
            continuation();
        }
    }
    public static class ExtensionMethods
    {
        public static UnityWebRequestAwaiter GetAwaiter(this UnityWebRequestAsyncOperation asyncOp)
        {
            return new UnityWebRequestAwaiter(asyncOp);
        }
    }
from2001 commented 10 months ago

【Unity】Visual Scripting(旧Bolt)でScript Machineのカスタムユニットを作成する方法まとめ - LIGHT11 https://light11.hatenadiary.com/entry/2021/08/10/192806

using System.Collections;
using Unity.VisualScripting;
using UnityEngine;

[UnitTitle("Example03")]
[UnitShortTitle("Example03")]
[UnitCategory("Test")]
public class Example03Unit : Unit
{
    [DoNotSerialize] [PortLabelHidden] public ControlInput Input { get; private set; }

    [DoNotSerialize] [PortLabelHidden] public ControlOutput Output { get; private set; }

    [DoNotSerialize] public ValueInput Value { get; private set; }

    protected override void Definition()
    {
        // ControlInputではなくControlInputCoroutineを使う
        Input = ControlInputCoroutine(nameof(Input), OnEnterRoutine);
        Output = ControlOutput(nameof(Output));
        Value = ValueInput<string>(nameof(Value));

        Requirement(Value, Input);
        Succession(Input, Output);
    }

    private IEnumerator OnEnterRoutine(Flow flow)
    {
        // 1秒後にログ出力する
        yield return new WaitForSeconds(1.0f);
        var value = flow.GetValue<string>(Value);
        Debug.Log(value);

        // Outputを返すこと
        yield return Output;
    }
}
from2001 commented 10 months ago

VisualScriptingとUniTaskを組み合わせる https://zenn.dev/fumo/articles/930b4b5993b117

from2001 commented 10 months ago

非asyncメソッドから値を返すUniTaskを呼び出す方法 UniTask 2.x を使った堅牢な非同期処理への移行ガイド #C# - Qiita https://qiita.com/mhama/items/0f2cba4a4a762589fc53#%E9%9D%9Easync%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E8%BF%94%E3%81%99unitask%E3%82%92%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%99%E6%96%B9%E6%B3%95

from2001 commented 10 months ago

Call async function in a non async function

private ControlOutput Enter(Flow flow)
{
    string url = "https://test.psychic-vr-lab.com/temp/temp.vrm";
    UniTask.Create(async () =>
    {
        var vrm = await LoadVrm(url);
        Debug.Log("vrm:" + vrm);
    }
    ).Forget();
    return null;
}

private async UniTask<Vrm10Instance> LoadVrm(string URL)
{
    //Load VRM codes
}
from2001 commented 10 months ago

UniVRM 利用アプリケーションの VRM 1.0 への移行について ライセンス・メタ情報の取得 https://speakerdeck.com/santarh/univrm-li-yong-apurikesiyonno-vrm-1-dot-0-henoyi-xing-nituite?slide=21

from2001 commented 10 months ago

https://github.com/from2001/VRM_VisualScriptingNodes/pull/2

from2001 commented 10 months ago

VRMの表情ブレンドシェイプをUnityのAnimationから操作する - けしごむメモ https://scrapbox.io/ke456memo/VRM%E3%81%AE%E8%A1%A8%E6%83%85%E3%83%96%E3%83%AC%E3%83%B3%E3%83%89%E3%82%B7%E3%82%A7%E3%82%A4%E3%83%97%E3%82%92Unity%E3%81%AEAnimation%E3%81%8B%E3%82%89%E6%93%8D%E4%BD%9C%E3%81%99%E3%82%8B

API更新 - UniVRM Programming ドキュメント

VRMBlendShapeProxy は Vrm10Instance.Runtime.Expression になりました。 ImmediatelySetValue と AccumulateValue は、SetWeight に一本化されました。 ImmediatelySetValue は無くなりました。

https://vrm-c.github.io/UniVRM/ja/vrm1/api_update.html#expression

from2001 commented 10 months ago

glbファイルはそのまま同じ関数では読み込めない 下記のように読み込みコードを書くとglbを読みこんでInstanceが作成されるがアニメーションなどが再生されない。要調査。またはgltFastを使う方針を検討

            void GlbLoad(byte[] bytes)
            {
                var data = new GlbBinaryParser(bytes, "LOAD_NAME").Parse();
                using (var loader = new UniGLTF.ImporterContext(data))
                {
                    var instance = loader.Load();
                    // SkinnedMeshRenderer に対する指示
                    instance.EnableUpdateWhenOffscreen();
                    // 準備ができたら表示する(デフォルトでは非表示)
                    instance.ShowMeshes();
                }
            }

=> I implemented glTF and glb Visual Scripting node as a separated project. https://github.com/from2001/glTFast_VisualScriptingNodes