PaperSloth’s diary

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

UE4 2の累乗か否かを判定する関数

目次

・2の累乗かを判定
・BPとUnreal C++での違い
・まとめ

環境

Visual Studio Community 2015
・Unreal Engine4.16


2の累乗かを判定

以前にBP MacroLibraryで2の累乗か否かを判定するマクロを制作しました。
その際は0, 0以下でエラーになることを指摘いただいた方々ありがとうございました。

・使用用途
 Textureのサイズが正しく2の累乗になっているか等で使用します。
 ゲーム中に使うよりはツール制作でのTextureの検索等で使うことが多いと思います。

今回は2の累乗の計算をビット演算を使って行っています。
ビットごとの AND 演算子 (&)

UObjectを親としたBlueprintMacroLibraryに追加しました。
下記はUObjectを継承したクラスから呼び出すことができるものです。
f:id:PaperSloth:20170708002659p:plain

呼び出し
f:id:PaperSloth:20170708002706p:plain

・計算
本当に2の累乗になっているかを見てみましょう。
value = 2のケース
(value & (value - 1)) == 0)

↓ 値を入れて2進数として見てみます。

(0010 & (0010 - 0001)) == 0)

0010 (value)
AND 0001 (value - 1)
----
0000 (結果)
結果が0なのでこれは2の累乗となります。

value = 7のケース
0111 & 0111 - 0001

0111 (value)
AND 0110 (value - 1)
----
0001 (結果)
結果が1なのでこれは2の累乗ではありません。

また、0の場合にもこの判定では2の累乗であるという結果が返ってきてしまいます。
しかし、0は2の累乗ではないため、最初の判定でfalseを返すようにしています。


少し話が逸れますがMath Expressionは非常に便利なので積極的に使っていきましょう
下記は

(value > 0) && ((value & (value - 1)) == 0)

の中身です。
f:id:PaperSloth:20170708002937p:plain


MathExpressionは数式を入力することで計算結果を得られます。
BPで計算を長々と行うとノードが肥大化して可読性が下がるため、必要に応じて使いましょう。
公式ドキュメントで使用可能な演算子などが載っています。
Unreal Engine | Math Expression ノード

BPとUnreal C++での違い

さて、先程のマクロを見て疑問を感じた方もいると思います。

value > 0

という判定部分です。
unsignedにすれば良いのではないかと思った方もいるかもしれません。
unsignedを雑に説明するとマイナスの数値を扱うか否かの指定です。
通常はsignedでマイナスの数値が扱えるようになっています。

これには理由があります。
あまり話題に上がらないのですが、

Blueprintではunsignedを指定できません。

Unreal C++では下記のような記述になると思います。

// header
bool IsPowerOfTwo(const uint32 value);

// cpp
bool ClassName::IsPowerOfTwo(const uint32 value)
{
    if (value == 0)
        return false;
    return !(value & (value - 1));
}

そこで、Unreal C++側でUBlueprintFunctionLibrary等を使用してuint32を指定したらどうか?と思うかもしれません。

UCLASS()
class PROJECTNAME_API UExampleBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
    GENERATED_BODY()
	
    UFUNCTION(BlueprintPure, Category = Math)
        static bool IsPowerOfTwo(const uint32 value);
};
bool UExampleBlueprintFunctionLibrary ::IsPowerOfTwo(const uint32 value)
{
    if (value == 0)
        return false;
    return !(value & (value - 1));
}

しかし、その場合は下記のようなエラーとなります。
"Error: Type 'uint32' is not supported by blueprint."
先も述べたようにBPではunsigendをサポートしていないからです。


よって、Unreal C++でBPに公開可能な同様の関数を定義したい場合は下記のようになります。

// header
UFUNCTION(BlueprintPure, Category = Math)
    static bool IsPowerOfTwo(const int32& value);

// cpp
bool UExampleBlueprintFunctionLibrary ::IsPowerOfTwo(const int32& value)
{
    if (value <= 0)
        return false;
    return !(value & (value - 1));
}

値渡しで使うことも少なそうな関数だったため、参照渡しに変更しています。
f:id:PaperSloth:20170708010141p:plain

因みにBPからも参照渡しの指定は可能です。
Pass-by-Referenceにチェックを入れるだけです。
f:id:PaperSloth:20170708010623p:plain

まとめ

今回伝えたかったことは2点です。
・Blueprintからはunsigned(プラスのみの指定)が使用できない
・MathExpressionは便利。使いどころを見分けて複雑な計算を整理しよう。

UE4 C++とUnreal C++の列挙型の扱い

目次

・結果
enumの種類
・まとめ

環境

Visual Studio Community 2015
・Unreal Engine4.16

結果

まず最初に結果を述べます。
Unreal C++では下記のような書き方が良さそうです。

UENUM(BlueprintType)
enum class EMusicType : uint8
{
    MT_Alternative UMETA(DisplayName="Alternative"),
    MT_Classic     UMETA(DisplayName="Classic"),
    MT_Dance       UMETA(DisplayName="Dance"),
    MT_Pop         UMETA(DisplayName="Pop"),
    MT_Rock        UMETA(DisplayName="Rock"),
};

DisplayNameを別途分けるか下記のような記述にするかは好みの問題だと思いますので、どちらでも。

UENUM(BlueprintType)
enum class EMusicType : uint8
{
    Alternative,
    Classic,
    Dance,
    Pop,
    Rock,
};

では長々と説明していきます。

enumの種類

先ずは通常のC++でのenumについてです。

enum Color
{
    Red,
    Green,
    Blue
};

最もよく見てきた宣言だと思います。

続いてUnreal C++でのenumについてです。
Unreal C++では"UENUM"を使用する必要があります
また、コーディング規約として接頭詞にEを付けます。

UENUM()
enum EColor
{
    Red,
    Green,
    Blue
};

これがUnreal C++での標準的な列挙型になります。
しかし、この場合は下記のようにプロパティ宣言するとエラーになります。
詳細は後ほど。

UENUM(BlueprintType)
enum EColor
{
    Red,
    Green,
    Blue
};

// ~省略~

UPROPERTY(BlueprintReadWrite, Category = Color)
    EColor ColorType;

続いてC++ではnamespaceを使用して宣言を行うようになりました。
理由としてはenumの名前をグローバルスコープにしないためです。

namespace Color
{
    enum Type
    {
        Red,
        Green,
        Blue
    };
}

上記の宣言はUnreal C++でも取り入れられました。
"KismetMathLibrary.h"で宣言されているものです。

UENUM(BlueprintType)
namespace EEasingFunc
{
    enum Type
    {
        Linear,
        Step,
        SinusoidalIn,
        SinusoidalOut,
        SinusoidalInOut,
        EaseIn,
        EaseOut,
        EaseInOut,
        ExpoIn,
        ExpoOut,
        ExpoInOut,
        CircularIn,
        CircularOut,
        CircularInOut,
    };
}

しかし、この記述ではローカルで宣言されたenumは、名前空間を使用出来ません。
この場合、ローカル構造体の中にenumを宣言します。

class FontColor
{
    struct Color
    {
        enum Type
        {
            Red,
            Green,
            Blue
        };
    };
}

これに関してはUE4でも同様のようです。
フラグとして使用している部分ですので、参考としてはイマイチですが
"UnrealClient.h"内で宣言されています。

class FViewportClient
{
public:
    struct ESoundShowFlags
    {
        enum Type
        {
            Disabled = 0x00,
            Debug = 0x01,
            Sort_Distance = 0x02,
            Sort_Class = 0x04,
            Sort_Name = 0x08,
            Sort_WavesNum = 0x10,
            Sort_Disabled = 0x20,
            Long_Names = 0x40,
        };
    };
// ~省略~
}


C++11からはenum classを使ってスコープを扱えるようになりました。

enum class Color
{
    Red,
    Green,
    Blue
};

Unreal C++もベースはモダンなC++11, 14のため、早速取り入れられています。
"ReflectionCaptureComponent.h"内で定義されています。

UENUM()
enum class EReflectionSourceType : uint8
{
    CapturedScene,
    SpecifiedCubemap,
};

また、UPROPERTYでBPに公開するenumを持たせたい場合は原則としてモダンな書き方にする必要があります。

UENUM(BlueprintType)
enum class EMusicType : uint8
{
    MT_Alternative UMETA(DisplayName = "Alternative"),
    MT_Classic     UMETA(DisplayName = "Classic"),
    MT_Dance       UMETA(DisplayName = "Dance"),
    MT_Pop         UMETA(DisplayName = "Pop"),
    MT_Rock        UMETA(DisplayName = "Rock"),
};

// ~省略~
UPROPERTY(BlueprintReadWrite, Category = Music)
    EMusicType MusicType;


下記の場合は全てUPROPERTYでBPに公開する事ができません。

enum EMusicType 

enum EMusicType : uint8

namespace EColorType {
    enum Type

namespace EColorType {
    enum Type : uint8

enum class EMusicType

無事にBPに公開できれば下記のようにGetして使うことが出来ます。
f:id:PaperSloth:20170707005116p:plain


まとめ

UE4でもエンジンコード内に旧形式のコードがあります。
徐々にモダンなC++に移行しています。
探せばnullptrでなくNULLも残っています。
理由としては変更に対する費用対効果が薄い。というもののようです。

エラーになる箇所やバグを生む危険性のある箇所はちゃんと修正してくれています。
おとなしく待ちましょう。
そして、見つけたら報告しましょう。
できればUDNで。
https://udn.unrealengine.com/users/login.html

無理ならAnswer Hubで。
Japanese - UE4 AnswerHub

日本語の誤植等はForumで。
日本語ドキュメント 誤植&誤訳 投稿所

そして、我々Engineを使う側の人間はモダンなC++を覚えましょう。

UE4 指定範囲内にActorを配置するBP

目次

・Spawnerの作成
・指定範囲にSpawnさせる方法

環境

・Unreal Engine4.16

Spawnerの作成

まずはSpawnerとなるBlueprintを作成します
親クラスはActorを選択しました。

ConstructionScriptにChildActorComponentの追加とChildActorComponentに設定するクラスを設定します。
f:id:PaperSloth:20170704230345p:plain


今回は図のようなStaticMeshだけが配置されたActorBPを使用します。
f:id:PaperSloth:20170704230241p:plain

先程のSpawnerのBPに設定します。
この時に"Instance Editable"にチェックを入れておきましょう。
Levelに配置後に任意のActor継承クラスを設定出来るようになります。
f:id:PaperSloth:20170704230608p:plain

ここまでで下記のように生成されることが確認できると思います。
f:id:PaperSloth:20170704230726p:plain


続いて、同一のActorクラスが複数生成されるように変更を加えます。
・ForLoopとSpawnNumを追加しました。
SpawnNumにはとりあえず10を入れました。
先程同様に"Instance Editable"にチェックを入れておきましょう。
f:id:PaperSloth:20170704231405p:plain
f:id:PaperSloth:20170704231519p:plain

また、Actorが複数生成されているか確認するために適当に250ずつ高さをずらしています。
とりあえず10個生成されていることが確認できました。
f:id:PaperSloth:20170704231713p:plain


試しにLevelに配置されたBPの値を変更してみてください。
・SpawnNumの数を変える
・ActorClassのStaticMeshを変えてみる。またはActorClassの指定を変えてみる。
Actorの派生クラスも使用可能なため、Characterクラスも指定可能です。
f:id:PaperSloth:20170704232015p:plain

指定範囲にSpawnさせる方法

今回は2種類のアプローチを書きます。

①距離、高さの上限を決めてその範囲内で生成する

まずはランダムで回転角を決めます。
最大角度のみ指定しておけば良いでしょう。
また、回転の方向もYawのみにしています。Roll, Pitchもランダムで指定したい場合は稀でしょう。
f:id:PaperSloth:20170704232602p:plain

次に生成させる位置を決める計算の元となるベクトルを生成します。
最大距離と最低、最高の高さを決めましょう。
f:id:PaperSloth:20170704233740p:plain


先程のノードと合わせてみましょう。
変更点は赤枠で囲っています。
SpawnNumという名前に対して生成される数が1つ多く感じてしまう紛らわしい名前だったため、LoopのStartIndexを1に変更しました。
あとは先程作成したノードを組み合わせているだけです。
f:id:PaperSloth:20170704234005p:plain


最大距離:1000
最低高さ: 0
最大高さ:1000
最大角度: 360
で設定した結果以下のようになりました。
f:id:PaperSloth:20170704234137p:plain

ConstructionScriptで実行しているため、移動したり実行したりするたびに違う結果となるでしょう。


②BoxCollisionを置いてその範囲内で生成する

まずはBoxCollisionを追加します。
サイズは適当にBoxExtentXYZを500にしています。
f:id:PaperSloth:20170704234451p:plain


次にBoxの範囲内でのランダムなベクトルの取得を行います。
内部の計算としては
Origin - BoxExtent を最小
Origin + BoxExtent を最大
とした範囲でXYZ成分の乱数を生成してベクトルとして返しているだけで非常にシンプルな実装です。
f:id:PaperSloth:20170704235711p:plain


あとは先程同様にノードをつなぎます。
f:id:PaperSloth:20170704235641p:plain


今回はBoxが地面に埋まる範囲にあったため、埋まってしまいました
f:id:PaperSloth:20170704235859p:plain

ですが先程の距離と高さでの実装に比べて生成される範囲が目に見えて分かりやすいため、汎用性が高いです。
また、flagをひとつかませてBoxでの生成と距離、高さ指定での生成方法を共存させてしまってもいいかもしれません。



ConstructionScriptを活用すれば色々なテストが楽に行なえますし、現場でのゲーム開発にも活かせる便利な機能を沢山作れるでしょう。
f:id:PaperSloth:20170705000735p:plain

UE4 便利なUPROPERTY(Bitmasks, EditCondition)

目次

・Bitmasks
・EditCondition

環境

Visual Studio Community 2015
・Unreal Engine4.16

Bitmasks

meta = (Bitmask)

オンオフの切り替えが可能なフラグをドロップダウン形式で編集可能になります。
追加方法はUPOPERTYのmetaに"bitmask"を追加します。

UPROPERTY(EditAnywhere, Category = BitMask, meta = (Bitmask))
    int bitTestFlag;

f:id:PaperSloth:20170704202246p:plain

図のようにFlagが連番で並びます。
BitMaskのみのUPROPERTYを使用したいということはまずないでしょう。


そこで、列挙型と組み合わせて使用することがあります。
今回はゲーム中の攻撃をイメージして使ってみます。

列挙型定義
通常は攻撃とダメージ種別は分けるでしょう。
ですが、今回は説明のために統合された列挙型があると仮定します。

UENUM(meta = (Bitflags))
namespace EAttackType
{
    enum Type
    {
        Blow,	// 打撃
        Slash,	// 斬撃
        Shot,	// 射撃
        Cannon,	// 砲撃
        Damage, // ダメージを与える
        Heal,	// 回復する
        Drain,	// 吸収する
    };
}

変数定義
Bitmaskと合わせてBitmaskEnumを加えました。

UPROPERTY(EditAnywhere, Category = Attack, meta = (Bitmask, BitmaskEnum = "EAttackType"))
    int8 attackType;

BitmaskEnumを加えることで理解しやすく意味のあるコードになりました。
f:id:PaperSloth:20170704203618p:plain

さらにbitmaskは複数の状態を持たせる事ができます。
そのため
回復効果のある射撃
f:id:PaperSloth:20170704203947p:plain
HP吸収の斬撃兼打撃属性の攻撃
f:id:PaperSloth:20170704203956p:plain
等を作ることが出来ます。
(先も述べたように通常は分けます。このような使い方はしないでしょう。)


EditCondition

meta = (EditCondition = boolean)

プロパティの編集が許可されているかどうかを示すための条件を指定します。
ようはdetailタブから変更できるかどうかを切り替えるものです。

今度はゲーム中のfadeをイメージして使ってみます。

UPROPERTY(EditAnywhere, Category = Fade)
    bool isFade;
UPROPERTY(EditAnywhere, Category = Fade, meta = (EditCondition = isFade))
    float fadeTime;

遷移が禁止されている場合はFadeIn, Outの時間を変更できません。
f:id:PaperSloth:20170704204840p:plain

遷移が許可されている場合はFadeIn, Outの時間を任意で変更することが可能になりました。
f:id:PaperSloth:20170704204921p:plain


最後に余談ですが
UPROPERTY()のmetaの定義は大文字、小文字どちらでも可能です。
UPROPERTY(meta = (EditCondition = isFade))
UPROPERTY(Meta = (EditCondition = isFade))

UE4 ファイルパスの話

目次

・ContentBrowserの話
Unreal C++からアセットをロードする時の注意点

環境

Visual Studio Community 2015
・Unreal Engine4.16

ContentBrowserの話

Unreal C++でプロジェクトを作成すると下記のように

  • Content
  • C++ Clsasses

という構成になります。
f:id:PaperSloth:20170703204116p:plain


Content Browser上でアセットを選択すると
Copy Referenceでそのアセットへのパスがクリップボードに保存されます。

f:id:PaperSloth:20170703204941p:plain
図の例では
StaticMesh'/Engine/VREditor/BasicMeshes/SM_Cube_01.SM_Cube_01'
が保存されます。

Unreal C++からアセットをロードする時の注意点

さて、ここからが本題です。

Content以下の自作のAssetをコード上から参照したい場合に詰まったことがあります。
(当時はCopy Referenceの存在を知らなかったので)

今回は下記のスタティックメッシュを参照してみようと思います。
f:id:PaperSloth:20170703205830p:plain

先程と同様にCopy Referenceを行ってみると
StaticMesh'/Game/Sandbox/Meshes/SM_Building.SM_Building'
というようなパスが取得できます。
そこで、気になったのが/Game/Sandbox/という部分です。
Engineのアセットの場合は/Engine/なのですが
Content以下の場合は/Game/となっており/Content/ではありません。


ロードする必要のあるアセットが正確に分かっていて、そのプロパティを初期化時に設定する場合の例です(あんまり使わない例です)。
header側

private:
    const FName MeshComponentName = TEXT("Mesh");

    UPROPERTY(Category = Actor, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
        class UStaticMeshComponent* Mesh;

public:
    ABaseActor(const FObjectInitializer& ObjectInitializer);

cpp側

ABaseActor::ABaseActor(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
    static ConstructorHelpers::FObjectFinder<UStaticMesh> buildingMesh(TEXT("/Game/Sandbox/Meshes/SM_Building"));
    Mesh = CreateOptionalDefaultSubobject<UStaticMeshComponent>(MeshComponentName);
    if (Mesh == nullptr)
        return;
    Mesh->SetStaticMesh(buildingMesh.Object);
}


結果
f:id:PaperSloth:20170703224659p:plain
無事にビルのモデルがセットされたActorが出来ました。




余談ですが、Content Browserは4つまで表示出来ます。
f:id:PaperSloth:20170703204541p:plain

Houdiniのお話01(ObjのExportのお話)

こんちは!


今回はHoudiniを使ったメッシュデータのエクスポートのお話です。
最近Houdiniを触り始めたけど、なかなか慣れなくて苦戦しています。

※Houdiniの情報等は2017/06/18のものです。

環境

Houdini Apprentice 16.0.633

目次

・Houdiniとは
・Objでエクスポートする方法

Houdiniとは

以下公式サイト
製品情報 | SideFX

ライセンスとか種類とか
・Houdini Core
 アーティストの為の様々な機能が含まれている。
・Houdini FX
 パーティクル等 VFXアーティストに必要なツールや機能が含まれている。
・Houdini Engine
 DCCツールやゲームエンジンのエディタにHoudiniのアセットをロードすることができる。

プロがお仕事で使う高いけどなんか色々出来てすごいやつです(
今回の記事では無縁なので割愛します。


・Houdini Indie
 小規模なスタジオ向けの制限付き商用ライセンス。
・Houdini Engine Indie
 DCCツールやエンジンにデータをロードできるHoudini EngineのIndie版
 3ライセンスまで無償。ありがたや。

・Houdini Apprentice
 今回使用しているもの
 Houdini FX の無料体験版で非商用利用のみ。
 レンダリング画像にはウォーターマークがつきます。

FBXのインポート"のみ"が可能で、Objのインポート、エクスポートが可能。

 つまり、FBXでエクスポートできない。とても悲しい。


Objでエクスポートする方法

Houdini ApprenticeではFBXでエクスポートできないため、Objでエクスポートしました。
やり方はとっても簡単です。


①エクスポートするメッシュ情報を作る
 今回は「Test Geometry→Test Geometry: Pig Head」を使用します。
 f:id:PaperSloth:20170618150304p:plain

②メッシュをエクスポートする
 「Geometryのノード上で右クリック→Save→Geometry...」
 f:id:PaperSloth:20170618150328p:plain

③書き出す際の形式を選択する
 図の赤枠を選択してobj形式を選択する
 f:id:PaperSloth:20170618150414p:plain
 f:id:PaperSloth:20170618150423p:plain

④Acceptボタンを押下して完了。


要はノード上でSave→Geometryを選択するだけです。
とっても簡単です!


あとはエンジンに持っていくなり煮るなり焼くなり、好きに遊びましょう(*´∀`)
f:id:PaperSloth:20170618150932j:plain



以上です!


ではまた!

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

こんちは!


今回は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を出すという簡単な内容にまとめてみました。
次回はもうちょっとちゃんとした説明ができるようにがんばります。


以上です!


ではまた!