UE4 Outerについて調査してみた

この記事はUnreal Engine 4 (UE4) Advent Calendar 2018の12日目の記事です。

qiita.com

Outer?

Unreal C++を書いていると、Outerというキーワードに遭遇します。これは NewObject の引数に存在したり、かなりクラス基底部分の UObjectBase::GetOuter 関数にも存在します。 今回、このOuterについて調べてみました。

まずはコードのコメントを読んでみる

Outerのコメントを見ると、『Object thier object resides in.(このオブジェクトが存在するオブジェクト)』と説明されております。 つまりOuterは、俗にいうOwner、そのオブジェクトの親を示している……?でもActorにはOwnerというのが別に存在しているけど……?

では実際はどうなのか、例から実際の動作を見ていきましょう。

ActorのOuter

テストコードは次のような単純なものです。

void AMyActor::BeginPlay()
{
  Super::BeginPlay();
    
  UObject* CurrentOuter = GetOuter();
  while (CurrentOuter != nullptr)
  {
    UE_LOG(LogTemp, Warning, TEXT("Outer:%s"), *CurrentOuter->GetName())
    CurrentOuter = CurrentOuter->GetOuter();
  }
}

ThirdPersonExampleに自分で作ったActorを継承したBlueprintをレベルに置き、実行してみます。 結果、そのActorのOuterを辿っていくと次のようになります。

MyActor AActor

PersistentLevel(MyActor->GetOuter) == ULevel

 ┗ThirdPersonExampleMap(PersistentLevel->GetOuter) == UWorld

  ┗/Game/ThirdPersonBP/Maps/ThirdPersonExampleMap(PIEだと名前変わります) == UPackage

MyActorはPersistentLevelに作られ、PersistentLevelはThirdPersonExampleMapに作られ……といった流れになっています。 しかし、ThirdPersonExampleMapが/Game/ThirdPersonBP/Maps/ThirdPersonExampleMapに作られたと考えるのは少し違和感を感じます。 /Game/ThirdPersonBP/Maps/ThirdPersonExampleMapはUPackageなのでアセット(ファイル)なのだから、ファイル自体から作られるのではなく、他の関数から読み込まれて作られそうなイメージがあります。

なので、Outerは誰に作られたかというよりも、何によって作られたかと考えるのがしっくりくるかもしれません。

また、UObjectBaseUtilityには GetOutermost という関数もありますが、これは存在する一番上の親を取得する関数です。 つまり、さきほどのMyActorで GetOutermost 関数を呼ぶと、/Game/ThirdPersonBP/Maps/ThirdPersonExampleMapのUPackageが取得できます。

LoadObjectのOuter

次に、 LoadObject<USkeletalMesh>(this, TEXT("/Game/Mannequin/Character/Mesh/SK_Mannequin.SK_Mannequin")) したUObjectのOuterを辿った場合は以下のとおりです。

/Game/Mannequin/Character/Mesh/SK_Mannequin UPackage

というように、 LoadObject したオブジェクトのOuterはUPackageのみでした。さきほどとは違って、 LoadObject を呼んだときに引数に渡したUObjectのポインタ this がOuterに含まれておりませんでした。 ソースコードを読んでみると、どうやら LoadObject 関数の引数のOuterは、オブジェクトの読み込み・既に読み込まれているかどうかの検索先の絞り込みの判断に使われるようです。

他にも、ActorとActorComponentは乗っているLevelのアセット、 LoadObject したUObjectではそれの元となるアセットがOuterの終点になるようです。

NewObjectのOuter

では通常の NewObject したUObjectの場合にはどうなるでしょうか。

NewObject テンプレート関数は、最初の引数でOuterオブジェクトを指定します。 こちらにNULLを渡した場合、TransientPackageと呼ばれるものがOuterに設定されるようです。そして、オーバーロードされている実装には、デフォルト引数で GetTransientPackage 関数が指定されているものが存在します。 これによりグローバル変数で持っている静的なUPackageとして存在しているTransientPackageがOuterとしてデフォルト引数で渡されます。

実際に NewObject<UObject>() として関数を呼び出したときのOuterは、/Engine/Transient(UPackage)が表示されます。 Transientとは一時的という意味で、プログラム内で一時的なものとして作られたという意味で指定されているものだと思われます。UPROPERTYにもオプションでありますね。

ちなみに、 NewObject のOuter引数にNULLではなく、MyActorの this を渡した場合には次のようになりました。

Object_0

MyActor(BuleprintでWorldに置いた場合には、Blueprint名になる)

 ┗PersistentLevel(MyActor->GetOuter)

  ┗ThirdPersonExampleMap(PersistentLevel->GetOuter)

   ┗/Game/ThirdPersonBP/Maps/ThirdPersonExampleMap(PIEだと名前変わります)

Outerのまとめ

Outerは派生クラスによって取得できるものが変わることがわかりました。

では最後にまとめてみると、Outerの終点(Outermost)は次のようになるようです。

  • ActorとActorComponentはSpawnした先のLevelのアセット
  • LoadObjectしたUObjectではロード先のデータアセット
  • NewObject関数経由の場合は、引数Outerに渡したものにより変化します
  • 実行中にしか作成されない一時的なものはTransientPackageがOuterに指定されます

Outerを理解して、さらにUnreal C++を便利に使っていきましょう。


宣伝

最近はVTuberが熱い、ということでバ美肉しました。セルフ受肉です。

UE4の動画もやるかもしれませんので、よろしければよろしくお願いします。

というわけで、明日はVTuber繋がり(?)の水瀬ツバキちゃんおかずさんの『UE4 & iOS開発時のデバッグ・プロファイリング方法 まとめ 2018』です。

いつもお世話になっております。

UnitychanToonShader2.0かわいい

ユニティちゃんトゥーンシェーダーVer.2.0が発表されました。

シェーダーのダウンロードはこちらから。 unity-chan.com

この記事は、そのUnitychanToonShader2.0について解説していただいた、ntnyさんの配信の個人的メモです。 動画を観るとUnitychanToonShader2.0の使い方がわかります。

www.twitch.tv

間違って書いてしまっている部分とかもあるかもしれませんが、そこはご了承ください。 また、何か問題があればTwitterなどで連絡ください。

こちらもどうぞ。

togetter.com

アウトラインなしシェーダー

アウトラインなしにしたい場合は、UnityChanToonShader->NoOutlineの中に同様のフォルダがあるのでその中のシェーダーを選択する。

天使の輪っかが欲しい(AngelRing)

アウトライン有りはUnityChanToonShader->AngelRing。 動画ではアウトラインなしの、UnityChanToonShader->NoOutline->AngelRing->ToonShadingGradeMapを使用。 目に髪の毛や眉毛を透過させたいといった場合には、ToonShadingGradeMap_StencilMaskとToonShadingGradeMap_StencilOutを使うことで対応できる。

HighColor_Powerが従来のハイライトの値。 これだと描いている感じがしない場合、AngelRingの機能を使用する。

AngelRingのチェックを付ける。 このままだと何もおきない。 AngelRingを使うには、uv2というものを作る必要がある。

通常のモデルに貼り付けるテクスチャがuv1。 ハイライトを制御するのがuv2である。

uv2の作り方

f:id:finap:20170513140059p:plain 今回はメタセコイヤでuvの値が入った髪の毛モデルを残して、FBXで出力。

メタセコイヤでは法線が調整できないので、他のDCCツールを使って、uv2を作る。

  • ntnyさん「メタセコの水野さん(?)見てくれないかな~どれだけ法線調整が大切か知ってくれないかな~(チラチラ)」

今回は3DSMAXを使って法線を調整する。 AngelRingは法線の影響が大きいので、まずは法線を調整する。 f:id:finap:20170513140112p:plain

UVは平面投影でやる。 f:id:finap:20170513140200p:plain 描いたハイライトが、そのまま平面投影される形になる。 テクスチャに描いた色も反映されるけど、シェーダー側で設定できる。

次にMaya。 FBX吐き出すだけ。Unity上で合うnamespaceになるからいいらしい。 Mayaで法線調整できる人はMayaでもいい。

UnityでUnityちゃんの髪の毛を消す。 先程吐き出した髪の毛をアタッチする。

シェーダーをいじる

BaseColor、1st_ShadeColorで色のみをつけられる。 2nd_ShadeColor(2影)制御が難しいので、もう一声欲しい人が使うといい。(最初はおすすめしない) 基本は2nd_ShadeColor_Stepを0にして切っておいて、1陰のみで調整したほうが後で2陰が役に立つ。 まず2陰は背景照り返し用に使うといった運用がいいらしい。

ハイライトを当てる

AngelRingを有効にして、 AngelRing_Samplerにテクスチャを適用すると、AngelRingが出る。 AR_OffsetUとAR_OffsetVのARはAngelRingの略。 AR_OffsetVの値が入ると、縦方向に動かしてもベタ貼りっぽくなく見せられる。

AR_OffsetV値が0の時。 f:id:finap:20170513131652g:plain

AR_OffsetV値が0以上の時。 f:id:finap:20170513131621g:plain

注意点。uv2は光源に追従しない。

質問コーナー

Q:水で濡れたような表現も可能ですか?

テカテカにしたいんだったら、通常のシェーダー使った方がいいのでは?

Q:凸凹関係なく輪っかがすっと入れることができるということですか?

概ね合っているのですが、法線に影響は受けてしまうので、調整しないと陰がバキバキになってしまう。 法線は調整しましょう。 f:id:finap:20170513131221p:plain 左が法線調整済み。右が調整前。濃い陰に注目。

アウトライン

法線押出でやっていると、目の凹んでいる部分が鬱陶しい。

Outline_Samplerを使うとモノクロマップでアウトラインを消せる。 黒いところが消える。Ver1でも使える。 (動画では白目部分を黒くのを忘れて苦戦していた)

Farthest_DistanceとNearest_Distanceは、カメラの距離に応じて線の太さが変わるオプション。

GradeMap

NormalMapを使わずに、いい感じに影を落とせるようになる。 NormalMapよりもアバウトに作れるので、描いた絵っぽくなる。 髪の毛とか、服のしわとか。 f:id:finap:20170513131248p:plain

Cull Mode

カリングモード。 OFFにすると両面。FRONTで前が見えなくなる。BACKは後ろが見えなくなる。

Tweak_SystemShade

落影の強さを調整できる。 1st_ShadeColor_Stepとセットで調整する。 凄い表現力が変わるのでおすすめとのこと。 f:id:finap:20170513135927g:plain

ブラシっぽい表現をする

1st_ShadeColor_Featherの値をいじると可能。 f:id:finap:20170513135954p:plain

2陰を使うと、色の違う陰を使う表現ができる

紫を陰に使うような表現ができる。 f:id:finap:20170513135834g:plain

トゥーン表現小技

凹凸を無視して影を落としたいとき、影専用の見えない板を用意する。 3DObjectのPlaneをアタッチする。Shadow Onlyにし、Layerを適用にしたいものにすればOK。 CullingMaskをNothingにしてから、適用したいものだけにすれば、専用の光源になる。 f:id:finap:20170513131342p:plain

カメラ近づけると歪んじゃうときに便利なスクリプト

UnityはSceneのFov値を調整できない。

それを調整できるようにしたのが、Matsuokaさんが作ってくれた、Release Experimental Release (0.1.9) · t-mat/UnitySceneViewFovControl · GitHubが便利。

就労ビザ問題を軽く調べた

はじめに

これはビザ問題とかあまりよくわからないエンジニアが調べた記事ですので、

実際に就労ビザ取得を目指す方は鵜呑みにしないで、きちんと調べるか知っている知人などに聞きましょう。

とある話題がバズった

最近話題になったある記事がありまして、

note.mu

これに関して英語や技術力があっても、結構ハードル高いよなーと思い、勇気を振り絞ってリプライしたら

shiro さんに返信もらった!恐れ多い……ありがとうございます。

実際にいただいた記事「Island Life - アメリカと言っても広うござんす」を読むと、

かなり運ゲー感が強い。

せっかくの機会ですので、再度調べてみました。

事前に知っていたこと

まず、この記事を読む前から知っていた知識です。 以前、とある時期から海外で働いてみたいという想いを持ち、どういった経緯で働けるのか調べてみると アメリカで働くためには就労ビザが必要という問題を知った。

最近の事情をまとめてくださった

このことについてtwitterを監視していたら、@splhackさんがビザ取得方法についてまとめてくださいました。ありがとうございます。

これを見ると、修士で卒業してビザを手に入れるのが良いんじゃない?といった流れになったのですが、

自分は大学卒業していない。

いろいろ調べても無難な方法は大学卒業が前提になっているっぽい。

H-1Bビザも上記の「Island Life - アメリカと言っても広うござんす」や「アメリカの就労ビザが欲しければ留学せよ | On Off and Beyond」で書かれていることを参考にすると、大学卒もしくはプログラマーとして12年働いてないとキツイらしい。

さらにこれを書いている途中にもっと詳しいのを書いてくださいました。

blogger.splhack.org

大体上の記事を読めばよいのですが、以下はせっかく書いたので置いておきます。

大学卒業していない場合どういう手段があるか

念のためいいますが、個人的に調べたことで確実性もあるか知りません。 (むしろが情報ありましたら教えてください……)

軽く調べた結果、個人的にありそうな手段は以下の通りかと。

大学に入りなおす

大学4年+修士で1~2年かかるので、これはなかなかハードルが高い……ただし、確実性は高い?

日本支社のある会社に入って、渡米

本社がアメリカにある会社に入って(本社日本、子会社がアメリカでもいい?)、L-1Aビザを取得する。 どのビザを取ればいいかは、このツイートを参考にしました。

H-1Bビザ頑張って取る

確実に取れない可能性があるけど、H-1Bビザを取る選択肢はまだチャンスがあるかもしれないと思っています。

が、最低12年は同業種で働いていないといけないですし、しかも当たるかどうかわからない。しかも有効期限付き?(グリーンカード以外は有効期限付きかな?)

上記のL-1Aビザも、

といった情報があったり、会社の都合で日本支社にいてほしい場合とかの方が多いでしょうし、渡米できるとは限らないので結構難しそう。

ちなみに

ビザ取得時には弁護士を通した方がいいかもしれないらしいです。調べておいた方がいいと思います。

いろんな弁護士がいるんだなと思いました。

検索すると、例えば www.tomitalaw.com とか見つかりました。

今後も情報は探していきます

結局まだどういうった方法があるのか、どの方法がよいのかは調査していきます。

現状としては、shiro さんの言う通り、

「ケースバイケース」「時期と運」

といったイメージ。

会社側や国が日本の人を欲しいと思っているかとかで結構ビザ発行の難易度が変わっていくようなので

常にチェックしたり、チャンスがあったらいつでもいけるように準備しておくのが大切っぽいですかね。

合わせて読みたい