読者です 読者をやめる 読者になる 読者になる

PaperSloth’s diary

Unity(C#)、UE4(Blueprint/C++)についての記事を書いたり日常のことをつぶやきます。

UE4で学ぶ初めてのプログラミングその1

UE4 プログラミング

こんちは!


今回はUE4を使ったプログラムのお話です。
UE4は触ったことがあるけど、プログラムがいまいち分からない人向けの情報と
そうでない人にもたまーーーに役に立つ情報が発信できればと思います。


主なツールとしてUE4を使用しますが、ちょくちょく脱線もする予定です。
たまに出る役に立ちそうな情報はTipsとして紹介しようと思います。

初心者だよーという人はBlueprint編だけサラッと眺めていただければと思います。


開発環境
Windows10
UE4.14.3
Visual Studio 2015

目次

Hello World (概要, C言語編)
Hello World (Blueprint編)
Hello World (Unreal C++編)



Hello World (概要, C言語編)

先ず、プログラムなどの新しい環境に触れる際や大抵のプログラミング言語の入門書では
"Hello World"と出力してみることを例題とすることが多いのです。
「世界一有名なプログラム」といっても過言ではないかもしれません。

有名なプログラミング言語Cではこのように書きます。

// HelloWorld.c

#include <stdio.h>

int main(int argc, char *args[])
{
    printf("Hello World!\n");
    return 0;
}

実行結果
f:id:PaperSloth:20170117214142p:plain



さて、本題のUE4ですが
UE4.14.3時点ではプログラミング環境が主に2種類あります。
・Blueprint
Unreal C++

それぞれにメリット・デメリットがありますが、
ここでは簡単にビジュアルスクリプト、テキストで記述するプログラミング言語とだけ認識していただければと思います。

Blueprint
- ノードを繋ぐことでプログラミングできるビジュアルスクリプト
- Level Blueprint, Class Blueprint, Animation Blueprintなどがある

Unreal C++
- C++11, 14をベースとしたテキストベースのプログラミング言語





Hello World (Blueprint編)

先ずは新しくBlueprintを作成します。

親クラスにActorを選択しています。
クラスとは何かというのはまた別の機会に説明するとして、
ようは新規にBlueprintを作成してActorを選択したという状態です。
f:id:PaperSloth:20170117215841p:plain

※Tips

親クラスはクラスBPを開くと右上に"Parent Class"として表示されます。
f:id:PaperSloth:20170117220540p:plain


さて、新規に作成されたBPのEvent Graph上には図のように3つの赤いノードがあると思います。
これらの赤いノードはEventと呼ばれるもので、
「何かが起きた」時に呼び出されるものです。

Blueprintでのプログラミングは
Eventが発生 → 処理を行う
というのが基本となっています。
f:id:PaperSloth:20170117220800p:plain
・BeginPlay
- このActor(BP)が生成された時に一度だけ実行されます。
Level上に配置している場合はそのLevelが読み込まれた最初の一回だけ呼び出されます。

・Tick
- このActor(BP)が存在する間、毎ループ呼び出されます。

・ActorBeginOverlap
- このActor(BP)が他のActorと重なった時に呼び出されます。
今回はあたり判定を持たないので、割愛。


Hello Worldを作成した結果は以下のようになります。
f:id:PaperSloth:20170117221447p:plain


作成したBPをレベル上に配置して確認してみましょう。
以下のような結果(左上にHello World!と出る)になるはずです。
f:id:PaperSloth:20170117221902p:plain


同様にTickに接続してみると
f:id:PaperSloth:20170117222224p:plain


Hello World!が出力され続けて、以下のようになると思います。
f:id:PaperSloth:20170117222244p:plain

※Tips

PrintStringにはTipsがいっぱい。
1. Duration = 0とすることでログが連続して大量に画面上に出なくなる。
f:id:PaperSloth:20170117222714p:plain

2. MetaでDevelopmentOnlyとなっており、関数定義側でも#if プリプロセッサ命令で弾かれている。
よって、ShippingBuildでは呼び出されない。

3. Networkに対応したゲーム制作の場合Prefixに
ClientではClient :
ServerではServer :
と追記される




Hello World (Unreal C++編)

Unreal C++を触るということは、ある程度UE4を理解されていると思いますので、ざっくりでいきます。

BP同様にAActorを継承して作成します。

先ほどの延長戦上の話になりますが、PrintStringの定義箇所
Engine/Source/Runtime/Engine/Classes/Kismet/KismetSystemLibrary.h
Engine/Source/Runtime/Engine/Private/KismetSystemLibrary.cpp

UFUNCTIONのMeta情報など、学べることが何気に多い関数です。
一度見てみることをオススメします。

コード

void AHelloWorldActor::BeginPlay()
{
    Super::BeginPlay();

    GEngine->AddOnScreenDebugMessage( (uint64)-1, 2.f, FColor::Cyan, TEXT( "Hello World!" ) );
}

Unreal C++側ではよくUE_LOGの方が使われると思いますが、
今回はPrintString同様に画面に描画するためにAddOnScreenDebugMessageを使用しました。
また、PrintString内でもAddOnScreenDebugMessageを使用されています。





今回はHello Worldを出すという簡単な内容にまとめてみました。
次回はもうちょっとちゃんとした説明ができるようにがんばります。


以上です!


ではまた!

UE4 Materialの小話01

UE4

こちらは「裏 Unreal Engine 4 (UE4) Advent Calendar 2016」18日目の記事です。
裏 Unreal Engine 4 (UE4) Advent Calendar 2016 - Qiita



今回はMaterialのCustomノードのお話です。


使用環境

・Unreal Engine4.13.2

目次

・参考文献
・Customノードとは
・別の方法でHLSLを書きたい

・参考文献

一昨年Advent Calenderのシモダさんのエンジン拡張の記事
UE4のShading Modelを拡張して独自のライティングや描画機能を追加する方法を公開するよ! - Qiita

昨年のAdvent CalenderのもんしょさんのCustomノードの記事
もんしょの巣穴blog [UE4] Customノード3分ハッキング

おかずさんのCustomノードの記事
UE4のCustomノード(カスタムHLSLシェーダ)を使ってみた - ぼっちプログラマのメモ



・Customノードとは

Customノードはノード内にHLSLを記述できる特殊なノードです。

公式ドキュメント
Unreal Engine | Custom 表現式

メリット
・ノードで書くと冗長な処理を楽に記述できる。
・マテリアルBPにはない、ローカル変数やループ処理が使える。

デメリット
・基本的には#includeが出来ない。
・ノードで作成したシェーダーよりも効率が悪い(詳しくは上記ドキュメント参照)
・コメントを書けない。(と思ったら書けるようになってました)


・別の方法でHLSLを書きたい

理由
・ノード内に書くのは書きにくい。IDEテキストエディタで書きたい。


方法

①参考文献で紹介したもんしょさんのinclude方式

ただし
「ハック的な手法なのでいつ穴を塞がれるかわかりません」
とのことでしたので、別の方法で書いてみたいと思いました。

そこでシモダさんのEditor拡張の記事を眺めていてふと思いました。

②Engineに書いちゃおう
Engine/Shaders/Common.usfに直接書いてしまえばいいのではないか、と。
ということで実際に書いてみました。
今回書いたのはこちら


で紹介されていた、Ditherのシャドウのちらつきを回避するコードです。

Engine/Shaders/Common.usf

float Dither(float DitherInput)
{
#if SHADOW_DEPTH_SHADER
    return 1;
#else
    return DitherInput;
#endif
}

後はエンジンを起動後にCtrl + Shift + . でシェーダーをコンパイル


実際の呼び出し
Customノード内で関数呼び出しを行うだけ。

return Dither(ditherInput);

f:id:PaperSloth:20161214223014p:plain


Dither(ditherInput);

f:id:PaperSloth:20161214223211p:plain

returnがあってもなくても良いみたいです。



余談ですが、Ditherと半透明の比較。
手前が半透明で奥がDitherです。
f:id:PaperSloth:20161214223813p:plain
ライティングが暗いので、分かりにくいのもありますがDitherは半透明の代替として十分なクオリティですね!

f:id:PaperSloth:20161214223913p:plain
空とCubeの一部が真っ赤なのはさておき、半透明とDitherではシェーダーパフォーマンスが随分と違うのがお分かりかと思います。


以上です!


明日のAdvent Calendar

明日(19日目)は どんぶつさん(@donbutsu17) による
UE4のロード周りの設定と検証 - Qiita」です。



ではまた!

Unreal C++のすゝめ03

C/C++ UE4 プログラミング

こんちは!


今回はUnreal C++入門のお話その3です。
Unreal Engine4.11 段階での内容となります。

前回の内容はこちら
papersloth.hatenablog.com

目次

Unreal C++入門( UFUNCTION編 )
・まとめ


Unreal C++入門( UFUNCTION編 )

・UFUNCTIONとは
UPROPERTY同様にさまざまな設定ができます。
ネットワークに関するClient, Server, Reliableなどの設定、
Blueprintに公開するか、Overrideさせるか否かなど。

前回同様にベーシックで簡単な物のみ紹介します。

・Blueprintとの連携

Blueprintから呼び出し可能なUFUNCTIONの特徴として、Categoryの指定がないとエラーになります。

C++側のコードをBlueprintから呼び出す
・UFUNCTION(BlueprintPure, Category = Actor)
・UFUNCTION(BlueprintCallable, Category = Character)


C++側で用意した関数にBlueprintでロジックを組み込む
・UFUNCTION(BlueprintImplementableEvent, Category = foo)
・UFUNCTION(BlueprintNativeEvent, Category = var)

・BlueprintPure

Blueprintから呼び出す際に緑色で f と書かれたものです。
特徴としては実行ピンを持ちません。
また、戻り値が必要となるため void ですとエラーになります。
f:id:PaperSloth:20160621164628p:plain


記述例:

UFUNCTION(BlueprintPure, Category = Actor)
    bool PureFunction() const;

f:id:PaperSloth:20160621171034p:plain


・BlueprintCallable

Blueprintから呼び出す際に青色で f と書かれたものです。
特徴としては実行ピンを持ちます。
f:id:PaperSloth:20160621171535p:plain


記述例:

UFUNCTION(BlueprintCallable, Category = Niagara)
    void CallableFunction() const;

f:id:PaperSloth:20160621173025p:plain


・BlueprintImplementableEvent

C++で定義した関数をBlueprintで呼び出す際に使用します。
Blueprintに実装する仮想関数のようなもので、実装がない場合この関数呼び出しは無視されます。
BlueprintImplementableEventは少し特殊で引数、戻り値を持たない場合はイベントとして表示されます。
引数、戻り値があれば、関数をOverrideすることができます。
また、BlueprintImplementableEventsはC++で実装を定義できません。


記述例:引数、戻り値なしのEventの場合

UFUNCTION(BlueprintImplementableEvent, Category = Actor)
    void ImplementableEvent();

f:id:PaperSloth:20160621181549p:plain


記述例:引数、戻り値ありの関数の場合

UFUNCTION(BlueprintImplementableEvent, Category = Actor)
    bool Implementable(float var);

f:id:PaperSloth:20160621182521p:plain


・BlueprintNativeEvent

BlueprintImplementableEventと似ています。
BlueprintNativeEventにはC++の実装があり、Blueprintがその関数をOverrideしなければ呼び出されます。
Blueprintが実装しないデフォルトの挙動を、必要に応じてBlueprintでオーバーライドしたい場合に便利です。
BlueprintNativeEventをOverrideしても、必要に応じてC++側の実装を呼び出すことができます。
イベントまたは関数エントリノードからAdd call to parent を選択すると元の関数が呼び出せます。


・まとめ

Unreal C++は素晴らC++

C++からBlueprintに関数提供をすることは勿論ながら、
BlueprintからC++へのコミュニケーションもサポートされています。

しかしながら、BlueprintNativeEventなどは負荷がより多くかかるため、限定的な条件での実装を行うべきだと思います。

さて、どこまでがC++でどこからがBlueprintで良いのかという疑問をもたれている方も多いでしょう。

※ここからは私見ですので、鵜呑みにはしないでください。

複数人で開発する場合
・プロジェクトメンバーにアーティスト、企画職が多い場合はBlueprintのみでの開発をオススメします。
Blueprint"のみ"です。

というのも、C++とBlueprintを見境なしにごちゃごちゃと書いていくと同じ処理を両方に書いていたり、処理分けがぐちゃぐちゃになることが予想されるからです。


・プロジェクトメンバーにプログラマが多い場合はC++のみでの開発をオススメします。
プログラマの大半はC++に慣れ親しんでおり、ビジュアルスクリプトを嫌う人も多いでしょう。
「Blueprintだとパフォーマンス遅いから」
「スパゲティになるし、扱いにくい」
などなど、使ったことがない人は使う前から不平不満をこぼすことでしょう。(少しでも触れた人はBlueprintの魅力に魅了されていることでしょう)
文句を言い始めたら無理にBlueprintを覚えさせるよりもC++を触らせておけば静かになることでしょう・・・


さて、最後に

・あなたが個人開発者の場合

目的は同人ゲーム開発でも、勉強のためでも何でもいいです。

Blueprintのみでいいと思います。
先ずはそれで1本ゲームを完成させてみてください。
それでも勉強のため、興味があるからなど様々な理由でC++を書きたいという方も多いでしょう。

いきなり全てをC++に書くことはオススメしません。
例えば、面倒な計算処理をC++に移植してみてはいかがでしょうか。

ちょっとした練習問題も用意してみました。
こちらはContentExampleのOwenというCharacterのBlueprintです。
この計算ではAimOffsetに使用するためのYaw, Pitchを求めています。
こういった簡単な計算をBlueprintからC++に移植してみるところから初めてみてください。
f:id:PaperSloth:20160621205222p:plain


今回私はMyActorにそれっぽい形を用意しただけですので、実装はしておりませんが
最終的にこんな感じになると思います。
f:id:PaperSloth:20160621205945p:plain


以上です!

ではまた!

Unreal C++のすゝめ02

C/C++ UE4 プログラミング

こんちは!


今回はUnreal C++入門のお話です。
Unreal Engine4.11 段階での内容となります。

前回の内容はこちら
papersloth.hatenablog.com

目次

Unreal C++入門( UPROPERTY編 )
・まとめ


Unreal C++入門( UPROPERTY編 )

・UPROPERTYとは
Unreal C++では変数定義した際にさまざまな設定ができます。
ネットワークに関する変数Replicationの設定、
BlueprintやLevelに公開するか、
BlueprintやLevelから編集可能かどうかです。

他にも設定可能なデータが沢山ありますが、今回はベーシックで簡単な物のみ紹介します。


・アクセス権限
簡潔に説明するためにちょっとした、略称で書かせていただきます。
Level → Level
Blueprint → BP
Read → R
Write → W
レベルエディター : 閲覧(Level R)
レベルエディター : 編集(Level W)
ブループリントエディター等 : 閲覧(BP R)
ブループリントエディター等 : 編集(BP W)

定義可能なアクセスに関するUPROPERTY一覧
- EditAnywhere :Level RW BP RW
- EditDefaultsOnly :Level BP RW
- EditInstanceOnly :Level RW BP
- VisibleAnywhere :Level R BP R
- VisibleDefaultsOnly :Level BP R
- VisibleInstanceOnly :Level R BP

記述例:

UPROPERTY(EditAnywhere)
    int EditAnywhere;


・Blueprintとの連携
UPROPERTY(BlueprintReadOnly) // Getのみ公開
UPROPERTY(BlueprintReadWrite) // Get・Set両方公開

記述例:

UPROPERTY(BlueprintReadOnly)
    bool ReadOnly;

この例の場合ですとLevelにもBlueprintにも表示がないため
Blueprint側から取得可能ですが、変数が定義されているのか分かりにくいです。


・カテゴリー分け
Blueprintから呼び出す際にどこに格納されているかを示すカテゴリです。
カテゴリ名は割りと何でもいいですが、わかりやすい名前を付けることをオススメします。

UPROPERTY( BlueprintReadOnly, Category = Foo )
    int foo;
UPROPERTY( BlueprintReadOnly, Category = "Foo" )
    int foo;

Categoryに定義する際は""を付けても付けなくても良いので、そこはお好みでどうぞ!

因みに

UPROPERTY( BlueprintReadOnly, Category = 'Foo' )
    int foo;

という記述をするとエラーとなります。

※追記 2016/06/21

呼び出しに階層構造を適用したい際の区切りは | となります。
記述例:Character.h 内の ACharacterの場合

UPROPERTY(BlueprintAssignable, Category="Pawn|Character")
    FCharacterMovementUpdatedSignature OnCharacterMovementUpdated;


下図のようになります。
f:id:PaperSloth:20160621145634p:plain
これで、Pawnの中のCharacterの中の変数という扱いになります。

また、Category指定がない場合について
Categoryを記述していない変数は
Valiables|クラス名 の中に格納されています。

記述例:Actorを基底としたMyActorクラスの場合

UPROPERTY(BlueprintReadWrite)
    int foo;

f:id:PaperSloth:20160621165022p:plain

・まとめ

Engineコードを見ると、UPROPERTYに色々とごちゃごちゃ書いていますが、
ひとつひとつを分解して読むと理解が深まりサクサク読めるようになると思います。

例えば、AActorクラスの中を見てみましょう。

/** The scale to apply to any billboard components in editor builds (happens in any WITH_EDITOR build, including non-cooked games). */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Rendering, meta=(DisplayName="Editor Billboard Scale"))
    float SpriteScale;

今回紹介していなかったmetaが使用されています。
DisplayNameというmetaですね。
これはSpriteScaleという変数名ですが、
Blueprintから呼び出す際にはEditor Billboard Scaleという名称で呼び出せます。

また、この変数の説明ですが、
こちらは #if WITH_EDITORONLY_DATA でくくられています。
そのため、Editorからしか使用できません。
この値を変えるとViewportで表示される画像のサイズが変更されます。



SceceComponentのScale1.0の例
f:id:PaperSloth:20160620185107p:plain

SceneComponentのScale5.0の例
f:id:PaperSloth:20160620185113p:plain


Unreal C++は素晴らC++

勿論ながら、大抵のジャンルのゲームやCGはBlueprintのみで構築可能ですし
パフォーマンスに関してもBlueprintで事足りることがほとんどです。
それでも、Unreal C++を使う必要が出てくる場面はいつかあるかもしれません。
そんな時は膨大なコードの海に怖気づかずにひとつひとつ要素を紐解いてコードを眺めてみましょう。


以上です!

ではまた!

Unreal C++のすゝめ01

UE4 プログラミング C/C++

こんちは!

今回はUnreal C++のお話です。
Unreal Engine4.11 段階での内容となります。

目次

Unreal C++は素晴らC
・おまけ


Unreal C++は素晴らC

UnrealC++は素晴らしい
Unreal Engine | UE4 の C++ プログラミング入門
公式ページでもUnrealC++は素晴らしいと書いています。


Unreal C++は通常のC++での記述と若干異なります。

Unreal C++の特徴

・エンジン全体で統一されたコーディング規約。
Unreal Engine | コーディング標準

GCを搭載しており、安全性の高いメモリ管理がされている。
Garbage Collection & Dynamic Memory Allocation - Epic Wiki

C++11ベースで設計された独自のSTL
Containers | Unreal Engine API Reference

・Blueprintとの連携をサポートしている。

・ホットリロードによって、エディタ実行中にコード変更が可能。

・おまけ

おまけというより、今回紹介したかったのがこの項目だったりします。
Goto Code Definitionというものです。

C++プロジェクトを制作した場合のみ出てくる項目です。
Blueprintのノードを選択してメニューからGoto Code Definitionを選択します。
f:id:PaperSloth:20160617133953p:plain

すると、VSが起動してコードが定義されたファイルを展開してくれます。

Unreal C++の学習をする際の参考になるのはもちろんですが、
新規機能制作の際の参考にすることもできます。
また、処理が重いノードが何してるんだろうというような負荷の検索にも使えます。

Engine側で定義されたコードはきれいに整えられており、読みやすいです。
特にC++のプロジェクトでなくても、色々と参考にすることはできますので是非ともお手すきの際に読んでみてください。



以上です!

ではまた!

UE4の古いバージョンをアンインストールしたが、メモリが足りないあなたへ

UE4

こんちは!

今回はUE4をUninstallしたけど、メモリが全然ないよー
って時のお話です。

強引にファイル消してるので、何かしら動かなくなっても自己責任でお願いします。


先ず、古いバージョンのUE4を消す時について。
Epic LauncherからEngine Uninstallされると思います。
f:id:PaperSloth:20160422145132p:plain


やった!Uninstallが成功したぞ!

しかし
なんだかメモリがあんまり空いていない...?
ということがあります。(ぼくはありました)


そこで、Program Filesの中身を見てみると...
Uninstallしたはずのバージョン名のフォルダがありました。
f:id:PaperSloth:20160422145433p:plain
これを手動で削除。


さらにさらに
User/UserName/AppData/Local/UnrealEngine
の中にも消したはずのバージョンファイルが残っています。
f:id:PaperSloth:20160422145159p:plain
これも手動で削除。


とりあえず、これでメモリが空きますがこの古いフォルダを
直接消すのって正直どうなんだろうって思います。

でも、まぁ動くからいいかと思ってます\(^o^)/

ぼくはこれに気付かず4.0~4.8くらいまでファイルがあってめちゃくちゃメモリ食ってました。
メモリの少ないノートPCの方などは自己責任でお試しあれ。

以上です!

ではまた!

UE4のパッケージングでデータ垂れ流した話

UE4

こんちは!

今回はUE4のパッケージングに失敗(設定間違い)して、プロジェクトデータをまるまるネットの海に公開してしまった話です(とても後悔しました)


環境
Windows10
UE4.11.2


UE4ではプロジェクトデータをパッケージングする際に様々なOptionがあり、
そこで自分のAssetを.pak拡張子として保存する設定があります。
f:id:PaperSloth:20160422145743p:plain

UE4.11現在ではDefaultではチェックが入っています。
f:id:PaperSloth:20160422141029p:plain


そこを誤ってチェックを外してしまった結果全ての.uassetを含めた形でパッケージングしてしまいました。


チェックボックス1つで自分の作り上げてきた物を盗まれることになる危険性があるため、気をつけてください。
ぼくの場合は関数化しようと思っていたダサいノードが公開されて恥ずかしにそうです。


もし、先日のIsuTarget.zipをDLされた方は削除していただけると幸いです。
データ寄越せって方はDMなりなんなりで、ご相談いただければと思います。


新しくちゃんとパッケージングしたものを公開しました。
www.dropbox.com



以上です!

ではまた!