UE4|IUE5 Delegate, EventDispatcherをC++で書く方法
目次
環境
・JetBraings Rider 2022.1.1
・Unreal Engine5.1.1
Unreal Engineで使用可能なDelegateについて
Delegateの種類について
シングルキャスト、マルチキャスト、ダイナミック(動的)、イベント等の種類があります。
公式docも併せて参照されるとより理解が深まるかと思います。
デリゲート | Unreal Engine ドキュメント
Delegates and Lamba Functions in Unreal Engine | Unreal Engine 5.1 Documentation
・シングルキャスト(Singlecast)
関数を1つだけデリゲートにバインドできます。
・マルチキャスト(Multicast)
複数の関数をバインドしてすべての関数を一度に実行できます。
・ダイナミック(Dynamic)
シリアライズ可能でリフレクションを使って関数を呼び出すことができます。
通常のデリゲートよりも動作が遅くなります。
・イベント(Event)
複数の関数をバインドしてすべての関数を一度に実行できます。
マルチキャストに近いですが、任意のクラス内で定義して使います。
イベントをデリゲートするクラスのみがそのイベントの Broadcast、IsBound、Clear 関数を呼び出すことが可能で
外部クラスが Broadcast、IsBound、Clear 関数を呼び出さないようにしています。
デリゲートの宣言について
引数なし~最大引数9個までの登録が可能です
Engineコードでは下記に宣言されています。
(EngineDir)\Engine\Source\Runtime\Core\Public\Delegates\DelegateCombinations.h
// 基本の宣言 DECLARE_DELEGATE(DelegateName); DECLARE_MULTICAST_DELEGATE(DelegateName); DECLARE_DYNAMIC_DELEGATE(Delegate); DECLARE_EVENT(OwningType, EventName); DECLARE_DYNAMIC_MULTICAST_DELEGATE(DelegateName); // 戻り値有 DECLARE_DELEGATE_RetVal(ReturnValueType, DelegateName); // 引数有 DECLARE_DELEGATE_OneParam(DelegateName, ValueType); DECLARE_DELEGATE_TwoParams(DelegateName, ValueType1, ValueType2) ... Nineまであります。 // 戻り値、引数有 DECLARE_DELEGATE_RetVal_OneParam(ReturnValueType, DelegateName, ValueType) DECLARE_DELEGATE_RetVal_TwoParam(ReturnValueType, DelegateName, ValueType1, ValueType2)
// 実際に宣言を行う際の使用例 DECLARE_DELEGATE(FOnPostEditChangeOwner); FOnPostEditChangeOwner OnPostEditChangeOwner; DECLARE_DELEGATE_RetVal(FString, FOnGetSelectedCurve); FOnGetSelectedCurve OnGetSelectedCurve; DECLARE_DELEGATE_OneParam(FOnIsTransitioningChanged, bool); FOnIsTransitioningChanged OnIsTransitioningChanged; DECLARE_DELEGATE_RetVal_OneParam(bool, FOnIsAssetAutoReimportAvailable, UObject*); FOnIsAssetAutoReimportAvailable IsAssetAutoReimportAvailableHandler; // DECLARE_DYNAMIC_MULTICAST_DELEGATEに関してはBlueprintと連携可能 DECLARE_DYNAMIC_MULTICAST_DELEGATE(FConnectedToSignallingServer); // Blueprintからアサイン可能にするためにBlueprintAssignableを付与する UPROPERTY(BlueprintAssignable, Category = "Pixel Streaming Delegates") FConnectedToSignallingServer OnConnectedToSignallingServer; // Blueprintからのアサイン、呼び出しを可能にする場合には // BlueprintAssignable, BlueprintCallableを付与する DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FDynamicOnFinalPassRendered, class ACompositingElement*, CompElement, UTexture*, Texture); UPROPERTY(BlueprintAssignable, BlueprintCallable, DisplayName=OnFinalPassRendered, Category="Composure") FDynamicOnFinalPassRendered OnFinalPassRendered_BP;
C++でDelegateを記述する方法
まずは新規にActorを追加した場合のheaderの記述
#pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "(ActorName).generated.h" // 1. delegateの宣言を追加する場合にはGlobalスコープに追加することが多いです。 // ここに追加 UCLASS() class (ModuleName)_API A(ActorName) : public AActor { GENERATED_BODY() public: A(ActorName)(); protected: virtual void BeginPlay() override; public: virtual void Tick(float DeltaTime) override; // 2. class内でdelegateの宣言を書くことも可能で // Blueprint連携する場合にはこちらに書くことが多いです // ここに追加 };
次にdelegateに処理を結合するための関数を見ていきます。
基本的には以下があります。
今回はこの中から一部の使い方を解説します。
BindStatic(); // staticなグローバル関数を結合 BindRaw(); // 生のC++ポインタdelegateを結合 BindLambda(); // ラムダ関数を結合 BindWeakLambda(); BindSP(); // shared pointerベースのメンバ関数を結合 BindThreadSafeSP(); BindUFunction(); // UFUNCTION()のメンバ関数を結合 BindUObject(); // UObject継承のクラスのメンバ関数を結合
Singlecast delegateの場合(DECLARE_DELEGATE)
まずこういった使い方はしないのですが、ctorでbindしてBeginPlayで呼び出しを行っています
BindLambdaを使用したシンプルな実装例です
... DECLARE_DELEGATE(FExampleDelegate); UCLASS() class SANDBOX510_API AExampleDelegateActor : public AActor { GENERATED_BODY() FExampleDelegate ExampleDelegate; public: AExampleDelegateActor() { PrimaryActorTick.bCanEverTick = true; ExampleDelegate.BindLambda([] { UE_LOG(LogTemp, Error, TEXT("Call singlecast delegate.")); }); } protected: virtual void BeginPlay() override { if (ExampleDelegate.IsBound()) { ExampleDelegate.Execute(); } } ... };
実行するとBindした処理がExecuteで呼ばれていることが確認できます

余談ですがOutput LogのFiltersからErrorsのみやWarningsのみの表示が便利です

Multicast delegateの場合(DECLARE_MULTICAST_DELEGATE)
続いて、同様にMulticast delegateのケースも書いていきます。
以下の例では1つの処理を登録していますが
実際にはMulticast delegateなので複数の処理を登録することができます。
Singlecast delegateとの違いは処理の登録がBindではなく、Addになっている点と
実行時の処理がExecuteではなく、Broadcastになっている点です。
... DECLARE_MULTICAST_DELEGATE(FExampleDelegate); UCLASS() class SANDBOX510_API AExampleDelegateActor : public AActor { GENERATED_BODY() FExampleDelegate ExampleDelegate; public: AExampleDelegateActor() { PrimaryActorTick.bCanEverTick = true; ExampleDelegate.AddLambda([] { UE_LOG(LogTemp, Error, TEXT("Call multicast delegate.")); }); } protected: virtual void BeginPlay() override { if (ExampleDelegate.IsBound()) { ExampleDelegate.Broadcast(); } } ... };
以下が実行結果になります。
Singlecastのケースとほとんど同じように使用することが出来ます。

Dynamic singlecast delegateの場合(DECLARE_DYNAMIC_DELEGATE)
Dynamic delegateはシリアライズ可能でリフレクションを使って関数を呼び出すことができます。
要約するとBindした処理を関数名で検索することが出来ます。
ただし、Dynamic delegateは通常のSinglecast delegateと比較して動作が遅くなるという特徴があります。
また、BindDynamicで登録する関数には必ずUFUNCTIONを付与する必要があります。
... DECLARE_DYNAMIC_DELEGATE(FExampleDelegate); UCLASS() class SANDBOX510_API AExampleDelegateActor : public AActor { GENERATED_BODY() FExampleDelegate ExampleDelegate; public: // Dynamic delegateにBindする関数にはUFUNCTION()が必須となる UFUNCTION() void OnCallDynamic() { UE_LOG(LogTemp, Error, TEXT("Call dynamic singlecast delegate.")); } AExampleDelegateActor() { PrimaryActorTick.bCanEverTick = true; ExampleDelegate.BindDynamic(this, &AExampleDelegateActor::OnCallDynamic); } protected: virtual void BeginPlay() override { // IsBound() でチェックしてExecute() をする場合と同様に、関数がBindされていれば実行する ExampleDelegate.ExecuteIfBound(); } ... };
以下が実行結果になります。

Eventの場合(DECLARE_EVENT)
Eventを使うユースケースがイマイチ掴めておらずなのですが…
公式docにも「イベントは マルチキャスト デリゲート と非常によく似ています」と記載があるように似た機能ではあります。
内部的にはMulticast delegateなのかなと思います。
相違点として、戻り値を指定できない点と実行できるのは宣言したクラスだけであるということなのですが
実際にはどこからでも呼び出しが出来てしまい、イマイチ有用性が理解できておらずです。
... DECLARE_EVENT(AExampleDelegateActor, FExampleEvent); UCLASS() class SANDBOX510_API AExampleDelegateActor : public AActor { GENERATED_BODY() FExampleEvent ExampleEvent; public: // 別クラスから OnUpdate().AddSP(this, &AnotherClass::Function)のような使い方をするのが良さそう? FExampleEvent& OnUpdate() { return ExampleEvent; } AExampleDelegateActor() { PrimaryActorTick.bCanEverTick = true; ExampleEvent.AddLambda([] { UE_LOG(LogTemp, Error, TEXT("Call event.")); }); } protected: virtual void BeginPlay() override { if (ExampleEvent.IsBound()) { ExampleEvent.Broadcast(); } } };
実行結果(Multicast delegateと同様)

Dynamic Multicast delegateの場合(DECLARE_DYNAMIC_MULTICAST_DELEGATE)
これは先程紹介したDynamic delegateとMulticast delegateを合わせたものです。
シリアライズ可能で複数Bindが可能なdelegateとなっています。
この後に紹介するBlueprint連携でも使用されるため、使う機会は他より多いと思います。
ただし、負荷的には一番大きなものになりますね。
... DECLARE_DYNAMIC_MULTICAST_DELEGATE(FExampleDynamicMulticast); UCLASS() class SANDBOX510_API AExampleDelegateActor : public AActor { GENERATED_BODY() FExampleDynamicMulticast ExampleDelegate; public: UFUNCTION() void OnDynamiMulticast() { UE_LOG(LogTemp, Error, TEXT("Call dynamic multicast.")); } AExampleDelegateActor() { PrimaryActorTick.bCanEverTick = true; ExampleDelegate.AddDynamic(this, &AExampleDelegateActor::OnDynamiMulticast); } protected: virtual void BeginPlay() override { if (ExampleDelegate.IsBound()) { ExampleDelegate.Broadcast(); } } };
実行結果は以下です。

Blueprintで呼び出し可能なDelegateをC++で記述する方法
ここから本題というか、特に使うケースが多いものになると思います。
基本的には先程紹介したDynamic multicast delegateを使うことで
Blueprint上でEvent Dispatcherを追加したのと同様の処理を組むことができます。
Dynamic Multicast delegateを使用する(Event Dispacher相当)
BlueprintからアクセスするためにはDelegateの宣言をした変数に
UPROPERTY(BlueprintAssignable)
を付与するだけです。
まずはC++側のコードから書いていきます。
... UCLASS() class SANDBOX510_API AExampleDelegateActor : public AActor { GENERATED_BODY() DECLARE_DYNAMIC_MULTICAST_DELEGATE(FExampleDynamicMulticast); UPROPERTY(BlueprintAssignable) FExampleDynamicMulticast ExampleDelegate; public: AExampleDelegateActor(); protected: virtual void BeginPlay() override; // BlueprintからDelegateを実行するための関数を用意 UFUNCTION(BlueprintCallable) void Invoke() { if (ExampleDelegate.IsBound()) { ExampleDelegate.Broadcast(); } } };
上記のC++クラスを継承したBlueprintを用意します。
ここで先程のDelegate変数のExampleDelegateを打つと、Event Dispatcherと同じように扱うことができます。

Delegateに対してCustomEventをBindしてログを出力するようにしました。
Bindしただけでは実行されないため、先ほど作成したInvoke() 関数を使用して実行しています。

実行結果は以下になります。

Singlecast delegateを使用する(実はできる)
DECLARE_DYNAMIC_DELEGATEで宣言したDelegateでBlueprintと連携することも可能です。
この場合は、BlueprintAssignableではなくBlueprintReadWriteの属性を付与します。
... UCLASS() class SANDBOX510_API AExampleDelegateActor : public AActor { GENERATED_BODY() public: AExampleDelegateActor(); protected: // BlueprintReadWriteな変数なのでprivateではエラーになる DECLARE_DYNAMIC_DELEGATE(FExampleDynamicDelegate); UPROPERTY(BlueprintReadWrite) FExampleDynamicDelegate ExampleDelegate; virtual void BeginPlay() override; // BlueprintからDelegateを実行するための関数を用意 UFUNCTION(BlueprintCallable) void Invoke() { ExampleDelegate.ExecuteIfBound(); } };
この場合のBlueprint連携はBindではなく、Setterを使用します。
そのあとにEventを繋ぐだけで処理を追加することが出来ます。
さきほど紹介したEventdispatchersの方式に比べて処理が軽いという利点もあります。
ただし、Singlecastなので複数の処理を登録することはできない点に注意です。

実行結果

まとめ
Delegate自体は複数用意されていて、記述方法も独特なため最初は困惑するかと思いますが
慣れてしまえばそんなに苦戦することもないと思います。
また、よく使われるケースとしてBlueprint連携があるかと思いますが
こちらについては主に使用されるのは上記の2つだと思いますので、覚えることも少なくて済むと思います。
他にも引数がある場合にはC++であれば型名のみでよくて、Blueprint連携の場合には型名と引数名が必要だったりと微妙に違う点もあります。
おまけ
SetTimer系の処理をC++で書く方法については以前に記事にしましたので、こちらを参照ください。
papersloth.hatenablog.com
BlueprintでDelegateを引数で使用する方法(ハック的な手法)も以前に記事にしていますので、こちらも必要に応じて活用ください。
papersloth.hatenablog.com
参考資料
Unreal Engine でのデリゲートとラムダ関数 | Unreal Engine 5.1 ドキュメント
Delegates in UE4, Raw C++, and BP Exposed - UE4: Guidebook
UML Notion × Mermaidはいいぞという話
目次
環境
・Visual Studio Code(ver:1.77.3)
・Mermaid
Visual Studio Codeに拡張Pluginを追加
まずはCtrl + Shift + Xあるいは拡張機能のアイコンをクリックして拡張機能の追加画面を出す

・Mermaid Markdown Syntax Highlighting
・Mermaid Preview
の2つをインストールする

ここで動作確認のために簡単なMermaidのシーケンス図を記述する
このとき、ファイルの拡張子は.mdに変更する必要がある
```mermaid
sequenceDiagram
%% Example Comment
Character Blueprint ->> Weapon Actor: Factory経由でSpawn
Weapon Actor -->> Character Blueprint: Spawnと同時にOwnerに対してAttach
```
続いて、Command Paletteを開く(Ctrl + Shift + P)

Mermaid Previewをインストールしている状態であれば
ここでPreview Mermaidが選択できる

Previewを開くと実際のMermaidの記述と、生成される図が表示されるようになる

NotionでMermaidを記述する
まずはUMLを追加したいページにコードを追加する

デフォルト設定がJava Scriptになっているため、これをMermaidに変更する

あとは先程記述したMermaidから```mermaid ```の部分を削除してコピペしてやれば簡単にプレビューできる

Mermaidについて
Mermaidで作成可能なものは非常に豊富で
フローチャート、シーケンス図、クラス図、ガントチャート...etcと様々なものを書くことができる
導入に至った経緯としては、図を書いて説明する工数を省きたいといったものからです。
また、Notionで使用できる点も優れていて、例えばチーム開発の際の情報共有にも使いやすいですね。
また、participant as を使うことでtypedef的な書き方が出来ます。
長い名称のものを書くときなんかには便利です。
participant rig as Control Rig participant animbp as Animation Blueprint

UE5 .NET Core関連のビルドエラーあるいは文字化けしたエラーの対処について
目次
環境
・Unreal Engine 5.1.1
・JetBraings Rider 2022.1.1
結論
.NetCoreをインストールすると解決する場合がある
.NET Core 3.1 Runtime (v3.1.32) - Windows x64 Installer のダウンロード
エラーについて
新規PCに移行後に、解決してしまったためスクショを載せれなかったのですが
UE5のプロジェクトに移行した後やBlueprintのプロジェクトを新規作成後に
C++コードを追加しようとするとエラーでビルドできなくなってしまった場合や
プロジェクトをパッケージ化しようとした際などに出力されるエラーになります。
例:
hostfxr.dllに関するエラー
Build.batを実行しているあとに、後半が文字化けしたエラーになっている場合も.NetCoreのComponentが不足しているだけの場合がある
このエラーのややこしい点はVisual Studio Installerで諸々のセットアップを行った際に
C++でのデスクトップ開発、ゲーム開発にチェックを入れていても、.NetCoreのSDK等が含まれないため、少し気付きにくかったりします。
また、この問題はUE5(恐らくUE5.1以降?)で発生するもので、UE4では使用する.Netのバージョンが異なるため発生しません。
お知らせ 株式会社インターネット立方体を設立しました
株式会社インターネット を設立しました
会社HPも作ったよ~(3時間の突貫工事なので、不備があったらこっそり教えてね)
www.internetcube.co
Twitterアカウント
twitter.com
主な事業内容
1. PC/家庭用テレビゲームソフトの企画及び制作 2. AR/VR/MR(Mixed Reality)の研究開発及びコンテンツの制作 3. VTuberのプロダクション/マネジメント/運営 4. 映像及び音楽等のコンテンツの制作 5. イベント、展示会の企画、制作、及び実施 6. 書籍、印刷物の企画、制作、出版及び販売 7. 前各号に附帯関連する一切の事業
基本的にはこれまでフリーランスでやってきたのと同様にゲーム作ったりXRコンテンツを作ったりするのがメインになります。
開発業務の請け負い自体は、夏以降まで一旦予約が埋まっていて難しいかも?という状況です
ただ、別途自身の事業を行う日を設けているため、その期間に色々とコネコネとしております。
今のところ正社員を雇用する予定はありません。
ただ、業務委託でエンジニアを募集することはあるかもです。
その際にはお手伝いしてもらえたら大喜びです!
で、事業内容の中で以下の2点について
3. VTuberのプロダクション/マネジメント/運営 5. イベント、展示会の企画、制作、及び実施
何かしらの配信プラットフォームでオーガナイザー契約を結べたらいいなぁとは思っとります。
また、会場をお借りしてのリアルイベントやアートコンペやゲームジャム等
そういったイベントを開催する際に個人Vの方やイベントをやってみたいけれど実施が難しいという開発者の方などで
法人名義が必要というケースではお手伝いできればと思っています。
(もちろん、状況によってはお応えできないケースもありますが)
上記に関しては会社HPにお問い合わせフォームを設置していますので気軽にご相談をいただければです。
当たり前の話ですが、その際に誰々さんからこういった相談をいただいたという内容を一切口外することはございません。
今後ともどうぞよろしくお願いします( ´∀`)
VTuberのためのトラブルシューティング
概要
VTuberさんが配信でなにかと遭遇したりしなかったりする諸々のトラブルの解決方法を書いていたり書いていなかったり
多分真面目に書くとキリがない
私自身はVTuberの配信を見ているただのおじさんです
環境
・PC
・OS: Windows10 Pro
・CPU: AMD Ryzen 5 3500
・GPU: NVIDIA GeForce RTX 2070
・RAM: 64GB
・Storage: SSD512GB + SSD2TB + 外付けSSD2TB
PC周り
・Monitor: 43UN700
・Keyboard1: HHKB Professional Type-S(PD-KB800BNS)
Keyboard2: ARESPEAR K100F
・Mouse1: MX Anywhere3
Mouse2: MX Master 2S
・配信機材
・AudioInterface: Yamaha AG03
・Microphone: Audio-Technica AT2035(コンデンサーマイク)
・CANARE XLRケーブル(1.5m)
・SUNMON シザーアームマイクスタンド
・キクタニ ポップブロッカー
・Luppet (Personal License Ver)
・LeapMotion
・LeapMotion用ネックマウンタ
商品諸々のリンクや定価は記事の末尾に貼っておきます。
どこにでもいるリスナーのよくある視聴環境ですね!
配信全般の設定
歌枠をやりたいけど、音源ってどうしたらいいの?
https://www.youtube.com/channel/UC1tk9F5-MGXEq4LWnjmrtpA
カラオケ歌っちゃ王の音源を使用するのが安全です
詳しい規約については上記チャンネルの概要欄を読んでください
MIDI打ち込みでの音源の場合は諸々の権利を侵害するリスクが少ないですが
各投稿者さんの動画説明やチャンネル概要を見て問題がないかを事前に確認する必要があります
歌枠をやろうとしたけど、YouTubeが真っ黒な画面で音しか聞こえない(Google Chrome)
原因としてはChromeのCacheがいっぱいになっていることが多いです
1. 先ずはGoogleの設定画面を開きます

2. プライバシーとセキュリティのタブから閲覧データの削除を選択

3. 全期間を選択してキャッシュされた画像とファイルにチェックを入れてデータを削除

これでひとまずは解決するとは思いますが、Cacheを消したことでYouTube等のWebサイトからログアウト状態になると思いますので
再ログインを行ってください。
歌枠をやろうとしたけど、YouTubeの画面がチラつく(Google Chrome)
原因としてはハードウェアアクセラレーションとの相性問題が多いようです
1. 先程同様にGoogleの設定画面を開きます
2. 詳細設定を開いてシステムタブのハードウェア アクセラレーションをオフにする

ハードウェアアクセラレーションが有効な場合はGPUで処理を行うのですが
GPUとの相性問題やSpec不足でチラつきが発生するようです
ハードウェアアクセラレーションをオフにすることでCPU側で処理を行うようになります
AG-03のエコーのかかり具合を調整したい
AG DSP CONTROLLER を使用することで調整が可能です
以下のURLから自身のPCのOSに該当したものをDLしてインストールしてください

ヤマハ - ウェブキャスティングミキサー - AG DSP Controller
Windowsの場合は「AG Controller V1.0.4 for Windows 11/10 (64-bit)」ですね
起動するとEASY / EXPERTのメニューがありますが
EASYのEFFECTのつまみを調整することでエコーの強さを調整することが可能です

配信に使えるBGMを探したい
フリーBGMのサイトから探すのが安心ですね
FREE BGM (music materials) free download|DOVA-SYNDROME
・Morning_2
・パステルハウス
・野良猫は宇宙を目指した_2
なんかは皆さんも聞き馴染みのあるBGMだと思います
雑談枠でBGM無しかつ、Live2Dや3Dではないラジオ配信の場合は
回線都合で止まっているのか、単純に無言の時間なのか判別がつきにくいため
何かしらを流しておくと親切です
VTube Studioの起動
SteamからDLする際にデスクトップショートカットを作成しておくと親切

デスクトップショートカットを作成し忘れた!って人向け
Steamの設定メニューを開く

ダウンロードタブのSTEAMライブラリフォルダーを開く

VTubeStudioをインストールしているドライブのフォルダーを表示


CommonのVTubeStudioの中にVTubeStudioがあるので、ここからショートカットを作成しておくと便利

かわいいにゃんね

VTube StudioがSteamとのサーバー同期に失敗したりする場合
Steam Clientの特定のProcessをkillして再実行するのが手ではありますが
間違ってSystemのProcessをkillする可能性があるため
大人しくPCを再起動するのが無難です
Steam側の障害の場合はお手上げかも。
因みにVTuber Studio ではなくてVTube Studioです
言い間違いが多くて気になる民
SHOWROOMで配信する際の設定
SHOWROOMでOBSを使用して配信をしたい
以下のサポートページにそってポチポチと設定をすればできます(難しいことはなかった記憶)
https://support.showroom-live.com/hc/ja/articles/900003010623-OBS-Studio%E6%9C%80%E6%96%B0%E7%89%88%E3%81%A8%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%A0%E3%82%AD%E3%83%BC%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E9%85%8D%E4%BF%A1
設定が多くてややこしいよね
以下にプロファイルが公開されているので、手順に従ってプロファイルをインポートするといい感じに設定してくれるよ
https://support.showroom-live.com/hc/ja/articles/900003224006-SHOWROOM%E6%8E%A8%E5%A5%A8%E8%A8%AD%E5%AE%9A%E3%82%92%E7%94%A8%E3%81%84%E3%81%A6OBS%E3%81%A7%E9%85%8D%E4%BF%A1%E3%82%92%E8%A1%8C%E3%81%86%E6%96%B9%E6%B3%95
SHOWROOM すこアニ (仮) β版 を使おう
すこアニを使うと配信画面にギフトや星を降らせたり配信が賑やかになって
SHOWROOMだけでは飛んでしまうコメントログが追いやすいです
SHOWROOM すこアニ♪ (仮) β版
自身の配信URLのhttps://www.showroom-live.com/ の後のURLを入力して接続を押せばつなげるよ
1. OBSのソースに「ウィンドウキャプチャ」を追加

2. ウィンドウキャプチャを選択して右クリックメニューから「プロパティ」を開こう

3. ウィンドウからすこアニを選択して一致優先順位をウィンドウのタイトルに一致か、タイトルに一致、同じ種類のウィンドウを選択

4. ウィンドウキャプチャを選択して右クリックメニューから「フィルタを追加」

5. フィルタにクロマキーを追加

6. 色キーの種類を「Custom」に変更

7. 色を選択を押してHTML: の欄に「#dcffdc」を入力

あとはすこアニのレイアウトを調整すればコメントログだけがリスナーに見れるようにできたりするよ

配信に使える背景画像やマイクをお借りしよう
OKUMONO | サムネイルや配信画面に使える背景フリー素材のOKUMONO。VTuber・配信活動に。
上記のサイトからDLできるよ
先程のすこアニと組み合わせるとこんな感じの画面が作れるね

商品リンクとか
(ここから買っても特にぼくにお金が入ることはないです)
AG-03 (定価: ¥18,150ほど)
https://www.yodobashi.com/product/100000001007024202/
AT2035 (定価: ¥19,580)
AT2035|マイクロホン|株式会社オーディオテクニカ
Luppet (個人向け: ¥6,000)
Luppet
LeapMotion (定価: ¥14,000)
Amazon.co.jp: 【国内正規代理店品】 Leap Motion 小型モーションコントローラー 3Dモーション キャプチャー システム : パソコン・周辺機器
LeapMotion ネックマウンタ (¥1,650 - ¥1,700)
LeapMotion用ネックマウンタ - 129製作所 - BOOTH
おまけ
Luppet + LeapMotionの精度が気になるから見てみたいという意見があったので。
標準の環境でもキーボード、マウスの操作がなんとなく分かるのと
じゃんけんをするぐらいならできます~
@tos pic.twitter.com/BtjRIJTW8M
— まめお@技 (@PaperSlothTech) 2022年5月13日
@tos pic.twitter.com/eTTzQ6sNR2
— まめお@技 (@PaperSlothTech) 2022年5月13日
実際にVTuberとして活動する場合は
UltraLeap IR170をセットアップして、より精度の高い手の制御をしたり
パーフェクトシンク対応をしてより豊かな表情を見せれる方がいいとは思いますが、最低限のお手軽セットだとこんな感じ
最後まで読んでくれたの嬉しいので、ついでに推しの歌でも聞いてって欲しいしチャンネル登録もしてほしい( ´∀`)
www.youtube.com
UE4 Material Expressionの気持ちが知りたい
環境
UE4.27.0
概要
Material Expressionの実装が知りたくて追っていました。
docを読むだけで使い方は分かるものの、具体的な実装までは分からないことが多いためです。
Material FunctionなんかはEditorから実装が見れてお手軽ですね!
Material Expressionの例
図のような緑のノード。ダブルクリックしても実装が見れません。

Desaturationのdocは以下。
Color Expressions | Unreal Engine Documentation
Material Functionの例
図のような青のノード。ダブルクリックすると実装が見れます。


Material Expression自体はかなりの種類があります。
詳細は以下のdocに目を通ると良いでしょう。(以下はUE5のdocです)
Unreal Engine Material Expressions Reference | Unreal Engine Documentation
Material Expressionはどこから見れるの?
1. HLSL Codeから追う
Material EditorのWindow -> Shader Code -> HLSL Codeを開けばMaterial 全体のHLSLが見れます。

適当なEditorにコピペして「desaturation」を検索しますがヒットしません。
これは困った。

実際にはちゃんと実装されているんですが、それは後程解説します。
因みにIncludeされている .ush ですが、これらはUnreal Shader Fileの略称(だと思います)で、色々と便利な関数等が登録されています。
2. MaterialExpression.cpp を追う
実際のMaterial Expressionの実装についてはMaterialExpression.cpp を追うのが一番確実でしょう。
Engine\Source\Runtime\Engine\Private\Materials\MaterialExpression.cpp 内に記述があります。
Desaturationの実装については、UMaterialExpressionDesaturation() を追っていきます。
UMaterialExpressionDesaturation::UMaterialExpressionDesaturation(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { // Structure to hold one-time initialization struct FConstructorStatics { FText NAME_Color; FText NAME_Utility; FConstructorStatics() : NAME_Color(LOCTEXT( "Color", "Color" )) , NAME_Utility(LOCTEXT( "Utility", "Utility" )) { } }; static FConstructorStatics ConstructorStatics; LuminanceFactors = FLinearColor(0.3f, 0.59f, 0.11f, 0.0f); #if WITH_EDITORONLY_DATA MenuCategories.Add(ConstructorStatics.NAME_Color); MenuCategories.Add(ConstructorStatics.NAME_Utility); #endif } #if WITH_EDITOR int32 UMaterialExpressionDesaturation::Compile(class FMaterialCompiler* Compiler, int32 OutputIndex) { if(!Input.GetTracedInput().Expression) return Compiler->Errorf(TEXT("Missing Desaturation input")); int32 Color = Compiler->ForceCast(Input.Compile(Compiler), MCT_Float3, MFCF_ExactMatch|MFCF_ReplicateValue), Grey = Compiler->Dot(Color,Compiler->Constant3(LuminanceFactors.R,LuminanceFactors.G,LuminanceFactors.B)); if(Fraction.GetTracedInput().Expression) return Compiler->Lerp(Color,Grey,Fraction.Compile(Compiler)); else return Grey; } #endif // WITH_EDITOR
パッと見は何をしているのかよくわからないかもしれませんが、実装自体は非常にシンプルです。
UMaterialExpressionDesaturation::Compile() 内の一部分だけを見ればよいです。
int32 UMaterialExpressionDesaturation::Compile(class FMaterialCompiler* Compiler, int32 OutputIndex) { ... int32 Color = Compiler->ForceCast(Input.Compile(Compiler), MCT_Float3, MFCF_ExactMatch|MFCF_ReplicateValue), Grey = Compiler->Dot(Color,Compiler->Constant3(LuminanceFactors.R,LuminanceFactors.G,LuminanceFactors.B)); if(Fraction.GetTracedInput().Expression) return Compiler->Lerp(Color,Grey,Fraction.Compile(Compiler)); else return Grey; }
入力されたColorにDot() でLuminanceFactorsを指定し
入力されたFractionがある場合にはLerpして、ない場合にはDot() の結果を返しています。
LuminanceFactors はUMaterialExpressionDesaturation() で定義されており、カラーからモノトーンな色に変換するための適当な係数です。
LuminanceFactors = FLinearColor(0.3f, 0.59f, 0.11f, 0.0f);
3. HLSL Codeでは追えないの?
1. でコピーしたHLSLをもう一度見てみます。
3000行近いコードが生成されて何がなんだか……という感じなのですが、実際に見るべきは
CalcPixelMaterialInputs() 内を見れば良いです。
void CalcPixelMaterialInputs(in out FMaterialPixelParameters Parameters, in out FPixelMaterialInputs PixelMaterialInputs) { // Initial calculations (required for Normal) // The Normal is a special case as it might have its own expressions and also be used to calculate other inputs, so perform the assignment here PixelMaterialInputs.Normal = MaterialFloat3(0.00000000,0.00000000,1.00000000); // Note that here MaterialNormal can be in world space or tangent space float3 MaterialNormal = GetMaterialNormal(Parameters, PixelMaterialInputs); #if MATERIAL_TANGENTSPACENORMAL #if SIMPLE_FORWARD_SHADING Parameters.WorldNormal = float3(0, 0, 1); #endif #if FEATURE_LEVEL >= FEATURE_LEVEL_SM4 // Mobile will rely on only the final normalize for performance MaterialNormal = normalize(MaterialNormal); #endif // normalizing after the tangent space to world space conversion improves quality with sheared bases (UV layout to WS causes shrearing) // use full precision normalize to avoid overflows Parameters.WorldNormal = TransformTangentNormalToWorld(Parameters.TangentToWorld, MaterialNormal); #else //MATERIAL_TANGENTSPACENORMAL Parameters.WorldNormal = normalize(MaterialNormal); #endif //MATERIAL_TANGENTSPACENORMAL #if MATERIAL_TANGENTSPACENORMAL // flip the normal for backfaces being rendered with a two-sided material Parameters.WorldNormal *= Parameters.TwoSidedSign; #endif Parameters.ReflectionVector = ReflectionAboutCustomWorldNormal(Parameters, Parameters.WorldNormal, false); #if !PARTICLE_SPRITE_FACTORY Parameters.Particle.MotionBlurFade = 1.0f; #endif // !PARTICLE_SPRITE_FACTORY // Now the rest of the inputs MaterialFloat3 Local0 = lerp(MaterialFloat3(0.00000000,0.00000000,0.00000000),Material.VectorExpressions[1].rgb,MaterialFloat(Material.ScalarExpressions[0].x)); MaterialFloat Local1 = MaterialStoreTexCoordScale(Parameters, Parameters.TexCoords[0].xy, 0); MaterialFloat4 Local2 = ProcessMaterialLinearColorTextureLookup(Texture2DSampleBias(Material.Texture2D_0, Material.Texture2D_0Sampler,Parameters.TexCoords[0].xy,View.MaterialTextureMipBias)); MaterialFloat Local3 = MaterialStoreTexSample(Parameters, Local2, 0); MaterialFloat Local4 = dot(Local2.rgb, MaterialFloat3(0.30000001,0.58999997,0.11000000)); MaterialFloat3 Local5 = lerp(Local2.rgb,MaterialFloat3(Local4,Local4,Local4),MaterialFloat(0.75000000)); PixelMaterialInputs.EmissiveColor = Local0; PixelMaterialInputs.Opacity = 1.00000000; PixelMaterialInputs.OpacityMask = 1.00000000; PixelMaterialInputs.BaseColor = Local5; PixelMaterialInputs.Metallic = 0.00000000; PixelMaterialInputs.Specular = 0.50000000; PixelMaterialInputs.Roughness = 0.50000000; PixelMaterialInputs.Anisotropy = 0.00000000; PixelMaterialInputs.Tangent = MaterialFloat3(1.00000000,0.00000000,0.00000000); PixelMaterialInputs.Subsurface = 0; PixelMaterialInputs.AmbientOcclusion = 1.00000000; PixelMaterialInputs.Refraction = 0; PixelMaterialInputs.PixelDepthOffset = 0.00000000; PixelMaterialInputs.ShadingModel = 1; #if MATERIAL_USES_ANISOTROPY Parameters.WorldTangent = CalculateAnisotropyTangent(Parameters, PixelMaterialInputs); #else Parameters.WorldTangent = 0; #endif }
またしても長くて何がなんだか……という感じなのですが、実際に見るべき箇所はたったの2行です。
MaterialFloat Local4 = dot(Local2.rgb, MaterialFloat3(0.30000001,0.58999997,0.11000000)); MaterialFloat3 Local5 = lerp(Local2.rgb,MaterialFloat3(Local4,Local4,Local4),MaterialFloat(0.75000000));
この処理をよく見るとDesaturation() の記述はないものの、実行している処理は先程MaterialExpression.cpp で見たものと同じです。
入力されたColor に対してdot() で LuminanceFactors = FLinearColor(0.3f, 0.59f, 0.11f, 0.0f);と同じ係数を使用して
入力されたFractionに対してLerp() を使用しているだけです。
まとめ
MathExpressionの実装がどうなっているのか知りたくて色々と追ってみましたが
上記のようにEngine側のCodeとHLSL Codeから追うことができます。
何かしらの参考になれば幸いです!
以上です。
書籍紹介 箱が一緒に働く人が読んでたら嬉しい書籍一覧
- 概要
- デザイン、グラフィックス
- 数学
- エンジニアリング (全般)
- エンジニアリング (C/C++)
- エンジニアリング ( C#)
- エンジニアリング (Python)
- エンジニアリング (Rust)
- エンジニアリング (Animation)
- エンジニアリング (AI)
- エンジニアリング(Graphics)
- Direct3D12 ゲームグラフィックス実践ガイド
- DirectX 12の魔導書 3Dレンダリングの基礎からMMDモデルを踊らせるまで
- Ray Tracing Gems II: Next Generation Real-Time Rendering with DXR, Vulkan, and OptiX (English Edition)
- リアルタイムレンダリング 第4版 (Real Time Rendering Fourth Edition 日本語版)
- ゲーム制作者になるための3Dグラフィックス技術 改訂3版
- 3Dゲームファンのためのグラフィックス講座
- HLSL シェーダーの魔導書 シェーディングの基礎からレイトレーシングまで
- マンガとイラストでわかる! GPU最適化入門
- その他
概要
※そのうちまとめる!!!!!!
まだ書いてる途中だけど、とりあえずババーンと公開しちゃうか~の気持ち
オススメ度とか、本の理解しやすさ、オススメ理由くらい書きなー?
とりあえず一部を列挙しただけ
最近、別業種でオススメ書籍一覧を公開されている方の記事を見てこれは良いなと思ったのでゲーム/AR/VRえんじにゃー向けに書いてみようと思って書きなぐりました。
割と仕事に関係ない趣味のものがちょいちょい混ざってます
ざっくり箱の経歴
| ツール/言語 | ジャンル | 期間 |
|---|---|---|
| Unity/C# | モバイル運営/開発 | 1年 |
| UE4/C++ | 家庭用ゲーム | 3ヶ月(会社ないなったので短め) |
| Unity/C# | モバイル新規開発 | 1年 |
| UE4/C++ | VR R&D | 1年半 |
| C++ | ツール作成 | 2年半 |
| Unity/C# | AR R&D | 5ヶ月 |
実務的にはUE4とUnityトントンぐらいですね
趣味としてはUE4の方が長めという感じです
こういう経歴の箱がなんか良いらしいって言ってたなぁぐらいの感じで読んでもらえればです
ここのリンクから買おうがどこから買おうが、箱には何の利益にもなりません。
デザイン、グラフィックス
COLOR DESIGN カラー別配色デザインブック
CGクリエイターになるためのポートフォリオ制作の教科書
カラーグレーディング 101:映像制作における色調補正の基礎
カラーグレーディング 101:映像制作における色調補正の基礎 | Charles Haine, 高木 了, 株式会社スタジオリズ |本 | 通販 | Amazon
エフェクトグラフィックス 動き・流れ・質感の表現カタログ
CGライティングの最強の教科書
CGライティングの最強の教科書 | Lee Lanier, 高木 了, 株式会社スタジオリズ |本 | 通販 | Amazon
テクニカルアーティストスタートキット 改訂版
Amazon.co.jp: テクニカルアーティストスタートキット 改訂版 eBook : 曽良洋介, Marc Salvati, 四倉達夫: 本
数学
その数式、プログラムできますか?
その数式、プログラムできますか? | アレクサンダー・A・ステパノフ, ダニエル・E・ローズ, 株式会社クイープ | コンピュータ・IT | Kindleストア | Amazon
まずはこの一冊から 意味がわかる線形代数
まずはこの一冊から 意味がわかる線形代数 (BERET SCIENCE) | 俊全, 石井 |本 | 通販 | Amazon
エンジニアリング (全般)
達人プログラマー(第2版): 熟達に向けたあなたの旅
達人プログラマー(第2版): 熟達に向けたあなたの旅 | Thomas,David, Hunt,Andrew, 雅章, 村上 |本 | 通販 | Amazon
ゲームを動かす技術と発想 R
プログラムはなぜ動くのか 第2版 知っておきたいプログラムの基礎知識
プログラムはなぜ動くのか 第2版 知っておきたいプログラムの基礎知識 | 矢沢 久雄, 日経ソフトウエア | コンピュータ・IT | Kindleストア | Amazon
CODE COMPLETE 第2版 上下セット
リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック
Game Programming Patterns ソフトウェア開発の問題解決メニュー
エンジニアリング ( C#)
.NETのクラスライブラリ設計 改訂新版
実戦で役立つ C#プログラミングのイディオム/定石&パターン
Effective C# 6.0/7.0
Effective C# 6.0/7.0 | Bill Wagner, 鈴木 幸敏, 鈴木 幸敏 |本 | 通販 | Amazon
エンジニアリング (Python)
退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング
退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング | Al Sweigart, 相川 愛三 |本 | 通販 | Amazon
エンジニアリング (Rust)
エンジニアリング (Animation)
キャラクタアニメーションの数理とシステム - 3次元ゲームにおける身体運動生成と人工知能
キャラクタアニメーションの数理とシステム - 3次元ゲームにおける身体運動生成と人工知能 - | 智彦, 向井, 克明, 川地, 陽一郎, 三宅 |本 | 通販 | Amazon
エンジニアリング (AI)
ゲームAI技術入門──広大な人工知能の世界を体系的に学ぶ
ゲームAI技術入門──広大な人工知能の世界を体系的に学ぶ (WEB+DB PRESS plusシリーズ) | 三宅 陽一郎 |本 | 通販 | Amazon
エンジニアリング(Graphics)
Direct3D12 ゲームグラフィックス実践ガイド
DirectX 12の魔導書 3Dレンダリングの基礎からMMDモデルを踊らせるまで
DirectX 12の魔導書 3Dレンダリングの基礎からMMDモデルを踊らせるまで | 川野 竜一 |本 | 通販 | Amazon
Ray Tracing Gems II: Next Generation Real-Time Rendering with DXR, Vulkan, and OptiX (English Edition)
リアルタイムレンダリング 第4版 (Real Time Rendering Fourth Edition 日本語版)
ゲーム制作者になるための3Dグラフィックス技術 改訂3版
3Dゲームファンのためのグラフィックス講座
HLSL シェーダーの魔導書 シェーディングの基礎からレイトレーシングまで
HLSL シェーダーの魔導書 シェーディングの基礎からレイトレーシングまで | 清原 隆行 |本 | 通販 | Amazon
マンガとイラストでわかる! GPU最適化入門
マンガとイラストでわかる! GPU最適化入門 | 小口 貴弘, ヨシムネ, 加藤 諒, 山田 優花, ヨシムネ |本 | 通販 | Amazon
