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

8/26(日)Caligula Overdose特別公演inアミューズメントメディア総合学院

$
0
0

8月26日(日)にアミューズメントメディア総合学院にて、Caligula Overdoseの特別講演を行いました。

講演者:Caligula/Caligula Overdose シナリオ原案/ディレクター/プロデューサー 山中 拓也 様

株式会社ヒストリア代表取締役 佐々木 瞬

 

当日はたくさんの方にお集まりいただき、誠にありがとうございました。

 

お集まりいただいた学生さん方は皆様勉強熱心で、ゲーム業界の将来がとても楽しみです。

 

アミューズメントメディア総合学院様のHPはこちら

 


[UE4][UMG]ぷちコンゲームジャムに参加してきました!&UMGでアナログ時計の作り方

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

こんにちは。新人UIデザイナーの板橋です。

先日弊社で開催させて頂きました、ぷちコンゲームジャムに参加してきたので、
レポートとゲームジャムで作成したUMGの作り方を載せていこうかと思います!

※「ぷちコンゲームジャム」の補足
弊社で年2回開催している「UE4ぷちコン」に向けて開催されるゲームジャムです。
今回のお題は「ぷち」で、ゲームジャムの制作期間は2日間でした。

 

制作の説明に入る前に、どんなゲームを作ったのかご覧ください!(ゲームジャム終了時のままのビルド状態です)


見事に時計がバグっていますね。ごめんなさい。

◇ 一日目・前半 ◇

まずはチーム決めです。今回のチーム名は干支から選ばれ、私のチームは「ねずみさんチーム」になりました。
構成はプログラマー・プランナー・デザイナー(自分)の3名です。
軽く自己紹介をしていくと、プランナーさんが九州地方からの参加と発覚!
貴重な滞在2日間を丸々ゲームジャムに使っていただくとは。ありがとうございます。

早速作るゲームの話に入っていきます。3人であれこれアイデアをだして、
テーマに沿っているか、3人で時間内に作れそうか、など議論していきます。

今回は、効果音として潰れる音の「ぷち」が採用されました。
巨人になってオブジェクトを踏み潰す「ぷち」から始まったのですが、
3人で昼食のタンタンメンやらチャーハンを食べているうち、
気が付いたら全てを吸い込み圧縮して潰すブラックホールの「ぷち」になっていました。(何故だっけ!?)
ぷちブラックホールがアイテムを飲み込み、巨大化していくゲームを目指すことになりました。
参考となるゲームは・・・上の動画で分かった人もいるかもしれません。
モノをくっつけて自分を大きくするゲーム「塊魂」です。

 

◇ 一日目・後半 ◇

方向性が決まったので、実際にどうやって作るかを考えていきます。
実際に大きくなっていくことを体感させるために、卓上・室内・街中と3ステージ構成としました。
ステージを一から作る時間は無いため、アセットストアから室内と街中の統一感がとれるものを採用しました。
ここで、3人の作業内容が決まっていきます。

プランナーさん   :ステージ内の吸い込み可能なオブジェクトのパラメーター設定・バランス調整 (主にレベルを編集)

デザイナー(自分) :UMGでのデザイン作業、UMGで処理する機能の作成(主にUMGを編集)

プログラマーさん  :パラメーターの設計、ゲームロジックの構築、データのマージ作業(主にゲームロジックを編集)

極力同じファイルを複数人で触る必要がない構造にできたため、データのやり取りの回数は比較的少なくすることができました。
あとはひたすら作業です。細かい疑問点などは声がけして確認していくことができたので、良いチームだったなと思います!

一日目の終了時点で、私の進捗は

・ブラックホールのデザインと回転し続ける機能のblueprint

・ブラックホールのウィジェットを徐々に拡大徐々に縮小する機能のblueprint

・時計のデザインと時計の短針と長針を進めるblueprint

こんなところでした。
2人の進捗はおおよそですが、ステージにあるアイテムを吸い込む機能ができ、パラメーターの設計、ステージ2のバランス調整の方針が決まった頃だったと思います。

みんなで仲良くハンバーガーを食べて帰りました。(会社の奢りで食べるご飯はおいしい!)

 

◇ 二日目 ◇

二日目、チームが集まると早速進捗が。
なんと早起きして3時間程度作業してきたとのこと!すごい!(私は夜に作業し、朝は熟睡しておりましたzzz…)
しかし、この時点で残りタスクを確認するとまだまだ先は遠く、早速作業を進めていきます。

朝の時点で、私の残りタスクは

・被害総額(スコア)の表示

・「ぷち」効果音表示の実装

・タイトル画面の作成

・リザルト画面の作成

・ステージ遷移のカットイン演出の作成

・文字テロップとワイプでフレーバーテキストの実装

うーん、昨日の作業量と比較するとなかなか厳しい!
結果、必死で作業するも、ステージ遷移とワイプ画像の処理は見送ることとなってしまいました。

チームメンバーの二人も限られた時間で優先度をつけてゲームを作っていきます。
進捗があると声掛けし、出来上がった機能を3人で確認してモチベーションが保たれていた感じがします。

どうにかロスタイム15分を貰いながらも、無事ゲームとして遊べる状態でゴールイン!
それが上で載せた動画となります。

普段、UE4はUMGを中心に作業していたため、ゲームジャムでどこまで役に立てるのか不安でしたが、
ゲームとして遊べるものができたので非常に嬉しかったです。
これからはいろんなアセットを作ったり組んだり、日々精進だな、と再認識する二日間でもありました。

心残りとしては、処理を組むのに時間使ってしまったため、
デザイン部分に時間を掛けれなかったところでしょうか・・・(タイトルとか特に)

後日、自分でゲームを見返して不親切だなぁ、と思うところを改良したのが次の動画になります。

キャラクターのリアクションを入れたり強調したり、
ステージ遷移のレベルロードを隠したり。
効果音を足したり、時間ギリギリで一曲しか設定できなかったBGMを入れたりしました。

 

では!せっかく作った機能なので、右上にある時計のUMGの作り方を説明したいと思います。

 

◇ アナログ時計の針の動かし方 ◇

組み方は色々考えられますが、今回はUMG上で4層のレイヤー構造で長針・短針をコントロールすることにしました。

こんな感じでシンプルにイメージを4つ並べたUMGを作成します。

今回は4枚同じサイズの画像を重ねていますが、テクスチャパッカーなどを使えばテクスチャサイズの削減も可能だと思います。

ただし、針の回転の中心がずれてしまうので、[Render Transform]タブの[Pivot]を操作して調整する必要が出てくると思います。

後は長針と短針のimageのwidgethのangleを操作し、くるくると回転させれば時計として機能させることができそうです。

まずは時計を動かすための時間を取得しましょう。

[Event Tick]ノードのIn Delta Timeからは、1フレーム当たりの時間がfloat値で入手できる出力ピンです。

毎フレームの経過時間を足していけば、tickが走り始めてからの経過時間が分かるわけですね。

float型に収まらない数が計算誤差として現れますが、今回はそこまで厳密ではないので良しとしましょう。

 

まずは長針をクルクル回していきましょう。

長針は1秒でangleが360回転すればいいので、先ほど取得した時間に360を掛ければ良さそうです。

ですが、例えば60秒経過したときの値が60×360の21600になるなど、

極端に大きな値がangleに設定されていくと、floatの限界桁数をオーバーしてしまいそうです。

ゲームジャム中では、1秒経過ごとに固定で1減算する処理を入れたのですが、見事に短針をバグらせていました。

なので、ここでは「経過時間を1で割ったときの余り」を使用することにします。

これで、1.1秒であれば1で割ったあまりの0.1秒、10.2秒であれば0.2秒といった、

0から1未満のfloat値を使うことができます。

今回はこれを[set timer by event]ノードを使用して更新していきました。

このノードは任意のイベントをtimeで指定した値の間隔で呼び出してくれる便利なノードです。

今回は時計の処理なのでLoopingにチェックを入れ、0.02~0.05ぐらいの間隔で呼んで綺麗に回って見える値にしました。

この処理を止めたい場合には、Return Valueからピンを伸ばし、

[Clear and Invalidate Timer by Handle]というノードを実行すれば止まります。

これでこのUMGがロードされたタイミングで長針がクルクル回ります!

 

これを応用して短針のほうも作っていきましょう!

今回の短針は、アナログ時計とは少し違い、残り時間を示す針になります。

3時方向からスタートして、3分で12時まで進むといったものです。

こんな処理にはLerp先輩に活躍していただきましょう!

[MIN]ノードを入れないと、Alphaの値に1以上のものが入り、360度を超えていくので最大1に制限させています。

これで短針は90度~360度を制限時間を掛けてゆっくり移動するようにできました。

できました。

 

ゲームジャムはまた機会があれば参加していきたいなと思います!(またお寿司も食べたいので!)

[UE4] 複数のレベルに配置しているアクターの中身を一括で調べる機能の紹介

$
0
0

 

執筆バージョン: Unreal Engine 4.20

今回はBlutilityの具体的な使用例を紹介したいと思います。

まずはじめにBlutilityの事がよくわからない、知らないという方は弊社ブログだったり様々な方が機能を紹介しているのでそちらを見て頂くのが早いと思います。

簡単に一言で説明すると、通常のBlueprintがゲーム中に実行される機能に対し、Blutilityはエディタ上で実行することができる機能と思ってもらえれば大丈夫です。

うまく使いこなす事ができれば、大量の単純作業をボタン一つでおこなえ、作業の効率化を図る事ができます。

機能説明系リンク

■alwei様のブログ
UE4 Blutilityによるお手軽なエディター拡張
Blutilityがどんな機能なのかを紹介しています

■MozPaca様のブログ
UE4 4.20 BlutilityとEditor Scriptingを試してみる その1
UE4 4.20 BlutilityとEditor Scriptingを試してみる その2
UE4 4.20 BlutilityとEditor Scriptingを試してみる その3
Blutilityの機能を紹介しつつ、選択したメッシュにコリジョンをつける機能を作例として挙げられています

作例系リンク

■弊社ブログ
[UE4]”OpenAsset”を使ってみよう
指定したスケルタルメッシュ内に含まれる全てのマテリアルを開く(マテリアルエディタを開く)機能を作例として挙げています

■株式会社アンナプルナ様のブログ
【UE4】プランナーがBlutilityでジェネレータを作ってみた
指定した範囲内にランダムに木や草などを配置する機能を作例として挙げられています

■株式会社アンナプルナ様のブログ
【UE4】プランナーがBlutilityで仕事を効率化してみた-その1-(Level編)
新規で複数のレベルを作成して、作成したレベル内にそれぞれ自動で指定のアクターを配置する機能を作例として挙げられています

■T_Sumisaki様の記事
BlutilityでStaticMeshのMaterialを一括置換するコマンドを作る
指定したスタティックメッシュのマテリアルを一括置換する機能を作例として挙げられています

 

目的

さて、今回作るのはサブレベルに配置しているアクターにどんな値が入っているのかを一括で知る方法です。

といっても、それだけだとゲーム実行中でもGetAllActors系の関数を使えば簡単にログに出せるので、わざわざBlutilityを使う必要はありません。今回Blutilityを使う強みは、ゲーム全体で使用しているアクターを簡単に調査できる点です。

具体的に言うと、例えばRPGを作る際に1つのダンジョンに宝箱がいくつあって、その中身が何かを知るのはBlueprintでも作れますが、そのためにはわわざわざそのダンジョンのレベルを開いて実行する必要があります。
そこで今から紹介する機能を使えば、全てのダンジョンでそれぞれ宝箱がいくつあって何が入っているかを一括でログ出力する事が可能になります。

この機能は開発後期にゲームバランスを調整したい場合や、デバッグで宝箱などの中身のパラメーターが想定通りになっているかをチェックしたい場合に大変便利かと思います。とくにダンジョンの数(レベルの数)が多ければ多いほど、こういった機能がとくに有効ではないでしょうか。

 

作成方法

それでは機能の作り方です。

その前にエディタの設定でBlutilityの機能を有効にしておいて下さい。方法は省略しますので、上記リンク集を参照して下さい。


今回はアクターに対する操作を行うので、基底クラスはActorActionUtilityを選択します。


BlueprintEditorを開くのはBlueprintと違って右クリックな事に注意して下さい。Blutilityのダブルクリックは実行のための操作と覚えておくとよいでしょう。


Blueprintと同じようにイベントをAddCustomEventを使って追加します。とりあえず今回はイベント名を「GetParameter」にしておきますが、イベント名は機能がわかるような名前にするとよいでしょう。
エディタ上からこのイベントが呼べるようにCallInEditorをOnにしておきます。

※ちなみにUE4.20.2の時点ではBlutilityをダブルクリックで実行できるようになるAutoRunDefaultActionを使用してレベル操作を行おうとするとエディタがクラッシュするようです。なので今回は「EventOnDefaultClicked」は使わないでおきます。


それではイベントの中身を書いていきましょう。
GetAssetsByPathで指定したフォルダ以下の全アセットを取得できます。RecursiveをOnにすると子のフォルダも全て対象になるのでOnにしておきます。
また、今回はやっていませんがフォルダの指定を変数にすれば、指定するフォルダを変更する場合にわざわざBlutilityを編集しなくてもよくなるでしょう。
そしてアセットを取得したらForEachLoopで回します。
次に1つずつレベルアセットかどうかをチェックして、レベルだった場合はLoadMapを使ってレベルを開きます。
ちなみにレベルはWorldクラスなので、GetClassを使ってWorldかどうかをチェックしています。もしこのチェックをせずにレベル以外をLoadMapで開こうとするとエディタがクラッシュするので注意して下さい。


LoadMap後の続きです。
GetAllActorsOfClassで指定した全アクターを取得します。
あとForEachLoopを使って、アクターの中身で知りたいプロパティをGetしてきてPrintStringなどでログに吐き出せば完了です。
この部分を改造すれば、色んなパラメーターを一括で取得できるようになるわけです。


最後に実行方法です。作成したBlutilityをダブルクリックで開き、先程作成したイベント名のボタンが表示されるので、それをクリックすれば完了です。

ちなみに出力したログは「プロジェクトフォルダ\Saved\Logs」にLogファイルとして吐き出されます。テキスト形式なので、正規表現などを駆使して必要な情報だけを取り出し、エクセルなどに貼り付ければ一覧表としても使えて完璧じゃないでしょうか。

いかがでしたでしょうか?
Blutilityは色々な方の記事や今回の記事から、開発中期の量産期だったり、開発後期のデバッグ期にこそパワーを発揮できるという事がご理解いただけたかと思います。
みなさんもBlutilityを活用し、効率良いゲーム開発を目指していきましょう!

 

[UE4]第10回UE4ぷちコン応募作品公開!その1

$
0
0

第10回UE4ぷちコンのエントリー作品一覧ページです。

今回は全部で87作品集まりました!!

応募いただいた皆様、ありがとうございます!!

第10回UE4ぷちコン応募作品一挙公開!

※コンテストの告知ページはこちらです。

第10回UE4ぷちコン応募作品一挙公開!その2はこちら

第10回UE4ぷちコン応募作品一挙公開!その3はこちら

第10回UE4ぷちコン応募作品一挙公開!その4はこちら

第10回UE4ぷちコン応募作品一挙公開!その5はこちら

 

[エントリーNo.1]  第21話 さらば、友よ!

もんしょ さま

▼応募者コメント▼

CGアニメ『キケンなふたり ブルー&グレー』の名場面をゲームで再現してみました。
画面に衝立を立てて遊ぶことを想定したちょっと特殊な対戦ゲームとなっています。
思い出深いあの名場面で相手を出し抜いてみてください!

[エントリーNo.2] プチプチコンボ

ActGamez さま

▼応募者コメント▼

丸い球体を操作して効率よく四角いものをプチプチしていく
時間制限や中央のゲージがたまり切ってしまったらクリアは難しい
ビッグになってプチプチを加速しよう

[エントリーNo.3] Figure Shooter!!

MackyMD さま

▼応募者コメント▼

ぷちサイズのフィギュア(図形)を操ってビッグサイズの敵と戦うゲームです。
敵は、操作キャラより圧倒的に物量のある強力な攻撃をしてきますが、自キャラが小さい故に敵の攻撃を華麗に躱すことが出来ます。
また、プレイヤーには切り札も…!
是非とも、自分より強大な敵を打ち負かす達成感に浸ってください。
最後に、やり込みポイントとして、グレイズ機能の実装があります。
「僕/私はシューティングゲームに自信があるぞ!」という方は、敵の攻撃をギリギリで躱すことで得点が上がるアクションにもチャレンジしてみてください。

[エントリーNo.4] プチ迷路

がみ さま

▼応募者コメント▼

本来は小さい迷路をたくさんこなしていくゲームを作る予定でしたが、技術的な問題で断念しました。。。。

壮大な迷路です。。。。

[エントリーNo.5] ぷ→ち

oMochi さま

▼応募者コメント▼

なるべく新しい素材は作らず、ぷちっとつくることを目指しました。
グレイマンのジャンプ制御の難しさに加え、正しい文字の見極めを遊びのルールとしてしみました。
浮いているタイルに乗るだけで点数が入りますが、「ぷ」と「ち」を続けて踏むとスコアとタイムにボーナス点が入ります。
タイルは乗って別の場所に着地すると、裏返って上昇します。

[エントリーNo.6] Speed Puchi-Puchi

ぱソんこ さま

▼応募者コメント▼

48時間で制作した(メイドインワリオ風の)ぷちゲームです。60コのボタンをすべて押すまでの時間を競いましょう。目指せ90秒切り!

[エントリーNo.7] プチマネキン

おかわり はくまい さま

▼応募者コメント▼

ぷちコン参加の緊張と焦燥とプレッシャーと不安、負の感情をすべて詰め込んだゲームです。
この絶望の先に見えるものはなんなのか?みなさんと考えていきたいと思います。

[エントリーNo.8]Sapphire Dreams

佐村木 友紀 さま

▼応募者コメント▼

夏の暑い日、あまりの暑さに耐えきれず、アンリアルな涼しさを求めて作りました。一人の初心者が、暑い夏に熱いハートとグラボを駆使して作り上げた一品です。主な「ぷち」ポイントは、BGM一曲で完結する短い作品になっているところです(映像のみの作品です)。

[エントリーNo.9]崖っぷちチキンレース

てらつむ さま

▼応募者コメント▼

崖っぷちから車が落ちないように停車させるゲームです。
停車位置が崖っぷちに近いほどベストスコアとなります。

[エントリーNo.10]ぷちぷちメイカー

ごりらびっと さま

▼応募者コメント▼

テーマは「ぷちぷち(梱包材)」で回収しました。
第10回ぷちコンのテーマが決まってからUE4を初めて触ったので、ひねりのある題材で勝負しようと思ったのですが、革新的なアイデアが思い浮かぶこともなく、最初に思い付いた案を信じました。
この作品は、いつもは我々の荷物を守ってくれるぷちぷちでグレイマンを守り、ゴールまで導くゲームです。
行く手を阻む様々な障害をぷちぷちで防いでグレイマンを守ってあげてください!
ぷちぷちは割ると気持ちいいものなので、多く割ってもらうために割れたぷちぷちの数がスコアに影響するようになっています。快感を得ながらハイスコアを目指しましょう!

[エントリーNo.11]EchoLabyrinth

うしさんチーム さま(ぷちコンゲームジャム)

▼応募者コメント▼

今回のテーマは「ぷち」ということなので、
「ぷち」という音を使って敵を誘導し、ゴールを目指すゲームです。
自分と同じ姿の敵を音で誘導し、捕まらないようにしてゴールを探します。
補足:このゲームはヒストリア主催のぷちコンゲームジャムでうしさんチームで制作した作品になります。

[エントリーNo.12]VRでワイン作りたい!

ワイン作り隊 さま

▼応募者コメント▼

今回のぷちコンのテーマは「ぷち」という事で、
大粒のブドウを「ぷちぷち」とつぶしてスコアを競うゲームを作りました。
VRトラッカーを足につけて坂から転がり落ちてくるブドウを足でつぶしてスコアを競うゲームです。
実際のワイン作りの工程でも素足でブドウをつぶす作業があるのですが、
この作品はまさに、この作業から着想を得ています。
大阪駆動開発様主催の「大阪ぷちコンゲームジャム」にて、4人チームで制作しました。

[エントリーNo.13]ぷっちんタクシードライバー

板庇 賢一 さま

▼応募者コメント▼

私(現在50歳)が小学生の頃に流行った物で、「スーパーカー消しゴム」というものがありました。ボールペンのノックの反動(親指でカチカチ押す)で、その消しゴムを移動させ、
レースをしたり、相手の消しゴムにぶつけて机から落とすなどの遊びをしていました。
その際に使用していたBOXYのボールペンのことを通称「ぷっちんぺん」と呼んでいました。※「カー消し」でググって画像検索すると、沢山のイメージ画像があります。
「プッチンペン」の画像検索では、それほど多くありませんでしたが、いくつかヒットします。そのような訳で、今回のテーマ「ぷち」は、ぷっちんペンを使って、車(タクシー)を移動させるゲームを作りました。
タクシーなので、お客様が伝えた目的地に連れていくだけです。
オープニングムービーにあるように、映画館、ヘアカット、レンタルビデオ屋、最後に友達の家(クリア)です。

目的地はナビゲーション(矢印)の方向に移動していけば、見つけることが出来ます。
爆弾を積んだ車にぶつかるミスをするとチェックポイントからやり直しになるので、ぷっちんペンの当てる方向を調整して
うまくタクシーを移動させてください。
時間制限はありませんので、しっかりと方向を定めて、目的地まで無事に お客様を届けてあげてください。

操作説明:
左のパッドでボールペンの方向を決め、ボールペンのボタンを押すことと、タクシーを移動させます。
右のパッドでカメラの回転操作が出来ますので、操作しやすいカメラ向きにしましょう。

※モバイルのバーチャルパッドにも対応しています。

使用アセット
Simple Town・・・街
Luos’s Particle Toolkit Vol. 1・・・パーティクルエフェクト
Iconic Pickup Items・・・ハートアイコン
Spline Looper・・・車と歩行者の移動
Paragon: Shinbi・・・クリア家の友達
Universal Sound FX ・・・サウンド
Ultimate Game Music Collection・・・サウンド

[エントリーNo.14]Little In The Dark

なつめ さま

▼応募者コメント▼

今回のテーマが「ぷち」ということで巨大な家から抜け出すゲームを作成しました。家の住人から気づかれないように逃げ隠れしながら部屋の鍵を見つけ、そして開け、最終的に玄関から抜け出します。この家の住民との距離が近くなると心拍の音が鳴り近くにつれて大きく鳴ります。逆に遠ざかると減衰します。なかなかの緊張感が味わえるゲームになったと思います。

[エントリーNo.15]ぷちロボコン

でじまい さま

▼応募者コメント▼

いつもUE4で使っているのより簡単で小さい「ぷちブループリント」を使ったゲームです。
記念すべき10回目おめでとうございますということで色々とリスペクトしました。
キャラとBGMはオリジナルでこだわりました。

[エントリーNo.16]ぷちリーマン

総合学園プチアカデミー さま

▼応募者コメント▼

悪評を潰して企画を通すつぶやきぷちっとVRアクション!悪評は社長の耳に入れず、でも好評は耳まで届け!

コントローラーのトリガーを引くと、つぶやきをぷちっと消せます。
社長に悪いつぶやきが当たると心証がダウン…
いいつぶやきが当たると心証アップ!

心証を良くして、俺の企画が採用だ!

[エントリーNo.17]怪盗 Gray ちゃん

U-MA さま

▼応募者コメント▼

Gray ちゃんが美術館に潜入し、女神像を盗むゲームです。テーマの「ぷち」の解釈は、麻酔銃から発射される麻酔注射が敵に当たる時の「ぷちっ」と感じる箇所に対応させています。

[エントリーNo.18]I am BubblePack

Duks さま

▼応募者コメント▼

BubblePack(気泡緩衝材)として空き缶を投げられてる人や足を滑らして落下する人、車に轢かれる人の衝撃を緩衝して「ぷちぷち」してください。

[エントリーNo.19]PETIT RUUUUUN!!

PavilionDv7 さま

▼応募者コメント▼

迫りくる岩から障害物を避けつつゴールまで逃げ切るゲームです。
エンジンコンテンツやInfinity Bladeアセットを利用し、見栄えよく、飽きづらい画面づくり、プレイヤーにとって心地よい操作感を目指しました。
飛び散る破片メッシュやステージクリア時の演出はとても気に入っています。

[エントリーNo.20]UnrealGolfChallenge

Polaris1080 さま

▼応募者コメント▼

最近のぷちコンは贅沢かつ複雑すぎる。回を重ねるごとにリッチになっていくし、どんどん「ぷち」とはかけ離れていっている。
それに伴い、使用されるコンテンツの数はどんどん増加し、サイズも増加している。
ぷちコンで複雑なモノを制作するなら、その努力をインディーズ開発につぎ込めばよい。ぷちコンの目的は、「チームによる力技のコンテスト」ではなく、
「UE4を学習するためのコンテスト」ではなかったのか?だがこの作品は違う。
『LightにSocketに入れる』、ただそれだけの*ぷち*である。
使用するコンテンツも出来るだけ減らし、サイズも可能な限り減らした。
この作品こそが、真にミニマルな『ぷち』だろう。

 

第10回UE4ぷちコン応募作品一挙公開!その2はこちら

第10回UE4ぷちコン応募作品一挙公開!その3はこちら

第10回UE4ぷちコン応募作品一挙公開!その4はこちら

第10回UE4ぷちコン応募作品一挙公開!その5はこちら

 

[UE4]第10回UE4ぷちコン応募作品公開!その2

$
0
0

第10回UE4ぷちコンのエントリー作品一覧ページです。

今回は全部で87作品集まりました!!

応募いただいた皆様、ありがとうございます!!

第10回UE4ぷちコン応募作品一挙公開!

※コンテストの告知ページはこちらです。

第10回UE4ぷちコン応募作品一挙公開!その1はこちら

第10回UE4ぷちコン応募作品一挙公開!その3はこちら

第10回UE4ぷちコン応募作品一挙公開!その4はこちら

第10回UE4ぷちコン応募作品一挙公開!その5はこちら

 

[エントリーNo.21]  ぷちっとラビリンス

松本ラボ さま

▼応募者コメント▼

迷路の中に散らばっている三角形のオブジェクトを集めるゲームです。
10個のオブジェクトをいかに早く集められるかというゲーム仕様になっています。
赤いライトと緑のライトが迷路の中にあり、赤いライトに触れるとおおきくなり、緑のライト触れると小さくなります。
小さくないと通れない場所や大きくないとオブジェクトをとることができない場所などがあります。
オブジェクトはいろんなところに配置してあるので、大きさやカメラアングルを駆使して細かいところまで探して最速のタイムを目指しましょう

[エントリーNo.22] NekoTsubushi

イクラ㌠ さま

▼応募者コメント▼

ねこを操作してビリヤード台の上を転がるイクラをぷちっと潰してスコアを競います!

[エントリーNo.23] PutiRebe ぷちぷちの逆襲

ひつじさんチーム さま(ぷちコンゲームジャム)

▼応募者コメント▼

ぷちぷちの主人公をつぶしにやってくる、グレーマンたちをぶっ飛ばして逆襲するゲームです。
サードパーソンテンプレートを使用しています。
ウェーブ制で、ウェーブ内のグレーマンをすべて倒すと次のウェーブに進みます。
ウェーブが進むごとにグレーマンの数が増していき、全4ウェーブをクリアするとゲームクリアです。

[エントリーNo.24]Petit Toma run (プチ トマ ラン)

raidako さま

▼応募者コメント▼

ぷちトマトの形をしたマトリョーシカのような入れ子構造のボールを高速で転がしてゴールを目指すタイムアタックゲームです。
赤く点滅する障害物にあたると外側が壊れて中から一回り小さいぷちトマトが現れます。
ダメージを受けるごとに段々小さくなり5回ダメージを受けるかコースアウトするとゲームオーバーです。突き抜ける疾走感をお楽しみください!

[エントリーNo.25] ねるちゃんのぷちぷちいくらシューティング

猫葉ねる さま

▼応募者コメント▼

いくらでぷちぷちと敵を倒しながらできるだけ遠くまで進むゲームです。
「次はもっと遠くまでいけるかも」と思ってたくさんやってもらえるような絶妙な難易度にしました。
自分で描いたイラストを使用したり、タイトル画面やリザルト画面で、自分のボイスが入っているのもポイントです。

[エントリーNo.26]お馬鹿な魔王と勇者ご一行

みけねこまいく さま

▼応募者コメント▼

プチを直球そのまま解釈して操作するものは基本的に小さいゲームです。
ゲームとしては、戦略ゲームで、頭のよさまで”プチ”な勇者と魔王をプレイヤーが上手く操って
魔王討伐を目指します。魔王「ガハハ、まずは小手調べだ」みたいな感じです。ちゃんと小手調べしてあげないと勇者たちは全滅してしまいます。

[エントリーNo.27] アンリアルディフェンダー

cgub さま

▼応募者コメント▼

テーマの「ぷち」は小さいものをイメージして、大きなモンスターを小さくすることで「ぷち」を表現しました。
大型モンスターをプチモンスターに変化させ撃退し拠点を防衛せよ!!

[エントリーNo.28]『petit KILLER -ぷちキラー-』

T&N さま

▼応募者コメント▼

このゲームはテーマである『ぷち』から”小さい”、”踏み潰される”をイメージして製作しました。プレイヤーは小さくなってターゲットを倒すという殺し屋を操作します。
ターゲットの部屋に侵入して様々なアイテムを使い、または組み合わせてターゲットを制限時間内に倒すのが目的です。

[エントリーNo.29]カメラから離れるな!Keep Camera FOV

ゅろ さま

▼応募者コメント▼

最大四人対戦の横アクションゲームです、スコア溜めるのが目的です。
得点方法は敵を倒すか、アイテム獲得することです。
HP 0または カメラの外に出るとスコア マイナス一点。
カメラの外へ吹っ飛ばされる、または自ら外へ走るとアウト。(ただ単に他のプレイヤーにカメラを引っ張られるならセーフ、)
アクションの所頑張りました、強い武器も拾えます。
先に10ポイントまたは、時間切れの時ポイント一番多いプレイヤーの勝ち

[エントリーNo.30]Escape

いおちさま

▼応募者コメント▼

脱出するときのワタワタした感じを出したくて作りました。HMD使用を前提にしてます。動画に載ってる部分で完結です。

[エントリーNo.31]ぷちラン

Zmix(ズミックス) さま

▼応募者コメント▼

「ふち」を走るゲームです。「●」が「ふち」にあるので、「ぷち」です。
「ぷち」のロゴにキャラクターぽさがあったので、使わせていただきました。
ミスが致命的になる「緊張感」、うまく走り抜けたときの「爽快感」がコンセプトです。

[エントリーNo.32]VS Virus

TeamSU さま

▼応募者コメント▼

学生四人のチームで制作しました。プレイヤーは体内の小さな(=ぷち)抗原細胞となって、体内に駆け回り、ウイルスを見つけては駆逐していくゲームです。ウイルスが隠れるエリアに近づくとノイズと音が発生し、プレイヤーがトリガーに侵入すればウイルスが出現します。より早く全てのウイルスを駆逐しましょう。

[エントリーNo.33]つぶしてぷっちん!

com04  さま

▼応募者コメント▼

ひたすらスライムをぷちっと潰し続けるゲームです。
Lifeがゼロになるか、PCが固まるとゲームオーバーです。

[エントリーNo.34]ベリーぷちぷち

恒吉星光 さま

▼応募者コメント▼

今までに見たことがありそうなプチ体験が詰まったゲームです。
ありがちなアイディアと保守的な手摘みシステムによってもたらされる旧世代のエクスペリエンスをぜひ味わってください。

[エントリーNo.35]イクラ

K_Z さま

▼応募者コメント▼

動画作品を制作しました。Niagaraをいろいろ試しています。
テーマが「ぷち」ということで、イクラをメインにしました。

[エントリーNo.36]PHUT

志紫もこも さま

▼応募者コメント▼

ローカルマルチ対戦ゲームです。締め切り当日に完成したのでデモプレイを1人で行うはめに。面白さが十分に伝わらないので少し悔しいです😭
「ぷち」要素はとっておきの箇所で表現しました。

[エントリーNo.37]崖っぷちバリスタ!!

高村優樹 さま

▼応募者コメント▼

崖っぷちでティーカップにミルクを注いで、カプチーノを作るゲームです。スティック操作でキャラクターを傾けて遊びます。
傾けないとカップにミルクを注げませんが、傾けすぎると自分が下に落っこちてしまいます。
ほどよいバランスを維持して、高ランクを目指しましょう!「ぷち」というテーマから「小さくて見づらい」「崖っぷち」「カプチーノ」を
連想し、作成したゲームになります。

[エントリーNo.38]IKURA-SMASH!!

take さま

▼応募者コメント▼

大玉と小玉をうまく切り替えながらゴールを目指します。大玉は、「イクラ」を潰せるが、ジャンプが低い。
小玉は、「イクラ」にハジかれるがジャンプが高い。物理シミュレーションにより、プレイヤーの想像を超えた
動きを楽しめます。★ストーリー
地球に侵略に来たイクラ星人を退治せよ!
食べると超美味しいぞ!

[エントリーNo.39]グレイマンスケール

ナスヴィッチ さま

▼応募者コメント▼

このたびは本製品をお買い上げいただきありがとうございます。グレイマンSは最新技術を駆使して生み出された自律型尺度可変人型駆動玩具です。
弊社での爆発テストにも数回耐えうることが実証された特殊素材製です。
なお、グレイマンSの一部ロットは開封後徐々に縮む不具合が報告されております。
上記不具合の修正マニュアルも製品に同梱されておりますのでご参照ください。
なお、特殊技術でグレイマンSを梱包している都合上、パッケージ開封時に修正マニュアルが吹き飛んでしまう不具合も報告されておりますのでご注意ください。
(グレイマンS取扱説明書より抜粋)

[エントリーNo.40]ぷちもす

タンジェリン さま

▼応募者コメント▼

プレイヤーはFPS視点のグレイマンを操作し、あの手この手で「蚊」をぷちっとするゲームです。 メニュー画面のカメラの遷移と、蚊をぷちっとしたときのカットイン演出がお気に入りです。

 

第10回UE4ぷちコン応募作品一挙公開!その1はこちら

第10回UE4ぷちコン応募作品一挙公開!その3はこちら

第10回UE4ぷちコン応募作品一挙公開!その4はこちら

第10回UE4ぷちコン応募作品一挙公開!その5はこちら

 

[UE4]第10回UE4ぷちコン応募作品公開!その3

$
0
0

第10回UE4ぷちコンのエントリー作品一覧ページです。

今回は全部で87作品集まりました!!

応募いただいた皆様、ありがとうございます!!

第10回UE4ぷちコン応募作品一挙公開!

※コンテストの告知ページはこちらです。

第10回UE4ぷちコン応募作品一挙公開!その1はこちら

第10回UE4ぷちコン応募作品一挙公開!その2はこちら

第10回UE4ぷちコン応募作品一挙公開!その4はこちら

第10回UE4ぷちコン応募作品一挙公開!その5はこちら

 

[エントリーNo.41]  ぷちBPちゃんとスイカ割りVR

まるプロ さま

▼応募者コメント▼

手を叩いてぷちBPちゃんをスイカまで誘導しよう。
天空スイカ割りなので落ちないように注意もしよう。
スイカ泥棒はバットを持って撃退だ。
無駄にVR。

[エントリーNo.42] ぷちTuber~配信を止めるな!~

小長井 元/Bastien Perritaz/藤原 稜/横山 拓也/山地 直彰 さま

▼応募者コメント▼

「ぷちTuber ~配信を止めるな!~」は、架空の地下アイドルの新曲配信をサポートする VRゲームです。
環境、機材、すべてが貧弱な中、次々と襲い掛かるトラブルに対処し、新曲の演奏が終わるまで配信を維持してください。
トラブルが起きると、ぷちぷちと配信が途切れたり、乱れたりして、視聴者が減っていってしまいますので、残りの視聴者数にも注意。今回のために新曲書き下ろし!予選通過すれば歌入りで聴けるかも!?

[エントリーNo.43] カピぷち

おさるさんチーム さま(ぷちコンゲームジャム)

▼応募者コメント▼

ぷちぷちを60秒以内に400個ぷちろう!

[エントリーNo.44]ぷちボールを1024個落とすゲーム!

あKAGIKEN さま

▼応募者コメント▼

ぷちボールをフィールドから1024個落とすゲーム
です。1024個落とした時点で終了してそれまでの時間が表示されます。

[エントリーNo.45] HipDropTown

T.K さま

▼応募者コメント▼

街にあるいろんな物をヒップドロップで【ぷち】っと潰しまくるゲームです。シングルプレイ、画面分割での二人プレイに対応しています。

[エントリーNo.46]Veloce

シカニカイ さま

▼応募者コメント▼

小さなヴェローチェが星を助けるお話

[エントリーNo.47] むげんDEぷちぷち

かたつむりの中の人 さま

▼応募者コメント▼

プチプチがあります。
あとは潰し続けるだけです。

[エントリーNo.48]ぷちぷちFIELD

TAT  さま

▼応募者コメント▼

ぷちぷちを潰す快感をゲームで表現しようと挑戦した作品です。
部屋の隅の段ボールの上で人形たちがどれだけ多くのぷちぷちを潰せるのかを競って遊んでいるという設定で非現実的なゲームの世界をセルシェーダーで描画し、背景は現実的なありふれたお部屋を表現するためにポストプロセスを工夫しました。また、ぷちぷちを潰した時の快感をアメコミ風のエフェクトで演出しています。
締め切りの2日前から3人で作り始め、なんとか完成させることができました。

[エントリーNo.49]ぷちレールシューティング

下谷航希 さま

▼応募者コメント▼

遊園地にあるレールシューティングゲームをモチーフに作成しました。
いかにもなアトラクション感が「ぷち」レールシューティングです。
レールの上を動く台に乗り、的の風船を壊すと破裂音とともにスコアが増えるゲームになっています。
補足:今回初めてアンリアルエンジン4を使用したのですが、高品質なゲームが簡単に作れて驚きました。

[エントリーNo.50]ぷちぷちレインボーロード

若草なずな&ハセオ さま

▼応募者コメント▼

テーマが”ぷち”ということで!
ぷちぷちを潰すゲームです!
レインボーロードに現れる虹ぷちは道で拾える”つまようじ”でしか潰せない。
耐久が低いぷちぷちを選んで潰してなるべく多くつまようじを残して進むゲームです!

[エントリーNo.51]ぷちぷち工場

ぶち さま

▼応募者コメント▼

UE4の勉強がてら、ミニゲームを作ってみました。
上下からやってくるターゲットを、プレス機でぷちぷちと潰してスコアを稼ぐゲームになっています。

[エントリーNo.52]アンリアル花占い

うなうなぎ さま

▼応募者コメント▼

花占いをしたいのに花がない。そんな時にも落ち着いて花占いが楽しめるシミュレーターです。

[エントリーNo.53]プチプチをつぶすぷちさん

Clock さま

▼応募者コメント▼

赤くないプチプチをぷちさんが10回潰すだけのゲームです
手の操作はWASDQEで行い 潰し終わると所定の位置に戻ります
もし間違って赤のプチプチを押してしまうと・・・
何かがアメリカに向かって飛んでゆきます
このゲームには時間の概念がないので
普通のプチプチが連続するタイミングを見て簡単にクリアする方法もあります
動画はその方法を使いましたこのゲームはフィクションです、実在する人物、団体、国家等の関係は一切ありません 大統領に似ていても関係ありません

[エントリーNo.54]ぷちコン魂

かつ さま

▼応募者コメント▼

このゲームは”ぷちブラックホール”を巨大なブラックホールへと成長をさせて、沢山の物を吸い込み被害総額を稼ぐゲームです。物を吸い込んだときのぷち音と、物をどんどん吸い込んでブラックホールを大きくしていく過程はハマるはずです!!

[エントリーNo.55]トカゲの操縦

gobori さま

▼応募者コメント▼

トカゲが物をなげるゲーム

[エントリーNo.56]ぷちファクトリー

石箱 さま

▼応募者コメント▼

不必要な機械を潰して工場を縮小化するのが目的のパズルゲームです。
機械には生産量が表示されており、赤い機会の生産量を指定値にすればステージクリアとなります。
下流の機械の生産量は上流の機械の生産量の合計となっているため、上流の機械を潰すことでコントロールできます。
結果を予測してどれを潰すかを考える必要があるゲームになりました。

[エントリーNo.57]ぷち魂

宇都 大地 さま

▼応募者コメント▼

小さな魂をコツコツ集めるゲームとなります。
ステージ落ちている。アイテムを拾うと音や時間、数、立体の概念が追加される仕組みとなっています。ゲームの中でゲームを作り上げていく感じを出したかった。

[エントリーNo.58]ぷちデス!

ヒロ助 さま

▼応募者コメント▼

フィールドに配置されている魂を利用して、自分の死体を足場として生成しゴールを目指すゲームです。

[エントリーNo.59]ぷちバスター

びっと さま

▼応募者コメント▼

今回のテーマは「ぷち」ということで、
原子を潰して混ぜるゲームです!!!

[エントリーNo.60]「ぷちっとスケールバトル!リブラス」

TiS さま

▼応募者コメント▼

質量を奪い合う、サバイバル型対戦シューティングゲーム。
シンプル操作でアツいバトル!敵から質量を奪って、倒し、最後まで生き延びろ!

 

第10回UE4ぷちコン応募作品一挙公開!その1はこちら

第10回UE4ぷちコン応募作品一挙公開!その2はこちら

第10回UE4ぷちコン応募作品一挙公開!その4はこちら

第10回UE4ぷちコン応募作品一挙公開!その5はこちら

 

[UE4]第10回UE4ぷちコン応募作品公開!その4

$
0
0

第10回UE4ぷちコンのエントリー作品一覧ページです。

今回は全部で87作品集まりました!!

応募いただいた皆様、ありがとうございます!!

第10回UE4ぷちコン応募作品一挙公開!

※コンテストの告知ページはこちらです。

第10回UE4ぷちコン応募作品一挙公開!その1はこちら

第10回UE4ぷちコン応募作品一挙公開!その2はこちら

第10回UE4ぷちコン応募作品一挙公開!その3はこちら

第10回UE4ぷちコン応募作品一挙公開!その5はこちら

 

[エントリーNo.61]  ぷちネコせんそう

TATSUNORU さま

▼応募者コメント▼

お腹をすかせたコネコの兄弟がたくさんいます。
他の兄弟達にまけないよう母猫のところにダッシュし
母乳をたくさんのんで他のコネコに負けないよう大きくなるのを目指す、そんなゲームです。

[エントリーNo.62] ぷちウィンドウシューター

汚猫 さま

▼応募者コメント▼

128×96の解像度で遊べる8bit風のぷち画面シューティングゲームを作ってみました。キャプチャがうまくいってないので動画からはかなりわかり辛いですが、実際はアッ〇ルウォッチで遊べそうなサイズ感です。

[エントリーNo.63] ぷちっ!通信切断上等!

湯浅賢悟  さま

▼応募者コメント▼

通信切断の擬音は「ぷちっ!」なので、通信切断が要素に入ったゲームを制作しました!
インディアンポーカーとTPSが組み合わさった対戦ゲームです。
おでこに張られた見れない数字が相手より高ければ勝ちになります。
自分の数字は世界に散らばった数字から推し量る事が可能です。
勝てると思ったら銃や剣で相手をボコボコにしましょう!
負けると思ったら通信感満載の線を切って通信切断しちゃいましょう!

[エントリーNo.64]ブチ転がせ!プチトマト!

Der3 さま

▼応募者コメント▼

テーマが「ぷち」ということだったので、プチトマトを転がすゲームを作りました。一般的に、普通のトマトよりもプチトマトの方が転がりやすいと思われるのでうまくテーマを生かせたと思います()。このゲームは、若干転がしづらいプチトマトを駆使して、2分間で出来るだけ高スコアを目指すゲームです。赤いトマトエネルギーを回収したり、緑の箱を叩くことでスコアが増えます。また、赤いトマトエネルギーを貯めれば貯めるほどプチトマトは巨大になり、スコアが稼ぎやすくなります。

[エントリーNo.65] Virtual Reality Rider

altalt さま

▼応募者コメント▼

ぷちレーシング × ぷちリズム × ぷちバトルアクション
レースゲームのコース取りと、簡単なバトルアクションに、リズムゲームの要素を加えました。
「ぷち」でも壮大な体験を!『VRR』

[エントリーNo.66]ぷちがいさがし ~学校編~

けしし  さま

▼応募者コメント▼

「ぷち」+「まちがいさがし」=ぷちがいさがし。
学校を舞台に微妙な間違いを探すゲームです。

[エントリーNo.67] 進撃の灰人

ふわーりん さま

▼応募者コメント▼

巨人となってしまったグレイマンにぷちっと潰されないように逃げるVRゲームです。アレをモデルに作成しました。

[エントリーNo.68]HAETATAKI

3人の一般人 さま

▼応募者コメント▼

今回のテーマが「ぷち」という事でどんなゲームを作ろうかとプッ〇ンプリンとブ〇ボン 〇チ食べながら考えた結果小さいハエをプチっと叩くプチっとしたハエたたきというコンセプトに収まり、自分他2人を巻き込み制作いたしました。
プチっと遊べるハエたたき、操作はマウスオンリー左クリック(液タブで遊ぶともっと楽しいかも)。シンプルTHEハエたたき。

[エントリーNo.69]捨て身ハードルジャンプ

けむしLabU さま

▼応募者コメント▼

周期的に現れるハードルを捨て身で乗り越えていくゲームです。単純なジャンプだけで超えられなさそうなハードルには、分身スキルが使えます。
身体が半分になり、身体的パラメータが低下しますがジャンプブーストとジャンプ中スローの合わせ技で通常ジャンプ以上の高さを飛ぶことが出来ます。徐々に加速するサイクルを前に出来るだけ身体を温存してハイスコアを目指してください。

[エントリーNo.70] Alice in Pitago land. (アリス イン ピタゴランド)

strato さま

▼応募者コメント▼

箱庭型理不尽脱出アクションゲーム第二弾! ぷちな体で脱出せよ!操作は至って簡単。 ゴール目指して、マップの中を駆け抜けるだけ!
ただし、マップには某ピタゴライクな物理演算を主体とした仕掛けの数々!
女王によってリリースされた玉は、アリスをぷちッと潰そうとするでしょう。
玉を避けつつも、ハンマーにはぷちッと潰され、ブロックにはぷちッと潰され!
ぷちアリスを操作して仕掛けを回避しつつ、ゴールを目指すゲームです。

[エントリーNo.71]Make it Petit

Bayesleaf さま

▼応募者コメント▼

グレイマンは青いアイテムを集めているのですが、邪魔なブロックで取れません。でも、ブロックを小さくするビーム銃を手に入れました。
これで、小さくしてしまおう!アイテムを取って進むアクションパズルゲームです。

[エントリーNo.72]カタナガールズ 第三話「恐怖!巨大グレイマン!」

おかず さま

▼応募者コメント▼

〆切日に急にこのゲームのイメージが思い浮かんだので急いで作りました。アクションゲームの中ボス戦のイメージで、たぶんこの後は巨大ロボに乗って戦うと思います。制作時間の割には自分好みな感じにできて大満足です!

[エントリーNo.73]ぷちTomatina

チームあかまる(akaren, kurotori, malony) さま

▼応募者コメント▼

ぷちトマトを収穫・出荷してお金を稼ぎながら戦う
マルチプレイプチバトルシューティング

[エントリーNo.74]VR ぷちバイク!

チームかっこかり さま

▼応募者コメント▼

VRで簡単に操作ができるゲームを目指そうとした中で、バイクという疾走感のあるゲームをコントローラ一つで簡単にプチ操作で行えるように考え作りました。座った状態で片手で簡単にプレイできる上、過度なカーブもないので疾走感を残しつつも疲れすぎないプチ感覚で遊べるゲームに出来ました。

[エントリーNo.75]DeathArithmetic

やねじ さま

▼応募者コメント▼

Modoの体験版を使用してぷちっとアクションゲーム+暗算を作ってみました。
MODOとUE4の連携はスムーズで非常に使いやすかったです。

[エントリーNo.76]ぷち神様のおかたづけ

チームぷち神 さま

▼応募者コメント▼

私たちの作品「ぷち神様のお片付け」は、小さな神様「ぷち神様」となって、歩き回る子供から逃げ回りながら部屋中に散らかっているガラクタを片付けていくゲームです。
子供は、ぷち神様を見つけると攻撃してくるので、子供をうまく回避しながら、お片付け箱にガラクタを投げてお片付けしていきましょう。
ガラクタを全てお片付けできればゲームクリア、子供に倒されてしまうとゲームオーバーです。
こだわった点は、部屋に転がる様々なタイプのガラクタを用意したこと、ぷち神様が小さく見えるように考えられたスケール感、子供の動きのAI、物を投げる際の処理です。

[エントリーNo.77]ユニコーンAR

石井聡 イシイサトシ さま

▼応募者コメント▼

ぷちキャラを召喚するスマホARです。

[エントリーNo.78]パチュリーのぷちライブ

らんらんら さま

▼応募者コメント▼

MMDを使用したUE4の動画制作に挑戦してみました。
今後UE4を使用した動画がもっと増えたらいいなと思います

[エントリーNo.79]Puchi STG

mwsss さま

▼応募者コメント▼

ぷちコン参加4回目。65.8MBの小さいSTGのモトです。
W 上
S  下
A 左
D 右
スペースキー ショット

[エントリーNo.80]PuddingPolling(プリンポリン)

waka2ya(わかにゃ) さま

▼応募者コメント▼

ぶるぶるのプッ○ンプリンをトランポリンのように使いながら上を目指すゲームです。
プリンを食べたいグレイちゃんの元へ届けましょう。
でも何故か妨害してくるグレイちゃんに屈するな!!
いい感じのプリンにするのが大変でした。こだわりの卵です。

 

第10回UE4ぷちコン応募作品一挙公開!その1はこちら

第10回UE4ぷちコン応募作品一挙公開!その2はこちら

第10回UE4ぷちコン応募作品一挙公開!その3はこちら

第10回UE4ぷちコン応募作品一挙公開!その5はこちら

 

[UE4]第10回UE4ぷちコン応募作品公開!その5

$
0
0

第10回UE4ぷちコンのエントリー作品一覧ページです。

今回は全部で87作品集まりました!!

応募いただいた皆様、ありがとうございます!!

第10回UE4ぷちコン応募作品一挙公開!

※コンテストの告知ページはこちらです。

第10回UE4ぷちコン応募作品一挙公開!その1はこちら

第10回UE4ぷちコン応募作品一挙公開!その2はこちら

第10回UE4ぷちコン応募作品一挙公開!その3はこちら

第10回UE4ぷちコン応募作品一挙公開!その4はこちら

 

[エントリーNo.81]  「ぷちっとおさんぽプチゾンビ」

ねばねばぐるぐる さま

▼応募者コメント▼

横スクロールゲーム、そしてゲーム内キャラクターたちの紹介映像を作成しました。
「プチゾンビ」をはじめとして、随所に「ぷち」要素を盛り込んでみました。
お楽しみいただければ幸いです。

[エントリーNo.82] ぷち地球をすくえ。

mike さま

▼応募者コメント▼

直球で緩衝材のプチプチをテーマに。 ぷちぷちしていると人生の嫌なこと忘れるよね、でもそんな事ばっかりやってたら人生成功出来ないよね、頑張れば地球だって救えるかも、だってぷちぷち、緩衝材はいつだって人生の縁の下の力持ちなんだぜ、そんな気持ちを思い出せる(ような気がする)ゲーム。 ぷちぷちと同じように他愛ない暇つぶしになるといいです。

[エントリーNo.83] ESCAVE

小竹秀磨  さま

▼応募者コメント▼

捕まってしまったスライムが小さくなる薬を使って魔物の巣の洞窟から脱出するゲームです。

[エントリーNo.84]ぷちラン

行本 和弘  さま

▼応募者コメント▼

お題の「ぷち」といえば想像するのはプチプチことエアキャップ!このゲームは「ぷ」→「ぷ」→「ぷ」→「ち」の順にチェックポイントを通過してプチプチをつぶしていくストレス解消ゲームです。コーナーは自動的に曲がりますので操作は必要ありません。チェックポイントを正しく通過するとスピードアップ、間違えるとスピードダウンです。赤のぷちはジャンプ、金のぷちは大幅スピードアップです。制限時間をすぎるとプチワードが読み上げられます。綺麗なコンボを決められるかな?ゆっくりプチプチしてもええんやで。レッツぷちぷち!

[エントリーNo.85] MAGITYPE(マギタイプ)

リンデロン さま

▼応募者コメント▼

タイピングゲームです。
タイピングゲームですが、タワーディフェンス的なシューティング的な変なゲームです。過去・今回の10回のぷちコンテーマを「呪文」として、キーボードを打ちこんでください。
迫りくるジャック・オー・ランタンを倒し、逃げ惑う村人を助けてあげてください。残念ながら、間に合っておらず、多くの要素が未実装ですが、
面白げな要素はできたと思えるので、未完ながら応募させていただきました。締め切りは過ぎましたが、完成まで作りたいと思います。

[エントリーNo.86]ぷち破壊__振り回せコントローラー (PRT)

NOK さま

▼応募者コメント▼

VRならではのゲームです。
VR空間内にて、どんどん迫ってくる ぷち をいがぐりに見立てたコントローラーで破壊するゲームです。
ゲーム内ですべてが完結するのではなく、実際にコントローラーを投げて遊ぶゲームになります。
コントローラーがどこかへ飛んでいかないように、ヒモで結び、またコントローラーをぶつけ怪我、破損が起こらないように、ぷちぷち(梱包材)にて
カバーしております。
ぷちを破壊したときに、実際に収録したぷちぷちの音も流れます、また少量ですがエフェクトも発生させています。
実際にコントローラーを投げるという、普通ゲームでは中々再現できないことに取り組みました。
現在も開発を進めています。

[エントリーNo.87] プチっと!イクラ君!

豊島 幸夫 さま

▼応募者コメント▼

自キャラリギング・リターゲット・弾を発射までUnrealの学習の為制作しました。

第10回UE4ぷちコン応募作品一挙公開!その1はこちら

第10回UE4ぷちコン応募作品一挙公開!その2はこちら

第10回UE4ぷちコン応募作品一挙公開!その3はこちら

第10回UE4ぷちコン応募作品一挙公開!その4はこちら

 


[UE4]UE4.20で追加されたListViewウィジェットについて

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

こんにちは。アシスタントエンジニアの小倉です。

今回は、UE4.20で新たに追加されたListViewウィジェットを紹介します。

目次

ListViewウィジェットとは

ListViewウィジェットの使い方

パフォーマンス検証

ListViewウィジェットとは

ListViewウィジェットは、UE4.20でUMGに新たに公開されたウィジェットの一つです。

ScrollBoxとよく似ており、主に次のような機能を持ちます。

○ 複数の子ウィジェットを追加できる

○ 子ウィジェットが表示領域を超えとき、スクロールで表示位置をスライドできる

ListViewがScrollBoxと異なる点は、追加できる子ウィジェットのクラスを1つしか指定できない代わりに、表示領域内の子ウィジェットを使い回すような挙動(例えば、下へのスクロールによって表示領域の上部を越えて見えなくなったウィジェットは、すぐスクロール先である表示領域下部に移動し、移動先に合わせて表示項目を更新します)をすることです。これにより、ListViewに追加される子ウィジェットは表示に必要な数だけとなり、結果として多量の子ウィジェットを追加するときのヒッチの軽減や、表示中の処理負荷の削減が期待できます。

子ウィジェットを使い回すイメージは次のようになります。

ListViewウィジェットの使い方

EntryItemクラスの作成

ListViewで表示したい項目の情報を保持するオブジェクトのクラスを作成します。

このオブジェクトはUObjectで保持するので、Actorのようなクラスも指定できます。しかし、情報を保持するだけのクラスには多機能すぎるため、ここではUObjectを継承した次のような「BP_EntryItem」クラスを作成しました。このクラスはListViewの項目として表示するテキストを保持する変数を1つだけ持ちます。この変数はConstructObjectノードで値を設定できるように、Expose on Spawnにチェックを入れます。

EntryWidgetクラスの作成

ListViewの項目となるウィジェットブループリントを作成します。

ここではアセットの名前を「WB_Entry」としました。作成したWB_Entryを開き、TextBlockウィジェットを配置します。

次に、Graphタブを開き、ToolBarパネルのClass Settingsを選択します。そして、DetailsパネルにあるInterfacesのAddボタンをクリックし、UserObjectListEntryインターフェースを追加します。

追加した後、インターフェースのイベントであるEventOnListItemObjectSetを実装します。

このイベントは、ListViewのスクロールによって使い回されるウィジェットの内容を更新するときに呼び出されるイベントです。更新する項目の情報を保持するオブジェクトが引数として与えられるので、そのオブジェクトに基づいてウィジェットの内容を更新する処理を実装します。

引数のオブジェクトはListViewに追加するオブジェクトなので、ここではBP_EntryItemオブジェクトになります。BP_EntryItemオブジェクトにキャストして保持するText変数でTextBlockの内容を更新します。

ListViewウィジェットの作成

ListViewウィジェットを表示するためのウィジェットブループリントを作成します。

ここではアセットの名前を「WB_ListView」としました。作成したWB_ListViewを開き、PaletteのListsグループからListViewを次のように配置します。

この状態ではListViewの中に「No EntryWidgetClass specified on this list」と表示されてコンパイルエラーとなってしまいます。

そこで、先ほど作成したWB_Entryウィジェットを、次のようにEntryWidgetClassに指定します。

これでListViewの設定は終了ですが、ListViewは動的にのみ項目を追加できます。

ここでは、ListViewの項目であるBP_EntryItemオブジェクトをListViewに100個追加する処理を作りました。Construct ObjectノードでBP_EntryItemオブジェクトを作成し、それをListViewに追加する処理をForloopで100回行っています。

WB_ListViewをViewportに追加して実行すると、次のようになります。

パフォーマンス検証

ListViewは表示領域中のウィジェットを使いまわしていますが、見た目はほとんどScrollBoxと同じで違いがわかりません。

そこで、多量のウィジェットを扱ったときの処理負荷を計測して、ListViewとScrollBoxのパフォーマンスの違いを検証します。

ウィジェット追加時の処理負荷

ここでは、ListViewとScrollBoxに項目を10000個生成・追加した瞬間の処理負荷を比較しました。

ScrollBoxにBP_Entryを追加する処理を次のようにしました。

表示するテキストによって違いが出ないように、BP_ListViewも変更しました。

これを実行した瞬間の処理負荷はそれぞれ次のようになりました。

ScrollBoxでは明らかなヒッチが起きていることが確認できます。

ListViewはウィジェットを追加しているのではなく、項目の情報を保持するオブジェクトを生成・追加しているだけに対し、ScrollBoxは比較的重いウィジェットの生成・追加処理を10000回も行っているため、このような結果になったと考えられます。

しかし、このような生成・追加時ヒッチは、処理を複数フレームに分散することである程度対処できます。

表示中の処理負荷

ここでは、先ほどと同様にBP_Entryを10000個追加した状態での処理負荷を計測しました。

ListViewには、特に大きな処理負荷がかかっていないのに対し、ScrollBoxはGameスレッドが明らかにボトルネックになっています。

特別な最適化をしていない状態の比較では、ListViewのパフォーマンスの方が優れていることを確認できました。

おわりに

いかがでしたでしょうか。

UE4.20には、ListView以外にもTile View、Tree View、DynamicEntryBoxなどのウィジェットが追加されました。

これらのウィジェットも、また機会があれば紹介したいと思います。

この記事は次のバージョンで作成されました。
Unreal Editor Version: 4.20.3-4369336+++UE4+Release-4.20

[UE4] ゲーム開始時にプレイアブルになる前にシーケンサーを再生する

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

こんにちは。
私はシーケンサー自体の作業をすることはありましたが、
それをゲーム側で呼び出すなどのブループリント周りの作業を行ったことがありませんでした。

今回の記事は、シーケンサーを作成したけれども、ブループリントをあまり触ったことが無く、
ゲーム中での使い方が分からない…といった方の助けになればと思います。

今回はゲーム開始前にシーケンサーを呼び出す方法、そのときに起こった問題と解決方法などを紹介しようと思います。サンプルのプロジェクトはぷちコンでグループ制作したものになります。

今回の目標とするシーケンサーを再生するタイミングとしては以下のようにタイトルとゲーム本編の間になります。


このゲームのレベルの構成や遷移については以下のようになります。


ではまず、シーケンサーがない状態でのゲームプレイ動画です。
シーケンサーがない状態のプレイ動画
ここにシーケンサーを追加して以下のようにするのが目標です。
シーケンサーを追加した状態のプレイ動画

では順に解説させていただきます。

 

1.ゲーム開始前にシーケンサーを呼び出す
ゲーム本編が開始する前に処理を入れたいので、ゲーム本編が開始する処理が書かれているレベルブループリントを開きます。(今回はこのレベルをゲーム本編のレベルと呼びます)
現在ゲーム開始前は以下のようなレベルブループリント(以下BPと略します)になっています。


(※ゲームモードにはゲームシステムのさまざまな処理、今回の場合はUIを表示更新したり、ゲームがクリアしたかを判定したり、プレイヤーの入力をコントロールしたりなどが入っているため、ゲームモード自体の説明は省かせていただきます。)

まずシーケンサーを再生するには、シーケンサーのカメラを呼び出さなければなりません。
今はプレイヤーのカメラになっていますので、このカメラをシーケンサーのカメラで上書きするような処理を作成します。
注意したいのが、シーケンサーでスポーンさせたカメラだとBPで呼び出せません。シーケンサーが再生されるまでそのカメラは存在していないためです。

プレイヤーのカメラ情報などを取得しているのがGet Player Controller、そのカメラを上書きするという処理をSet View Target with Blend、何で上書きするかはNew View TargetにつながっているCine Camera Actorです。Cine Camera Actorのノードはワールドアウトライナからシーケンサーで使用しているカメラを選択し、レベルブループリントにドラッグ&ドロップすると、カメラのノードがBPに作成されます。

次にシーケンサーをプレイする処理を追加します。
カメラを呼び出したあとに、シーケンサーをプレイします。ワールドアウトライナからレベルシーケンサーを選択した状態で、BPで右クリックするとシーケンサーのノードが下図のようにサジェストされます。

シーケンサーのノードが作成できたらそこから再生するという処理、Play(SequencePlayer)を設定します。シーケンサーのPlay以降にはもともとの処理をつなげておきます。

今回、シーケンサーを再生するときにプレイヤーが邪魔になってしまうので、レベルに配置しているプレイヤーはActor Hidden in Gameになっています。
この状態ではBP側はシーケンサーを再生する、という処理で終わってしまいます。シーケンサーで設定した尺を超えても、ゲーム画面には戻りません。
シーケンサー側からBPへ、シーケンサーはここで終わります、というイベントを送り、そのイベントをBP側で取得したら、ゲームを開始するという処理を繋げなければなりません。また非表示にしているプレイヤーも表示しなければいけません。

2.シーケンサーの終了を設定し、ゲーム開始の合図にする
ではシーケンサーの終了を設定してみます。
シーケンサーを開いてEventTrackを追加します。トラックが追加できたら、シーケンサーの再生を終了したい部分にキーを設定します。
キーを作成したらキー上で右クリックし、PropertiesからEvent Nameをつけておきます。ここではSeq_Endとしています。
※ここで注意したいのが、シーケンサーの尺終わりピッタリにEventTrackのキーを設定してしまうとBP側でそのキーをうまく取得できない場合があります。

作成できたらBPに移り、CustomEventを作成して、先程設定したキーの名前にします。
これにより、シーケンサーが再生され、EventTrackのキーのある位置が再生されると、キーの名前をつけたイベントがBP上で呼ばれるようになります。このイベントが呼ばれる=シーケンサーの再生が終了する、ということなので、ゲームができるようにBPのノードをつなげます。
必要なものはゲームモードの呼び出し、シーケンサーのカメラに設定したものをプレイヤーのカメラに設定し直す、プレイヤーキャラクターの表示、です。
BPは以下のようになります。上記のシーケンサーのPlayのあとにつなげていたCast to BP_RollingGameModeやOn Load Levelなどはゲーム本編に関連する処理のため、シーケンサー再生終了後に動いてほしいので、Seq_Endのイベントが起こったあとに処理されるようにつなぎ直します。
New View TargetなどにつなげているCast To BP_PhysicsBallはピュア関数というものにしておきます。ピュア関数にしておかないと実行ピンが存在してしまい、その実行ピンが繋がれていないとエラーとなってしまうためです。


ピュア関数にするには、ピュア関数にしたいノードの上で右クリック、Convert to Pure Castで行えます。


これでシーケンサーが再生し、ゲームがスタートするのですが、いくつか問題が発生します。
シーケンサーを再生している裏で、非表示にしているプレイヤーのコリジョンがぷちぷちや地面に反応して動いてしまうのです。

 

3.コリジョンの発生タイミングを変更する
キャラクターの初期配置を変更すれば上記の問題は解決できますが、初期位置をあまり変更したくない+スタートするまでは絶対に動いてほしくない(今回この作品はUE4のテンプレートのBallを使用しているので、球体がPhysicsで動いている=物理が効いてしまい完全に静止状態から始めることが困難)ため、コリジョンをカウントダウン後まで無効にする方法を取りました。プレイヤーのボール部分のフィジックスの設定はNo Collisionに設定しておきます。

この処理はGameModeに追加します。なぜならプレイヤーの入力を無効、受付可能のタイミングを決めているのがこのBPのためです。プレイヤーの入力を無効にしているところにコリジョンの無効を、プレイヤーの入力を受付可能にしているところにコリジョンを有効にするノードを追加します。


これでコリジョンがカウントダウン後のプレイヤーが動かせるタイミングで有効になり、シーケンサー再生中にプレイヤーが動いてしまうこともなくなりました。

4.おまけ:初回とタイトルに戻ったときのみシーケンサーが再生されるようにする
シーケンサーを再生し、無事にゲームをプレイできるようになりました。しかし、このゲームにはリトライできる機能があり、そのリトライをするたびにシーケンサーが流れていては煩わしく感じます。そこでシーケンサーを初回プレイ時と、タイトルに戻ってプレイをする時に限定し、「もう一回」を選択したときには流れないようにします。


初回プレイ時にシーケンサーを再生したか、タイトルに戻ったか、をフラグとして取得できるようにします。変数を作成して、フラグのONOFFをできるようにします。ここでは変数名をSeq_Playとします。

変数Seq_Playですが、レベルBPに作成するとレベル遷移時に読めなくなってしまいます。GameModeも同じく、パーシスタントレベルをまたいで値を保持することができません。そのため、レベルを遷移しても値を保存できるもの、が必要になります。
それを満たすのがGameInstanceです。コンテンツブラウザから右クリック→ブループリントを作成で、名前を検索して新規アセットとしてGameInstanceを作成します。
  
このGameInstanceには今回の使用方法としては、変数に値を保持させておくだけのため、特にBPなどは書きません。

まずシーケンサーを再生したときに、フラグが立つようにします。BPは以下のようになります。
シーケンサーを再生しているのはゲーム本編のレベルなので、そこに追加します。シーケンサーのPlayノードの後ろに、GameInstanceの呼び出しと、変数の値のセットを行います。
変数(フラグ)がONになるようにします。

そしてタイトルに戻ったときに上記とは逆の値(フラグがOFF)を変数Seq_Playにセットします。タイトルのレベルBPに以下のように追加します。

これでフラグをONOFFすることはできました。しかし、シーケンサーを再生するか、しないかの分岐をまだ追加していません。シーケンサーを再生する命令を出しているゲーム本編のレベルBPに以下のような処理を追加します。ここで変数を利用してどちらに分岐するかを決定します。上記の変数を設定している場所により、ゲームをプレイしたあとはフラグがONになっているのでその時はシーケンサーをプレイしないで、ゲームをリスタート、フラグがOFFになっているときにはシーケンサーを流してからゲームをプレイするようにします。
これで変数に入っている値を参照して、シーケンサーを再生するかどうかの分岐ができました。

長くなりましたが、BP初心者がシーケンサーをゲーム中に入れるときに躓いた点と、解決策を書かせていただきました。
参考になるものがあれば幸いです。

[UE4] 第10回UE4ぷちコン ノミネート作品発表!

$
0
0

第10回UE4ぷちコンの結果発表です。

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

テーマの解釈が多岐に渡り、様々な”ぷち”が集まりました!!

その中からノミネート8作品を選出いたしました!

最優秀賞作品は10月14日(日)開催の【Unreal Fest East 2018】会場にて展示いたします。

それでは、ノミネート作品をご覧ください!

審査員: Epic Games Japan 今井様岡田様

株式会社ヒストリア 佐々木

 第10回UE4ぷちコン審査結果発表会

 


【ノミネートNo.1】VRでワイン作りたい!

ワイン作り隊 さま

 


【ノミネートNo.2】ぷちロボコン

でじまい さま

nicodo display=”player”]sm33853984[/nicodo]

 


【ノミネートNo.3】Petit Toma run (プチ トマ ラン)

raidako さま

 


【ノミネートNo.4】ねるちゃんのぷちぷちいくらシューティング

猫葉ねる  さま

 


【ノミネートNo.5】ベリーぷちぷち

恒吉星光 さま

 


【ノミネートNo.6】イクラ

K_Z  さま

 


【ノミネートNo.7】カピぷち

おさるさんチーム(ぷちコンゲームジャム)  さま

nicodo display=”player”]sm33866750[/nicodo]

 


【ノミネートNo.8】Veloce

シカニカイ さま

 

 

 

ノミネートおめでとうございます!

 

※コンテストの告知ページはこちらです。

 

[UE4] Pythonを使って、開発を自動化してみよう!

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

 

こんにちは、エンジニアです。

今回は、UE4でPythonを使用できる面白そうな「Python Editor Script Plugin」をご紹介します!

 

Python Editor Script Pluginとは!

BluetilityのようなエディタのスクリプティングでPythonを使用できるようにするプラグインです。

※記事執筆バージョン、UE4.20.3でのPythonのバージョンは2.7となっております。

※このプラグインはまだベータで実験的な機能となっておりますので開発で使う場合はお気を付けください。また、あくまでエディタのスクリプティングを行うためのプラグインになっています。実際のゲーム開発をPythonで行うためのプラグインではございません。

主な特徴としては、

1.Pythonを使用する

2.C++からBlueprintに公開されている機能をほぼ使用できる

3.エディタ起動時に自動的に実行できる

4.コマンドライン上からエディタを起動しなくても実行できる

が挙げられます。

やはり、一番の注目ポイントはPythonで記述ができることです。BluetilityはBlueprintなためUE4の機能しか使用できませんが、Pythonでは他APIを使用することで得意なデータ解析や自動化がうまく活用できるかもしれません。もしかしたら、今流行りのディープラーニングで何か面白いことができるかもしれないですね。また、コマンドライン上からスクリプトを実行できるのもJenkinsでの自動化に使いやすく個人的にポイントが高いです。

 

導入方法

〇プラグインを有効化

エディタの「編集」→「Plugins」を開きます。左のメニューから「Scripting」を選択し、「Editor Scripting Utilities」と「Python Editor Script Plugin」のEnableにチェックを入れるだけでOKです。このプラグインにはすでにPythonが入っているため、別でPythonをインストールする必要はありません。

 

〇APIについて

PythonでUnrealAPIを使用するにはAPIをインポートしてあげる必要があります。

import unreal

また、APIのドキュメントはコチラです。

Unreal Python API Documentation

 

〇パスについて

エディタがデフォルトで認識しているパスは以下の4つになります。

・プロジェクトのContent/Python/

・エンジンのContent/Python/

・プラグインのContent/Python/

・Windows上のDocuments/UnrealEngine/Python/

です。追加でパスを追加したい場合は、「編集」→「プロジェクト設定」から左のメニューの「プラグイン」→「Python」の「Additional Paths」に追加しましょう。

 

使用方法

〇エディタ上からスクリプトを実行する

アウトプットログの左下のCmdと表示されている場所からプルダウンでPythonが選択できるようになっています。Pythonに切り替えるとスクリプトが入力できるようになります。

試しに、「unreal.log(“Hello World :D”)」 と入力してみましょう。アウトプットログにログが表示されます。

Pythonのファイル「.py」を実行する場合は、「py “D:\MyProject\MyPython.py”」でpyファイルを実行できます。

 

〇コマンドライン上からスクリプトを実行する

コマンドラインでスクリプトを実行する方法は2種類存在します。

1.エディタを起動して、スクリプトを実行する

この場合、エディタが起動しデフォルト設定されているマップも開き準備が整った後に実行されます。

UE4Editor-Cmd.exe MyProject.uproject -ExecutePythonScript = "D:\MyProject\MyPython.py"

2.エディタを起動せずにスクリプトだけ実行する

エディタを起動しないためとても高速に実行されます。しかし、マップ上にアクターをスポーンさせたり、アセットを読み込むなどスクリプトによっては正常に動作しない場合がありますので注意が必要です。

UE4Editor-Cmd.exe -run = pythonscript -script = "D:\MyProject\MyPython.py"

 

〇エディタが起動したタイミングでスクリプトを自動的に実行させる

実行させる方法は2種類存在します。どちらもエディタが起動しデフォルト設定されているマップも開き準備が整った後に実行されます。

1.init_unreal.pyを使用する

前述した「パスについて」で紹介したパス以下に「init_unreal.py」が存在した場合、自動的に「init_unreal.py」が実行されます。

例:/Content/Python/init_unreal.py

2.Startup Scriptsを設定する

「編集」→「プロジェクト設定」から左のメニューの「プラグイン」→「Python」の「Startup Scripts」にpyファイルを追加します。

 

最後に

お疲れさまでした。一通りざっと紹介しました。導入手順も難しくなく、APIも簡単に使えそうです。正直自分も実際の開発でどう運用すればいいのかまだわかっていませんが、今までできるけどめんどくさかったことが簡単にできるようになる気がします。色々考えてみたいと思います。

また、エディタのスクリプティングを行うには3種類ありますが、簡単にエディタ内で実装したいならBluetility、がっつりエディタ拡張を行いたいならC++、Bluetilityだと難しかったりPythonのAPIを使いたかったらPythonって感じでしょうか。

英語ですが公式ドキュメントはコチラになります。

Scripting the Editor using Python

[UE4]複数のConditionをもつBranchノードを作る

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

こんにちは。アシスタントエンジニアの小倉です。
今回は、複数のConditionをもつBranchノードを作成します。

 

目次

開発経緯

UK2Nodeによる実装

実行結果

ソースコード

開発経緯

複数の条件式の論理積をとってBranchで分岐したいことがあります。しかしUE4では論理演算が短絡評価しないために、上図のような横に伸びる冗長なノードを組むことになります。

この対応として、マクロによってノードを1つにまとめる方法が考えられます。

しかし、マクロを用いると、引数の数に応じたマクロを用意する必要があります。

そこで、上記のマクロとほぼ同じ実装で、動的にConditionピンの数が変わるようなBranchノードを作成します。

UK2Nodeによる実装

UK2Nodeについて記述した弊社記事があります。

[UE4] ノードの入力ピンによって出力ピン等の内容を動的に変える仕組みについて ~実装例編~

[UE4] ノードの入力ピンによって出力ピン等の内容を動的に変える仕組みについて ~解説編~

UK2Nodeの詳細については、これらの記事を参照してください。

ここでは、上記のようなBranchノードの実装について詳しく紹介します。

ノード外観の設定

// ノードタイトルの設定
FText UK2Node_SEAndBranch::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
	return LOCTEXT("GetNodeTitleDefault", "SE And Branch");
}

// ノード説明の設定
FText UK2Node_SEAndBranch::GetTooltipText() const
{
	return LOCTEXT("GetTooltipText", "Evaluate from the smaller pin number.");
}

// ノードタイトル色の設定
FLinearColor UK2Node_SEAndBranch::GetNodeTitleColor() const
{
	return GetDefault<UGraphEditorSettings>()->ExecBranchNodeTitleColor;
}

// ノードのメニュー上におけるカテゴリの設定
FText UK2Node_SEAndBranch::GetMenuCategory() const
{
	return FEditorCategoryUtils::GetCommonCategory(FCommonEditorCategory::FlowControl);
}

// ノードアイコンの設定
FSlateIcon UK2Node_SEAndBranch::GetIconAndTint(FLinearColor& OutColor) const
{
	static FSlateIcon Icon("EditorStyle", "GraphEditor.Branch_16x");
	return Icon;
}

// メニューアクションの登録(コンテキストメニューからノードをスポーンさせるようにする)
void UK2Node_SEAndBranch::GetMenuActions(FBlueprintActionDatabaseRegistrar & ActionRegistrar) const
{
	// actions get registered under specific object-keys; the idea is that 
	// actions might have to be updated (or deleted) if their object-key is  
	// mutated (or removed)... here we use the node's class (so if the node 
	// type disappears, then the action should go with it)
	UClass* ActionKey = GetClass();
	// to keep from needlessly instantiating a UBlueprintNodeSpawner, first   
	// check to make sure that the registrar is looking for actions of this type
	// (could be regenerating actions for a specific asset, and therefore the 
	// registrar would only accept actions corresponding to that asset)
	if (ActionRegistrar.IsOpenForRegistration(ActionKey))
	{
		UBlueprintNodeSpawner* NodeSpawner = UBlueprintNodeSpawner::Create(GetClass());
		check(NodeSpawner != nullptr);

		ActionRegistrar.AddBlueprintAction(ActionKey, NodeSpawner);
	}
}

UK2Nodeの作法その1です。他のUK2Nodeクラスからのコピペがほとんどで、必ずしも記述する必要のないものもあります。

GetMenuActionsに関しては、メニューからノードをスポーンするときに必要なので必ず定義します。

デフォルトピンの作成

// ノードのデフォルトのピン定義
void UK2Node_SEAndBranch::AllocateDefaultPins()
{
	// 入力実行ピン
	CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute);

	// 出力Then実行ピン
	UEdGraphPin* TruePin = CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Then);
	TruePin->PinFriendlyName = LOCTEXT("AllocateDefaultPins_True", "true");

	// 出力Else実行ピン
	UEdGraphPin* FalsePin = CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Else);
	FalsePin->PinFriendlyName = LOCTEXT("AllocateDefaultPins_False", "false");

	// 入力Conditionピン
	AddUniqueConditionPin();

	Super::AllocateDefaultPins();
}

// 未使用番号のConditionピンを作成する
UEdGraphPin * UK2Node_SEAndBranch::AddUniqueConditionPin()
{
	UEdGraphPin* Pin = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Boolean, GetUniquePinName());
	Pin->DefaultValue = TEXT("true");
	return Pin;
}

// 未使用番号のConditionピンの名前を取得
FName UK2Node_SEAndBranch::GetUniquePinName() const
{
	FName NewPinName;
	for (int32 i = 0; true; i++)
	{
		NewPinName = GetPinNameGivenIndex(i);
		if (!FindPin(NewPinName))
		{
			break;
		}
	}
	return NewPinName;
}

// 番号つきConditionピンの名前を取得
FName UK2Node_SEAndBranch::GetPinNameGivenIndex(int32 Index) const
{
	return *FString::Printf(TEXT("%s_%d"), *UEdGraphSchema_K2::PN_Condition.ToString(), Index);
}

ノードを最初にスポーンしたときのピン部分を作成します。図の4つの黄枠部分を作成しています。

今回作るノードは、基本的にはBranchと同じですが、Conditionピンにワイヤーが接続された場合、新しいConditionピンを追加して、任意の数のConditionを引数に取れるようにします。

そこで、複数のConditionピンは、Condition0, Condition1, Condition2, ……といった番号付きの名前で管理します。ここで、GetPinNameGivenIndex()は、前述のような番号つきConditionピン名を作成する関数です。

GetPinNameGivenIndex()によって作成したConditionピン名を0から順にFindPin()で検索すると、使用されていないConditionピン名でnullptrになります。これを利用して、GetUniquePinName()は使用されていないConditionピン名を取得します。AddUniqueConditionPin()は、使用されていないConditionピン名から新しいConditionピンを追加する関数です。

ノードピンの取得

// Thenピンの取得(主にExpandNode内や、SpawnIntermediateNodeでUK2Node_SEAndBranchが使われるときに使用する)
UEdGraphPin * UK2Node_SEAndBranch::GetThenPin() const
{
	UEdGraphPin* Pin = FindPin(UEdGraphSchema_K2::PN_Then);
	check(Pin);
	return Pin;
}

// Elseピンの取得(主にExpandNode内や、SpawnIntermediateNodeでUK2Node_SEAndBranchが使われるときに使用する)
UEdGraphPin * UK2Node_SEAndBranch::GetElsePin() const
{
	UEdGraphPin* Pin = FindPin(UEdGraphSchema_K2::PN_Else);
	check(Pin);
	return Pin;
}

// Conditionピンの取得(主にExpandNode内や、SpawnIntermediateNodeでUK2Node_SEAndBranchが使われるときに使用する)
UEdGraphPin * UK2Node_SEAndBranch::GetConditionPinGivenIndex(const int32 Index)
{
	return FindPin(GetPinNameGivenIndex(Index));
}

UK2Nodeの作法その2です。ピンを取得するだけであれば、FindPin()を直接呼び出しても問題ありません。

しかし、外部のUK2NodeのExpandNode上でこのノードがスポーンされたとき、繋ぐことのできるピンを明示するという意味合いもあるため、慣習としてピンの取得関数は記述した方がよいです(そうでなくとも、適切に関数に分けるべきですね)。

ピンの動的追加・削除

// ピンの追加と削除(ピンとワイヤーが接続されたり切断されたときに呼ばれる)
void UK2Node_SEAndBranch::PinConnectionListChanged(UEdGraphPin * Pin)
{
	if (IsConditionPin(Pin))
	{
		// Conditionピンからワイヤーが切断されたとき、切断されたワイヤーを削除
		if (Pin->LinkedTo.Num() == 0)
		{
			RemovePin(Pin);
		}

		// ワイヤーで繋がったピンしかないとき、ピンを追加
		if (!IsHaveUnlinkConditionPin())
		{
			AddUniqueConditionPin();
		}

		// ノード外観を更新する
		GetGraph()->NotifyGraphChanged();
	}

	Super::PinConnectionListChanged(Pin);
}

// 指定したピンがConditionピンか取得
bool UK2Node_SEAndBranch::IsConditionPin(UEdGraphPin* TargetPin) const
{
	return TargetPin && TargetPin->PinType.PinCategory == UEdGraphSchema_K2::PC_Boolean;
}


// ピンの削除
void UK2Node_SEAndBranch::RemovePin(UEdGraphPin * TargetPin)
{
	// 指定したピンを削除する
	DestroyPin(TargetPin);
	Pins.Remove(TargetPin);

	// Conditionピンの番号を詰める
	int32 ThenIndex = 0;
	for (auto Pin : Pins)
	{
		if (IsConditionPin(Pin))
		{
			Pin->PinName = GetPinNameGivenIndex(ThenIndex++);
		}
	}
}

// ワイヤーの繋がっていないConditionピンを含むか
bool UK2Node_SEAndBranch::IsHaveUnlinkConditionPin() const
{
	for (const auto& Pin : Pins)
	{
		if (IsConditionPin(Pin) && Pin->LinkedTo.Num() == 0)
		{
			return true;
		}
	}
	return false;
}

PinConnectionListChanged()は、ピン同士が接続・切断されたときに実行されます。

この関数はConditionピンだけでなく、実行ピンが接続・切断されたときにも実行されます。そこで、IsConditionPin()でピンを調べることで、Conditionピンの接続・切断のみを取り扱うようにフィルタリングします。

ピンの切断は、LinkedTo配列の要素が空かどうかで判断できます。もし切断された場合は、RemovePinによって切断されたピンを削除します。

ノードの要件として、必ず1つデフォルトピンを持つようにしたいので、IsHaveUnlinkConnectionPin()によって、接続されていないピンがあるか確認します。もしなかった場合は、新しいピンを追加します。

ExpandNod

全てのConditionピンを列挙

void UK2Node_SEAndBranch::ExpandNode(FKismetCompilerContext & CompilerContext, UEdGraph * SourceGraph)
{
	Super::ExpandNode(CompilerContext, SourceGraph);

	// Conditionピンを取得
	TArray<UEdGraphPin*> ConditionPins;
	for (int32 i = 0; true; i++)
	{
		// TODO
		// 必要であればデフォルトピンの値による自明なフロー制御を行う
		// ・Trueデフォルトピンは、ConditionPinsに含めない
		// ・Falseデフォルトピンは、結果が自明(必ずElseに実行が流れる)
		UEdGraphPin* ConditionPin = FindPin(GetPinNameGivenIndex(i));
		if (!ConditionPin)
		{
			break;
		}
		ConditionPins.Add(ConditionPin);
	}

ExpandNodeでノードの内部の挙動を作成します。主に以下を行います。

・SpawnIntermediateNode()で既存のUK2Nodeをスポーンし、スポーンしたノードのピン同士をMakeLinkToで接続

・MovePinLinksToIntermediate()で、ExpandNodeするノードの入力ピンと出力ピンのリンクを、スポーンしたピンに移動

・BreakAllNodeLinks()で、ExpandNodeするノードにつながるリンクを切断

上記のコードでは、ノードが持っている全てのConditionピンを配列にキャッシュしています。

この時点でのExpandNodeのイメージ図は次のようになります。

Rerouteノードをスポーン

// Rerouteノードをスポーンする
	UK2Node_Knot* RerouteNode = CompilerContext.SpawnIntermediateNode<UK2Node_Knot>(this, SourceGraph);
	RerouteNode->AllocateDefaultPins();
	UEdGraphPin* RerouteExecPin = RerouteNode->GetInputPin();

次にRerouteノードをSpawnIntermediateNode()を使ってスポーンします。

スポーンしたノードは、ピンが初期化されていないため、必ずAllocateDefaultPin()を呼び出して初期化します。

この時点でのExpandNodeのイメージ図は次のようになります。Rerouteノードが配置されました。

Branchノードをスポーン

// Branchノードをスポーンする
	TArray<UK2Node_IfThenElse*> BranchNodes;
	for (auto ConditionPin : ConditionPins)
	{
		UK2Node_IfThenElse* BranchNode = CompilerContext.SpawnIntermediateNode<UK2Node_IfThenElse>(this, SourceGraph);
		BranchNode->AllocateDefaultPins();
		BranchNode->GetElsePin()->MakeLinkTo(RerouteExecPin);
		CompilerContext.MovePinLinksToIntermediate(*ConditionPin, *BranchNode->GetConditionPin());
		BranchNodes.Add(BranchNode);
	}

次に、Branchノードをスポーンします。BranchノードはConditionの数だけ必要なので、for文でConditionピンの数だけスポーン処理を行います。

Branchノードをスポーンしたら、BranchのFalse(Else)出力ピンと、Rerouteノードの入力実行ピンをMakeLinkTo()で接続します。

また、ConditionピンとスポーンしたBranchノードの実行入力ピンをMovePinLinksToIntermediate()で移動します。

この時点でのExpandNodeのイメージ図は次のようになります。MakeLinkTo()とMovePinLinksToIntermediate()は、イメージ図ではどちらもピンの接続をしている処理で、使い分けが難しいように感じます。ですが基本的には、「スポーンしたノードのピン同士を接続するときはMakeLinkTo()を使う」「Expandするノードのピンとスポーンしたノードのピンを接続するときはMovePinLinksToIntermediate()を使う」ぐらいに考えてしまっても問題はありません。

Branchノード同士を接続

// Branchノード同士を接続する
	for (int32 i = 0; i < BranchNodes.Num() - 1; i++)
	{
		UEdGraphPin* PrevBranchThenPin = BranchNodes[i]->GetThenPin();
		UEdGraphPin* PostBranchExecPin = BranchNodes[i + 1]->GetExecPin();
		PrevBranchThenPin->MakeLinkTo(PostBranchExecPin);
	}

スポーンしたBranchノードのTrue出力ピンと、次にスポーンしたBranchノードの実行入力ピンをMakeLinkTo()で接続します。

この時点でのExpandNodeのイメージ図は次のようになります。

ピンリンクの移動

// ピンリンクの移動
	CompilerContext.MovePinLinksToIntermediate(*GetExecPin(), *BranchNodes[0]->GetExecPin());
	CompilerContext.MovePinLinksToIntermediate(*GetThenPin(), *BranchNodes.Last()->GetThenPin());
	CompilerContext.MovePinLinksToIntermediate(*GetElsePin(), *RerouteNode->GetOutputPin());

	BreakAllNodeLinks();

まだ接続していない残ったピンをMovePinLinksToIntermediate()で接続します。

まず、ExpandNodeするノードの実行入力ピンと、最初のBranchノード実行入力ピンに接続します。

次に、最後にスポーンしたBranchノードのTrue実行出力ピンと、このノードのTrue実行出力ピンを接続します。

次に、Rerouteノードの実行出力ピンと、このノードのFalse実行出力ピンを接続します。

最後に、BreakAllLinks()で、このノードの全てのリンクを切断します。

最終的なExpandNodeのイメージ図は次のようになります。

実行結果

作成したノードを使用します。レベルブループリント上で次のようにしました。

Func1, Func2, Func3ノードは、それぞれPrintStringでノードが実行されたことを表示して、Bool値を返します。

これを、Funcの返り値をそれぞれ変えたときの結果は、次のようになりました。

Func1 False True False True False True False True
Func2 False False True True False False True True
Func3 False False False False True True True True
表示 call func1

False

 

 

call func1

call func2

False

 

call func1

False

 

 

call func1

call func2

call func3

False

call func1

False

 

 

call func1

call func2

False

 

call func1

False

 

 

call func1

call func2

call func3

True

正しく分岐し、また短絡評価もしていることが確認できました。

ソースコード

// Fill out your copyright notice in the Description page of Project Settings.

using UnrealBuildTool;

public class BlogTest420BEditor : ModuleRules
{
	public BlogTest420BEditor(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
	
		PublicDependencyModuleNames.AddRange(new string[] {
            "Core",
            "CoreUObject",
            "Engine",
            "InputCore",
            "Slate",
            "EditorStyle",
        });

		PrivateDependencyModuleNames.AddRange(new string[] {
            "EditorStyle",
            "KismetCompiler",
            "UnrealEd",
            "GraphEditor",
            "SlateCore",
            "Kismet",
            "KismetWidgets",
            "PropertyEditor",
            "BlueprintGraph",
        });
	}
}

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "K2Node.h"
#include "EdGraph/EdGraphNodeUtils.h"
#include "K2Node_SEAndBranch.generated.h"

UCLASS()
class BLOGTEST420BEDITOR_API UK2Node_SEAndBranch : public UK2Node
{
	GENERATED_BODY()

public:
	// Begin UEdGraphNode interface.
	virtual void AllocateDefaultPins() override;
	virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
	virtual FText GetTooltipText() const override;
	virtual FLinearColor GetNodeTitleColor() const override;
	virtual FSlateIcon GetIconAndTint(FLinearColor& OutColor) const override;
	virtual void PinConnectionListChanged(UEdGraphPin* Pin) override;
	// End UEdGraphNode interface.

	// Begin UK2Node interface
	virtual bool IsNodeSafeToIgnore() const override { return true; }
	virtual bool CanEverInsertExecutionPin() const override { return true; }
	virtual bool CanEverRemoveExecutionPin() const override { return true; }
	virtual void GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const override;
	virtual FText GetMenuCategory() const override;
	virtual void ReallocatePinsDuringReconstruction(TArray<UEdGraphPin*>& OldPins) override;
	virtual void ExpandNode(class FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) override;
	// End UK2Node interface

public:
	FName GetPinNameGivenIndex(int32 Index) const;           // 名前つきConditionピン名の取得
	FName GetUniquePinName() const;                          // 未使用番号のConditionピン名の取得
	UEdGraphPin* AddUniqueConditionPin();                    // 未使用番号のConditionピンの追加
	void RemovePin(UEdGraphPin* TargetPin);                  // 指定ピンの削除
	bool IsHaveUnlinkConditionPin() const;                   // ノードがリンクのないConditionピンを持っているか取得
	bool IsConditionPin(UEdGraphPin* TargetPin) const;       // 指定ピンがConditionピンか取得

	UEdGraphPin* GetThenPin() const;
	UEdGraphPin* GetElsePin() const;
	UEdGraphPin* GetConditionPinGivenIndex(const int32 Index);
};

#include "K2Node_SEAndBranch.h"
#include "EdGraphSchema_K2.h"
#include "BlueprintActionDatabaseRegistrar.h"
#include "BlueprintNodeSpawner.h"
#include "GraphEditorSettings.h"
#include "EditorCategoryUtils.h"
#include "KismetCompiler.h"
#include "K2Node_IfThenElse.h"
#include "K2Node_Knot.h"

#define LOCTEXT_NAMESPACE "K2Node_SEAndBranch"

// ノードのデフォルトのピン定義
void UK2Node_SEAndBranch::AllocateDefaultPins()
{
	// 入力実行ピン
	CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute);

	// 出力Then実行ピン
	UEdGraphPin* TruePin = CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Then);
	TruePin->PinFriendlyName = LOCTEXT("AllocateDefaultPins_True", "true");

	// 出力Else実行ピン
	UEdGraphPin* FalsePin = CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Else);
	FalsePin->PinFriendlyName = LOCTEXT("AllocateDefaultPins_False", "false");

	// 入力Conditionピン
	AddUniqueConditionPin();

	Super::AllocateDefaultPins();
}

// ノードタイトルの設定
FText UK2Node_SEAndBranch::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
	return LOCTEXT("GetNodeTitleDefault", "SE And Branch");
}

// ノード説明の設定
FText UK2Node_SEAndBranch::GetTooltipText() const
{
	return LOCTEXT("GetTooltipText", "Evaluate from the smaller pin number.");
}

// ノードタイトル色の設定
FLinearColor UK2Node_SEAndBranch::GetNodeTitleColor() const
{
	return GetDefault<UGraphEditorSettings>()->ExecBranchNodeTitleColor;
}

// ノードのメニュー上におけるカテゴリの設定
FText UK2Node_SEAndBranch::GetMenuCategory() const
{
	return FEditorCategoryUtils::GetCommonCategory(FCommonEditorCategory::FlowControl);
}

// ノードアイコンの設定
FSlateIcon UK2Node_SEAndBranch::GetIconAndTint(FLinearColor& OutColor) const
{
	static FSlateIcon Icon("EditorStyle", "GraphEditor.Branch_16x");
	return Icon;
}

// 番号つきConditionピンの名前を取得
FName UK2Node_SEAndBranch::GetPinNameGivenIndex(int32 Index) const
{
	return *FString::Printf(TEXT("%s_%d"), *UEdGraphSchema_K2::PN_Condition.ToString(), Index);
}

// 指定したピンがConditionピンか取得
bool UK2Node_SEAndBranch::IsConditionPin(UEdGraphPin* TargetPin) const
{
	return TargetPin && TargetPin->PinType.PinCategory == UEdGraphSchema_K2::PC_Boolean;
}

// Thenピンの取得(主にExpandNode内や、SpawnIntermediateNodeでUK2Node_SEAndBranchが使われるときに使用する)
UEdGraphPin * UK2Node_SEAndBranch::GetThenPin() const
{
	UEdGraphPin* Pin = FindPin(UEdGraphSchema_K2::PN_Then);
	check(Pin);
	return Pin;
}

// Elseピンの取得(主にExpandNode内や、SpawnIntermediateNodeでUK2Node_SEAndBranchが使われるときに使用する)
UEdGraphPin * UK2Node_SEAndBranch::GetElsePin() const
{
	UEdGraphPin* Pin = FindPin(UEdGraphSchema_K2::PN_Else);
	check(Pin);
	return Pin;
}

// Conditionピンの取得(主にExpandNode内や、SpawnIntermediateNodeでUK2Node_SEAndBranchが使われるときに使用する)
UEdGraphPin * UK2Node_SEAndBranch::GetConditionPinGivenIndex(const int32 Index)
{
	return FindPin(GetPinNameGivenIndex(Index));
}

// ワイヤーの繋がっていないConditionピンを含むか
bool UK2Node_SEAndBranch::IsHaveUnlinkConditionPin() const
{
	for (const auto& Pin : Pins)
	{
		if (IsConditionPin(Pin) && Pin->LinkedTo.Num() == 0)
		{
			return true;
		}
	}
	return false;
}

// 未使用番号のConditionピンの名前を取得
FName UK2Node_SEAndBranch::GetUniquePinName() const
{
	FName NewPinName;
	for (int32 i = 0; true; i++)
	{
		NewPinName = GetPinNameGivenIndex(i);
		if (!FindPin(NewPinName))
		{
			break;
		}
	}
	return NewPinName;
}

// 未使用番号のConditionピンを作成する
UEdGraphPin * UK2Node_SEAndBranch::AddUniqueConditionPin()
{
	UEdGraphPin* Pin = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Boolean, GetUniquePinName());
	Pin->DefaultValue = TEXT("true");
	return Pin;
}

// ピンの削除
void UK2Node_SEAndBranch::RemovePin(UEdGraphPin * TargetPin)
{
	// 指定したピンを削除する
	DestroyPin(TargetPin);
	Pins.Remove(TargetPin);

	// Conditionピンの番号を詰める
	int32 ThenIndex = 0;
	for (auto Pin : Pins)
	{
		if (IsConditionPin(Pin))
		{
			Pin->PinName = GetPinNameGivenIndex(ThenIndex++);
		}
	}
}

// ピンの追加と削除(ピンとワイヤーが接続されたり切断されたときに呼ばれる)
void UK2Node_SEAndBranch::PinConnectionListChanged(UEdGraphPin * Pin)
{
	if (IsConditionPin(Pin))
	{
		// Conditionピンからワイヤーが切断されたとき、切断されたワイヤーを削除
		if (Pin->LinkedTo.Num() == 0)
		{
			RemovePin(Pin);
		}

		// ワイヤーで繋がったピンしかないとき、ピンを追加
		if (!IsHaveUnlinkConditionPin())
		{
			AddUniqueConditionPin();
		}

		// ノード外観を更新する
		GetGraph()->NotifyGraphChanged();
	}

	Super::PinConnectionListChanged(Pin);
}

// ピンの再構築(主にこのノードがあるBlueprintGraphがロードされたときに呼ばれる関数)
void UK2Node_SEAndBranch::ReallocatePinsDuringReconstruction(TArray<UEdGraphPin*>& OldPins)
{
	Super::ReallocatePinsDuringReconstruction(OldPins); // 内部でAllocateDefaultPins()が呼ばれる

	const int32 AlreadyPinNum = Pins.Num();
	for (int i = 0; i < OldPins.Num() - AlreadyPinNum; i++)
	{
		AddUniqueConditionPin();
	}
}

// メニューアクションの登録(コンテキストメニューからノードをスポーンさせるようにする)
void UK2Node_SEAndBranch::GetMenuActions(FBlueprintActionDatabaseRegistrar & ActionRegistrar) const
{
	// actions get registered under specific object-keys; the idea is that 
	// actions might have to be updated (or deleted) if their object-key is  
	// mutated (or removed)... here we use the node's class (so if the node 
	// type disappears, then the action should go with it)
	UClass* ActionKey = GetClass();
	// to keep from needlessly instantiating a UBlueprintNodeSpawner, first   
	// check to make sure that the registrar is looking for actions of this type
	// (could be regenerating actions for a specific asset, and therefore the 
	// registrar would only accept actions corresponding to that asset)
	if (ActionRegistrar.IsOpenForRegistration(ActionKey))
	{
		UBlueprintNodeSpawner* NodeSpawner = UBlueprintNodeSpawner::Create(GetClass());
		check(NodeSpawner != nullptr);

		ActionRegistrar.AddBlueprintAction(ActionKey, NodeSpawner);
	}
}

void UK2Node_SEAndBranch::ExpandNode(FKismetCompilerContext & CompilerContext, UEdGraph * SourceGraph)
{
	Super::ExpandNode(CompilerContext, SourceGraph);

	// Conditionピンを取得
	TArray<UEdGraphPin*> ConditionPins;
	for (int32 i = 0; true; i++)
	{
		// TODO
		// 必要であればデフォルトピンの値による自明なフロー制御を行う
		// ・Trueデフォルトピンは、ConditionPinsに含めない
		// ・Falseデフォルトピンは、結果が自明(必ずElseに実行が流れる)
		UEdGraphPin* ConditionPin = FindPin(GetPinNameGivenIndex(i));
		if (!ConditionPin)
		{
			break;
		}
		ConditionPins.Add(ConditionPin);
	}

	// Rerouteノードをスポーンする
	UK2Node_Knot* RerouteNode = CompilerContext.SpawnIntermediateNode<UK2Node_Knot>(this, SourceGraph);
	RerouteNode->AllocateDefaultPins();
	UEdGraphPin* RerouteExecPin = RerouteNode->GetInputPin();

	// Branchノードをスポーンする
	TArray<UK2Node_IfThenElse*> BranchNodes;
	for (auto ConditionPin : ConditionPins)
	{
		UK2Node_IfThenElse* BranchNode = CompilerContext.SpawnIntermediateNode<UK2Node_IfThenElse>(this, SourceGraph);
		BranchNode->AllocateDefaultPins();
		BranchNode->GetElsePin()->MakeLinkTo(RerouteExecPin);
		CompilerContext.MovePinLinksToIntermediate(*ConditionPin, *BranchNode->GetConditionPin());
		BranchNodes.Add(BranchNode);
	}
	
	// Branchノード同士を接続する
	for (int32 i = 0; i < BranchNodes.Num() - 1; i++)
	{
		UEdGraphPin* PrevBranchThenPin = BranchNodes[i]->GetThenPin();
		UEdGraphPin* PostBranchExecPin = BranchNodes[i + 1]->GetExecPin();
		PrevBranchThenPin->MakeLinkTo(PostBranchExecPin);
	}

	// ピンリンクの移動
	CompilerContext.MovePinLinksToIntermediate(*GetExecPin(), *BranchNodes[0]->GetExecPin());
	CompilerContext.MovePinLinksToIntermediate(*GetThenPin(), *BranchNodes.Last()->GetThenPin());
	CompilerContext.MovePinLinksToIntermediate(*GetElsePin(), *RerouteNode->GetOutputPin());

	BreakAllNodeLinks();
}

#undef LOCTEXT_NAMESPACE

 

この記事は次のバージョンで作成されました。
Unreal Editor Version: 4.20.3-4369336+++UE4+Release-4.20
Microsoft Visual Studio Community 2017 Version 15.8.6

[UE4] VIVE PROのAR機能をUE4で動かしてみる

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

HTCから配布されているVIVE PRO SRworks SDKを使用します。

この機能を使用することで、VIVR PROのステレオフロントカメラへアクセスが可能となり、

ヘッドセットを被った状態で現実の空間を見ることができます。

 

以下からAR機能を導入することが出来ます。

VIVE PRO SRworks SDK

 

導入後、SteamVRのカメラを有効にする必要があります。

SteamVRメニューから

【設定】→【カメラ】→【カメラを有効にする】

UE4側に導入後、プラグインが有効になっているか確認しておきます。

これで準備ができましたので、【VR Preview】からプレイします。


以下、VIVEヘッドセットを被った状態で、外が見えている状態です。

周囲はぼけていますが、メッシュははっきりと見えます。

↓のようにARからVRモードに切り替えることも出来ます。

 

以下4種のポストエフェクトをかけることも出来ました。

 

 

Depth(深度):立体情報を確認することが出来ます。

 

見えている物に対してリアルタイムにメッシュを生成することが出来ます。

このメッシュ情報ですがセーブ・ロードが行え、

1度やればその場で再度同じメッシュを呼び出すことが出来ます。

わちゃわちゃ物理が気持ちいいです。

 

現実のインテリアがゲームデザインに関わる、

AR↔VRの合わせ技等、新しい表現が出来そうで遊びが広がりそうです。

是非お試し下さい!

[UE4]コリジョンの作成方法のまとめ

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

今回はコリジョンを作成した事が無い方向けにコリジョンの作成方法をまとめました

UE4でコリジョンを確認する方法ですが、
スタティックメッシュエディターでは、ビューモードをPlayerCollisionにする事でシェーディングされた状態で確認できます。

またはメニューのColisionからSimpleCollisionにチェックを入れることでワイヤーフレームで確認できます。

基本的にはFBX Importの際にOptionで、MeshのAuto GenerateCollisionにチェックを入れるとコリジョンが作成されます。
上の画像の椅子のコリジョンはインポート時に生成されたものになりますが、大まかに全体を囲った形になり、メッシュの凹んでいるところは考慮されません。

K-DOPでシンプルなコリジョンを作成。

スタティックメッシュエディターのCollisionメニューから

Add Sphere Simplified Collision 球形状のコリジョンが作成されます。
Add Cupsle Simplified Collision カプセル形状のコリジョンが作成されます。
Add Box Simplified Collision ボックス形状のコリジョンが作成されます。
Add 10DOP-XSimplified Collision X軸から投影した4 つのエッジが面取りされたボックス形状のコリジョンが作成されます。
Add 10DOP-YSimplified Collision Y軸から投影した4 つのエッジが面取りされたボックス形状のコリジョンが作成されます。
Add 10DOP-ZSimplified Collision Z軸から投影した4 つのエッジが面取りされたボックス形状のコリジョンが作成されます。
Add 18DOP Simplified Collision すべてのエッジが面取りされたボックス形状のコリジョンが作成されます。
初めに紹介したAuto GenerateCollisionにチェック入れてできた形と同じようです。
Add 26DOP Simplified Collision すべてのエッジと角で面取りされたボックス形状のコリジョンが作成されます。

※~DOPは全部元はボックスで、どこをどんだけ面取りするかの違いになります。
上に紹介したものは全てレンダリングメッシュの凹みをコリジョンでは再現できていませんが、
Add~で作成するとコリジョンをどんどん追加できるので、複製して移動、スケール、回転でも
単純な形であれば組み合わせで凹形状に対応することも可能です。

シンプルなボックスコリジョンを3つ追加してスケールと移動で作成した例

AutoConvexCollisionで凹形状に対応したコリジョンを生成。

スタティックメッシュエディターのCollisionからAutoConvexCollisionを押下します。

DetailsのConvexDecomposのApplyでコリジョンが自動生成されます。

複数の凸型形状のコリジョンが生成されるのでパラメーターをいじれば椅子の凹みにも対応できます。
ですが、正確な形の生成は難しいようです。
暫定的なものとしては使用できそうです。(プロジェクトによりますが)

Use Complex Collision As Simpleでスタティックメッシュをコリジョンとして設定。

DetailsタブのCollisionのCollision Complexityから、Use Complex Collision As Simpleを選びます。
検索すると絞り込めるので早くておすすめです。

メッシュがそのままコリジョンになっているので当然ですがとてもきれいです。
※注意点としましては負荷が高い、物理シミュレーションに対応していないなどがあるようですが、
詳しくは公式サイトをご確認ください!

DCCツールで作成したメッシュをコリジョンとして読み込む。

自由に意図した形のコリジョンを作りたい場合はDCCツールで作成したものを読み込むことが可能です。
DCCツール(maya)でコリジョンを作成する際のルールは以下になります。
レンダリング メッシュと同名にしてプレフィックスにUCX_を付ける。
複数の場合サフィックスに_01を付ける。_02 _03と続きます。
UCX_は凸型形状のコリジョンを定義する為の命名規則で他にもいくつか種類がありますが、今回は割愛します。

凸型形状にする。
画像は複数の凸形状の組み合わせで椅子のコリジョンを作成した例です。
椅子のメッシュを覆うように大まかに作成した後、凸型形状になる形にフェースを分割して、最後にできた穴をふさいで作成しています。
全てを凸型形状だけで構成する為にオブジェクトを分解すると結構な数になります。

凸型形状とは凹んでいるところが無い形、または穴などが開いていない3D形状の事です。
※以前は凹んでいたりすると自動で補完されるメッシュが生成されたり、
ポリゴンに穴が開いていると読み込まれなかったと思いますが、(個人的な記憶なので間違っていたらすみません)
最近のバージョンでは自動で凸型形状に形が変換されるので、ポリゴンに穴が開いていても読みこめたり、
窪んでるところは自動的に平らになるようです。

コリジョンメッシュのピボットの位置をメッシュのピボットと同位置にしてトランスフォームをフリーズする
試してみたところ、最新版ではフリーズしなくても読みこめたりしましたが、
念のためフリーズはしておいたほうが良いでしょう。

最後にレンダリング メッシュとコリジョンメッシュを一緒にエクスポートし、UEにインポートします。

まとめ
今回は椅子のコリジョンを簡単に作りましたが、プレイヤーが歩いたりする建物などの大きなアセットや岩などの自然物は
足との接地を考えるとかなり正確さが求められます。
アーティストが使用するのはUse Complex Collision As SimpleかDCCツールで作成する事がほとんどではないでしょうか。
DCCツールで複雑かつ正確なコリジョンを作るのはとてもしんどいので、
個人的にはAutoConvexCollisionがさらに進化して全自動になってくれればと願う今日この頃です。

 

最後におまけとしてプロパティーマトリクスで一度に複数のコリジョンの設定を変更する方法をご紹介します。
コンテンツブラウザーで複数のアセットを選択して右クリックAssetActionsのBuik Edit via Property Matrixを選択


collisionを検索して、CollisionComplesityからUse Complex Collision As Simpleを選びます。
これで全部メッシュがコリジョンになります!めっちゃ楽ちんですね!

他にも色々できるのでお試しあれ!

参考リンク
http://api.unrealengine.com/JPN/Engine/Content/Types/StaticMeshes/HowTo/SettingCollision/
http://api.unrealengine.com/JPN/Engine/Physics/Collision/HowTo/AddDOP/
http://api.unrealengine.com/JPN/Engine/Content/FBX/StaticMeshes/
http://api.unrealengine.com/JPN/Engine/Physics/SimpleVsComplex/
http://api.unrealengine.com/JPN/Engine/UI/PropertyMatrix/


[UE4]カーブアトラス(Curve Atlas)アセットを使ってみる

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

 

今回の記事では、4.20で追加されたカーブアトラスアセットについてご紹介します。

これまでもカーブアセット(http://historia.co.jp/archives/2678/)は使えましたが、マテリアルエディタにおいてカラー情報などを使用するためには、ブループリントを経由する必要があり、一手間必要でした。

新しく追加されたカーブアトラスアセットを使うと、カーブアセットで作成したカラーグラデーションを直接マテリアルエディタから参照することができるようになります。

 

カーブアトラスの設定

では、早速カーブアトラスアセットを作ってみましょう。

コンテンツブラウザを右クリックし、Miscellaneous > Curve Atlas からカーブアトラスアセットを作成します。

また、同じくMiscellaneous > Curveから後で必要になるカーブアセットも作っておきます。

カーブアセット作成時には、Curve Linear Colorを選んでください。

では、NewCurveLinearColorAtlas アセットを開きましょう。

Detail内のGradient Curvesにカーブアセットを追加できるようになっています。

ここに先程作成されたカーブカラーアセット(NewCurveBase)を指定します。

カーブを指定したあと、拡大してよく見てみるとテクスチャの上端にグラデーションが乗っているかと思います。指定したカーブアセットが上から順に並べられます。

デフォルトのTexture Size256と大きく確認しづらいので小さい値を入れました。

 

マテリアルの設定

次にカーブアトラスをマテリアルから使用してみましょう。

コンテンツブラウザからマテリアルを作成し開きます。

マテリアルエディタ内でCurveAtlasRowParameterノードを追加し、

選択したCurveAtlasRowParameterノードのDetailパネルに先程作成したCurveとCurveAtlasアセットを割り当てます。

色がわかりやすいようにEmissive Colorにつなぎました。

CurveAtlasRowParameterCurveTime入力にスカラー値を入れることで参照するCurveの値が出力されます。

デフォルトのNewCurveBase(リニアグラデーション)にサイン波を入力すると次のように変化します。

  

では、新しく別のカーブアセットも作ってみましょう。

まず、カーブアセット(Curve Linear Color)を作成したらグラデーションを作り、

カーブアトラスに追加

マテリアルのノードにも設定します。

色数の多いグラデーションも簡単に作成でき、マテリアルエディタだけでプレビューできるので便利です。

LUT用途にも使い勝手がいいかなと思います。

 

また、マテリアルインスタンスを作成するとCurveAtlasRowParameterCurveアセットを上書きできます。

バリエーションも増やしやすいです。

グラデーションが必要なときカーブアトラスを使えば、わざわざテクスチャを画像編集ソフトで用意しなくてもUE4エディタだけで対応できそうですね。色の調整も簡単にできるので効率的です。

 

 

設立5周年を迎えました&第六期に突入しました

$
0
0

2018年10月31日に株式会社ヒストリアは設立5周年を迎えました。また、9月末に第五期を終え、10月から第六期に突入しました。

この一年では、PS4パッケージソフトの「Caligula Overdose/カリギュラ オーバードーズ」、VR ZONE SHINJUKU/OSAKAで稼働中の「冒険川下りVR ラピッドリバー」をはじめ、数々のタイトルをリリース出来ました。コンソールパッケージソフトを1本丸々請け負ってリリース出来たことは、感慨深いものがあります。また、四苦八苦しながらではありますが複数ラインを維持できていることを嬉しく思います。

イベント/コミュニティー面でも、”UE4ぷちコン”、”出張ヒストリア!ゲーム開発勉強会2018″、”Unreal Fest”(展示・講演)、”ヒストリア中学生職業体験会2017″、をはじめとした数々のイベントを行うことが出来ました。

このように良い1年を過ごせたのも、そして5周年を達成できたのも、取引先の皆様、そしてコミュニティの皆様のおかげです。いつも気にかけて頂き、大変ありがとうございます。そして5年やってきて思うことは、”企業は人なり”とは本当にその通りでして、日々会社を支えてくれているヒストリアメンバーにもこの場を借りて、感謝を伝えさせてください。

5年というのは、ベンチャー企業にとって生き残れるかのひとつの壁と言われています。私が感じたところでは、1年はビジネスに慣れることが出来るかの壁、3年はビジネスが回るかどうかの壁、5年は組織を作れるかの壁、があったように思います。(まだその壁を超えられたかというと、道半ばですが) 10年の壁には何が待っているのか分かりませんが、次は世の中の変化に組織が対応できるか?の壁があるような気がしています。流れの早いゲーム業界のことなので、5年後にはまたいつものように全く違う景色が広がっていることでしょう。だからこそ面白い業界でもあります。その時にも、面白いことが出来ている組織で居られるよう、精進して参ります。

また新たに10年に向けての歩みが始まったわけですが、先を見据えつつもまずは第六期。社員一同力を合わせて良い作品をお届けできるよう力を尽くして参りますので、どうぞよろしくお願いいたします。

株式会社ヒストリア
代表取締役 佐々木 瞬

[UE4] 建築シーンでエリアライトを使ってみました。

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

 

今回は4.20で新しく追加されたエリアライトについて、
サンプルのインテリアシーンを使ってご紹介させていただきます。

エリアライトについて
UE4.19までは、下の画像のように擬似的な方法でエリアライトを表現するしかありませんでした。

UE4.20からエリアライト用の新しいライト『Rect Light』が追加されました。

使用上の注意(Unreal Engine 4の2018年上半期アップデート情報まとめp93~101より)
・Forward Renderingには未対応
・Spot LightやPoint Lightに比べて処理不可が高い
・動的な影の精度が少し甘い

詳細については公式ドキュメントをお読みください。

下の画像のサンプルシーン(Realistic Rendering)を使って、試してみました。


※デフォルトのシーン

元々ある窓の外からのSpot Lightは削除した下のシーンにRect Lightを配置します。

modes>LightからRect Lightをシーンに追加します。
X軸の正方向のみに光を放射するようです。

設定は一旦ですが、下の画像のようにしました。

配置したのが下記の画像です。

ホワイトバランスなどを調整して、デフォルトに近づけてみました。

色味や明るさの調整は必要ですが、外光に使用するのに便利かなと思います。

建築シーンですと、天井などの間接照明やTVの明かりなどにも使えるかと思います。
下の画像は試しに間接照明を試した画像です。

今まで表現が難しかったですが、簡単に反映することができました。
他にも使い方はありそうなので、試していければと思います。

 

 

[UE4] UE 4.21 で新規追加!Sun Position Calculator Plugin について

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

今回は、Sun Position Calculator Plugin について紹介します。

Sun Position Calculator Plugin は UE 4.21 から追加されたプラグインで、その名のとおり太陽の位置を計算するためのものです。

※ 本プラグインは Early Access 扱いです。今後仕様が変更される可能性がありますのでご注意ください。

関数 GetSunPosition について

このプラグインを有効にすることで利用できるようになる関数は GetSunPosition ただ一つなので、この関数について解説していきます。

GetSunPosition は、太陽を観測する位置と時間を与えることで、太陽の高度と方位などを返す関数です。

入力の Latitude は緯度、Longitude は経度のことです。また、夏時間で日時情報を与える場合は、IsDaylightSavingTime を true を設定してください。

返却される FSunPositionData の要素である Elevation は太陽の高度のことで、単位は度 (Degree) です。一般的に高度といえば仰角で表現されるものだと思われますが、Elevation には仰角に 180 を足した値が格納されるので注意してください。恐らく 180 を足した方が UE4 上で扱うのに都合が良いからだと思われます。

Elevation は『実際の』太陽の高度を表しています。しかし、地球の大気によって光が屈折する関係上、地球上から太陽を見ると、実際よりも少し高い位置にあるように見えることがあります (太陽の位置が地平線に近いほど、この屈折は大きくなります)。この『見かけの』太陽の高度を表すのが Corrected Elevation です。

Azimuth は太陽の方位で、こちらも単位は度 (Degree) です。北を 0° として、そこから東方向への回転で増加する値となります。

FSunPositionData には時間情報も含まれています。SunriseTime、SunsetTime、SolarNoon はそれぞれ日の出、日の入り、南中 (太陽が真南に来るとき) のローカル時刻です。

BP_SkySphere を利用して太陽の位置を確認する

UE4 の Default Map には、”Sky Sphere” という名前の BP_SkySphere が配置されています。BP_SkySphere には、DirectionalLightActor に設定した DirectionalLight の向きに応じて、太陽の描画や空の色の変更を行う機能があります。

つまり、GetSunPosition から得られた太陽の高度・方位の情報を元に、”Sky Sphere” の DirectionalLightActor に設定されている “Light Source” の向きを適切に変更することで、特定の位置・時間における太陽の位置を確認することができます。

例えば、Level Blueprint に以下のようなノードを組むと、2018 年 11 月 1 日の 午後 3 時に日本から観測できる太陽の位置を確認できます。なお、”Light Source” の Mobility は Movable にする必要があります。

『どのように見えるか』を確認したいので、Elevation ではなく Correct Elevation の値を利用しています。

(Correct) Elevation に 仰角 + 180° の値が入っているおかげで、(Correct) Elevation を Pitch、Azimuth を Yaw とする Rotator で DirectionalLight を回転させるだけの簡単な処理で実現できています。

実行してみると、南西に日が落ち始めている様子が確認できます。

Tick で時間を更新し続ければ、動きの確認もできます。

日照シミュレーションに活用できそうな機能です。簡単に扱えますので是非お試しください。

弊社が監修・制作協力を行った「映像屋さんのためのリアルタイムBG制作マニュアル」が無料公開されました!

$
0
0

代表の佐々木です。

弊社と株式会社ポリゴン・ピクチュアズの合弁会社である株式会社エレメントファクトリーが、「映像屋さんのためのリアルタイムBG制作マニュアル」を無料公開しました! 本マニュアルは普段プリレンダーを主に扱っているCGアーティストに向けた、リアルタイムレンダリング用BGアセット制作のマニュアルです。弊社は企画立ち上げから関り、監修・制作協力を行いました。

ヒストリアではいままで10を超えるCGスタジオに対して、技術サポート(コンサルティング業務)を行ってまいりました。プリレンダーとリアルタイムではレンダリングに使用する技術が異なり、アセット制作の作法や考え方が大きく異なります。技術サポートを通じて、みなさんが初期につまづきやすい場所がほぼ同じだということを感じていました。せっかくリアルタイムに興味を持っていただいている昨今、その入り口でつまづかないよう、ぜひその知識をまとめて布教したいという想いがありました。

今年1月にポリゴン・ピクチュアズ様と合同で設立したエレメントファクトリーは、まさにその想いを実現する場でした。私も参画しているエレメントファクトリー指揮の元、ポリゴン・ピクチュアズ様(アセット、マニュアル執筆はほぼポリゴン・ピクチュアズ様が行ってます!)とその第一歩として、BGマニュアルを配布させていただきます。本当に入り口の最初の部分ではありますが、お役に立てれば幸いです。今後もこのような情報発信を行ってまいりますので、お使いいただけた際にはぜひご意見を頂ければと!(マニュアルのキャラは気にしないでください……)

DLはこちらから!
https://www.element-factory.co.jp/

Viewing all 997 articles
Browse latest View live