Quantcast
Channel: historia Inc –株式会社ヒストリア
Viewing all 1002 articles
Browse latest View live

一時的なオフィスクローズおよびリモートワーク移行のお知らせ

$
0
0

平素より大変お世話になっております。

この度弊社は、新型コロナウイルス感染症(COVID-19)への対策として4月3日にオフィスを閉鎖し、全員リモートワークへ切り替えを行いましたことをお知らせいたします。※社内で発症例が発覚した等の事実はございません。

業務はいままでと変わらず進行して参りますが、電話・郵便等のオフィス機能が一時的に休止となります。郵送物は定期的に確認いたしますが、確認が遅れますことご了承ください。この期間中における電話のご連絡は、メールをはじめとしたオンラインの連絡手段にて代替頂ければと存じます。(総合お問い合わせ窓口:info@historia.co.jp)

本施策はGWの5月6日までを期限としておりますが、情勢を鑑みて延長を行う予定です。オフィス業務を再開する際には、改めて告知いたします。

皆様におかれましては大変ご不便おかけいたしますが、よろしくお願いいたします。

 

株式会社ヒストリア


[新型コロナウイルス感染症対策] ゲーム開発会社のオフィスクローズ&フルリモート移行の事例紹介

$
0
0

代表の佐々木です。

弊社は対COVID-19(新型コロナウイルス感染症)の観点から、4/3に一時的にオフィスクローズを行い、4/6からはフルリモートワーク(テレワーク)へ移行しました。一時的なオフィスクローズおよびリモートワーク移行のお知らせ)”フルリモートへ移行しました”と言っても、新しいチャレンジを行ったというような華々しいものではなく、方々にご迷惑をかけながらの一時しのぎの施策です。

判断自体が苦渋の決断でしたが、数日のうちにフルリモート環境を整える(全く整ってないですが)ところが頭を悩ませました。その間、他社事例があれば参考にしたいと思っていたため、非常に悩みましたが情報共有のためにブログにまとめて公開することにしました。

この記事は、弊社と同じような中小企業の経営層/マネージャー層/バックオフィスを対象としています。個人的な感性の話になってしまいますが、私自身今回のような騒動の中で、このようなことを書くことで自社のPRのようになってしまうことは好みません。(そもそも対応が早い方ではない) 各企業、事業の質が違い、取れる手段も違います。経営者の皆様は様々なパラメーターを天秤にかけながら、現実的かつ継続可能な手段を頭を悩ませながら探っていることかと思います。よって、このような対応を推奨する用途(もしくは批判)としてではなく、純粋な事例紹介・知見シェアとして使用されることを望みます。

書きやすかったため、ざっくりと時系列でまとめさせていただきました。少し長いので、必要そうな部分のみお読みください。

 

弊社の事業の性質

最初に、弊社の事情をご説明いたします。現在弊社で走っているプロジェクトを明かすことはできないので、公表済みの過去実績から推測できる点のみお話しします。

弊社は現在、メイン事業をゲーム制作とし、そのほかに非ゲーム(エンタープライズ)案件を扱っています。現時点では規模的にゲーム事業が8割のため、ゲーム開発会社として語らせていただきます。

一般的に、ゲーム開発会社にはいくつか種類が存在します。ソーシャルゲーム系、コンシューマー(家庭用)系、アーケード系、その他などです。その中で弊社は、モバイルの事業はほとんど行っておらず、コンシューマー(家庭用)・アーケード(ゲームセンター)・VRアトラクションをメインに扱っています。

このような事業領域では、開発は量産フェイズの量産タスク以外はコミュニケーションベースで試行錯誤をしながらモノづくりをしていくことが多く、特に弊社は各職種が立ち話やホワイトボードの前に集まって、頻繁に意見交換を行いながら開発を進めるスタイルを取っています。そのため、フルリモートによる環境の不便さ、相談の減少、伝達ミス、巻き込み力の弱まりで、開発効率が3~5割落ちるのではないかと思っています。また、専用の機器が必要になることが多く、PCのみで完結するプロジェクトは稀です。それらのプロジェクトは、リモートにしたときに進められるところまで進めて止めておく判断も必要になります。

弊社の状況をまとめると以下の通りです。

・社内55名ほど勤務(内、外部スタッフ20名ほど)
・各自デスクトップのゲーミングPC、モニターは2枚
・専用機器を使うプロジェクトが多い
・小規模プロジェクトも走っており、プロジェクト数が多い
・セキュリティ的に厳しいプロジェクトが多い
・外部協力会社で常駐いただいている方が多い
・リモートワークは産休・育休で2名のみ事例がある状態
・通常の使用ツールは、基盤としてOffice365、チャットツールとしてSlack、社内共有にConfluence、バージョン管理にPerforce(Helix Core)

以上のことから、経営的なダメージは受け入れたうえでの今回の判断となりました。同じような事業領域のゲーム開発会社の皆様は、同様の悩みを抱えているのではないでしょうか。今回弊社は、リモートを一部チームや曜日で導入するよりも、全体会やPCを持ち帰る都合もあり、やるなら一斉にやったほうが逆に統率が取りやすいとの方針で動きました。(もちろん早く全員在宅にしたかったということもあります)

それでは、弊社の事例を時系列で記載していきます。

3月下旬から、もしロックダウンしたときの対応を考え始め、話す機会のあったクライアントの皆様へ「フルリモート移行時に納期が満たせるか怪しい」旨を相談し始めました。本格的な動きは、オフィスクローズ4日前くらいからです。

 

オフィスクローズ4日前

社内で自宅環境のアンケート実施。以下の項目をMicrosoft Fomesでアンケートを取りました。まだオフィスクローズの判断は行っておらず、今後の動きを決めるために取ったアンケートでした。

・自宅に作業可能なハイスペックPCはあるか?
・そのPCは個人専用のPCか?
・そのPCにセキュリティ的に不安なソフトウェアはインストールしてあるか?(いくつか例を挙げて)
・自宅にWEBカメラはあるか?
・自宅に固定IPは持っているか?(持っていないと思うが、一応確認)
・PCに接続できる高速な有線ネットワーク回線はあるか?
・PCの設置場所はあるか?
・同居人がいる場合、個室等、同居人に作業を見られない環境はあるか?
・常時、映像 / 音声接続可能な状況か?

この時に、ヘッドセットの有無も聞いておけばよかったとあとで思いました。

 

オフィスクローズ3日前

感染者の拡大を受け、オンラインミーティングの推奨と、飲み会等を控えるようにガイドラインを改定。とりあえず念のために持っていない人数分のWEBカメラを購入。また、デスクトップはWi-Fi受信機がついていないため、有線が繋げないけど家庭にWi-Fiが飛んでいる人のためにWi-Fiのアンテナも購入

これはいよいよだと感じ、いままではヒアリングするだけだった情報をまとめることに。状況を分析の結果、最初に解決すべきは各クライアントの皆様に対して、以下の点だと情報を整理

・セキュリティの観点で環境条件を示してリモートワークの許可を頂く
・納期のご相談(施行した場合に納期を満たせなそうな見通しの場合)
・支払いの分割相談(納期調整後、必要な場合)

上記の質問状況を全プロジェクトでまとめた1つのExcelシートを作りました。ここでのフォーマットづくりは状況を一覧して思考するのに非常に便利でした。(同様に、協力会社の対応状況や相談状況をまとめた別のExcelシートも作成しました)

 

オフィスクローズ2日前

複数の知人からよく知っている企業での感染者報告を複数聞き、昼過ぎに明日か明後日をターゲットにオフィスクローズを行うと判断。各クライアントの皆様に、上記の3点を急ぎ確認を取る(Excelの空欄を埋める)ことに。

セキュリティについては、以下の3点をお約束して、ご理解いただきました。

・共有のPCではない(その人しか触らないPC)
・セキュリティ的に危ないソフトウェア(セキュリティの切れたOS、ファイル交換ソフト、エミュレーター等)をインストールしていない
・同居人に画面が見られない、ビデオチャットで情報が漏れない環境を作る

納期が満たせなそうな案件については納期のご相談をさせていただいたのですが、全クライアントの皆様に「こんな状況ですから……」と言っていただき、心より感謝しております。そう言っていただけて、本当に心が軽くなりました。

そのほか、この日から一気に物事を動かしました。ただ、この日の時点ではまだ全クライアントの皆様に確認が取れてなかったため、社内公表はしてませんでした。この日に行ったその他のことは以下の通りです。

COVID-19対策チームの発足(佐々木、プロデューサー2名、バックオフィス1名)
・対策チームのSlack部屋を作成
・オフィスクローズ実行までのタスクリストを作成
・VPNアカウントの大量発行ができるか確認
・リモート時の勤怠レギュレーションの作成開始
・リモート時に”ここを見ればOK”という、対象者全員が見られるConfluenceページのひな型作成

対策チームを人数絞ってすぐに立ち上げ、この後も日に何回も突発的なミーティングを行い、連携が甘いのを前提に担当者を割り振りながらスピード感を持って進められたのは良い流れでした。

 

オフィスクローズ前日

幸いにもこの日の午前中までに全クライアントに返答を頂けました。全体発表に向けてまずは各プロジェクトのリーダー陣に先行して伝達。発表後にプロジェクトごとに進め方の提案をレポートで上げてもらい、それを元に全プロジェクト順番にミーティングを行い、来週の動きを決めるようにしました。その際に各プロジェクトで決めるべきことと基準は以下の内容で進めました。

・できる限りプロジェクトを前に進めることを目標とする
・各プロジェクトメンバー、来週何をすればいいのかを決める
・納期の相談は終わっているので、納期合わせで考えるのではなく実現可能なプランを
・序盤は混乱が予想されるので、動きずらいスタッフに無理にタスクを振らない

全プロジェクトリーダーに先行伝達後、終業時刻の少し前に全体発表を行いました。どよめきはありつつも、明るく話を前に進めてくれたスタッフには本当に感謝です。ひとまずこの場では、オフィスクローズを明日行うこと、設備補助金(ヘッドセット、机、椅子、カーテン等を想定)を若干配布するので、急ぎ自宅環境を整えてほしいことを伝達。

この日は、ほかにもこのようなことを行いました。

・佐川さんにPC送付が可能か? →13台まで可能との返答。
・全体発表後、各クライアントの皆様に正式伝達(翌日にかけて)
・全体発表後、各協力会社の皆様に正式伝達(翌日にかけて) →特に出向に来ていただいている方、派遣の方の確認。

 

オフィスクローズ当日(4月3日(金))

この日は社内全体で準備に追われる日でした。対策チームの4名を中心に、以下のことを行いました。

・自宅環境の個別ヒアリング(特にセキュリティ面を満たせるか)
「リモート環境運用チーム」を3名指名して発足し、VPNのドキュメント、Zoomの調査、自宅のリモート環境構築のTipsをまとめてもらう ※このうち2名が元々のリモート対象者(現在も育児で併用していた)で、社内に経験者が居て助かりました。
・リモート中の「物理的セキュリティ責任者(正しく自宅環境が運用されているか)」「機材相談窓口」「ソフトウェア相談窓口」の担当者決め
・WEBカメラ配布
・この期間の就業ルールの詰め
・VPNアカウント配布(全員分の手配がギリギリ間に合いました)
・全体への就業レギュレーション発表&質問会
・PC送付(佐川さんにお願いできない分は各自タクシーで持って帰る)

就業レギュレーションは、いったん以下のようにしました。

・始業時間にZoomで全員で朝礼。出欠を取る。
・その後、チームごとに15分の朝会をZoom開催(通常時もオフィスで行っている)
・夕方に、朝会の夕方バージョンをZoom開催(減少するコミュニケーションの補填)
・退勤前、日報記入(チームごとに全員に見える形でExcelオンラインのシートに記入)
・常時接続できる人はプロジェクトごとのRoomにZoomで常時接続
・週明けの月曜日は自宅環境の構築に充てる

正直、この辺りは我々は経験が無さ過ぎて一度これで試してみよう、という形です。みなさんの事例を教えていただけると幸いです。

 

その後2日(週末)

その後、少し落ち着いて週末は以下のことを行いました。

・Zoomの有料アカウント配布(まずは各リーダー陣のみに)
・Zoomの共有部屋を立てる
・日報フォーマット作成
・自宅環境セットアップチェックリストを作成して告知

最後の自宅環境セットアップチェックリストは以下の通りです。

・物理的なリモート環境の構築
・Confluence(社内Wiki)の接続
・(PC持ち帰り以外の人は)Officeツールのセットアップ
・VPNの接続
・ネットワークドライブへのアクセス
・Perforceのアクセス
・Zoomの接続
・会社から借りた機材のリスト記入

 

週明け月曜日(リモートワーク初日)

この記事を書いている当日となりますが、朝に環境が整っている人だけでZoom朝礼を30人くらいで行いました。そして、その後チームごとの朝会も。それぞれ壁紙を工夫したりFaceRigを使ってアバターになってる人が居たりと、Zoomの操作に若干戸惑いながらも順調に終えました。通信環境は割と快適で、現時点では問題なさそうです。

Slackでトラブル報告・知見共有部屋を作り、そこで情報交換が行われています。(マイクが利かない、VPNが接続できない、などのお決まりのトラブルが出てます) 各種PCツールを使うことには慣れているので、今日明日である程度慣れるところまでは行けそうです。

 

おわりに

凄まじいスピードで動いてくれた対策チームのメンバー、突然のことながら前向きに協力してくれたメンバーには本当に感謝です。

序文の繰り返しになりますが、本記事は中小企業の経営層/マネージャー層/バックオフィスに向けて書いた事例紹介・知見共有の記事です。今まで経験したことのないこの事態において、各企業、情報共有をしながら乗り越えていければと思い書かせていただきました。急造の環境でのフルリモートワークとなってしまったので、もし同じ境遇の会社さんがいらっしゃいましたら、ぜひ情報交換しましょう。

[UE4]Statコマンドに情報を追加しよう

$
0
0

皆さん!計測してますかー!

計測といっても時間だけでしょうか?処理負荷=処理にかかった時間ですので主に時間計測をイメージするか思います。
ですが、処理に失敗した回数、存在するアクターの数、それらの最大・最小・平均値と様々情報を取得できるとより、
処理の現状を把握することができます。
これらの統計情報を確認するためにStat コマンドをつかうのですが、独自に計測情報を追加することができます。
今回はその追加方法について触れたいと思います。

Statコマンド

参考ページ
https://docs.unrealengine.com/ja/Engine/Performance/StatCommands/index.html

基本的に標準で用意されている情報で様々な統計情報を確認することができます。
自分でSTAT グループを追加することで、標準で用意されているStatコマンド以外に追加することができます。

実装方法

Statのグループの作成
書式
DECLARE_STATS_GROUP(GroupDesc, GroupId, GroupCat)
引数
GroupDesc グループ名(テキスト形式)
GroupId グループの ユニークID STATGROUP_XXX形式で指定してください。
    ※ここの「XXX」は Statコマンドの引数に渡す文字にもなります。
GroupCat 将来の使用のために予約されています。(STATCAT_Advancedを入れておけばOKです)


DECLARE_STATS_GROUP(TEXT(“StatTest”),STATGROUP_StatTest, STATCAT_Advanced);
この宣言をしてコンパイルし、「Stat StatTest」コマンドを実行するとそのグループに属した情報が表示されます。

Statの計測項目の宣言

統計情報の集める形式にはいくつか種類があります。
Cycle Counter
主に処理時間計測に使用 呼び出し回数もカウントします。
関数スコープ内の処理を計測する形式と、計測の開始と終了を任意で呼び出す手法があります。
Float/Dword Counte
フレームごとにクリアされるカウンターです。
1フレーム中に起きている情報を集計する場合に使用します。
Float/Dword Accumulator
フレームごとにクリアされずに、任意でリセット可能なカウンターです。
フレームをまたいで、情報を集計する場合はこちらを使用します。
Memory
メモリ用に最適化された特殊なカウンター、Accumulatorと同じくフレーム毎にクリアされない。
・桁数によりキロ、メガ 表記になる。
・メモリアロケータの種類を管理できる(物理メモリ、GPU、テクスチャプール等)

宣言方法
統計情報を使用するためには予めIDの宣言をする必要があります。

DECLARE_CYCLE_STAT(CounterName, StatId, GroupId)
引数
CounterName 表示される名前
StatId スタットのID(ユニークID)
GroupId グループID

各カウンターの宣言マクロ
Cycle Counter
DECLARE_CYCLE_STAT(CounterName, StatId, GroupId)
Float型(内部的にはdouble 型 (8 バイト) がベースとなっています)
DECLARE_FLOAT_COUNTER_STAT(CounterName, StatId, GroupId)
DWord 型
DECLARE_DWORD_COUNTER_STAT(CounterName, StatId, GroupId)
Float型 Accumulator
DECLARE_FLOAT_ACCUMULATOR_STAT(CounterName, StatId, GroupId)
Dword側 Accumulator
DECLARE_DWORD_ACCUMULATOR_STAT(CounterName, StatId, GroupId)
メモリ用
DECLARE_MEMORY_STAT(CounterName, StatId, GroupId)
メモリ用 メモリプール指定有り
DECLARE_MEMORY_STAT_POOL(CounterName, StatId, GroupId, Pool)
プールを使用するメモリ カウンターを宣言します。
Poolにはどのプールであることを定義できます。

FPlatformMemory::MCR_Invalid   メモリ以外
FPlatformMemory::MCR_Physical,  システムメモリ
FPlatformMemory::MCR_GPU,     GPUメモリ
FPlatformMemory::MCR_GPUSystem  GPU が直接アクセスできるシステム メモリ
FPlatformMemory::MCR_TexturePool テクスチャプール

複数のCPPファイルにまたぐ場合
先程紹介した、宣言用のマクロは1つのCPPファイル内だけ使用する場合にしか使用できません。
externバージョンを使用してください。各マクロに_EXTERNが追加されたバージョンを使用してください。
DECLARE_CYCLE_STAT_EXTERN(CounterName, StatId, GroupId, API)
DECLARE_FLOAT_COUNTER_STAT_EXTERN(CounterName, StatId, GroupId, API)
DECLARE_DWORD_COUNTER_STAT_EXTERN(CounterName, StatId, GroupId, API)
DECLARE_FLOAT_ACCUMULATOR_STAT_EXTERN(CounterName, StatId, GroupId, API)
DECLARE_DWORD_ACCUMULATOR_STAT_EXTERN(CounterName, StatId, GroupId, API)
DECLARE_MEMORY_STAT_EXTERN(CounterName, StatId, GroupId, API)
DECLARE_MEMORY_STAT_POOL_EXTERN(CounterName, StatId, GroupId, Pool, API)

使用方法
関数スコープ内時間の計測
SCOPE_CYCLE_COUNTER(StatId);
関数スコープ内(中括弧{}の区間)の時間を計測します。

使用例

DECLARE_CYCLE_STAT(TEXT("CYCLE_COUNTER") STAT_CYCLE_COUNTER, STATGROUP_StatTest);

void AStatTestActor::Tick(float DeltaTime)
{
	{
		SCOPE_CYCLE_COUNTER(STAT_CYCLE_COUNTER);
		// ここから

		// ここまでにかかった時間・呼び出された回数が記録されます。
	}
}

カウンター操作
時間計測以外のカウンターの値の統計を取りたい場合は以下のマクロを使用してください。

カウンターのインクリメント(1増やす)
INC_DWORD_STAT(StatId)
カウンターのデクリメント(1減らす)
DEC_DWORD_STAT(StatId)

指定した値分カウンターを増やす
DWORD型
INC_DWORD_STAT_BY(StatId, Amount)
Float型
INC_FLOAT_STAT_BY(StatId, Amount)
メモリ
INC_MEMORY_STAT_BY(StatId, Amount);

指定した値分カウンターを減らす
DWORD型
DEC_DWORD_STAT_BY(StatId, Amount)
Float型
DEC_FLOAT_STAT_BY(StatId, Amount)
メモリ
DEC_MEMORY_STAT_BY(STAT_PixelBufferMemory,NumBytes);

カウンターの値を設定
DWORD型
SET_DWORD_STAT(StatId, Value)
Float型
SET_FLOAT_STAT(StatId, Value)
メモリ
SET_MEMORY_STAT(StatId, Value);

UE4の標準機能で十分間に合う部分もあるのですが、
ゲームやプラグイン固有の情報を集めるために可視化してみてはいかがでしょうか?

[UE4] NavModifierComponentの活用及び機能変更の方法

$
0
0
執筆バージョン: Unreal Engine 4.24

皆さん、今日も元気にナビメッシュを活用してますでしょうか?

キャラクターを動かす時に重宝するナビメッシュですが、なかなかクセが強くて大変ですよね。ビルドしたのに昔のナビメッシュデータが残っていたり、うまく生成してくれなかったり……

今日はそんなナビメッシュに関して、機能をちょっとだけ拡張してナビメッシュ関連のボリュームを配置するワークフローを改善してみたいと思います。

まずはNavModifierVolumeについて軽く説明します。このボリュームはナビメッシュに対して重み(優先度)を付ける事ができます。どういう事かというと、通常AIは目的地に向かって最短ルートを進もうとしますが、このボリュームによって指定した範囲を避けて通るような動きをつける事ができるというものです。

画像を使って説明します。通常時は画像のように最短ルートを通ります。

次に最短ルートの途中にNavModifierVolumeを配置して「AreaClass」を「NavArea_Obstacle」にしてここに障害物があることにします。

するとAIは障害物を避けて遠回りするルートを使用します。

ちなみに両方に障害物を配置すると、諦めて最短ルートを通ります。

さて、ここからが本題です。障害物を配置するたびにNavModifierVolumeを同じように配置するのは苦行ですよね。そこで活用できそうなのが、NavModifierComponentです。これを使用すれば、障害物用のアクターに対してNavModifierVolumeを追加できるようになります。なりますが、なかなかにクセが強くて扱いが難しいです。

色々試してみたり、UNavModifierComponentのソースを読んで分かった事が以下の通りです。

まず、アクターにコリジョンがついていると、それぞれのコンポーネントに対してNavModifierの範囲が適用されます。なので例えばStaticMeshが1つだけのアクターにNavModifierComponentを付けてもあまり意味がありません。もともとそのStaticMeshのサイズでナビメッシュは削除されるからです。

そこでStaticMesh以外にも影響範囲として別途CollisionComponentを追加すると、その範囲分も含めてNavModifierが適用されます。ここまでは非常に便利な機能だと思います。

次にアクター側のコリジョンをNoCollision(全てのComponentがNoCollision)にした場合は、NavModifierComponentのFailsafeExtentの範囲が適用されます。

そしてこれはバグだと思うのですが、このFailsafeExtentは回転に対応していません。対応していないというか、正確にいうと移動と回転の計算が逆になっているようです。アクターを回転すると全然違う座標にNavModifierが適用されてしまってます。FailsafeExtentが適用されてしまっている状態の場合は注意しましょう。(Failsafeとは…)

ここまでで分かったことは、UNavModifierComponentはコリジョンに深く依存しているということです。逆にいえばコリジョンに関係のない範囲でNavModifierを指定しようとすると実質無理だという事がわかります。

ですが、そうしたい場合は少なからずあるかと思います。例えば宝箱やギミックなどに敵を近づけさせたくない場合、レギュレーションとしてギミックの半径何m以内は敵が侵入できないようにしたいなどです。

今回はそれらのケースに対応した機能をUNavModifierComponentを派生させて別途作成する手法の紹介をしたいと思います。

まずはUNavModifierComponentを基底とした派生クラスをC++で新規作成します。

次にソースコードの中身です。

#pragma once

#include "CoreMinimal.h"
#include "NavModifierComponent.h"
#include "TestNavModifierComponent.generated.h"

/**
 * 
 */
UCLASS( ClassGroup = (Navigation), meta = (BlueprintSpawnableComponent) )
class NAVTEST_API UTestNavModifierComponent : public UNavModifierComponent
{
	GENERATED_BODY()
	
public:

	// 影響範囲
	UPROPERTY( EditAnywhere )
	FVector NavExtent;

	// 中心座標の調整用
	UPROPERTY( EditDefaultsOnly )
	FVector OffsetLocation;

public:

	UTestNavModifierComponent( const FObjectInitializer& ObjectInitializer );

	virtual void GetNavigationData( FNavigationRelevantData& Data ) const override;

};

cppはこちらになります。

#include "TestNavModifierComponent.h"

UTestNavModifierComponent::UTestNavModifierComponent( const FObjectInitializer& ObjectInitializer )
	: Super( ObjectInitializer )
	, NavExtent( 100.0f, 100.0f, 100.0f )
	, OffsetLocation( 0.0f, 0.0f, 0.0f )
{
}


void UTestNavModifierComponent::GetNavigationData( FNavigationRelevantData& Data ) const
{
	FTransform ActorTransform( GetOwner()->GetActorTransform() );
	FTransform OffsetTransfrom( OffsetLocation );
	FTransform OutTransfrom;

	// 今回はアクターのスケール値は無視する
	ActorTransform.SetScale3D( FVector( 1.0f, 1.0f, 1.0f ) );
	FTransform::Multiply( &OutTransfrom, &OffsetTransfrom, &ActorTransform );

	Data.Modifiers.Add( FAreaNavModifier( NavExtent, OutTransfrom, AreaClass ).SetIncludeAgentHeight( bIncludeAgentHeight ) );
}

NavExtentを編集することで影響範囲を自由に変更する事が可能になりました。また、UNavModifierComponentはUActorComponentが基底クラスになっているため、コンポーネント単体での座標情報を持っていません。そのため中心座標を調整できるようにしています。

これをビルドするとアクターに追加するコンポーネントの一覧に「Test Nav Modifier」が追加されるので自作したアクターに追加してみます。

NavExtentでデフォルトのサイズ、OffsetLocationで中心点を指定して、あとはレベルに配置するだけで完成です。これでコリジョンとは無関係にNavModifierを配置できるようになりました。

いかがでしょうか?
既存のNavModifierComponentと今回作成したComponentとを使い分ける事で大抵のケースはカバーできそうな気がします。

ただ、現状だとNavModifierの範囲がナビメッシュを表示しないとわからないという問題を抱えていますが、こちらは視認用のprimitiveComponentを用意して、その値をNavModifierに範囲させるなどの対応を取ればなんとかなりそうです。
是非活用してみて下さい。

[UE4] 第13回UE4ぷちコン 受賞作品発表!

$
0
0

第13回UE4ぷちコン 受賞作品が決定!

応募総数は81作品! 今回もたくさんのご応募ありがとうございました!

王道から意外なものまで、本当にさまざまな”さく”が集まりました。
その中から最優秀賞含む8作品を選出いたしましたのご紹介します♪

受賞作品の発表は【第13回UE4ぷちコン】審査結果発表会!【拡張版】で行いました!

 

【第13回UE4ぷちコン】審査結果発表会!【拡張版】


今回は普段の作品紹介と受賞作品発表に加え、ゲストをお呼びしていつもと違った放送をおこないました。
アーカイブを残しておりますので是非ご視聴ください♪

<審査員>
Epic Games Japan おかずさま
株式会社ヒストリア 代表 佐々木 瞬
株式会社ヒストリア 広報 けーちん

<ゲスト>
紙パレットさま
もんしょさま

 


【最優秀賞】サクサク斬り裂く侍

でじまい さま


【準最優秀賞】Flower Pinball

wvigler さま


【グッドルッキング賞】安全対柵

Penguin Gamers さま

 


【テーマに沿ってるで賞】SAKURA FRONT LINE

yeczrtu さま

 


【徳が高いで賞】蓮華

oMochi さま

 


【おかず賞】Little John

zohyo u さま


【ささき賞】YOSAKU – The Legendary Woodcutter

JUGANDO さま

 


【けーちん賞】トンカツフリースロー!サクっとスライサー

kanio さま

 

 

 

受賞おめでとうございました!
そしてご参加いただきありがとうございました!

少しでもみなさんのUE4に触るきっかけになっていたら嬉しいです♪

 

第13回UE4ぷちコン イベントページ

 

[UE4]ドアの動きをTimeLineとCurveアセットで管理する方法

$
0
0
執筆バージョン: Unreal Engine 4.24

過去のブログにCurveアセットを使うことでどうなるかの使用例がなかったので、今回は使い方の一例についてやっていきます。
今回やるのはタイムラインのキーフレームをCurveアセットで置き換える方法です。

過去のCurveアセットに関してはこちら
[UE4]TimeLineノードでCurveアセットを使う方法
[UE4] 色々な所で使えるCurveアセットの使い方

今回はドアの開閉を例に作っていきます。あらかじめドアのスタティックメッシュをご用意ください。
UE4のプロジェクトにスターターコンテンツを追加し、【 Content\StarterContent\Props\SM_Door 】 を使うといい感じです。

まずはドアのスタティックメッシュからブループリントを作成し、画像のようにドアの開閉部分のプループリントを組みます。

左の赤いノードのOpenとCloseは『カスタムイベント』というノードで、他アセットからイベントを呼び出してドアの開閉を管理できるようにしています。
右側の2つのノードでドアを最大120度まで開くようにしています。

そして今回大切なのが真ん中の『タイムラインノード』です。
このノードは開発者側が用意したキーフレームに沿って、Playされてからの時間経過に依存して値が変化していくものです。
この『タイムラインノード』をダブルクリックするとタイムライン編集専用の画面に飛ぶことができます。

タイムライン編集画面の『f』のマークを押すことでタイムライン中の時間経過による値の推移を決めることができるようになります。

これにより追加されたものが『トラック』と呼ばれるものです。タイムラインノードの出力ピンに出てくるのできちんと名前を変更しておきましょう。
トラックのグラフ以外の部分で右クリックすると『Rename』が出てくるのでこれでトラック名を変更することができます。

トラックのグラフ上で右クリックして、Add Key to ○○ を押して、キーを追加しましょう。

このキーが2つ以上あれば、キー同士が線で結ばれ、この線に沿って値が変化するようになります。
時間と値が手動でうまくいかないときはTimeの値とValueの値を直接入力するといい感じです。

このままだとタイムラインが終了するまでの時間が5秒かかるので、開け閉めの切り替えに不具合が出てしまいます。
『Length』の値がタイムライン終了までの時間(秒単位)なのでこれを2つめのキーの時間と同じ値に設定します。

これでイベントを呼べばドアが開閉するようになりました。
しかし、このままではいろんなパターンを試したり、ドアごとに動きを変えるのが大変です。
なのでそれに対応できるようにしていきましょう!

まずはトラック上の動きを1つのアセットとして保存していきます。
トラックのグラフ上で右クリックして『Create External Curve』を選択します。
わかりやすい場所と名前を選んでOKを押します。今回はdoorフォルダの下にTypeAという名前で保存しました。
この保存されたものを『Curveアセット』と言います。
タイムラインから出力する以外にもエディタ側で直接Curveアセットを作ることができます。

次にエディタ側からアクタに割り当てたいCurveアセットを選択できるようにしていきます。
ブループリント内の『Valiables(変数)』の追加をします①
適切な名前を付けと変数の型を変更していきます。
『ValiablesType(変数の型)』の欄をクリックすると検索欄が出てくるので、『Curve Float』と検索してCurve Floatの『ObjectReference』を選択します。②
このままではエディタ側から指定できないので、Curve Float変数の右側の目玉マークを開かせます。③

変更後がこちらです

変数の追加を反映させるためにここで一度コンパイルしておきましょう。
これでこのようにエディタ側からCurveアセット用の変数を変更できるようになりました。

しかしこのままでは変数の中身が変わるだけで、タイムラインに反映されていません。
なので早速反映させていきましょう

ドアのブループリントを再度開き、ConstractionScript(コンストラクションスクリプト)を開きます。
コンストラクションスクリプトはアクタがゲーム内で生成されるときに呼び出されるイベントです。
今回は生成時にタイムラインの中身を指定したCurveアセットで上書きしていきます。
そこで使用するのが『Set Float Curve』というノードです。
実行ピンからだと検索しても出てこないので、タイムライン変数から線を引っ張った状態で検索してください
『Target』には上書きしたいタイムラインを、
『New Float Curve』には上書きするCurveアセットを、
『FloatTrackName』には先ほどタイムラインに追加したトラック名を入れてください。

これでエディタ側で選択したCurveアセットが反映されるようになりました。
しかしこのままだと1秒で開閉していたものを2秒にしようとした際、1秒の時点で動作がとまってしまい、扉が半開きになってしまいます。
なのでその対応をしていきます。

ドアのブループリントで置いたタイムラインノードを開き、『UseLastKeyframe』にチェックを入れましょう!
これによってタイムラインの長さが自動的に最終キーフレームの時間までになります。
つまりCurveアセットに合わせて自動でタイムラインの長さが変わります!

それでは作成したドアをマップに置いて実際に動いているところを見てみましょう。
今回は次の3つのCurveアセットを用意しました。
A 1秒で開く
B 2秒で開く
C 2秒で曲線的に開く
 
向かって左からA.B.CのCurveアセットをアタッチしています。
ちなみに青扉は橙扉の子クラスですが、特別なことをしなくても無事動いています。

余談ですがCurveアセットはFloat型だけでなく、Vector型にも対応してるのでぜひいろいろと試してみてください。

【第13回UE4ぷちコン】審査結果発表会レポート&ゲーム制作で使えるサウンドサイト紹介!

$
0
0

こんにちは、ヒストリア広報のけーちんです!

初めてヒストリアBLOGを書かせていただきます。
何かイベントごとがあった時にレポートが書けたらと思ってます( `ー´)ノ
よろしくお願いしますー! !

 

2020年2月14日(金)~3月29日(日)まで行われた「第13回UE4ぷちコン」

新型コロナウイルスの影響により、元々予定していた「UNREAL FEST WEST 2020」や、
「第13回UE4ぷちコン ゲームジャム」も中止となってしまいましたが
コンテスト自体はオンラインでの応募と審査発表だった為、なんとか無事完走することができました。

SNSにたくさんの制作過程やレポート、ビルドデータを公開してくださったりと
コンテストを盛り上げていただけてとても嬉しかったです!

 

ぷちコン最新情報はここから!

ヒストリア広報部Twitter

皆さんいつもありがとうございます!(*’▽’)

 

さて、先週4月18日(土)に「第13回UE4ぷちコン 審査結果発表会」がありました。

イベント中止が重なったこともあり、普段と違った事をして楽しんで貰えないかと検討した結果、

・ゲスト出演とゲストにちなんだ企画
・オンラインでの生放送
・休日開催
・長時間放送(5時間もいくとは思ってなかった)

・・・と、初の試みをしました( `ー´)ノ
長時間でしたが、たくさんの人がほぼ全編をみていただけてたとの事で驚き&喜んでいます。
(初出演だったのですが、温かいコメントが多くてとても優しい現場でした・・・! )

初の試みの多い生放送だったこともありレポートさせていただければと思います♪

 

まず、ぷちコン初のゲストはこのお二人でした!

 


紙パレットさん

UE4でハートフルアドベンチャー+リズムアクションの「ジラフとアンニカ」を制作、現在steamにて配信中です!

更に! 8/27(木)にNintendo Switch/PS4日本版の発売も決定しておりますー! すごい!(*’▽’)

生放送では「ジラフとアンニカ」をプレイさせていただきました。
冒険を楽しみながら、リズムゲームも挑戦しました!
リズムゲーム、大好きなので楽しかったです( `ー´)ノ

そして紙パレットさんからは制作エピソードやゲーム内の見どころなんかを教えていだたきました!
木の裏でもアンニカちゃんが透けて見える工夫なんて素敵でしたね☆

詳しくはアーカイブをご覧ください♪(2:40:00~)

 

 

 

 

 


もんしょさん

もんしょさんはなんと「UE4ぷちコン」の皆勤賞のうちの1人!
(皆勤賞は2人いらっしゃるみたいです。)

そして応募作品数No.1のお方です!

なんと全19作品も応募してくださっています!
(あれ・・・ぷちコンは13回目だぞ・・・?)

 

生放送では、そんなもんしょさんの応募作品を振り返りましたー( `ー´)ノ

ブルーマンを愛し、狂・・・変わった作品作りをするもんしょさん。
応募当初は普通の作品を応募していたのが徐々に変化していくさまが見れて面白いプレイリストになっております♪

 

そんなもんしょさん、昔からグラフィックスプログラミングについて沢山のブログ記事を書いていらっしゃいます!

 

グラフィックスプログラミングの研究・開発ブログ
「もんしょの巣穴 ver2.0」

Substance DesingerやUE4のTIPSを紹介するブログ
「もんしょの巣穴ブログ Ver2.0」

実は凄いかたなんですね・・・(*’ω’*)

 

 

 

 

 

審査員には弊社代表の佐々木と私けーちん、

そしてEPIC GAMES JAPANのおかずさんに参加していただきました!


おかずさん

ぷちコン審査員としてお馴染みですね!

(リモートワークのはずなのに家に人あげちゃだめですよ・・・?)

 

 

 

 

 

オンライン完結というのもなかなか不思議な経験でした!

全員バラバラの場所にいるのも面白いですね!
(全員笑顔の素敵なスクリーンショットが撮れました☆)

休日に生放送を行うのも初めてだったのですがいかがでしたでしょうか?

サ〇エさんやちび〇子ちゃんみたいにお家でのんびり何かをしながら
見てもらえる番組になっていたら嬉しいです(*’ω’*)

 

普段行っている「惜しかった作品紹介」も、
いつも以上にたくさん紹介してみました!

まだまだ紹介したい作品も多く、これはなかなか選ぶのに苦戦しました・・・
(紹介できなかった方、ごめんなさい! また応募してくださいね! ( ;∀;))

 

そして受賞者発表! !
合計8作品の受賞者を選ばせてもらいました。

これ、本当に長い時間応募映像を見て話し合いをしました。
どれも素敵な作品が多く、審査って大変なんだなと感じました。

最優秀賞のでじまいさん、
そしてその他の受賞者の方々、本当におめでとうございました! (*^-^*)

 

 

 

 

 

そしてお待ちかね!
生放送中に紹介する予定でした、
ゲーム制作に使えるおすすめのサウンドサイトの紹介になります!

ぷちコンの作品をたくさん見させていただきましたが、
音選びからセンスがある人もいれば「この作品に音が付いたものを見たい・・・! 」
と思う作品もありました。

ぜひ皆さんのサウンドの選び方なんかもSNSでシェアして貰いたいものです( *´艸`)

 

 

今回は、紙パレットさんが生放送用に用意してくださったものを元に紹介したいと思います☆
(紙パレットさん、急なお願いにすぐ対応してくれました、感謝です・・・! )

 

 

・「魔王魂」

歌もの素材からBGM素材、効果音素材まで様々な素材が無料で使用できます。
著作の表記さえして貰えれば、個人利用・商用利用OKです。
初心者におすすめのサイトな気がしますね♪

 

・ポケットサウンド

効果音素材やBGM素材を公開しているサイトです。
日本のゲームらしいSEが豊富でゲームジャンル別のカテゴリもあり見るのが楽しそう。
リンクを貼ることで無料で使用可能。BGM制作も有料で依頼できるみたいです。

 

・SONICWIRE

「音」に関するソフトウェア、プラグイン、素材の総合ダウンロードストア。
有料のSE販売サイトです。セットの販売がたくさんありますが単品でも購入できます。

 

紙パレットさんおすすめのサウンドアセットもあるみたいなので紹介。

・Pro Sound Collection

UE4のマーケットプレイスのアセット。8076個のSEデータが約5000円で手に入っちゃう!
使える音が多いのでオススメみたいです!

 

最後になんと、音楽素材を管理する無料ソフトも紹介して貰いました。

・MUTANT

膨大なサウンドファイルを一元管理できるソフト。なんと無料。
たくさんの音楽を使用するならグループ分けで管理できるのは便利ですね。

UE4のアセットはそのままだとuasset形式になっていて検索性が悪いので、
紙パレットさんは一度エクスポートして、MUTANTで管理しているみたいです♪

 

 

 

 

 

以上、サウンドサイトの紹介でした!

みなさんのゲーム制作に役立ちましたら嬉しいです!

それでは以上で「第13回UE4ぷちコン 審査結果発表会」生放送レポートを終了します。

最後まで読んでいただきありがとうございました( `ー´)ノ

[UE4] AvoidanceManager (RVO) とは?

$
0
0
執筆バージョン: Unreal Engine 4.24

はじめに

キャラクター同士の衝突回避を実現するためにUnrealEngineではCrowdManager(※1)とAvoidanceManagerというものがあります。

プロジェクト設定からも確認できるCrowdManagerとは違い,エディター上ではどこらかも存在を確認するこができないAvoidanceManager…

今回はそんな自分で探さない限り知り得ないであろうAvoidanceManagerについて紹介したいと思います。

特徴

AvoidanceManagerは衝突回避アルゴリズムであるRVO(Reciprocal Velocity Obstacles)(※2)をUEで使用するためのクラスで

以下の2種類のComponent内で使用されています

  • CharacterMovementComponent
  • WheeledVehicleMovementComponent

2つのComponentの基本的な使用方法、処理の流れはだいたい同じなため以降はCharacterMovementComponentでの使用を想定しての説明になります。

特徴

  • ブループリントのみで動作可能
  • 使用するまでのセットアップが簡単(CharacterMovementComponent,WheeledVehicleMovementComponentであればすぐ使用できる)
  • 調整項目数が少ないため習熟コストが低い
  • キャラクター以外でも対応がさせやすい(UMovementComponentにIRVOAvoidanceInterfaceを継承させることでAvoidanceManagerに登録可能)
  • ゲームプレイ中にブループリントから機能のオンオフ、回避動作相手の変更などができる

気になる点

  • 回避動作にNavMeshが考慮されないため領域外に出ることがある

↓はNavMeshギリギリの位置にある目標ポイントに向かうときにグレイマンが常にグリーンマンの回避方向に妨害し続けた結果NavMesh外に移動してしまったグリーンマン…
その後、彼が動くことはありませんでした…

  • 拡張にはC++が必要
  • デバック機能があまりない

使用方法

使用するための手順は非常にシンプルで

  • CharacterMovementComponentのUseRVOAvoidanceにチェックを入れる
  • CharacterMovementComponentのSetAvoidanceEnabledを使用し有効にする

  

のいずれかで使用可能です。

CharacterMovementComponentで公開されている変数情報

次にブループリント上で公開されてる変数まとめました。(それとよくわからなかった変数の日本語訳を画像で…)

変数名 説明
bUseRVOAvoidance RVOを使用した回避処理を動作させる(サーバー上でのみ動作)

クライアント環境では強制的にComponentの登録処理時、Falseに変更される

AvoidanceConsiderationRadius 回避処理をしだす範囲を指定します。

AvoidanceManagerではIRVOAvoidanceInterfaceのGetRVOAvoidanceOrigin(※2)から位置を取得しそこからの距離(高さは無視された2D距離)に回避対象者がいれば回避処理が継続されます。

AvoidanceWeight 回避時の重み付け。0.0以上1.0未満を指定する(1以上を指定すると回避処理されなくなるため注意)

AvoidanceUID RVO機能を有効にしたMovementComponentを識別するためのユニークなID。

AvoidanceManagerに登録される際にIDがセットされます。

登録されたとき1からではなく0から使用されるため最初のComponentのみ登録されてたかの確認がとれないので注意)

AvoidanceGroup 自身が属する回避グループ。

GroupsToAvoid 回避動作をするべきグループ。デフォルトですべてのグループにチェックされてます。

チェックを外すことで回避動作をしなくすることもできますが次の項目で設定するほうが

わかりやすいかと思います。

GroupsToIgnore 回避動作を無視するグループ。ここにチェックしたグループが回避動作の範囲内に来ても何もしなくなります。

処理の流れ

UCharacterMovementComponentのbUseRVOAvoidanceがTrueにした場合

1.UCharacterMovementComponentのOnRegisterでNetModeのチェックが入りサーバーなら2に進み、クライアントだった場合強制的にbUseRVOAvoidanceがFalseになり終了

2.UCharacterMovementComponentのSetUpdatedComponentでbUseRVOAvoidanceがTrueの場合、AvoidanceManagerのRegisterMovementComponentでManagerに登録される

3.UCharacterMovementComponentのCalcVelocityでVelocityの計算がされるとき最後にCalcAvoidanceVelocityで回避動作するかの条件判定がされ回避が必要になった場合ここでVelocityが上書きされる

4.CalcAvoidanceVelocityで回避が必要ではなかった場合UpdateDefaultAvoidanceが処理される

BP上から設定可能なもの

コンソールコマンド

コンソールコマンドとして使用できるものは2種類あります。

注意点してRVO機能はServer上でのみ処理されるためDebug表示もServerでのみ確認可能になっています

AvoidanceSystemToggle Avoidanceのシステムをオンオフする
AvoidanceDisplayAll Avoidanceのデバック表示

↑のような感じでAvoidanceManagerに登録される対象者に青い線が表示され実際回避処理がされる間は

赤い線に変わり足元に回避した方向が表示されます。

Engine.ini で設定できる項目

[/Script/Engine.AvoidanceManager]
DeltaTimeToPredict=0.5

デフォルト値 説明
DefaultTimeToLive 1.5 RVO機能をオフにしてからAvoidanceManager内で完全に使用されなくなるまでの時間の猶予
LockTimeAfterAvoid 0.2 回避処理がされVelocityが設定された後、再度計算し直されるまでの時間

(UCharacterMovementComponentではSetAvoidanceVelocityLockで設定し時間が経過するまで同じVelocityで動作し続けます)

LockTimeAfterClean 0.001 回避処理されなかったときの再度計算し直されるまでの時間。基本は毎フレームになる時間を指定。

またキャラクター同時が接触した場合などもこれが指定されすぐ再計算されるようにしてる模様

DeltaTimeToPredict 0.5 衝突回避をする速度を求めるための予測時間
ArtificialRadiusExpansion 1.5 オブジェクトの半径に掛けられる係数(CharacterならGetScaledCapsuleRadius *ArtificialRadiusExpansionが実際計算で使用される半径のサイズ)
HeightCheckMargin 10.0 回避対象オブジェクトとの許容可能な高さ

対象オブジェクトとのZ値の差分が「対象オブジェクトの高さ+自分の高さ+HeightCheckMargin」を超えているならスルーされる(UCharacterMovementComponentの場合はカプセルの半分サイズを高さとして使用されてます)

プロジェクト専用に拡張する場合

Engin.iniにAvoidanceManagerを指定することができるためプロジェクト用AvoidanceManagerを登録することは可能です。

[/Script/Engine.Engine]
AvoidanceManagerClassName=/Script/Engine.AvoidanceManager

なのでずがこのAvoidanceManagerの関数はほぼvirtualがなかったりで有用ではないかもしれません…

Velocityを調整したい場合はUCharacterMovementComponentに限っては変数「bUseRVOPostProcess」をTrueにすることで関数「PostProcessAvoidanceVelocity」が使用できるのでこれを使用すればエンジン修正せずVelocityの調整が可能かと思います。

 

 

簡単ではありますがAvoidanceManagerについての紹介は以上となります、また機会があればCrowdManagerとの比較などやってみたいと思います。

少しでも皆様の開発に役立てばと思います。

ここまで読んでいただきありがとうございました。

 

※1

CrowdManagerの特徴や使用方法などはこちらを参考にさせていただきました。

https://qiita.com/EGJ-Ken_Kuwano/items/120901d259467568e4f7

※2

RVOに関しては以下のものを参考にさせていただきました。

https://qiita.com/Dv7Pavilion/items/5ef3cc4e95463027219a

※3

CharacterMovementComponentの場合、すでにIRVOAvoidanceInterfaceを継承しておりGetRVOAvoidanceOriginで返している位置は

キャラクターのカプセルの足元位置を返すようにしています。

 


【UE4】アーティスト向けライトマップ作成方法

$
0
0
執筆バージョン: Unreal Engine 4.24

今回は、UE4初心者やアーティスト向けに、ライトマップの作成方法と、
ライトマップ作成時に知っておいたほうが良さそうな周辺情報を書いてみようと思います。

ご存知かもしれませんが、ライトマップとは何か?
UE4では事前計算で行ったライティングの情報をテクスチャマップとして保存することができます。
そのテクスチャマップがライトマップです。

なぜライトマップを作るのか?
光源が動かない環境下での、静止している物体の影や反射光は、
テクスチャマップとして保存しておくことでリアルタイムで計算する処理を省くことが可能な為、
ライトの数や種類が多くても重くならない、ゲームプレイ時に影響がほとんど無い、
つまり処理負荷がかからないというのが一つ。
また、GIやエリアライトなどで見た目を良くすることもできるので、見た目のためというのも理由の一つでしょう。
(レイトレGI、SSGI、などの例外はあります。GIやライティング関係にはほとんど触れません)

ちなみにキャラクターは動くので通常はライトマップは作りません。主に背景などで使用します。

それでは本題のライトマップの作り方になります。

ライトマップの作り方

UE4のライトやスタティックメッシュには、スタティック、ステーショナリー、ムーバブルと3種類の状態があります。
ライトマップを作成する場合ライトとメッシュはすべてスタティック(静的)か、ステーショナリーにします。

DetailsのTranceformのMobilityからStaticを選択します。

ちなみにステーショナリーやムーバブルになっていると
アイコンに黄色とオレンジの丸がついているのでわかりやすいです。
Stationary

Movable

詳しい解説はしませんが、3つの状態の解説は以下にあります。
https://docs.unrealengine.com/ja/Engine/Actors/Mobility/index.html

基本的にはライトマップを作るには、通常のテクスチャ用のUVとは別に、
ライトマップ専用のUVを作ります。

ライトマップUVの作成方法はいくつかありますが、大きく分けると2通りあります。
UE4で自動生成する方法とDCCツールで作る方法です。

ライトマップUVを作成したらライティングをしてライトビルドを行います。
すると自動でライトマップが作成されます。

それでは実際にやっていきます。

今回ライトマップ検証用にDCCツールで画像のような物体を作りました。

特にディティールの無い白い物体にベベルしたハイポリをベイクしました。

ゲームモデルを想定して、通常のテクスチャの節約のために立方体の側面、上面、裏面、下面の5面と、
前面の凹んでるところの側面どうしと、上面と下面をUVを重ねてみました。
Mayaでは青色が濃い所がUVを重ねているところです。(赤紫はUVが裏返ってるところです)

UE4でライトマップUVを作る

インポート時に自動生成する。

メッシュのインポート時に、MeshのGenerateLightMapUVsにチェック入れてインポート。

チェックしないでインポートした場合、もともと作成したメッシュのUVだけの状態で
インポートされます。UVChannel0 のみです。

チェックを入れてインポートすると

UVChannel1が作成されたのがわかります。
重ねていたUVは自動でバラバラに配置されています。
これはUE4がアイランドのオーバーラップを自動で回避したためです。
またパディング領域(UVアイランド間の隙間)も設定されている解像度に応じて自動で計算して確保されます。

通常のテクスチャのUVを元にして、ライトマップUVを生成する。

DetailsのLOD0のBuildSettingのGenerate Lightmap UVsにチェックを入れて
Apply Changesを押下することでインポート時にライトマップを生成しなくても、後から生成することもできます。

その際に元になるUVチャンネルと生成先のUVチャンネルを指定して生成します。

Source Lightmap Indexを0
Distination Lightmap Indexを1 にしてApply Changesを押下することで
インポート時に生成したときと同じ用にUVチャンネル1が生成されます。

最後に忘れがちなのですが、General StettingsのLightMapCoordinate Indexを1に設定します。

ライトマップができたので、ライティングしてライトビルドを行ってみます。

DirectionalLight一つと、SkyLightを配置しました。
また、BP_Sky_SphereとLightmassImportanceVolumeも配置しています。(こちらは今回解説しません)

ちなみに左上に赤字でLIGHTING NEEDS TO BE REBUILD(2 unbuilt object)と出ています。

この警告は新しくアセットをインポートしたり、移動したりしたときや、
ライトマップの解像度を変更したりしたときも出ます。

BuildからBuild Lighting Onlyを選択します。

無事に赤字が消えてライティングできました。

でも少し汚いです。
落ちた影もギザギザしていますし、変なシミもあります。

解像度を上げてみます。

DetailsのGeneral Settings の LightmapResolutionを128にします。

解像度を変更する際に、LOD0のBuld SettingsのMin LightmapResolutionも同時に変更して
Apply Changesを押下することで解像度に応じてパディング領域が変更されます。

Min LightmapResolutionが64のパディング

Min LightmapResolutionが128のパディング

落影のジャギーが緩和されたのと、シミも減ったようですが、エッジが黒く際立ったままです。

地面の影のジャギーが汚いので地面も128に変更します。


地面のジャギーが緩和されましたが、BOXよりまだ解像度が低く感じます。

ライトマップの密度をビジュアルで見たい時はLightmapDensity
ショートカットAlt+0で見ることができます。

地面とBOXで解像度があっていないようです。

256で大体合いました。

こちらは解像度128、Min LightmapResolutionが128の画像ですが、左上のシミやエッジが黒く残っています。

解像度は128そのままで、Min Lightmapresolutionを32に下げてパディング領域を広げてみたところシミやエッジが消えました。

ただし同じ解像度でパディング領域が増えたということはUVアイランドのサイズは小さくなるということになります。
なので凹み部分に落ちた影のジャギーが若干大きくなっているのがわかるかと思います。

※解像度が128の時にMin Lightmapresolutionが128ではパディングの領域は4×4のピクセルより小さいという事かと思います。
Min Lightmapresolutionの数値が具体的に何を表しているのか、どんな計算なのかはよくわからないのでどなたかわかる方是非教えていただけると嬉しいです。

通常のテクスチャのUVをそのままライトマップのUVとして使用する。

Generate Lightmap UVsのチェックをはずして
Source Lightmap Indexを0
Distination Lightmap Indexを0にして Apply Changesを押下
General StettingsのLightMapCoordinate Indexを0に設定することで
通常のUV領域をそのままライトマップUVに設定することも可能なようです。

結果はUVが重なっているところは真っ黒になってしまいました。
MesageLogを表示するとエラーが出ています。
エラーの下線がある文字をクリックすることでコンテンツブラウザーの該当のアセットの階層に飛んでくれてアセットが選択された状態になります。
ライトマップを作成する時は常にMesageLogを表示してエラーを潰していくと良いでしょう

また、BuildからUseErrorColoringにチェックを入れてBuildする事で、

UVが重なっているところが赤く表示されます。

絵的に確認したい時に便利そうです。
Build option menuからLighting QualityをMediumかPrevewを使用した時に動作するようです。

ちなみに床の板ポリに関しはテクスチャUVをそのままライトマップUVに設定しました。

今回ベベルしたハイポリをベイクしたローポリのモデルだったので、どこがシミなのか、分かりづらい、
ライトマップの情報だけに絞って見たいと思うかもしれません。
そんな時はVewModeをLightingOnly(ショートカットはAlt+6)に切り替えると分かりやすいです。

さらにわかりやすくするためにはポストプロセスでオクルージョンもオフにしたほうが良いでしょう。

また、ベイクされたライトマップそのものをWorldSettingから画像として見る事もできます。

※この画像の詳しい解説は探しても見当たらなかったのでどなたかわかる方いらっしゃいましたら是非教えていただけると幸いです。

ライトマップUV作成におけるルール

ライトマップを作成するにはいくつか守らなければいけないルールがあります。

・UVアイランドを重ねてはいけない。
テクスチャマップでは節約のためUVアイランドを重ねたりしますが、
ライト情報は固有に持たないと、陰影が混ざってしまう為、重ねてはいけない。
重なっているとエラーが出ます。

・ライトマップテクスチャの圧縮の際ににじみ(アーティファクト)ができるのを防ぐ為、
適切なパディングの確保が必要。
パディングとはUVアイランドとUVアイランドの間の領域の事です。
公式ではUE4のDXT圧縮が4×4テクセルのブロックで動作するからとありますが、今回は掘り下げないです。
厳密にパディング領域を守りアイランドの解像度を節約するにはDCCツールで作成したほうが良い場合があります。
また、UE4ではUVアイランドを切り離したり、繋げたりすることはできない為、DCCツールで行う必要が出てきたりします。

ライトマップ作成のコツ

・UV領域確保の為、UVをつなげる
パーツが多いアセットの場合特にUVアイランドの数も多くなりがちですが、そうするとパディング領域が増え、
各アイランドの解像度が低くなる為、可能な限りUVをつなげてアイランド数を減らす必要がある。

・影の領域が明るい領域ににじむのを防ぐ為、確実に暗い箇所はUVアイランドを分けたり小さくする。
UVをつなげるとなめらかな陰影が得られるが、暗い面とつながっていると明るいはずの箇所に暗い領域がにじむので、
それを防ぐことが可能。(ただし陰影が途切れるのとパディング領域が必要になる)

・裏面ポリゴンや、重なっている領域のポリゴンは可能なら削除する。
もしくは、そもそも重なる領域の無い一体成型のメッシュを心がける。
削除することでUV解像度の確保、影のにじみを防ぐ

・パーツがとても多くパディング領域が多くなって、どうしても解像度が下がってしまうような場合は、諦めて解像度を上げるか、パーツを分ける。
テクスチャも含め最終的な見た目でごまかせることもあるので、多少のにじみは妥協することも。

・有機的なオブジェクトはUVをつなげる。
UVを分けるとエッジが際立ち、有機的な見た目が損なわれる。
ライトマップの場合はUVの歪みなどはあまり気にしなくても良いので、極力つなげて緩和させておく。

・UVをグリッドに沿わせる。
DCCツールでピクセル単位でグリッドを敷いて、UVをグリッドに沿わせることで領域を節約できる。

長くなってしまったのでまたの機会に
上記のコツやルールを踏まえてDCCツールでライトマップを作ってみようと思います。

それでは何かのお役に立てれば幸いです。

参考サイト

ライトマップで UV をアンラップする
https://docs.unrealengine.com/ja/Engine/Content/Types/StaticMeshes/LightmapUnwrapping/index.html

ライトマップ UV を生成する
https://docs.unrealengine.com/ja/Engine/Content/Types/StaticMeshes/AutoGeneratedLightmaps/index.html

[UE4] MathExpressionで自作の関数を使う

$
0
0
執筆バージョン: Unreal Engine 4.24.3

みなさん、MathExpression 使ってますか?
公式ドキュメントにもあるように、MathExpressionには以下のような特徴があります:

  • 計算式を直接書ける。
  • ブループリントにない変数名は入力ピンになる。
  • ブループリントにある変数名を書くと、変数値を使える。
  • 一部の関数を使える。

今回は、この中でも、「一部の関数を使える。」にフォーカスしてみようと思います。
改めて公式ドキュメントを読んでみると
「コード化された関数ライブラリにあるブループリント純粋関数は、すべて利用できます。」
と書かれています。これはどういうことでしょうか?

エンジンコードを探してみると、MathExpression で使用できる関数かどうかは、以下のような条件があるようです:

  • static 関数である
  • BlueprintPure である
  • ネイティブ関数である
  • 出力が1つ(ReturnValue)だけある
  • (他にもいくつかあります、気になる方は FKCHandler_MathExpression::CanBeCalledByMathExpression() (MathExpressionHandler.cpp) を見てみてください!)

と、いうことは、UBlueprintFunctionLibrary を継承した C++ クラスで、static で BlueprintPure な関数を作成して
ブループリントで使えるようにすれば、MathExpression でも自作関数を扱えそうです。

一方で、UE4標準の関数でも、DisplayName に “()” を含む関数は、MathExpression では使えないようです…
(どなたかエスケープ方法などご存じでしたら教えてください!)
例えば、”Lerp” 関数は使えますが、 “Lerp (Vector)” 関数はエラーになります。
KismetMathLibrary.h 上での定義名である、VLerp でもダメなようです。

Lerp と Lerp (Vector)
※関数名の大文字小文字は区別されないようです。

そこで、オリジナルのラッパー関数を作成して、VLerp を MathExpression で扱えるようにしてみましょう。
UBlueprintFunctionLibrary を継承した MyFunctionLibrary クラスを作成し、VLerp という static 関数を作成します。

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Kismet/KismetMathLibrary.h"
#include "MyFunctionLibrary.generated.h"

UCLASS()
class MATHEXPRESSION_API UMyFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
	
public:

	UFUNCTION(BlueprintPure, BlueprintCallable, Category = "MyMath")
	static FVector VLerp(FVector A, FVector B, float Alpha) { return UKismetMathLibrary::VLerp(A, B, Alpha); }
};

これをビルドすると、MathExpression で VLerp という関数が使えるようになります。

MathExpression を追加して、vlerp を指定する。

このように、C++ 限定ではありますが、自作の static な BlueprintPure 関数を作ることで、MathExpression で使うことができるようになります。
プロジェクトでよく使う計算などは、このようにして MathExpression でも扱えるようにしておくと便利そうですね。
ぜひご活用ください!

[UE5] Unreal Engine 5 が正式発表されました!

$
0
0

代表の佐々木です。ついに、Unreal Engine 5 が正式発表&初公開されました!
一昨年くらいからUE5の存在は明らかにされてましたが、UE4のリリースから6年が経ち、ついにこの日が来ました。
興奮して眠れないので、記事を書こうと思います!

↓なにはともあれ、こちらのデモ(&解説動画)をご覧ください。

Unreal Engine 5 Revealed! | Next-Gen Real-Time Demo Running on PlayStation 5 from Unreal Engine on Vimeo.

 

こちらの 公式サイトの記事 にも解説が載っています。

今回発表されたUE5の情報の中から、何がすごいのかを書いていこうと思います。(UE5の字面がまだ見慣れないですね!)

メジャーバージョンアップによって変更される場所はいろいろあると予想されますが、今回公開された中での目玉はこの2つです。

 

●超ハイポリをそのまま使えるNanite

いままのゲーム開発は、ロードメモリ、そして描画の3つの観点から、3Dモデルを最適化してノーマルマップなどのフェイクの技術を使い、(誤解を恐れない言い方をすると)いかにポリゴンが多いように見せるかを頑張る時代でした。このNaniteによって今までの何百・何千倍ものポリゴン数のアセットをインポートしてゲーム内で使用できることを、このデモは示しています。ロード・メモリの問題はジオメトリをストリーミングで読み込むことにより解決しているという点が、単なるハードスペックの向上による解決とは大きく異なる点です。

昔からオフラインレンダリングによる映像のリアルさに比べて、ゲームのリアルさはどうしても劣っていました。UE4の世代になって近づきましたが、そこにはまだ隔たりがありました。その原因のひとつが、このポリゴン数です。Naniteによって映画品質のアセットをそのままゲームでも使うことができるようになりました。

また、Natiteはリアルさを上げるだけでなく、いままで非常に多くの時間を費やしていた最適化の工数、そしてその制限によってセーブされていた表現の幅が大きく広がることを意味しています。この動画の内容が実現されれば、アセット制作環境が大きく変わることでしょう。(とはいえ、動画にはエリアをまたぐ時にストリーミングのロード時間を稼いでいるのかな?と思える演出が入っているので、完全に制限から解放されるわけではないかもしれません)

余談ですが、この動画ではMegascansのアセットがふんだんに使われていますが、実際にタイトルを制作しようとすると既存アセットと自作アセットを併用する必要があります。現実問題として、その時に自作アセットを同じクオリティで制作することは非常にハードルが高いです。今後、これまで以上に高品質アセットがDLして手に入るようになるかと思いますが、その時に1つのゲームタイトルとしてどのように既存アセットを使用するのかは、今後重要なテクニックになってくるのかもしれません。

 

●完全動的グローバルイルミネーションのLumen

ゲームはユーザーの入力によって絵が変化するため、超高速(おおよそ16ms~33ms)にレンダリングを行う必要があります。そのため、事前に計算できるものはリアルタイムではなく事前に計算を行うというテクニックが良く使われます。その代表的なものがライトの計算で、光源と地形の環境が変わらない場合は事前に計算を行っていました。(ライトマップとGIの計算) リアルタイムに地形を変化できない、もしくは地形が変化したときは若干ライトの質が落ちるという制限の上でゲームを制作していました。また、この事前計算を行うためにアーティストはライトマップUVの作成と、事前計算(ベイク)に多くの時間を費やしてきました。ライトを完全に動的に計算し、これらの問題をすべて解決したのがLumenです。

これにより絵が向上し、アーティストの作業が減るのは明白ですが、それ以外にもゲームデザイン(ゲームの仕様)上の大きなメリットが存在します。いままでは上記の理由により、壁を破壊して光が差し込んだりする遊びを入れることが簡単にはできませんでした。Lumenはそういった遊びを簡単に実現し、ゲームのルールをより自由に設計できることを示しています。これは、仮想世界の表現力が、さらに現実に近づいたと言えるでしょう。

実はこの動的グローバルイルミネーションですが、UE4が発表された当初はUE4に実装される予定でした。その時は時代的にまだ早かったので見送られましたが、UE5の時代になってようやくそれが実現しようとしています。

 

●そのほかの注目ポイント

個人的に注目したのが、オーディオシステムに言及があったことです。最近のUE4はアップデートのたびにオーディオシステムに更新が入っていました。正直そこまで注目していなかったのですが、このデモを見ていて”ここまで絵のリアリティが上がると、サウンドのリアルさを求めないと音が浮いてしまう”と感じ、最近のUE4の動向に納得しました。UE5世代になり、よりオーディオの重要性が上がるかもしれません。(ああ、開発コストがまた……気軽に洞窟に収録なんて行けないよ……)

正式リリースされたエフェクトシステムのNiagaraですが、今回のデモではインタラクティブな小さな生き物に使われていたのが印象的でした。UE5の時代は、まわりの環境からより多くの影響を受けられるようになり、エフェクトシステムというよりもう一回り幅広い概念でとらえた方が良いかもしれません。

アニメーションシステムも新規機能が動画で軽く解説されていますが、この部分は続報が待たれます。

また、以前から宣言されていましたが、UE4のデータをUE5に移行可能なことが明言されました。UE3とUE4は全くの別のツールで、Unreal Engineは代々互換性を全く保ってきませんでした。UE5ではこの互換性が改めて明言されたことは非常に安心できる材料です。

 

唐突に発表されたUE5ですが、ゲームがよりクリエイティブに、そして映像用途へより広がっていく可能性を見せつけてくれました! 未来への想像が膨らみます!

UE5は2021年後半にリリースとのこと。この1年は新規情報がどんどん出てきて、興奮する日々が送れそうです。

7~8年に1度のこの機会、一緒に楽しい日々を過ごしましょう!

[UE4]Megascansで映像制作・映像を盛ってみる

$
0
0
執筆バージョン: Unreal Engine 4.24

Megascansで映像制作の関連記事はこちらです。
Megascansについて https://historia.co.jp/archives/13752/
最適化してみる https://historia.co.jp/archives/14276/

こちらの動画を元に、動画をより良く見せるのに便利な機能を紹介したいと思います。今回の記事はライティングはすべて動的で行われています。
また合わせて最後の方でBridgeについても紹介します。Bridgeは以前サインインがうまくできない問題が有りましたがアップデートで修正されていますので、この機会に是非!

目次
・Volumetric Fogを使ったゴッドレイ表現
・Light Shaftについて
・暗すぎる部分のディテールを出す
・Bloom Convolutionを使用する
・被写界深度(Depth of Field)を設定する
・パーティクルを追加する
・Bridgeについて

 

まずは映像を盛るためのTipsです。

・Volumetric Fogを使ったゴッドレイ表現

画像のようなゴッドレイ表現の手法の一つとして、Volumetric Fogを使用する方法があります。

Volumetric FogはExponential Height Fogとライトの設定で行えます。UE4には2種類のフォグがあります。デフォルトのシーンに置かれているフォグはAtmospheric Fogという別のフォグですので注意してください。

まずExponential Height Fog側の設定項目を見ていきます。


Volumetric Fog チェックボックスを入れることによってVolumetric fogを使用することが可能になります。
Scattering Distribution 拡散の指向性です。値が1に行くとライト寄りの拡散となるため、光源に近い方にVolumetric fogの効果がより現れます。
Extinction Scale フォグの粒子がライトの光を受け止める量をスケールします。1以上にするとゴッドレイの効果が出ているところ以外も光を受け止めるため、フォグ全体が濃くなってしまう可能性があります。

次はライト側のVolumetric fogの設定項目を見ていきます。


Volumetric Scattering
Intensity
Voluemetric Fogへのライトの効果を調整します。ただしこちらの項目もFogのExtinction Scaleと同様にDirectional Lightなど、広い範囲を照らしているライトのVolumetric Scattering Intensityを上げすぎると全体的にFogが濃くなってしまうので注意が必要です。
Cast Volumetric Shadow チェックを入れるとVolumetric Fogが遮蔽物を考慮するようになります。こちらはDirectional Lightにはデフォルトでチェックが入っています。

Cast Volumetric Shadowの項目はPoint LightやSpot Lightで使用する場合にはチェックを入れる必要がありますが、処理負荷が上がる項目ですので注意が必要です。以下の画像の左がDirectional LightのCast Volumetric ShadowONの状態で洞窟の穴の空いている部分から入ってくる光のみにVolumetric Fogの効果が出ていますが、OFFにすると光の遮蔽を考慮しないため、全体的にVolumetric fogがかかってしまいます。

・Light Shaftについて

ゴッドレイを表現する別の手法としてLight Shaftがあります。Light ShaftはFog無しで、ライトのオプションのみで機能します。

Light Shaft Occlusion Directional Lightでのみ設定可能です。チェックを入れるとフォグなどの大気中へのライトシャフトの影響をスクリーンスペースでオクルージョンしてくれます。
BloomScale Light Shaft効果の強度をスケールします。

Volumetric fogと異なる点は光源の方に向かないとゴッドレイが見えない点です。下の画像の左側はやや光源の方を見ているのでゴッドレイが出ていますが、右のように光源の方を全く見ていないとゴッドレイ効果は出なくなります。今回は光源の方を向かなくてもゴッドレイ効果が出てほしいため、Volumetric fogを選択しましたが、光源の方を見たときにだけ効果が欲しい場合はこちらのほうが効果的かもしれません。

・暗すぎる部分のディテールを出す

今回の動画の様に、影になる部分が多く、またその部分が真っ黒になってしまう場合があります。狙ってそのような状態を作っている場合でなければ、真っ黒に塗りつぶされてしまい、その部分の絵の情報がなくなってしまいます。そのために黒く潰れてしまった部分を見やすくする方法を紹介したいと思います。(※動的ライトで照らしている場合です。ライトビルドを行えば間接光が計算されます。)

紹介するのはFog、Directional LightのShadow Amount、Sky Lightです。

まずシーンのメインのライトであるDirectional Lightだけにしてみます。ライトビルドなどを行ったりしないと、UnrealEngineでは間接光的な表現を生み出さないため、影の部分は真っ黒です。

上記のシーンにExponential Height Fogを追加すると以下のようになります。表面の詳細な情報はまだ不明瞭ですが、奥行きの差があるときのシルエットが見やすくなっています。

さらにDirectional LightShadow Amountを1から0.97に変更してみます。この値は影(Shadow)の濃度のみをコントロールできます。形状によるオブジェクト自体の陰(Shade)には影響を及ぼしません。
これで陰の部分が真っ黒から少し見えるようになりました。

最後にSky Lightを追加してみます。シーン全体がCubemapを元にライティングされたため、暗いところが見えるようになっています。Cubemapに使用するHDR画像はできるだけ作成しているシーンと似たような画像を用意したほうが、より自然な効果になりやすいです。

このように黒く潰れてしまった部分をいくつかの方法で少し見えるようにしてあげることで画面の情報量を上げることができます。ただし、やりすぎるとどれも本来のライティングでできた影を打ち消してしまい、のっぺりとした画面になったり、光源がどこにあるのか不明瞭になったりするので注意して調整しましょう。(記事の画像もあくまで説明用のものになります)

また間接光代わりに、薄くライトを置くのも効果的です。(ライトの置きすぎは映像用といえども重たくなる+作業の混乱のもとになりやすいので注意しましょう)

では次にPostProcessについてはBloom Convolutionと被写界深度について触れていきます。

・Bloom Convolutionを使用する

通常のBloomはGaussian Blurを使用しているため、光が均一に拡散するようにBloomがかかります。ConvolutionではBloomの形状をテクスチャで制御することができます。テクスチャを特に指定しない場合は8方向へとBloomするようになっています。画像の左が通常のBloom、右がConvolutionのBloomです。

Bloom Convolutionを使用するにはPostProcessのBloomのMethodをConvolutionに変更します。また、Convolution Kernelにテクスチャを適用することで、Bloom形状を変更できます。

星型のテクスチャを適用するとBloomの形状もテクスチャに合わせて星型になります。

テクスチャ全体は以下の様に、Bloomの形状自体は小さく描いたほうが良いです。また階調がなめらかに変化していると、Bloomがきれいに出ます。

・被写界深度(Depth of Field)を設定する

UE4の被写界深度は4.23を境に設定項目が変わります。以前はボケの種類がBokehGaussianCircleから選べるようになっていますが、4.23以降のバージョンではMobile以外は1種類(Cinematic)のみとなっています。
今回4.24で作業しているため新しいCinematicの方を使用しています。

まず、カメラのFocus SettingsからManual Focus Distanceを調整してピントが合う位置を調整します。Draw Debug Focus Planeにチェックを入れると焦点位置を示すプレーンが表示されるので、どこに焦点位置があるのかわかりやすいです。

焦点位置を決めたら、次はボケ具合を調整します。カメラ自体のPostProcess、もしくはPostProcessボリュームを配置して、Lens>Depth of Fieldから調整することができます。

Depth Blur km for 50% Depth Blur Radiusで設定した半径の半分でブラーされる距離を調整します。より近い距離からブラーを掛けたい場合は小さい値を入れましょう。
Depth Blur Radius 画面解像度が1080pのときのピクセル単位で指定するブラー半径です。より強いブラーを掛けたい場合は大きな値を入れましょう。

以下はDoF(Depth of Field)の効果の比較です。DoFを使用することにより距離感をわかりやすくしたり、注目させたい部分以外をぼかすことで見る人に対してわかりやすい絵にする効果があります。

次に空気感を出すためのパーティクルについてです。

・パーティクルを追加する

この動画のシーンには2種類のパーティクルを使用しています。

まず1つ目は空気中の塵などを模しているパーティクルです。このパーティクルはごく小さいものですが、カメラに近い塵と遠くの塵で差ができ、また揺らいでいることで手軽に空気感や奥行きを表現できます。
 

2つ目に部分的なFog的な効果を出すパーティクルです。以下のシーンでは、オブジェクトをあまりはっきりと見せたくなかったため、パーティクルを置いています。このような範囲の狭いFog効果は通常のFog(Exponential HeightもしくはAtomosheric)ではやりづらいため、エフェクトで追加しています。

Tipsは以上になります。最後にBridgeについてです。

・Bridgeについて

Bridgeを使用するとUE4へのMegascansの管理やインポートが簡単になります。
Bridgeはこちらからダウンロードすることができます。
https://quixel.com/bridge
Bridgeを使用するにはサインイン用のアカウント(Megascans同様Epicアカウントで可能)が必要です。

Bridgeをインストールしたらひとまず何かアセットをダウンロードしてみます。

アセットをダウンロードする前に保存先を設定しておきます。
保存先はEdit>Settings>LOCAL LIBRARY PATHから設定できます。

アセットをクリックすると右側にDOWNLOAD SETTTINGSが出てきます。
ダウンロード設定は以下の項目を設定変更できます。Material PresetはUnreal 4に設定しておくと良いでしょう。


LODなどメッシュに関する設定はメッシュが含まれているアセットでのみ設定項目が表示されます。マテリアルのみのアセットはテクスチャ設定のみが表示されます。
ストレージの容量がある場合は、高解像度のテクスチャ、必要になりそうなテクスチャやLODやデータをダウンロードしておいて、UE4へエクスポートするときにダウンロードしたものから要素を省いたり、低解像度を選択することができます。

アセットがダウンロードできたら、左のAcquiredからダウンロードしたアセットをクリックします。
すると右側にEXPORT SETTINGSが出てくるので設定します。
ここでBridgeとUE4の連携させためのエンジンバージョンの指定やプラグインのダウンロード、使用するプロジェクトのパス設定を行います。


EngineVersionにはPluginを使用するエンジンのバージョンを設定し、Instollation Folderには使用するUE4のプラグインフォルダを設定してください。
Instollation Folderを設定すると自動的にPluginのインストールが始まります。
ProjectLocationはMegascansをインポートしたいUE4プロジェクトフォルダを設定してください。

これでBridgeを利用する設定は完了です。設定が完了したら使用するUE4プロジェクトを開いてMegascansPluginが有効になっているか確認しましょう。
有効になっていればメニューアイコンにMeg
ascansが並んでいるはずです。


このメニューをクリックするとインポート時の設定を変更することができますが、デフォルトの設定でも特に問題は無いようです。

UE4での設定が確認できたらBridgeに戻り、アセットをエクスポートしてみます。
BridgeからUE4へのエクスポート設定は以下になります。エクスポート時に変更できる項目は少ないため、ダウンロード時に必要な設定を確認しておきましょう。テクスチャ解像度やLODはダウンロード時のものから下げることができます。

設定ができたらExportを押します。エクスポートしたものが自動的にフォルダ分けやマテリアルやLODの作成、設定が行われます。この部分が自動で行ってくれるのはとても便利ですので、この機会にぜひ使って見てください。

[UE4]Megascansで映像制作・シーンを最適化してみる(初心者向け)

$
0
0
執筆バージョン: Unreal Engine 4.24

Megascansで映像制作の関連記事はこちらです。
Megascansについて https://historia.co.jp/archives/13752/
映像を盛ってみる https://historia.co.jp/archives/14197/

前回の記事ではシーンを作成しました。しかしそのままだと処理負荷が高いので、今回は簡単にですが最適化します。

今回の記事では特定のコンソールに向けてではなくエディタ上で見ているだけのため、かなり簡易的なものになります。
本来はターゲットのハードウェアや出したいフレームレート(ms)、ゲームの処理を除いた描画部分でそれぞれどれくらいのmsまで許されているのか、ボトルネックになっている部分など、仕様や状況に合わせての最適化が必要になってきます。
本記事では簡単なVisualizerの見方と、負荷が高いライトとFogの項目だけ対応することにしています。映像でUE4を触っている人がゲーム用シーンなど、処理負荷を気にするシーンを作るときの手がかりとなれば幸いです。

UE4のヘルプでも最適化のガイドラインが書かれているのでご参照ください。
https://docs.unrealengine.com/ja/Engine/Performance/Guidelines/index.html

目次
・GPU Visualizerを開く
・UE4のライト軽量化の手法について
・Volumetric Fogのライトビルド時の対応
・Volumetric Fogの代替表現について

 

・GPU Visualizerを開く

それではシーンを見ていきます。

ひとまず、プロファイルを取ってみます。UE4のGPU Visualizerでどの部分が一番負荷がかかっているのか見てみます。

ctrl+shift+,のショートカットを押すとGPU Visualizerのウィンドウが出てきてショートカットキーを押した瞬間のフレームの処理負荷を出力してくれます。瞬間的な負荷処理をみているので、いくつかのカットや同じ場所で比較する際にも何度かキャプチャして、一時的な処理負荷がかかっているのではないことを確認します。するとだいたいのカット(場所)でも一番処理負荷がかかっているのが、ShadowDepth(Directional Lightのもの)、次にVolumetric fog、以下はBasepassもしくはPostProcessとなっています。


今回はShadowDepthとVolumetric Fogについて主に見ていきますが、本来は前述の様に、何msにするのかという目標を決めて負荷がかかっている原因と、それにあった解決方法を取るかと思います。

いくつか上記のパラメータを簡単に紹介したいと思います。

PrePass 深度情報を計算します。メッシュの前後関係を予め計算しておくことで、余計な計算をしないための工程です。ポリゴン数が多いと負荷がかかります。
BasePass ビューポートのView Mode>Buffer Visualization>Overviewから表示できるものを計算している工程です。ここの項目の負荷原因には、ポリゴン数、マテリアルの複雑さ、テクスチャの解像度などの複数の要素が関わってきます。すべての項目に関することですがカリングをしっかりして画面外のものを描画しないことも大事です。
ShadowDepth 動的に生成される影(Movaleなライトからの影、Statinalyの動的メッシュに対する影など)の項目です。
Volumetric Fog Volumetric Fog効果による負荷です。Fogそのものの負荷はExponential Height FogもしくはAtomoshpereの項目にあります。
Light ライトの計算に関する項目です。ライトの個数よりも、ライトの影響範囲が重なると重くなっていきます。ライトの計算をするかどうかはライトの影響範囲(Attenuation Radius)で決まるため、光が減衰しきっているのにライトの影響範囲が広すぎると無駄に計算させてしまうことになります。
PostProcessing ポストプロセスによる負荷です。ポストプロセスの項目や設定によって負荷が異なるため、ポストプロセス内の何の効果が重いのか特定しましょう。
Translucency 半透明で描画しなければいけないもの、例えばエフェクトなどがたくさんあると負荷が増えていきます。半透明は重なっている部分は重なっている分だけ同じピクセルが複数回計算されます。

 

・UE4のライト軽量化の手法について

現在このシーンはすべて動的ライティングがなされ、ライトビルドなどを使用せず、負荷を考慮していないシーンになっています。

ライトを常に計算させる(Movableなライト)のは処理が重くなってしまいます。
そのため、UE4ではLightmassという機能をつかってライティングを事前に計算して軽くする手法があります。LightBuildを行うことでLightmass機能を使ってLightmap、Shadowmap、Precomputed Light Volumeが生成されます。
LightmapとShadowmapはStaticなメッシュに対して生成され、Precomputed Light Volumeは空間中のライティング情報を持っていて、Movableなメッシュをライティングすることができます。
ちなみに、Volumetric FogはUE4.18からの入った方法のVolumetric Lightmapによって事前計算されたライティングをVolumetric Fogに反映することができています。

(通常のLightmass設定であればVolumetric Lightmapになっていますが、設定で以前の手法Indirect Lighting Cacheにすることができます。Volumetric LightmapとIndirect Lighting Chcheの比較はこちらのページの下段に記載されています。
https://docs.unrealengine.com/ja/Engine/Rendering/LightingAndShadows/VolumetricLightmaps/index.html

このシーンはほとんど動的ライトで照らされているため、ShadowDepthの処理負荷がメインとなっています。
Shadow Depthとは動的に生成されている影のことを指しています。
一度Directional LightをStatinaly(ライトのVolumetric Fog効果がStatinalyもしくはMovaleでないと現れないため)、その他のライトをStaticに変更します。(今回のシーンでは動的なオブジェクトが無い=動的な影を生成する必要が無いため、すべてStaticにしています。動的なオブジェクトがある場合、ライトによる落ち影はStastionaly、もしくはMovableでないと出ないので注意してください)

 

・Volumetric Fogのライトビルド時の対応

Volumetric Fogをそのまま使いたい場合はVolumetric Lightmapを生成しましょう。Volumetric Lightmapが正しく生成されているかはビューポートのShow > Visualize > Volumetric Lightmapで確認することができます。
空間中に球体が表示されればその空間中にPLV(Precomputed Light Volume)が作成されていることを示しています。

Volumetric Lightmapの密度を変更するにはWorldSettings>Lightmass>Volumetric Lightmap Detail Cell Sizeをから変更できます。
イテレーションのためにビルド時間を短くしたいときや、デフォルト値だと密度が高すぎる場合は値を上げましょう。
Volumetric Lightmapは何もしないとUE4側で自動でメッシュ付近に生成されますが、望んだ場所に生成されない場合もあります。その場合は
Lightmass Importance Volumeを置くと生成されます。

Volumetric Fogをライトビルドに対応するにはいくつか注意する点があります。
まずはVolumetric Fogの効果はStaticなライトには出ません。
そのため、Volumetric Fogの効果を持たせたいライトを事前計算したい場合はStatinalyになります。ライトビルドしたらVolumetric Fogの効果が消えてしまった!という場合はライトのMobilityがStaticになっていないか確認してみましょう。

他にもVolumetric Fogの効果が消えてしまう、もしくは見た目がライトビルド前と異なってしまうことがあります。
その原因はShadow Resolution Scaleの値が足りていないためです。下の画像はライトビルド前とライトビルド後の比較です。Shadow Resolution Scaleがデフォルトのままの状態です。
 
隙間から入ってくる光の筋が隙間の形状と合っていません。また天井などにも効果が滲んでしまっています。
Shadow Resolution Scaleを上げてみると、以下の画像の様になります。

ライトビルド前と全く同じ、というわけではありませんが、大きく形状が崩れている状態は改善できています。
ただし、Statinaly LightのShadowmap Resolutionを上げるということは、Movable、もしくはStatinalyなメッシュの動的な影に使用されるテクスチャの解像度を上げているので、その分の負荷は上がってしまいます。
例としてMovableに設定したボックスをたくさん置いて、Shadowmap Resolutionが1のときと、5のときをGPU Visualizerでキャプチャして比較してみます。
 
処理速度が約0.23ms増えています。
Shadowmap Resolutionを上げていくと影の解像度が上がったことで、1つのメッシュの影に対して使用するピクセルが増えることにより、Shadow mapのテクスチャ枚数が増える場合もあります。

また名前からのイメージで関連がありそうですが、Volumetric LightmapのCell Sizeを細かくしてもVolumetric Fogに対しての影響は有りません。
 
ライトビルドを行うと以下のような見た目になります。動的なライティングと静的なライティングは仕組みが異なるため、見た目が変わってしまうことがあります。それぞれのライトの強度や、ポストプロセスでのGIなどで調整しましょう。

ライトビルド後にもう一度GPU Visualizerでキャプチャしてみます。
MovableなライトをDirectional Lightを除いてStaticにして事前計算にすると、シーン中にMovaleなメッシュも無いため動的に生成される影がほとんどなくなり、以下のようにShadowDepthの処理負荷がほぼなくなったことがわかります。

 

 

・Volumetric Fogの代替表現について

では次にVolumetric Fogの項目の処理負荷を軽減してみます。

ただ、ライトに対するLightBuildとは異なり、Volumetric Fogそのものを事前処理させたりして軽くする手段はないため、別の方法で表現することにします。今回はゴッドレイ表現をメッシュに置き換えることで、処理負荷を軽減することを目指します。ExponentialHeightFogはそのままVolumetric Fogのオプションは外して通常のFogとして利用します。

以下のようなゴッドレイ表現用のマテリアルとメッシュを用意し、Volumetric Fogの代わりに配置して見ます。
 


再びGPUVisualizerでキャプチャしてみます。
Volumetric Fogの負荷がなくなり、またゴッドレイの変わりのメッシュは透過マテリアルを使用していますが、Translucencyの項目の処理負荷として特に目立った数値の上昇もなさそうです。
 

これで代替表現を用いることで、見た目を損なうことなくVolumetric Fogの処理負荷を無くすことができました。

最適化の際にはひとまずどの部分が重いのか確認し、重いものを最適化する機能がUE4に用意されているのか、もしくは代替的なものを使うのか検討して見てください。

簡単にですが、初めての最適化の足がかりになれば幸いです。

 

 

 

”アスレチックVR PAC-MAN CHALLENGE(パックマンチャレンジ)”制作事例 ~Oculus Questを使用した我々の挑戦~ 資料公開!!

$
0
0

みなさんこんにちは!ヒストリア広報部です(๑˃ᴗ˂)و
普段はツイッターでヒストリアのお知らせだったり、ぷちコンを盛り上げています♪

今回は、1つ講演資料が公開されたのでブログを書いてみましたー!

出張ヒストリア! ゲーム開発勉強会2019」で行った講演の1つ
“アスレチックVR PAC-MAN CHALLENGE(パックマンチャレンジ)”
制作事例 ~Oculus Questを使用した我々の挑戦~

の技術的なパートの内容に、UNREAL FEST EAST 2019で行った
講演内容を書き加えたものをSlideShareに公開いたしました!


また、マーカーキャリブレーションの解説及びサンプルプロジェクトはこちらからDLできます!
マーカーキャリブレーションの解説及びサンプルプロジェクトのダウンロード

講演者
株式会社バンダイナムコアミューズメント 濵野 孝正 (プロデューサー)
株式会社ヒストリア 金山 善春(ゲームデザイナー/宴会ボーイ)、小倉 裕貴(エンジニア)、佐々木 瞬

概要
以下、セッション概要より抜粋。下記のセッションの技術パートのみとなっております。
MAZARIA(池袋)にて稼働中のOculus Quest(PCが必要無く、コードが無いタイプの新VRゴーグル)を使用したフィールドVRアクティビティ、”アスレチックVR PAC–MAN CHALLENGE(パックマンチャレンジ)”。
コードが無いというのは自由に歩き回れるというだけではなく、新たな価値を生み出していました。
前半では本タイトルを通じて得た、コードレスによりもたらされた新たなゲームデザインについてお話いたします。
また、後半ではハードウェアスペックとの戦いや、どのように複数人プレイを実現したかなどの技術的知見をシェア出来ればと思います。


“出張ヒストリア! ゲーム開発勉強会2019″のその他のスライド

また、せっかくなので同じ”出張ヒストリア! ゲーム開発勉強会2019″で講演された内容で
資料が公開されているものが何種類かあるので一緒に紹介させてください♪

・「COLORSプロジェクト、フォトグラメトリに挑戦してみた! 」


講演者
株式会社ヒストリア 小林 大輔 (背景アーティスト)

概要
1人1ヶ月、自由なテーマで作品制作が行えるヒストリアの制度、COLORSプロジェクト。
今回は技術検証を兼ねて、手持ちカメラによるフォトグラメトリを行い、日本庭園の作成に挑戦しました。
フォトグラメトリとは、複数アングルから撮影した写真を解析して3Dモデルを生成する手法です。
撮影方法、3Dモデル化の工程、UE4での基本的なマテリアル、シーン構築まで
実際にアセットを制作してみて、得た事や失敗した事など、お話しさせて頂きます。

・「UE4新機能リアルタイム レイトレーシングで建築ビジュアライズ」

3ds Max でも~っと!3DCGを活用しよう!建築ビジュアライゼーションセミナー

講演者
株式会社ヒストリア 小笠原 彰 (建築ビジュアライズアーティスト/UE4アーティスト)

概要
建築シーンでUnreal Engine 4.22で追加されたリアルタイム レイトレーシングを使ってどんな表現が出来るのか、
また、使用した場合の負荷などについてご説明します。
※2019年5月30日に開催されたボーンデジタルセミナーでの講演をアレンジした内容です。

・ゲストセッション「アーティストの為のプロファイル入門! ~楽しいRenderDocの使い方~」


講演者
Epic Games Japan 斎藤 修 (テクニカルアーティスト)

概要
プロファイルって難しそう…、プログラマさんの仕事ですよね…。
と思っているアーティストの方!いいえ、難しいどころか実は楽しいんです!
本講演では、UE4に標準プラグインとして搭載されているRenderDocを使用して、
基本的なGPUプロファイルの概要、方法などをご説明致します。
UE4の絵がどうやって出来ているのか、Photoshopのレイヤーを剥がすように一緒に見ていきませんか?


以上、皆さんのお気に入りの講演は見つかりましたか?(๑˃ᴗ˂)و

ヒストリアでは毎年UE4を初めとした、様々なゲーム開発に関する技術セッションや
事例紹介勉強会を行っております!

少しでも皆さんの参考になれば嬉しいです♪

[UE4]Spectacular Test Drive 都市 (DistanceFieldを使ってお手軽にディティールアップ。)

$
0
0

 

執筆バージョン: Unreal Engine 4.24

Spectacular Test Driveの都市ゾーンのアートを担当しました。

このシーンではビル街の道路を車で走行します。

Spectacular Test Driveの都市制作プロセス

中々の広いシーンでしたが大半のアセットはマーケットプレイスのものを調整して配置していきましたので、

おおよそのボリュームが並ぶまでは比較的短時間でできました。

とはいえ、並べただけだとやはり情報量が乏しいです。

まず、面積が広い割に情報量の少ない路面に手を加えようと思いました。

ブラッシュアップの方向性としてはコンテンツ内で雨天モードがあることもあり

”雨上がりの晴れの日だが建物の隅やオブジェクトの周りにはまだ水気があり濡れた落ち葉が残っている”

ようなイメージでした。

 

路面に情報量を足す際はデカールや頂点カラーを使ってランダムにしていくのが常套手段かと思いますが、

この都市はレベル全体で片側2車線道路が2km以上あります。

 

プロシージャルにディティールアップしたい

広大なレベル全体に手作業で調整を加えるのは大変です。

レイアウトもまだ変わる可能性がありました。

そこで、DistanceFieldを使ってプロシージャルかつお手軽にディティールアップした方法をご紹介します。

スタティックメッシュを動かすとリアルタイムに雨の濡れと落ち葉がついてきます。

レイアウト変更に柔軟に対応できるのがいいですね。

 

DistanceFieldのドキュメント

https://docs.unrealengine.com/ja/Engine/Rendering/LightingAndShadows/MeshDistanceFields/index.html

 

 

DistanceFieldを使ったマテリアルサンプル

 

上記のシーンとマテリアルは関係のない要素が多く含まれているので

シンプルなシーンとマテリアルでご説明していきます

 

before

ベンチがある路地裏の路面のマテリアルです。アスファルトの質感のテクスチャ直結のシンプルなものですが、

UVの異なる色々なメッシュに使いまわしたいのでワールド座標からUVを生成しています。

 

after

この画像を作成していきます。

 

 

 

・事前準備

プロジェクト設定のレンダリングタブでGenerateMeshDistanceFieldをオンにします。

 

 

 

 

 

 

 

路面のメッシュを選択して「AffectDistanceFieldLighting」はオフにします。

これを行わないと後の工程でマスクが真っ黒になってしまいます。

 

・マテリアル作成

新規にマテリアルを作成していきます。

マスクから作成するのでEmissiveにつないで形状を確認しながら進めていきます。

画像のようにノードを組んだら路面のメッシュに設定します。

すると壁やベンチから「Wet_SpreadDistance」の距離だけ白くなったマスクができました。

ベンチを動かしてもちゃんとついてくるはずです。

DistanceFieldが有効になっていると

DistanceToNearestSurfaceノードが一番近いサーフェイスまでのマスクを取得してくれます。

今回の記事の内容はこのマスクができたら半分以上完成したようなものです。

 

ただし、これだけだと濡れた路面には見えないので

ノイズテクスチャを使って水たまりが乾きかけているようなマスク形状に整えていきます。

ランダム感がほしいので画像のようにノードを組むと雲模様ができました。

ちなみにノイズのテクスチャはエンジンに入っている

Engine/Content/MapTemplates/TilingNoise05.uasset を使いました。

 

さきほど作ったDistanceFieldのマスクのグラデーション部分だけにランダム感が出るように雲模様を合成してみます。

 

先程より自然になりましたが、もう少しマスクのエッジを複雑にしたいので

同じテクスチャを少し小さくマッピングしてさらに合成を行います。

 

このマスクを使って乾いた地面と濡れた質感を合成します。

2つの質感はシンプルですが

配置に沿っているので簡単にそれっぽくなりました。

 

 

 

同様の方法で濡れた部分より一回り小さいマスクを作り

乾いた路面、濡れた路面の質感にさらに濡れた落ち葉の質感を合成しました。

一つのマテリアルに3つも質感が入ってきたので

見やすくするためにマテリアルアトリビュートを使いましたが

考え方は先程と同じです。

 

 

DistanceFieldの更新に描画負荷は多少かかりますが

お手軽に路面の情報量を増やすことができました。

広大なシーンのプロジェクトや動的ライティングのプロジェクトでは

そもそもDistanceFieldをオンにしていることも多いと思いますので相性がいいかもしれませんね。

 

ぜひお試しください。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


[UE4] 第13回UE4ぷちコン 受賞作品発表!

$
0
0

第13回UE4ぷちコン 受賞作品が決定!

応募総数は81作品! 今回もたくさんのご応募ありがとうございました!

王道から意外なものまで、本当にさまざまな”さく”が集まりました。
その中から最優秀賞含む8作品を選出いたしましたのご紹介します♪

受賞作品の発表は【第13回UE4ぷちコン】審査結果発表会!【拡張版】で行いました!

 

【第13回UE4ぷちコン】審査結果発表会!【拡張版】


今回は普段の作品紹介と受賞作品発表に加え、ゲストをお呼びしていつもと違った放送をおこないました。
アーカイブを残しておりますので是非ご視聴ください♪

<審査員>
Epic Games Japan おかずさま
株式会社ヒストリア 代表 佐々木 瞬
株式会社ヒストリア 広報 けーちん

<ゲスト>
紙パレットさま
もんしょさま

 


【最優秀賞】サクサク斬り裂く侍

でじまい さま


【準最優秀賞】Flower Pinball

wvigler さま


【グッドルッキング賞】安全対柵

Penguin Gamers さま

 


【テーマに沿ってるで賞】SAKURA FRONT LINE

yeczrtu さま

 


【徳が高いで賞】蓮華

oMochi さま

 


【おかず賞】Little John

zohyo u さま


【ささき賞】YOSAKU – The Legendary Woodcutter

JUGANDO さま

 


【けーちん賞】トンカツフリースロー!サクっとスライサー

kanio さま

 

 

 

受賞おめでとうございました!
そしてご参加いただきありがとうございました!

少しでもみなさんのUE4に触るきっかけになっていたら嬉しいです♪

 

第13回UE4ぷちコン イベントページ

 

[UE4]カーブアトラスを使って色を管理/共有する

$
0
0
執筆バージョン: Unreal Engine 4.24

以前紹介されているカーブアトラス(Curve Atlas)【1】【2】【3】を使って、
実際にUI実装でカラーパレット代わりに使用する方法などを紹介します。

 

■カーブアトラスで色を管理/共有する

現状は随時変化するUMGカラーパレットを自動で他者と共有する方法はありません。
そこで、【カーブアトラス】を使うことでカラーパレットの役割を補う方法をご紹介します!
※iniファイルを更新していく方法は【 EpicGamesJapan斎藤さんの記事 [UE4]カラーピッカーのパレットを共有する方法 】をご参照ください。

 

メリット

●他のアセットと同様にサブミットすれば共有される!
●グラデーションも登録できる!
●どの色をどんな場所で使用しているかReferenceViewerで辿ることができる!
●マテリアルで使えるからマスクにもアニメーションのタイミングとしてもやたらと使える!

 

実際のプロジェクトで以下のように管理しています。

このように色を管理することで、
色の変更があった場合も【カラーカーブ】を変更してしまえば該当の色を使っているパ-ツ全ての色を変更することが可能です。
どの色をどんな場所で使用しているかもReferenceViewerで辿ることができます。
テクスチャも基本は白やチャンネル画像にして色はUE4上で乗せる方が容量的にも作業の後戻りの少なさとしても良いです。

カラーカーブ、カーブアトラスの作り方は【 [UE4]カーブアトラス(Curve Atlas)アセットを使ってみるを参考にしてください。

色情報の部分をダブルクリックすればカラーピッカーがちゃんと出ますし(カーブをいじらなくていい!)、
カーブ具合もアンカーをいじってよりなめらかにすることができます。

 

■カーブアトラスを入れたマテリアル

ざっくり3パターンを用意して運用しています。

●色(Curve Atlas)のみのマテリアル(単色、グラデーション)
●テクスチャと色(Curve Atlas)とマスク(Curve Atlas)を合わせたマテリアル
●アニメーション用のアルファ情報(Curve Atlas)を持ったマテリアル

色のみ
主にテキストなどに使います。
こちらの記事中盤と同じ作りです[UE4]UMGで使えるでシンプルなグラデーションを作り方あれこれ

テクスチャ+色+マスク入り
こちらは色のカーブアトラスとマスクのカーブアトラスの2つを登録しています

▼UMG上で上記2つをあわせた楽しい画像

アニメーション用
こちらはカーブアトラスのカラーカーブをアルファ値の0~1で作り、
その間隔でアニメーションするようになっています。
なんとなーくランダムな動きをつけるのに便利ですし、
UMGのアニメーションは大変重いのでマテリアルで作るとプログラマさんがスーパーハッピーです。


▼アニメーションします

複数人でのUMG作業では色の共有が不可欠です。
デザインから離れ、実装しながら簡単なレイアウトを起こすとき等
どこでどの色が使われているか、どんなグラデーションの作りなのかなど
UE4上で確認できてその場で作れると早くて便利です。

 

よろしければ、ご活用ください!

 

UE4とMegascansを使用したインタラクティブデモ “Cutting-Edge Test Drive”公開!-操作説明-

$
0
0
執筆バージョン: Unreal Engine 4.24.3

本記事はヒストリア・エンタープライズチームにより制作された
インタラクティブデモ「Cutting-Edge Test Drive」についての連載記事です。
全5回にわたって記事を公開していきます。

関連記事
第1弾 UE4とMegascansを使用したインタラクティブデモ “Cutting-Edge Test Drive” 公開!-操作説明-

第2弾 coming soon
第3弾 coming soon
第4弾 coming soon
第5弾 coming soon


自動車業界におけるUnreal Engine 4(以下、UE4)の活用例を示したインタラクティブデモ
「Cutting-Edge Test Drive」(カッティング エッジ テスト ドライブ)を公開し、
特設ページにて期間限定で実行ファイルを配布いたしました。

【期間限定】6月30日まで! 実行ファイルを無料DL!
“Cutting-Edge Test Drive”公式ページ

UE4やMegascansといった最新技術により作られており、カーコンフィギュレーター、ハイクオリティムービー、
都市走行シミュレーションの3つの用途を想定したパートが体験できます

バーチャル展示場で自身の車を好きなボディカラーに変更、展示場を離れて壮大な荒野へ走り出し、都市へ。

エンタープライズチームCETD連載ブログ第1弾
「”Cutting-Edge Test Drive” 操作説明」

今回このデモに携わった開発陣達による連載記事を更新していきます。
連載第1弾目の記事では、デモ中のさまざまな場面を画像で紹介すると共に操作説明をさせていただきます。

バーチャル展示場、荒野、都市の3パートにわけて紹介します。

 

■バーチャル展示場

バーチャル展示場で行える機能を解説していきます。

このモードでは、リアルタイムにボディカラーの変更やアングルの変更、
回転台を回す、カラーを変更した車でイメージ映像を見ることが可能です。

車両カラーの変更

Colorボタンを押すことで、ボタンに示されている色に車両のボディカラーを変更することができます。
チェックマークがついている色が現在のボディカラーになります。

 

車両の回転

Rotationボタンを押すことで回転台を回転させることができます。
ボタンを押している間、押しているボタンに表示されている方向に回転します。ボタンを離すと、回転は止まります。

 

ビデオモードの再生

Videoボタンを押すことで、カスタマイズしたボディカラーでの映像を再生することができます。
Escキーまたは画面をクリックすることで映像を終了できます。

 

 

カメラ位置の変更

Viewボタンを押すことでカメラ位置の変更を行うことができます。
カメラ位置の変更を行うことで、様々な角度から車体を見ることができます。

 

荒野デモシーンへ遷移

GOボタンを押すと、車の発進映像が再生され、荒野パートへ遷移します。

 

 

 

■荒野

荒野パートでは、マウスを動かすと画面にHomeボタンが表示されます。
Homeボタンを押すことでバーチャル展示場へ戻ることができます。

各パートの車両には、バーチャル展示場でカスタマイズしたボディカラーが反映されます。

 

 

 

■都市

都市パートは車の走行シミュレーション環境をイメージしております。
さまざまな機能がありますので順番に解説していきます。

①~④は、それぞれボタンをクリックすることでON/OFFを切り替えます。
UIはマウスを動かすことで表示でき、一定時間経過すると非表示となります。

天候の切り替え

Rainボタンを押すことで天候(晴れ/雨)を切り替えることができます。
天候が雨になると、車のワイパーが可動します。

 

画像認識タグ表示の切り替え

Tagボタンを押すことで画像認識タグを表示します。
(本コンテンツのタグはイメージとして表示しているため、実際に画像認識は行っておりません。)

 

輪郭線表示の切り替え

Wireボタンを押すことで輪郭線を表示することができます。

 

車内/車外カメラの切り替え

Viewボタンを押すことでカメラを切り替えてデフォルトの車内視点から車外視点に切り替えられます。

 

バーチャル展示場に戻る

Homeボタンを押すことで荒野パートと同じく、バーチャル展示場へ戻ることができます。

 

 

 

■その他各種機能

コンテンツを終了するには

Escキーを押すことで終了ダイアログを開くことができます。
YESボタンを押すことで終了、NOボタンを押すことでダイアログを閉じます。

 

映像のスキップ機能

場面転換の映像と荒野パートの映像は再生中に画面をクリックするとSKIPダイアログが表示されます。
YESで映像をスキップ、NOでダイアログを閉じます。

機能説明は以上になります。
併せて、機能紹介動画も公開しておりますのでご覧ください。

ぜひみなさんの手で、実際に操作してみてください!

[UE4] ”Cutting-Edge Test Drive” バーチャル展示場 -初心者に向けたUE4シーン作成-

$
0
0
執筆バージョン: Unreal Engine 4.24

本記事はヒストリア・エンタープライズチームにより制作された
インタラクティブデモ「Cutting-Edge Test Drive」についての連載記事です。
全5回にわたって記事を公開していきます。

関連記事
第1弾 UE4とMegascansを使用したインタラクティブデモ “Cutting-Edge Test Drive” 公開!-操作説明-
第2弾 [UE4] ”Cutting-Edge Test Drive” バーチャル展示場 -初心者に向けたUE4シーン作成-
第3弾 coming soon
第4弾 coming soon
第5弾 coming soon


エンタープライズチームCETD連載ブログ第2弾
「バーチャル展示場 -初心者に向けたUE4シーン作成-」

今回はUE4における制作ワークフローの紹介として、
バーチャル展示場のシーンがどのような手順で作られたのかを解説していきたいと思います。


手順

・グレーボックス

デザインからおおまかにUE4上でボックスで背景を作成します。
このとき実際の大きさの人や車のモデルなど大きさを比較できるものを配置します。

カメラの位置を決め、この状態で軽くライティングを決めます。

ボックスのデフォルトの白色だと明るすぎて、
それに合わせると本番のときに室内が暗く感じるのでグレーより少し暗い色に変えておくのがおすすめです。
木など明るめの質感のものはこの時点で木材マテリアルを個別に割り当てています。

メインとなる車だけはこの時点で質感を決めたものを配置しておきましょう。

ここでのライティングは時間をかけすぎてもマテリアルを割り当てたときに印象が変わり、
やり直しになる部分も多いので6割くらいできたら完成にし次へ進みます。

 

・必要な部分をモデリング

車を除けばMAYAで実際に作成したのは画像の部分のみになります。

モデリング前にデザイン画を見てどの部分はアセットでよいか、モデリングが必要かを調べておきます。

 

・マテリアルの割り当て

今回建物系のマテリアルの大半はMegascansのマテリアルを使用しました。
荒野で使用したようなスキャンした岩や草などが注目されがちですが、
マテリアルも非常に優秀です。

デザインの段階でどの部分にどのマテリアルを割り当てるかを決めておきます。
この時点でマーケットプレイスアセットの家具などの配置を行いました。

この作業はデザインを元にしつつも置きながら考えていきます。

 

・本番のライティング

ポストプロセス含め最終ルックを決めます。
シーンを全体をみて一部質感も変更していきます。
これで完成になります。
マーケットプレイスとMegascansのマテリアルを使用してかなり効率的にシーンが作成できました。

[UE4]GameplayAbilitySystemでコンボ攻撃を作る

$
0
0
執筆バージョン: Unreal Engine 4.24

ハローアンリアル!エンジニアの片平です。
今回はBPで組むと複雑になりがちなアクションゲームのコンボ攻撃の処理を、GameplayAbilitySystemAbilityTag機能を使って作成してみました。

GameplayAbilitySystemとは

RPGやMOBA等で頻繁に使用されるアビリティを管理するシステムです。

アビリティとは、キャラクターが繰り出す攻撃、スキル、アイテム使用などのひとつひとつの「行為」です。
また、アビリティによって引き起こされるアトリビュート(=キャラクターの持つ数値、ステータス)の変化、発生するエフェクトなどの見た目上の挙動など関連する要素を効率的に実装することができます。

まだベータな機能ではありますが、FortniteやParagonなどの大型タイトルでも採用されているそうです。

今回は詳細や導入は省きます。上記の記事をご参照ください。
リファレンスプロジェクトとしてはActionRPGが非常に参考になります。

カバーする範囲が広い分、全体を把握しようと思うとかなり覚えることが多いですが、今回はGameplayAbilityComponentGameplayAbilityのみを使用します。
GameplayEffect、GameplayAttribute、GameplayCue、GameplayTask、GameplayEventについては知らなくても構いません。

セットアップにはC++が必須となります。

AbilltyTagとは

GameplayAbilityに設定することができるTag(GameplayTag)です。

AbilityTagでAbilityの呼び出しや実行制限などの制御ができます。
つまり、Tagの設定だけでステート管理をすることができます

今回使用する設定項目の効果について下記にまとめました。

AbilityTags Ability自身が持っているTag
Cancel Abilities with Tag Abilityが実行されているときに、このTagをもつAbilityをキャンセルする
Block abilities with Tag Abilityが実行されているときに、このTagを持つAbilityを実行させない
Activation Owned Tags Abilityを実行している間、所有者にこのTagが付与される
Activation Required Tags 所有者がこのTagを持っているときのみ実行できる。
Activation Blocked Tags 所有者がこのTagを持っているときは実行できない。

コンボ攻撃を作成する

プロジェクト作成

ThirdPersonテンプレートからC++プロジェクトを作成します。
今回はBlogComboというプロジェクト名で作成しました。

アニメーションアセットを用意

今回はマーケットプレイスのやたらかっこいいアニメーションアセットを使用しました。

Frank Action RPG Sword 1 (Basic Set)

以下のアニメーションを使用しています。

  • コンボ1段目:52_Frank_ActionRPG_Sword_Combo_B1
  • コンボ2段目:53_Frank_ActionRPG_Sword_Combo_B2
  • コンボ3段目:54_Frank_ActionRPG_Sword_Combo_B3

ThirdPersonのMannequinで使用できるように上記のアニメーションをリターゲットしておきます。
今回のアニメーションはrootに移動が入っているのでEnableRootMotionにチェックを入れておきました。

GameplayAbilitySystemプラグイン有効化

GameplayAbilitySystem はプラグインによって提供されています。
プラグイン設定からGameplay → GameplayAbilitiesのEnabledにチェックを入れて、指示通りエディタを再起動してください。

GameplayAbilitySystemセットアップ

セットアップに関してはおかわり はくまい様の記事で非常に分かりやすくまとめられているため、そちらをご参照ください。

GameplayAbilityを拡張する都合上、(プロジェクト名).Build.csのPublicDependencyModuleNames.AddRangeには、GameplayAbilitiesの他、GameplayTagsGameplayTasksも追加しておいてください。

ThirdPersonテンプレートから作成していると、ThirdPersonCharacterの親となるCharacterクラス(ここではBlogComboCharacter)が出来ていると思うので、こちらにC++でGameplayAbilityComponentを追加します。

ビルドが終わると継承しているThirdPersonCharacterにもAbilitySystemComponentが追加されます。

AbilityTagの追加/削除ができるようにGameplayAbilityを拡張

デフォルトのGameplayAbilityではBP側から任意のタイミングでAbilityTagの追加/削除ができないためGameplayAbilityを継承したクラスで拡張します。

BlogComboGameplayAbility.h

#pragma once

#include "CoreMinimal.h"
#include "Abilities/GameplayAbility.h"
#include "BlogComboGameplayAbility.generated.h"

/**
*
*/
UCLASS()
class BLOGCOMBO_API UBlogComboGameplayAbility : public UGameplayAbility
{
GENERATED_BODY()

/** AbilitySystemComponentのGameplayTagCountContainerに新しいGameplayTagを追加する */
UFUNCTION(BlueprintCallable, Category = "GamePlayAbility")
virtual void AddGameplayTags(const FGameplayTagContainer GameplayTags);

/** AbilitySystemComponentのGameplayTagCountContainerのGameplayTagを削除する */
加する */
UFUNCTION(BlueprintCallable, Category = "GamePlayAbility")
virtual void RemoveGameplayTags(const FGameplayTagContainer GameplayTags);

};

BlogComboGameplayAbility.cpp

#include "BlogComboGameplayAbility.h"
#include "AbilitySystemComponent.h"

void UBlogComboGameplayAbility::AddGameplayTags(const FGameplayTagContainer GameplayTags)
{
UAbilitySystemComponent* Comp = GetAbilitySystemComponentFromActorInfo();

Comp->AddLooseGameplayTags(GameplayTags);
}

void UBlogComboGameplayAbility::RemoveGameplayTags(const FGameplayTagContainer GameplayTags)
{
UAbilitySystemComponent* Comp = GetAbilitySystemComponentFromActorInfo();

Comp->RemoveLooseGameplayTags(GameplayTags);
}

これでBPからAbilityTagの追加/削除ができるようになりました。

コンボ1段目の作成

AnimationMontageの作成

コンボ1段目のAnimationMontageを作成します。

作成したAnimationMontangeに1段目のコンボで使用するアニメーションを追加します。

AnimationBluePrintの編集

ThirdPerson_AnimBPを開き、AnimGraphを以下のようにつなぎ変えます。

これでDefaultSlotでAnimationMontageを再生することができるようになります。

GameplayAbilityの作成

先ほど作成したBlogComboGameplayAbilityを継承したBPを作成します。

作成したGameplayAbilityを開いて、以下のようにBPを組みます。

PlayMontageではMontage to Playに先ほど作成した1段目のAnimationMontageを指定します。

ClassDefaultsのTagsを以下のように設定します。

これによってAbility開始時にAbility.State.Combo1が所有者に付与され、Ability.Stateが付与されているときは実行できない、つまり二重に実行されるのを防ぐことができます。

Characterの設定

ThirdPersonCaracterを編集していきます。

以下のようにClassDefaultsのAbilities – Ability Listに先ほど作成したGameplayAbilityを追加します。

以下のようなBPを組みます。

Zキーを押すとTryActiveAbilitiesbyTagノードでAbility.Action.Attackを指定して実行します。
これでAbilityList内でAbilityTagにAbility.Action.Attackを持つものが実行されます。

武器を持たせないと雰囲気が出ないため適当に持たせましょう。

コンボ1段目完成!

以上の手順でZキーを押すと攻撃を繰り出すことができるようになります。

連打しても多重実行を禁止しているため、アニメーションが終わるまで再度実行はできません。

コンボ2段目の作成

コンボ1段目のAnimationMontageにNotifyの追加

2段目のコンボを作成するには1段目のAnimationMontageにNotifyを設定する必要があります。
今回は先行入力も入れたいので、下の画像のようにアニメーション中に2種類の通知が必要となります。

  • A.入力可能 … この期間に次の攻撃の入力が受け取れます。
  • B.次の攻撃に移行可能 … この期間に次の攻撃に移行することができます。

1段目のAnimationMontageのNotifiesのトラックを右クリックし、Add Notify State → Montage Notify Windowを追加します。

これを上記の「A.入力可能」の通知として、始点を振り切るちょっと前くらい、終点を振り切ったちょっとあとくらいに設定しておきます。
DetailからNotifyNameを「Combo1.Input」としておきます。

さらに+ボタンでトラックを増やし、Montage Notify Windowを追加します。
これを上記の「B.次の攻撃に移行可能」の通知として、始点を振り切る瞬間、終点をAの終点と同時に設定します。

DetailからNotifyNameを「Combo1.Branch」としておきます。

2段目のAnimationMontage作成

1段目と同様にAnimationMontageを作成します。

2段目のアニメーションをセットします。3段目のためにNotifyも追加しておきましょう。

1段目のGameplayAbilityに追加

PlayMontageのOnNotifyBegin、OnNotifyEndから伸ばす形で以下のようなBPを追加します。

OnNotifyBeginが呼ばれた時にはNotify対応するタグを追加し、RemoveGameplayTagsが呼ばれた時にはNotifyに対応するタグを消してます。

<対応するタグ>

  • Combo1.Input → Ability.Ready.Combo2
  • Combo1.Branch → Ability.Begin.Combo2

また、OnEndAbilityにもRemoveGameplayTagsを追加しましょう。

これでAbilityが終了したときに必ずAbility.Ready.Combo2、Ability.Begin.Combo2が消えるようになります。

2段目のGameplayAbilityの作成

2段目のGameplayAbilityを作成します。作成したBlogComboGameplayAbilityを継承します。

ClassDefaultsのTagsを以下のように設定します。

ActivationRequiredTagsにAbility.Ready.Combo2が入っているので、1段目のAnimationMontageで設定した「A.入力可能」の期間のみ実行することができます。

以下のようなBPを組みます。

WaitGameplayTagAddは指定したAbilityTagの追加があるまで待つノードです。
ここにAbility.Begin.Combo2を設定しているので、1段目のAnimationMonageで設定した「B.次の攻撃に移行可能」期間のみコンボアニメーションを再生できます。

Characterの設定

ThirdPersonCaracterのClassDefaultsのAbilities – Ability Listに2段目のGameplayAbilityを追加します。

コンボ2段目完成!

以上の手順で2段目のコンボができました。

連打すれば最速で2段目が出ます。ちょっと遅らせて入力すれば入力した瞬間2段目が出ます。

コンボ3段目以降の作成

3段目以降も基本的に2段目と同様の作成の手順で作成できます。

  • 前段のAnimMontageのNotify追加
  • 前段のGameplayAbilityでNotifyに対応したAbilityTagを追加/削除
  • AnimationMontageの作成
  • GameplayAbilityの作成
  • Characterへの設定

まとめ

というわけで今回はGameplayAbilitySystemのAbilityTagを使ってコンボ攻撃を作成してみました。
GamepalyAbilitySystemを使うことで非同期処理や効率的なネットワーク実装など様々なメリットが得られるのですが、今回はロジックを分散できる点が非常に嬉しいと実感できました。

CharacterのBPこれで済んじゃいますからね。

(参考)趣味で作ったプロジェクトのコンボ処理↓

GamepalyAbilitySystemは今回使ったもの以外にも便利な機能が盛りだくさんなので是非、活用してみてください!

Viewing all 1002 articles
Browse latest View live
<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>