20201108のUnityに関する記事は7件です。

もなふわすい~とる~む in the VRChat

この記事は、もなふわすい~とる~む Advent Calendar 2020の7日目です。

6日目の記事は、izmさんによる「東京都内おすすめグルメマップ (推しの勧めてた店に行ってみた)」でした!
ねこねこチーズケーキは通販もやっているので、ぜひクリスマスのケーキなどに食べてみてください!

TL;DR

 VRChatのアバター・ワールドアップツールであるUnityのインストールから、ワールドを作成しVRchatへワールドをアップロードするまでのワークフローを解説する記事です。
 この記事は、公式のドキュメントに含まれる内容を、日本語に訳し図を加えて解説したものです。Creating Your First Worldに、この記事に書いてある内容はすべて書いてあります。
 リンク先の内容より、日本語での解説+画像のキャプチャによる補足で、少しだけわかりやすくなっています。

前提

 ワールドをアップロードすることができるのは、Trust LevelがNew User以降なので、VRChatを始めてから少しだけ経っている人向けの記事となります。
 また、この記事では静的なワールドの作成及びアップロードにとどまり、UDONやVRSDKのコンポーネントを用いたワールドギミックなどについては取り扱いません。

環境設定

VRChatのワールドを作成して、作成したワールドをアップロードするための環境を整えます。

Unity Hub、Unityのインストール

1. Unityのアカウント登録を行います。
2. Unity Hubをダウンロードおよびインストールをします。
unityhub_download1.png

3. 後述するVRCHAT SDK3に対応するUnityのバージョンのインストーラ(今回は2018.4.20f1)をダウンロードおよびインストールします。
unitydl1.png

unitydl2.png

4. 画面の指示に従って、インストールを進めます。

unityinstall1.PNG

5. Unity Hubを起動し、インストールしたUnityのバージョンを追加する設定をします。

unity_version_add1.png

6. インストールしたUnityのディレクトリ以下にある「Unity.exe」を指定します。
unityinstall4.PNG

VRCHAT SDK3のダウンロード

  1. ブラウザでVRChatにログインします。

  2. ブラウザ上の画面左に表示されているメニューのDownloadをクリックします。

download1.png

  1. VRCHATSDK3Download SDK3 - Worldをクリックし、SDKをダウンロードします。

download2.png

Unityプロジェクトの作成

  1. UnityHubを起動しプロジェクトをUnity2018.4.20.f1で新規作成します。 create1.PNG

create2.PNG

  1. VRCHAT SDK3のダウンロードの項でダウンロードしたSDKのファイルをダブルクリックしてプロジェクトにインポートを行います。

create3.PNG

スプラッシュ画面が表示されるので閉じます。
create4.PNG

ワールドの作成

  1. シーン上にVRCWorld(Assets/VRChat Examples/Prefabs/VRCWorld.prefab)というプレハブを配置します。
    画面下部の青枠に囲われた、青色のまm立方体のアイコンを、画面左のタブ内にドラッグアンドドロップをすることで配置することができます。
    VRCWorld1_2.png

  2. シーン上にPlaneを配置します(作成時の状態がPositionが0,0,0以外の場合があるので、注意してください。)
    画面左のHierarchyタブ内で右クリックをし、表示されたメニューの「3D Objects > Plane」を選択することで配置することができます。
    VRCWorld2.png

ここまでで、VRChatにアップロードする最低限の要素はそろいました。

ワールドのアップロード

  1. メニューバーのVRChat SDKメニューからShow Control Panelをクリックします。
    update1.png

  2. 表示されたVRChat SDKウィンドウのAuthenticationタブを開き、VRChatのアカウントでログインをします。
    upload2.PNG

  3. Builderタブを開き、ウィンドウ下部のBuild & Testをクリックします。

upload3.PNG

  1. 表示された入力フィールドに、ワールドの説明などを入力したりし、チェック項目を確認しチェックを入れたりし、最後にUploadをクリックします。

upload4.PNG

ワールドに入ってみる

テスト

アップロードする際に、Builderタブの「Online Publishing」ではなく、その上の「Local Testing」の「Build & Test」をクリックすることで、アップロード前に自分だけが入ることができるワールドでテストをすることができます。
testworld1.png

これはシェーダーエラーのブラシ(なんで?)
testworld2.png

Private

SteamでVRChatのクライアントを起動し、WorldタブからMineの欄を探します。
world1.png

world2.png

シェーダーエラーのブラシなんてなかったんだ。
world3.PNG

Public

New Userだと、Publicにアップロードできません。。。
下記の画像の緑色の枠内の部分に、チェックを入れられるようになり、チェックを入れることでPublicでアップロードすることができます。
upload5.PNG

VRChat+に加入すれば、すぐにアップロードできるようになるのかな?試したら記事更新します。
https://docs.vrchat.com/docs/vrchat-community-labs

感想

いかがでしたか?
解説する記事と言いながら、VRChatのワールドのアップロードは初めてだったので、わからないことは調べながら書きました。
ギミックを実装しなければノンコーディングで完結するので、Clusterと同様に簡単にできますね!

Unity AssetStoreやBoothの3Dモデルを組みあわせて、君だけの最強のもなふわすい~とる~むを作ろう!
(年末年始の休暇中にPublicでもなふわすい~とる~むをアップロードしなおします。よろしくお願いします。)

本当は、もなふわすい~とる~むに由来するものを置いたワールドを作成しPublicで公開するまで終えたかったですが、ひとまずここまで(随時更新していきます。)

もなふわすい~とる~む Advent Calendar 2020の8日目の記事は、バーチャルHigh Performance C#erもといスーギ・ノウコ自治区さんの「C# Source GeneratorによるAOSOAを活用したDOTSプログラミング補助の試みとそのUnityにおける敗北」です。
果たして、彼女は敗北の先に何を見たのか?

最後に推し語り

 巻乃もなかさんに出会って、大体1年くらいが立ちました。
 はじめの出会いは、Twitterの人が「たすけて!!!もなふわすい~とる~む!!!」と言っているのを見て、そのひとが貼っていた配信のリンクから飛んだのが始まりだと記憶しています。

 配信を開いて1分くらいは「ふーん、おもしれー女」くらいの感想だったんですが、あいさつしたら「あ、サンマックスさんだ~!」と言われ、その印象は一瞬で「やべー女」に変わりました。たぶん、ふぁぼかRTか何かの通知から名前を見かけられていたんでしょうけど、すごいですよね。すごい。。。配信に来るかどうかもわからない人の名前を覚えられる・・・?

 たしか、その初めましての配信ではバイクだったか工具だったかの話題に触れられていて、自分の前職がその手の職だったり、趣味でバイクに乗っていたことも併せて、とても惹かれる配信内容でした。

 息継ぎもせずに語られるそのフルスロットルなトーク、その趣味に通じている人なら「こいつ、わかっている」と思わせる、浅くない内容。僕が「バイクの排ガスのにおい良いよね」とコメントすると「2stのにおいすき~!」と返される。思わずニヤリとしてしまいました。

 そのほかにも、女の子らしい(最近はこういう表現は憚られますが、前述の話題とのギャップもあって、あえて女の子らしいと表現します)「最近みつけたコンビニスイーツ」や「動物の話(猫やカニ、ゴリラ(どうして?))」、「お星さまの話」など様々なジャンルでトークを展開しています。

また、「お星さまの話」といえば、巻乃もなかさんの趣味の一つに「天体観測」もあります。
これも前述のバイクと同じように「オッ」と思わせる内容です。以下、参考リンク

初めての天体撮影入門

みんなもハマろうレンズ沼

端書ですが、これにてもなふわアドベントカレンダーの7日目の記事を締めたいと思います。

後日談というか今回のオチ

もなふわアドベントカレンダー 26日目です。
25日目は巻乃もなかさんの記事でした!

以下、7日目の続き。

VRChat+に登録したら、「New User」から「User」を飛び越え「Known User」になりました!
キャプチャ.PNG

ということで、さっそく作成したワールドをPublicにアップロードしてみました!(アップロードの仕方については前述のとおりです!

パブリックリンクはこちらで、ワールドの様子は以下のような感じです!

・羊の国の一角
VRChat_1920x1080_2021-01-02_10-31-44.043.png

・バイクに腰掛けられます。
VRChat_1920x1080_2021-01-02_10-36-25.678.png

・みんな大好きミラー
VRChat_1920x1080_2021-01-02_10-37-04.200.png

・家の中にある矢印を追うと・・・
VRChat_1920x1080_2021-01-02_10-37-59.641.png

・親の顔より見たもなふわすい~とる~む
VRChat_1920x1080_2020-12-31_18-16-18.792.png

使用したアセットについての紹介

  • Suburb Neighborhood House Pack (Modular)
    • 家の概観(屋根、床、壁など)、道路などを構成しているアセットです。年末年始セール中で$69→$34.5になっているので、気になった方はぜひ。
  • House Furniture Pack
    • 上記と同じパブリッシャさんのインテリアのパックです。上記同様年末年始セール中で半額になっています。
  • Farm Animals FullPack
    • かわいい動物たちのアニメーション付きのモデルが入っているパックです。
  • Animating Bunting Flags
    • もなふわすい~とる~むの背景をかざるフラッグです。
  • Dessert Heaven Pack
    • もなふわすい~とる~むの背景を飾るアイスです。
  • JSGorilla
    • もなふわすい~とる~むの背景をかざるゴリラです。
  • Snow Crab (Chionoecetes)
    • + もなふわすい~とる~むのゆかいな仲間たちのカニです。探してみてね。年末年始セール中で半額。
  • Next-gen Camera
    • もなふわすい~とる~むにおいてあるカメラです。
  • Cloudy Day Skybox - Vol. 2
    • スカイボックスに使用しました。年末年始セール中で30%オフ。
  • 14 Arrow Animations
    • 矢印です。家の中にある矢印を追うといいことあるよ。
  • Deserted Village
    • ガレージを抜けた庭にある机に使用しています。年末年始セール中で半額。
  • Old Motorcycle PBR
    • ガレージにあるバイクです。
  • BMW R75
    • BMW・R75は、BMW製のサイドカー付きオートバイである。
      • 概要
        • 主に第二次世界大戦中のナチス・ドイツ軍において使用された。その出自はやや特殊で、オートバイではあるがサイドカーの装着を前提としている。サイドカー側の車輪もレバーで駆動させることができる「パートタイム二輪駆動」構造になっていて、不整地走破性能は当時のサイドカー付きオートバイとしては、非常に高いものであった。
        • 戦後、本車両のデザイン、二輪駆動構造を模倣・参考にしたソ連-ロシア製「IMZ・ウラル」や、現ウクライナ製「KMZ-DNEPR」が現在でも製造されている。また、戦後の東ドイツでは、本車のエンジン改良型「AWO-700」というサイドカーも製造されていた。
        • なお、後年BMW・R75/5と呼ばれる車種が生産されたが、これは、上記車種とはエンジンのシリンダーレイアウトなどに共通性を見出すことができるものの、実質的には別の車両である。
  • Garage Props Collection
    • ガレージ内のツールや棚などに使用しています。
  • ビール
    • ガレージを抜けた庭にあるビールに使用しています。
  • オリジナル3Dモデル Rgray【アルグレイ】
    • 前述のワールド紹介に使用しているアバターです。僕の愛用のアバターでもあります。
    • 期間限定でベルガモッド(バイク)が付属していました。どこかZX-10Rみのあるバイク。
    • Kawasakiはいいぞ。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unityの非同期復帰の実装を覗いてみた(Async/Await/Coroutine)

WPFの非同期復帰の実装を覗いてみた(Async/Await/Dispatch.BeginInvoke)
のUnity版です。合わせて読んでいただきたい想定です。

Unityのコルーチンシステム

Unityの非同期システムは基本的にはイテレーターオブジェクトを転用したコルーチンです。

StartCoroutine(MethodAsync());
IEnumerator MethodAsync()
{
    // メインスレッド
    yield return new WaitForSecond(10);
    m_UIText.color = Color.black;
    // メインスレッド
    bool isWaiting = true;
    int result = 0;
    // メインスレッド
    new Thread(() =>
    {     
      // ワーカースレッド
      for(int i = 0; i < 100000000; i++) result += i; // ハチャメチャ重い処理
      isWaiting = false;
      // ワーカースレッド
    }).Start()
    // メインスレッド
    while(isWaiting) yield return null; // ワーカースレッドの処理が終わるまでフレームを送り続ける
    m_UIText.text = $"RESULT: {result}";
}

WPFでは、ワーカースレッド側のコンテキスト(≒スレッド)でDispatch.BeginInvokeを叩くことで、後続のメインスレッドでやって欲しい処理をキューに積んでいました。Unityでは「終わってるかどうかをメインスレッド側から積極的に確認しに行く」という実装ができます。
そして多分このやり方が一般なんじゃないかなと個人的には思います。

言葉を濁しているのは、ゲームというアプリケーションの特性上、ワーカースレッドを使うよりもタイムスライス(複数フレームでちょっとずつ進める)や、そもそも待つほど重い処理をすることが稀で待ちが発生するのはディスクアクセスやネットワークアクセス等標準ライブラリで事足りてワーカースレッドを意識しなくてもよい場合が多いからです。そしてそれら標準ライブラリの中身がどうなっているのかは公開されていません。

その代わりに、WPFのDispatcher.BeginInvokeを使った場合だとどんどんネストが深くなっていくのに対して、コルーチンでは結構フラットに書くことができます。

内部は公開されていないのですが、おそらく次のような実装になっているものと思われます。(あくまでイメージです)

static void Main(string[] _)
{
  var coroutinIterators = new List<IEnumerator<YieldInstruction>>(); // 終了していないコルーチンのリスト

  while(true) // 半無限ループ
  {
    var frameTime = StopWatch.Start();
    foreach(var coroutine in coroutinIterators.ToArray())
    {
      var completed = !coroutine.MoveNext();
      var next = coroutine.Current;
      if(completed)
      {
        coroutinIterators.Remove(coroutine);
      }
      else if(next != null)
      {
        coroutinIterators.Remove(coroutine);
        coroutinIterators.Add(WaitInstruction(instruction, coroutine));
      }
    }
    while(frameTime.Elapsed < TimeSpan.FromSeconds(1.0/60)); // 60FPS
    Repaint();
  }
}

static IEnumerator WaitInstruction(YieldInstruction instruction, IEnumerator<YieldInstruction> continueCoroutinr)
{
  while(instruction.keepWaiting) yield return null;

  forech(var item in continueCoroutinr)
  {
    yield return item;
  }
}

AsyncAwaitの動作の実装

UnityでもC#である以上、awaitするとSynchronizationContext.Current.Postによってメインスレッドに復帰するということは代わりません。WPFではSynchronizationContext.CurrentDispatcherSynchronizationContextというDispatcher.BeginInvokeに流す実装になっていました。Unityではこれに相当するUnitySynchronizationContextがあります。
https://github.com/Unity-Technologies/UnityCsReference/blob/master/Runtime/Export/Scripting/UnitySynchronizationContext.cs#L59

m_AsyncWorkerQueueというのが出てきますが、これは恐らくコルーチンのリストとは別のキューだと思われます。
そしてこのm_AsyncWorkerQueueの中身を実行しているのがUnitySynchronizationContext.ExecuteTasks…なのですが、これはネイティブから呼ばれているのでこの先は公になっていないところです。おそらくですが、以下のようなコルーチンがグローバルで走っているイメージなんじゃないかなと思います。

StartCoroutine(ExecuteTaskCoroutin()); // エンジンの初期化タイミング(ユーザーコードが走りだす前に)
IEnumerator ExecuteTaskCoroutin()
{
  while(true)
  {
    UnitySynchronizationContext.ExecuteTasks();
    yield return null;
  }
}

Coroutine vs AsyncAwait

UnityのC#は周回遅れということもあって、そもそもAsyncAwaitが使えないPJも多々あると思います。
また、長いことコルーチンでやってきた中に現れたAsyncAwaitは眉唾ものとして扱われがちな気がします…
(いやC#に入ったのもう10年前なんですけど…)

パフォーマンスの観点からみると、コルーチンはアクティブなコルーチン全てに対して毎フレーム監視をする必要がああります。(さすがにWaitForSecondとかは最適化が入ってそうですが)一方でAwaitでは、毎フレームの監視対象はキュー一つだけで済みます。確かにTaskや取れに類するオブジェクトは軽くはないですが、それはEnumeratorも同じです。故にAsyncAwaitに軍配が上がるケースが大半に思われます。

表現力の観点からみると、コルーチンにはいいところが一つもありません。Awaitでは「戻り値が返せる」「例外を伝播できる」「ラムダ式で書ける」「Task関連の便利ライブラリが使える」などありますが、コルーチンでは一切できません。強いて言うなら普通の配列からGetEteratorでコルーチンをつくることもできますが、使い道はないでしょう。

読みやすさの観点からみると、これは主観に依るところが大きいので何とも言えませんが…。Coroutineではメソッド中でコンテキストが変わってしまう可能性がありませんが、Asyncの場合それがありえます。ConfigureAwait(false)は完了後の呼び出し元コンテキストへの復帰を無効にします。こういったけ―スは多くはないでしょうけど。

まとめというか余談

実際に中身を覗いてみると、特性がよくわかりますね。
私は今、幸いにもAwait書いてもいいよーな環境にしばらく居るのですが、頑張ってコルーチンこねこねしているところを直すときなどに何か言われそうな気がしてしまします。そういったときにちゃんと説明できないと「やっぱりレガシーの方が良いんじゃないの?」ってなっちゃいますし、コードレビューをする際にも自信をもって「Awaitですっきり書けないでしょうか?」と提案ができるものです。
そんなことを思って書いた二本でした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unityでプログレスバー(ライフゲージ)を実装する



プログレスバーとは、よくゲームで見かけるライフゲージとかローディング中とかに使えわれるこんなやつ、
Image from Gyazo
自分で作るのは大変だけど、Unityのアセットを利用したら簡単に実装できる。

動作確認バージョン

Unity 2019.4.13f1

手順

アセットのダウンロード

いろいろあるけど、無料で簡単そうな
ProgressBar Pack
Image from Gyazo
をダウンロード&インポート

Canvasでの作業

Hierachy > + > UI > Canvas
Image from Gyazo

PrehabをCanvasへ
Image from Gyazo

プログレスバーが現れた
Image from Gyazo

スクリプト作成

空のGameObjectを作成
Hierachy > + > Create Empty
Image from Gyazo

Scriptを新規作成
project > + > C#Script

名前をDemoScriptとしておく。(なんでもいい)

そのScriptをGameObjectにアタッチ
Image from Gyazo

以下のコードを書く

DemoScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DemoScript : MonoBehaviour
{
    public ProgressBar Pb;
        public int value = 60;

    void Update()
    {
        Pb.BarValue = value; 
    }
}

GameObjectのInspector
DemoScript(Script) > Pb に
UI ProgressBar(ProgressBar)
をセット
Image from Gyazo

PLAY

できた!
Image from Gyazo


参考サイト

Asset Store UPLN : ProgressBar Pack How To Use

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unityでライフゲージなどに使われるプログレスバーを実装する



プログレスバーとは、よくゲームで見かけるライフゲージとかローディング中とかに使われるこんなやつ、
Image from Gyazo
自分で作るのは大変だけど、Unityのアセットを利用したら簡単に実装できる。

動作確認バージョン

Unity 2019.4.13f1

手順

アセットのダウンロード

いろいろあるけど、無料で簡単そうな
ProgressBar Pack
Image from Gyazo
をダウンロード&インポート

Canvasでの作業

Hierachy > + > UI > Canvas
Image from Gyazo

PrehabをCanvasへ
Image from Gyazo

プログレスバーが現れた
Image from Gyazo

スクリプト作成

空のGameObjectを作成
Hierachy > + > Create Empty
Image from Gyazo

Scriptを新規作成
project > + > C#Script

名前をDemoScriptとしておく。

そのScriptをGameObjectにアタッチ
Image from Gyazo

以下のコードを書く

DemoScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DemoScript : MonoBehaviour
{
    public ProgressBar Pb;
        public int value = 60;

    void Update()
    {
        Pb.BarValue = value; 
    }
}



GameObjectのInspector
DemoScript(Script) > Pb に
UI ProgressBar(ProgressBar)
をセット
Image from Gyazo

PLAY

できた!
Image from Gyazo


参考サイト

Asset Store UPLN : ProgressBar Pack How To Use

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DepthFade(ソフトパーティクル)を利用したシェーダーをUnityで実装する

初めに

DepthFadeでこんなの作れます
シェーダーをアタッチした半透明オブジェクトが、不透明オブジェクトに触れている時、その境界線に色が描画される
DepthFadeRim.PNG

DepthFadeとは

元々はUE4のマテリアルノードの一つ
これから描画しようとするオブジェクトの深度と、既に描画されている深度バッファの差を算出して、値に応じて透過処理を行う
これにより半透明オブジェクトが不透明オブジェクトに対して、めり込んだり刺さっているように見える状態を緩和してくれるメリットがある
名前の由来はその名の通り、深度値を利用してフェード処理を行っている所から付けられている

因みに全く同じ手法をパーティクルに当て嵌めたものを「ソフトパーティクル」と言い、主に煙のパーティクルなどでめり込みを防いだり重なりを緩和する目的で使われている

サンプル画像
tmp1.PNG

DepthFadeの機能を使って交差位置に線を描画する

今回はDepthFadeの「これから描画しようとするオブジェクトの深度と、既に描画されている深度バッファの差を算出して、値に応じて透過処理を行う」部分を利用して「透過処理」を「指定した色の描画に置き換える」という事をする
こうすることにより、オブジェクトの交差部分に境界線を描画する事が出来る
※バリアの境界線や、空間スキャン、水際の境界線などで良く見る表現

シェーダーコード概要

UnityのUnlitシェーダーを改造して実装。以下の流れで処理を行っている
※シェーダーコードの一部を抜粋
※シェーダー内で使われている定義関数(ComputeScreenPosとか)については、ページ下部の参考サイトで詳しく説明されているのでそちらを参照

「頂点シェーダー」
            v2f vert (appdata v)
            {
                v2f o;
                // 3次元座標をクリップ空間座標に変換
                o.vertex = UnityObjectToClipPos(v.vertex);
                // テクスチャスケールとオフセットを考慮した値を格納
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);

                // ワールド座標系のカメラ方向のベクトルを取得する
                o.viewDir = normalize(WorldSpaceViewDir(v.vertex));
                // ワールド空間上の法線を取得
                o.normal = UnityObjectToWorldNormal(v.normal);
                // クリップ空間座標を元にスクリーンスペースでの位置を求める(xyが0~wの値になる)
                // プラットフォームごとのY座標上下反転問題も修正
                o.screenPosition = ComputeScreenPos(o.vertex);
                // ビュー空間におけるZ値(深度値)をscreenPosition.zに格納
                COMPUTE_EYEDEPTH(o.screenPosition.z);

                return o;
            }
「フラグメントシェーダー(リムライトの処理は無くても問題無し)」
            // リム値の取得
            inline fixed CalculateRim(half3 viewDir, half3 normal, half fPow, half fMul)
            {
                // 視線ベクトルと法線ベクトルの内積を求める
                half inverse = 1 - abs(dot(viewDir, normal));
                // 減衰させるため乗算を行い0~1に丸め込んで返す
                return saturate(pow(inverse, fPow) * fMul);
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // メインテクスチャ読み込み
                fixed4 texColor = tex2D(_MainTex, i.uv);

                // リムライト計算
                fixed rim = CalculateRim(i.viewDir, i.normal, _FresnelPow, _FresnelMul);

                // デプスフェード計算
                float depth = abs(LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPosition))) - i.screenPosition.z); 
                fixed depthIntersect = saturate(depth / _DepthFadeMul);
                fixed4 depthIntersectColor = (1 - depthIntersect) * _DepthIntersectColor;

                /*
                // 以下はデプスフェード計算をもう少し分かりやすく行ったもの

                // このシェーダーが実行される前のscreenPos上のカメラ深度値を取得する
                float depthSample = tex2Dproj(_CameraDepthTexture, i.screenPosition).r;
                // 深度値をカメラからのワールド空間における距離として取得する(線形化)
                float depth = LinearEyeDepth(depthSample);
                // 頂点シェーダーで求めた深度値を引いて、交差部分の値を求める(0になっていると完全に交差している)
                float screenDepth = abs(depth - i.screenPosition.z);
                // パラメーターに定義した値で交差値を調整して0~1の範囲に丸める
                fixed depthIntersect = saturate(screenDepth / _DepthFadeMul);
                // 1が交差、0が非交差という形にするため1から引いている。その結果に指定した色を反映させている
                fixed4 depthIntersectColor = (1 - depthIntersect) * _DepthIntersectColor;
                */

                // 出力色設定
                fixed4 col = texColor * _FresnelColor * rim + depthIntersectColor;
                return col;
            }

サンプルプロジェクト

コード全文は以下のプロジェクトを参照してください
※Windows10 + Unity2019.4.11f1で動作確認済み。
※URPプロジェクトを使用していますが、DepthTextureの取得をONにすればStandardプロジェクトやHDRPプロジェクトでも動作すると思います
(逆に言うとDepthTextureをONにしないとURP環境下でも動きません)
https://github.com/madoramu/DepthFade_URP

実行結果(UnlitDepthFade.shader, UnlitDepthFade.mat)
DepthFadeRim.PNG

ノーマルマップ、マスクテクスチャ付きUVアニメーションを追加したバージョン(Barrier.shader, Barrier.mat)
hoge8.gif

余談

DepthFadeとソフトパーティクルって手法は全く同じですがどっちが通じやすいんでしょうね・・・?

参考サイト

Depth Expressions
https://docs.unrealengine.com/en-US/Engine/Rendering/Materials/ExpressionReference/Depth/index.html
[UE4] マテリアルノードの解説 その3
http://monsho.blog63.fc2.com/blog-entry-136.html
Unityで水際シェーダー
https://makingt.hatenablog.com/entry/2018/08/31/154247
Shield shader
https://medium.com/@aarhed/shield-shader-85cdaf903db7
[Tutorial] Hexagon Barrier
https://darkcatgame.tistory.com/87
【Unity】Shaderでオブジェクトの交差位置に色をつける
https://www.wwwmaplesyrup-cs6.work/entry/2020/08/11/172850
【Unity】【シェーダ】カメラから見た深度を描画する
https://light11.hatenadiary.com/entry/2018/05/08/012149
ソフトパーティクルの仕組みを応用した表現
https://edom18.hateblo.jp/entry/2019/07/30/091403
Unity のソフトパーティクルのシェーダについて調べてみた
http://tips.hecomi.com/entry/2018/09/15/014050

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Mac】Unity Hubでインストールが失敗した話

今回はMacのUnityHubで新しいバージョンのエディタやモジュールが
インストールできず苦労したので備忘録を書くことにしました。
同じ問題で苦労されている方の参考になれば幸いです。

ブログ本文はこちらです。
https://tedenglish.site/mac-unityhub-installation-failed/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EVMC4UとBoltを連携させる

はじめに

拙作のEVMC4UとBoltを連携させたいというツイートを見かけました。
Boltは、最近Unity Technologiesに買収され無償化された、ビジュアルスクリプティング環境です

私自身Boltを触ったことがあまりないのですが、手探りで試してみましたので記録しておきます。

環境

  • Unity 2020.1.2f1
  • EVMC4U v3.7
  • Bolt Version 1.4.13 - September 28, 2020

EVMC4Uのセットアップ

EVMC4U v3.7は以下からダウンロードして使用します。

booth
https://booth.pm/ja/items/1801535
もしくはgithub
https://github.com/gpsnmeajp/EasyVirtualMotionCaptureForUnity

EVMC4U自体のセットアップは、UnityPackageを導入した直後に出るチュートリアルに従ってください。

image.png

Bolt のセットアップ

導入

Boltは、AssetStoreで導入後、PackageManagerから導入します。

Download後、Importできなくて困ったのですが、Toolsから「Install Bolt」をクリックで導入されるようです。
image.png

その後、セットアップに入るのですが、重要な手順がいくつかあります
image.png
image.png

Programmer Namingを選択してください。

image.png

Assembly Optionsは特に変更ありません

Type Options にてEVMC4U関係のTypeを追加してください

※これは一例です。
image.png

完了

作例

MIDI CC値を取り出す

直接取り出せます。

image.png

image.png

キャリブレーション状態を取り出す

直接取り出せます。
image.png

トラッカーの姿勢をTransformにセットする

直接取り出せますが、少し工夫が必要です。
どのデバイスが、どの位置に格納されるかは一定ではないため、リストをスキャンして、予め設定したシリアル番号に一致する姿勢にセットしています。

image.png

コントローラー情報を取り出す

以下の補助スクリプトを導入してください。
https://github.com/gpsnmeajp/EVMC4U-Bolt-Bridge/blob/main/InputReceiverForBolt.cs

適当なオブジェクトにアタッチし、ReceiverにEVMC4UのInputReceiverのGameObjectを登録します。
image.png

Boltに登録し、認識させます。
image.png

image.png

そして以下のように組むと、スティック操作でオブジェクトが動きます。
image.png

入力状態は以下のようにInspectorから確認できます。
執筆時点のバーチャルモーションキャプチャーの動作に合わせて作成しています。

image.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む