てんちょーの技術日誌

自分がつまづいたこととかメモ

【UE4】Switchの作り方にこだわってみたくなった話【小ネタ】

今年に入ってまだ全然ブログ更新出来てないので書いてみた。

最近BPのリファクタリング?的な感じでどう組むのが一番いいのか 考える余裕が出来てきて、「あれすれば出来るけど、もっといい方法ないかな」 みたいなことがGGJ中にも思ったりしてて、今回の件に至りました。

そんな堅苦しい感じじゃなく ぼくのかんがえたさいきょうのすいっち みたいな感じです

作りたいスイッチ

押したら終わりではなくて、押して数秒後に元に戻るスイッチを前提に考えて います。UE4本でもありましたね。(P262くらいからのお話)

基本Switchに追加したBoxCollisionをTriggerにしてLerpノードで沈ませてDelayして元に戻すみたいな実装だと思います。 (他にあるなら知りたい)

で、今回やりたかったのはこれ

でできたのがこちらです

実際のActor

f:id:shop_0761:20160215212948p:plain

BP全体図

f:id:shop_0761:20160215212426p:plain

中身

では左側から

f:id:shop_0761:20160215212500p:plain

複数ヒットを避けるためにDoOnceしてます。一巡したらResetするようにしてます。 イベントディスパッチャで拾えるようにしたりしてます。

右側は

f:id:shop_0761:20160215212706p:plain

Switchって変数はStaticMeshで用意した実際に押したら引っ込むところです。 今回の肝はGetUpVectorとTimeLineノードのDirectionピンです。 DirectionピンはTimelineノードが順再生なのか逆再生を取れるピンです。便利。

ここで何してるかというと、GetUpVectorで取った向きにDirectionで取ったTimeLineノードの向きから 押すのか戻すのかを取った後、SwitchMoveOffsetで移動する距離を準備して元のSwitchのLocationに加算したものをLerpかけてます。(すごい呪文みたいになった

これ、さっきのTweetのように一時変数を用意すればこんなことする必要もなくTimeLineノードを逆再生すれば済む話なんです。けど用意するのはなんか嫌だし、出番がそこしか無いのに使うのは美しくない!!そう思ったわけです。

そこでDirectionピンから加算するVectorの符号を変えることで成し遂げました。

であとはDirectionピンからswitchしてSwitchTurnOffTime分だけDelayをかけて逆再生した後にイベントディスパッチャ呼んで終わりみたいな流れです。

実際に動いてるのはこんな感じ

足元にスイッチ、奥には同じように実装したブロックです。 よくよくみるとちゃんとスイッチが浮き沈みしてます!

おわりに

なにかとよくあるSwitchを皆さんどんな風に実装してるか興味あるので どしどし教えて下さい!(勉強したい

今回はまだ腑に落ちない点はSwitchMoveOffsetで手動でボタンの凹み具合を調整しなきゃならないところなので思いついたら更新します。 多分スケールとかから取ったりしたらよさそう。

現状 ぼくのかんがえたさいきょうのすいっち でした。

【UE4】GGJ2016 Sapporoに初参加してきた

今年最初はGGJに参加してきたのでそれについて少し

GGJとは

Global Game Jam といって世界各地で48時間以内にゲームを作るイベントです。

公式はこちら

Home | Global Game Jam®

そして札幌は2会場ありまして、定山渓会場と、札幌会場の2つです。

札幌会場はこちらで

www.iga.ac.jp

定山渓会場は端的に言えば温泉です。

ぼくは札幌会場のほうに参加したので終始温泉に入っているとか、ポトフ食べてるとか、二度寝してるみたいな情報ばかり入ってきてうらやましかったです。

作ったもの

こちらからダウンロードできます。DK2が必要です。

Straight Sheep | Global Game Jam®

実行には一手間必要でコマンドプロンプトから起動しなきゃいけないです コマンドは

$ Path\to\StraySheep.exe ?Listen -vr && Path\to\StraySheep.exe 127.0.0.1

でPathには自分で保存したとこのディレクトリを指定してやる必要があります。 やり方が分からなければ @shop_0761 まで聞いてください

(余裕があったら対処法考えます)

実績は5つ解除してます!!

今回はHMDをかぶってる人だけでなく、かぶってない人も楽しめるゲームを作ろうということでマルチプレイ出来るようにしました。

実際のプレイしてるやつはこれ

VRの人はマップ上の通路からの視点、外の人はマップを横から見た視点になってます。

これは説明用にVR側のウィンドウとかぶってない人側のウィンドウを出してますが、VRのほうは隠すことができます。 なので実際にやってもらう時はVRの方を隠してプレイするのがいいと思います。

基本的には2人プレイです。1人はVR、もう1人はコントローラを持ってマップ上の仕掛けを操作します。 VR側の人はなされるがまま前進しかできません。なのでマップ上にある仕掛け(落とし穴とエレベータ)が どこにあるか、エレベータは上に行くのか下に行くのか(中にエレベータの移動先を示す矢印がある)、 など見えている情報をパートナーに伝える必要があります。 それを受けてコントローラで落とし穴を開けたり、エレベータの方向を変えたりして誘導していく、といったゲームです。

ファミコンマッピー的な感じですね。

マッピー - Wikipedia

発表時のスライドは まえはなさん(@sandinist)に作っていただきました。

www.slideshare.net

そのうちプレイ動画を撮って公開するつもりです。

作ってたときのお話

バージョン管理

今回はbacklog + SVNで管理してました。特に大きな問題もなく作業できました。ただ回線が…ってくらいです。

最後の最後でこんなことも

役割分担

ぼくはひたす色んなBPを量産してました。落とし穴とかエレベータとかPlayerとかレベルBPとかいろいろやりました。

まえはなさんはひたすらネットワーク回りを調べてその辺をBPで実装していただきました。 (なのでその辺は謎技術で動いてるように思えますw)

こむろさん(@com4dc)は最初Androidと連携する予定だったので調査してもらってたんですが、間に合わなさそうなので いろいろなActorを作ってもらったりmadness worldを作ったりしていただきました。

みくP(@0039P)さんとこだいら(@raidako3D)さんはモデリングとかレベルデザイン周りを作っていただきました。

あと今回は音周りができる方がおらず、急遽ぼくの友達(見学)がSEやらBGMを探してくれましたw

あのレベルデザインの完成度は正直びびりました… (ぼくがぷちコンで作ったやつはInfinity Bladeのアセットの暴力で解決したので)

それと途中で 俺ばっかり簡単なActorを作ったりしてていいんだろうか… 楽してる気がする… と思ってましたw

でも結果的にはいい感じで進んでたし、ある程度簡単なものなら一人でどんどん量産していったほうが形になりやすいとは思いました。 まあTimeLineノードが思うように動かなくて苦しめられてましたがw

madness worldとは

こむろさんがBPでいろいろActorを作っていた時にできた偶然の産物的なもので構成された世界です。

動画はこちら

www.youtube.com

ここがはじまりっぽい

ほんとは回転していくのをEventTickで作ろうとしたみたいなんですが、途中の計算がおかしいせいで、徐々に微振動し始めて どんどん加速していく 死んだ魚のような動きをするものが出来上がってしまいました。

そのBPはこれ

f:id:shop_0761:20160202005053p:plain

このTickからのdeltaSecを加算してるせいで振り切ってしまってるっぽいです。

その他謎のActorがたくさん爆誕したのでシュール極まりない世界です。Githubに公開したそうです。

github.com

VRを想定してないのでこんな方も

-変態デバイスチーム-

同じ部屋で作業していた変態デバイスチーム。

発表時には筋肉を使ってスライドを動かしてました。

そんな彼ら(特にmao @TEST_H_さん)の変態ぶりを他の方のTweetから拝借して見てみましょう。(迷惑だったら言ってください 消します)

などなど

他の作品

他にも個性(狂気)的な作品が多かったです。一覧はここから見れます。

札幌

Sapporo Games | Global Game Jam®

定山渓

Global Game Jam 2016 Sapporo Jozankei Games | Global Game Jam®

2/2現在で個人的に面白いなと思ったものを紹介しておきます。

Team without a programmerのリリーさんゲーム

これのコンセプトは「プレイした人をいかに不快な気持ちにさせるか」だそうです。その発想面白いなと思ったので書いておきます。

Team without a programmer | Global Game Jam®

Team without a programmerのふぇるくんげーむ

これはパズルっぽさのある横スクロールアクションです。一度時を止めて、プレイヤーが加速できるオブジェクトを配置して高い壁とかを越えていく みたいな感じです。(上手く説明できないけど仕組みは面白い)

Team without a programmer | Global Game Jam®

Kimotic Procedure

ここはデザイナーさんが作りたいものを作って、それをプログラマーさんが作りたいものを作るという新しいゲームジャムをしてました。 そのおかげでサイケデリックでクレイジーなゲームになってます。(しかもフレームワークやライブラリから自作したとかなんとか

KIMOTIC procedure | Global Game Jam®

spa ; hotspring ; onsen (定山渓)

プログラマ不在のチームでHTMLで書いた昔懐かしい感じのクリックで進むゲームです。デザイナーさん二人の絵柄をなるべくなくすためにグレースケールで描いてるとか

spa ; hotspring ; onsen | Global Game Jam®

まとめ

開発環境としては回線に終始苦しめられた感はありますが楽しかったです。いやーこだいらさんのレベルデザインがすごかった…

他のチームの様子を見に行く余裕は無かったけど、うちのチームは徹夜してない健全なチームです!! 徹夜しなくてもゲームは作れます!!

温泉入っててもゲームは作れます! 興味があれば参加してみるといいと思います。

チームの皆さん、運営のみなさんありがとうございました。

【UE4】GearVRのタッチパッドの入力を取ってみた

探しても思ったより見つからないので、とりあえずメモ的に書いておきます。

今回はこちらを参考にしました。

Why does the touchpad on Gear VR fire multiple release events? - UE4 AnswerHub

UE4.11 previewです。

実装

といってもInputTouchノードで戻る以外は全て取れそうです。

で試しにこんな感じでやってみると、それなりにいい感じなのかなとは思いました。

f:id:shop_0761:20151229170137p:plain

普通にpressedはタッチ開始時に一度だけ、releasedはタッチ終了後に一度だけ実行されます。(そりゃそうだ)

Movedは座標が変わる度に取ってるような気がするので、setTimerで少し間引いてから座標を取って、指が前に行ったのか後ろに行ったのかみたいなことをしてます。

戻るボタンについてはUnityの方ではEscキーだったり、最初に貼ったリンクではAndroid backで取れそうな感じなんですが UE4.11 previewではどちらの方法でも反応しませんでした…

ちなみに試したボタンはこちら

f:id:shop_0761:20151229171317p:plain

Androidのinput系とescとかbackspaceとかありそうなのをやってみたのですが、ダメでした。 何かご存知の方お教えいただけると幸いです。

2016/1/2 追記 なんか試してた環境が良くなかったらしく上手くいったのでメモを

普通に入力全てとれました。

  • Android Back -> 戻る
  • Android Menu -> 戻る長押し
  • Android VolumeUp -> ボリュームボタン上
  • Android VolumeDown -> ボリュームボタン下

でいけます。(たまたま別のテストをしてる時に上手く行った

上手く取れなかった原因は分かりませんがとりあえず入力取れればおっけーですよね!!

【UE4】GearVRで20fpsから60fpsを目指してやったこと

発売日にGearVRが届きました!

やばい…楽しい…ナニコレお手軽… と初日から楽しんでました。

で、どうせなら何か作ろう そう思って色々考えてはプロトタイプを作ってはいましたがいろいろトラブってたので一旦投げました。

そこで何ならぷちコンで作ったやつを試しに60fps目指して改良しよう!と思いついたのでやったお話です。

注)以下は個人的な意見なのであってるかどうかは分かりません。参考程度にしてください。

ゲームはこちら。マグマのところのステージを対象にやってみました。

shop-0761.hatenablog.com

また途中結果がtwitterにしかないので細かいところはご愛嬌ください。

結果

使っているもの

  • Infinity BladeのAsset
  • 中野シスターズ ver1.2

です。

何もしてない状態

でした。

やったこと

まずは背景用にもりもり突っ込んだメッシュをゴリゴリ消しました。

Before

f:id:shop_0761:20151220130242p:plain

After

f:id:shop_0761:20151220130328p:plain

そりゃ軽くなるよ!!こんだけ消したんだもの!!

それからこのあたりを参考にゴリゴリ削ります。

pafuhana1213.hatenablog.com

qiita.com

docs.unrealengine.com

定番のLightをstaticにしたり、色々staticにしました。Collisionなんかもstaticになるんですね(知らなかった

幸か不幸かPostprocessには手が回ってなかったのでVolume自体なかった…

またFogは残してあります。なんか雰囲気ほしかった。(もちろんstaticで

f:id:shop_0761:20151220133225p:plain

staticMeshのシャドウも消してます。 LightMapはもう思い切って削りまくりました。

けど、エディタの詳細から設定できるシャドウの方は一部有効にしてます。(でないと真っ黒になった

それとこちらのMaterialの設定はMobileでは有用そうです。

[編集中]24時間でUnreal Engine4で #GearVR コンテンツを作る方法#vrfes2015spring | Develog.VR

ここのMobile設定のことです。ついでにスペキュラ使ってるマテリアルあったので切りました。(なぜ使っていた…

f:id:shop_0761:20151220131631p:plain

そしてこの件

一応こちらに載ってはいるのですがUE4公式ドキュメントではETC2になってます。(どっちがいいかは分かりません

developer.oculus.com

今回はなんとなくASTCでやってます。

これの存在も頭にいれつついきます。(いつも勝手にお世話になってます

このくらいやった時に問題になったのがこれ

このprofileGPUって項目名でそのまま調べてもいまいち出てこないんですよね…

なのでそのままの意味で解釈するしかないと 思い至ったわけです。

半透明なフィルタのVolume… これBlockingVolumeでは!? と思って削ったら

この時のBlockingVolume

f:id:shop_0761:20151220134736p:plain

f:id:shop_0761:20151220134800p:plain

この棒状Volumeでもちゃんと機能します。そしてコスト削減できる! やったね!!(ジャンプさせたりするなら2本にするとか

とにかく必要ない部分もVolumeとして存在するので棒状にしてみました。

ついでにPainCousingVolumeも使ってたのですが、消し去ってkillZに乗り換えました。(この時点でBlockingVolumeの出番はなくなった

減った減ったー…と思ってもまだ残存勢力がいる模様。もうさすがに無いだろ…と思ってた矢先に

これCollisionも計算されてるかも!?

と思い、すでについていたstaticMeshのCollisionや、不要なCollisionもバリバリ消しました。 今となっては確かに計算しなきゃならないからコストかかるじゃん…ってなりました はい。

そして、Triggerとして使用していたCollisionも1cm四方の立方体に圧縮しました。

でこれ

あと一歩って感じですよね。

ChalacterのCollisionも削ればひょっとして…と思いやってみた。

f:id:shop_0761:20151220140139p:plain

足元だけにしました。

他にもこんなロボットと戦う場面があります。手のところにつけてたCollisionをダメージ判定に使ってたのですが、 AnimBPのイベントディスパッチャーで発火された時にもうダメージを与えるようにしました。(確認はしてない

f:id:shop_0761:20151220141525p:plain

すると安定気味になりましたとさ。

まとめ

意外な盲点としてこのVolume周りがあるのではと思った。他の方の記事をみるとあまりこの項目が出てないのでなんでだろ…と思ってましたが、 なんとか60付近になってよかったです。

なによりInfinity BladeのAssetの出来の良さのおかげで素材そのものをゴリゴリいじらなくてもいけたのが大きいです。

ただ、まだHMDでのカメラ周りのBPとか設定がよく分かってないので思うように動かせてませんw

とりあえずこの後は歩き回れるようにしようと思います。

追記

いろいろ変更したりビルドした後に保存しないと反映されないと思うので、こまめに「すべてを保存」をしてました。

今回あまりコマンドを使ってません。 これだけ

f:id:shop_0761:20160122221256p:plain

こういう方法もあるよくらいに思ってください。(コマンドを知らなかっただけ    GPUビジュアライザーで見た時にどの項目に対してどのコマンドを使ったらいいかは こりんさん(@k0rin) のサイトが参考になると思います。

framesynthesis.jp

【UE4】OculusAudioSDKを使う【小ネタ】

ちょいと無駄なことをしてしまったのでメモ

OculusAudioSDKとは

2015/12/10に正式版がリリースされました。 ダウンロードはこちら。

developer.oculus.com

UnityやらWwiseプラグインが入ってます。

UE4で使う

UE4ならすでにプラグインが公式であります。こちらを使えばおっけーとのことです。

設定->Plugins->Audio の中にあるOculus Audio SDKです。

おかずさんに教えて頂きました。(ありがとうございます!

2015 12 27追記 ちなみにその設定は各Cueの詳細にありました

f:id:shop_0761:20151227012718p:plain

OculusAudioPack1とは

最近話題になったつよいサンプルデータです。(他のフリーの音源提供サイトを潰しにかかってるとか言われてたような…

developer.oculus.com

UE4で使う場合はこれをダウンロードしてインポートするだけかと(まだやってない

2015 12 27追記

やりました ちょいと注意事項を

AudioPackのファイル名が丁寧なため、ファイルパスが長くなってしまいます。 なので、ファイルを置く階層に注意しないとパッケージングの時に怒られます。(怒られた人

moguraVRさんの記事も貼っておきます。

www.moguravr.com

いい音はいい体験を生むのでバッシバシ使っていきましょう!!

【UE4】カノ神拳【AdventCalendar13日目】

AdventCalendar13日目です。

qiita.com

カノ神拳とは

前の記事を書いてる時に発見したこのあたり

それとこの前ぼけーっと眺めてたAnswerHabのこの質問が鍵になった気がします。

モデルの四肢切断について - UE4 AnswerHub

なんて物騒な…と思ったけどこれ北斗の拳っぽいことできるんじゃねっと思って作ったのがこちら。

youtu.be

アフレコ募集中です(カノちゃんのボイス改造していれたけどしっくりこなかった

ポイント

肝となる部分はこのTransform(Modify)Boneノードだけです。

f:id:shop_0761:20151207002335p:plain

これAnimBPのAnimGraphで使うノードで、設定できるものはこちら。

f:id:shop_0761:20151207002417p:plain

単純に言えば、弄りたいBoneを選択して、各プロパティの○○Mode ->Replace Existingにすれば入力ピンで設定したものが反映されます。

あとはこんな感じで使ってあげてください。(不要なピンは消せます)

f:id:shop_0761:20151207003516p:plain

以上です!!簡単!!

実装したこと

ここからは以下に北斗の拳っぽく見えるか調整したり、さっきのノードをどうやって使ってるかを書いておきます。(余談です

今回は後々のことも考えて色々拡張できるように考えた(つもり)です。 (Scaleのことしか考えてなかったけど

まず主要になりそうなボーン19個を全てさっきと同じようにつくりました。

f:id:shop_0761:20151207003719p:plain

で、これらの変数をセットする関数がこちら。

f:id:shop_0761:20151207003901p:plain

芸術はスパゲッティだ!!

今回はこれ以上ボーンが増えないだろうと高をくくって作ってます。なのでこれもありっちゃありかなと思いました。

で、説明する前に用意した変数について説明しておきます。

ThirdPersonCharacter内部

  • DesiredScales(Vector配列) 目標のScale値を格納しておきます。
  • TargetBoneNumber(Int配列) Boneに擬似的に番号を振ってます。これでSwitchしたいからです。なのでHeadScale_14とかって変数名にしてます。14がこのBone番号です。
  • Scales(Vector配列) これがAnimBPに参照される空の配列。DesiredScalesのLengthに応じて初期化して使います。

上2つはPublicにしてあります。で、手入力です。(連想配列的な機能が欲しかった… 手入力なのでエラー対策頑張りました。それは後ほど。

で先ほどのスパゲッティを拡大すると

f:id:shop_0761:20151207004644p:plain

普通です。

そしてThirdPersonCharacterの中身へ

とりあえずの全景

f:id:shop_0761:20151207005046p:plain

右側のふつくしい感じのところはSequenceでそれぞれ5種類のボーンに対して各々Timeline+マクロで処理してます。 Timelineを使ってるのは北斗の拳って、なんか腕とか頭とか微妙なラグがあって各部位が膨れ上がる印象だったので別々にしたほうがいいかなって思ったからです。

大事なのはそのマクロの方ですね。

f:id:shop_0761:20151207005311p:plain

引数のAlphaはTimelineノードから、Indexは手入力です!! なので適切かどうか一応検知できるようにしてます。(Javaっぽいエラーメッセージにしてみた。

なんでマクロにしたかっていうと早速これで見たローカル変数のやつ取り入れたかったからです。

unrealengine.hatenablog.com

結果的に言えば出来ませんでした(多分できそう というよりこの設計がそもそもアウトな気もする

個人的な見解としては今回のマクロの仕様上、Timelineノードでそれぞれのalpha値とボーン固有のindexが絡んできてるせいでローカル変数使っても…って感じになりました。 (同じマクロ使い回しがalpha値のせいでできない)

ただいい勉強になったので、ぜひ使っていきたいところです。

あとはめげずにいい感じにアニメーションを組み合わせたり、アニメーションモンタージュのセクション名で分岐したりしてます。

多分今回BPで一番気を回したエラー処理をば

f:id:shop_0761:20151207010431p:plain

大きく分けて3つです。

f:id:shop_0761:20151207010522p:plain

最初Scalesも手動で設定するようにしてたのでさすがにまずいと思って初期化

f:id:shop_0761:20151207010637p:plain

手入力なので起こりうるミスのひとつかなと思ったもの

f:id:shop_0761:20151207010750p:plain

これが地味いい仕事します。というのもVector変数を作ると初期値(0,0,0)なのでうっかりしてるとエディタが落ちます。(2回くらい落ちた

Scaleを0にしようとすると死ぬっぽいので作りました。 コメントの英語はやっつけで書いたので文法的にあってるか分かりません。

ForEachLoopWithBreakにしてるのは始めは0を含む時点でBreakしようと思ったんですが、いくつか0があるときにそれとなく個数が分かったほうがいいなと思って直した時の なごりです。意味はありません。

このノード使ってる時に思ったことは不正な処理をした時にBreakする意味でBreak使いたい時に、

  • 問題なく全てのノード実行 (completed)
  • breakしちゃった (broke)

の検出できたらいいなとは思いました。今回はリベンジと言わんばかりにLocal変数でやりました。

おまけ

mixamoで片っ端からモーションをダウンロードしてきたのですが、その中にあった一風変わったモーションを紹介します。 やり方はこちら。

shop-0761.hatenablog.com

1つ目

最初見た時なんだかわからなかったんですけど、これbeing_carriedってモーションで誘拐されてるように見えるのは俺だけ? こんなのどこで使うんだろ…

2つ目

convulsingです。痙攣です。こわいこわい…

3つ目

administering_cprとreceiving_cprです。CPRとは

心肺蘇生法(しんぱいそせいほう、CardioPulmonary Resuscitation; CPR)は、呼吸が止まり、心臓も動いていないと見られる人の救命へのチャンスを維持するために行う循環の補助方法である。 心臓マッサージを主に行い、熟練者は呼吸の補助方法である人工呼吸も行う。 Wikipedia

だそうです。なんと限定的な…

こんな感じで特殊なモーションが眠ってます。もちろん普通のモーションもあります。歩いたり走ったりとか。 なので興味があれば見に行ってみるといいと思います。

そしてここで言っておきたいのが、

全部無表情なんですよ!!

自分でモーフターゲットを仕込もうと思ってまずは まばたき だ!とやってみると上まぶただけがびろ~んって伸びた感じにしかならず辛かったです。 もう少し勉強すればいけるかもしれませんが、本家に作って欲しいわけですよ。

なのでメールしました。 すると

とのこと。楽しみです。頑張って欲しいです。(僕はシモダさんも入れて欲しいと言ってたの聞きましたよ

2015/12/13/10:48 追記 らりほまさんのご指摘によりモーフターゲット発見しました。すいません。(単にImport時にチェック入れてなかっただけ

ただ現状なぜかカノちゃんだけモーフターゲットの頂点数が異様に少ないので調査中です。

2015/12/13/16:41 追記 らりほまさんに教えていただいた方法がこちらです。参考にしてください。

2015/12/13/19:21 追記 何故か自分の環境では上手く行かなかったので、らりほまさんのコメントを参考にお試しください。

こんな感じになるかと思います。

f:id:shop_0761:20151213192304p:plain

まとめ

明日はEpicのシモダさんの"UE4のデバッグ機能いろいろ紹介するよ!マスターしてバリバリ開発しよう!"です。

僕はこの件楽しみにしてますよシモダさん…

2015/12/23 追記 書いていただきました! ぜひこちらも qiita.com

【UE4】鷺宮流結界術入門【AdventCalendar11日目_後編】

UE4のAdventCalendar11日目です。前編の続きです。

UE4.10で行ってます。

qiita.com

結界術とは

僕は少し前にサンデーで連載していた結界師という漫画が大好きです。あの結界術大好きです。(一時期ゴールデンで放送してました) 知らない方はアニメのOPのリンク貼っておくので見てみるとこれからやることのイメージ湧くと思います。

www.youtube.com

見るのが面倒な方へ簡単に説明すると、結界術とは妖を退治するときに使う異能の力のことです。動画で言う青色/緑色の透明な箱を出して、粉砕するやつ。

これ基本的に腕を下から上に振り上げたりするような動作が主なので、Leapと相性良さそうだと思いました。

実装したいこと

忘れそうなのでメモ程度に残すのでスルーしてください

  • 敵の位置に透明な箱を出す サイズは敵が入るくらいの大きさ 出来れば足元に四角->立方体の順 この時手から線のようなエフェクト
  • 敵と箱ごと小さく圧縮してある程度小さくなったら粉砕パーティクル
  • 余裕があれば足場にできるようにしたい
  • leapで方位、定礎、結、滅、解
  • 敵は視線からのライントレースで位置把握

鷺宮流結界術

原作通りには行かないので鷺宮流ということにしてますw

まず、術の発動手順として、

  • 方囲(ほうい) 標的指定
  • 定礎(じょうそ) 位置指定
  • 結(けつ) 成形・発動
  • 滅(めつ)/解(かい) 滅却/解除

とそれぞれ発声しながら、右腕の動きと共に行ってます。 手元の公式ガイドブックにあったイメージ図も載せます。

f:id:shop_0761:20151202235811j:plain

細かい詳細設定を挟むとややこしくなるので、今回はこの"結"をメインに考えていきます。

実装方針としては

  1. 方囲と定礎はなかなか大変なので今回はまとめて処理
  2. 結で生成される箱は半透明。けど処理が重そうなので半透明に見えるように。
  3. 滅の時は盛大に爆散してほしい。(解は実装しない。)

と大きく3つに分けてみました。

またLeapの操作も簡単にしたいので、

  • 手を下から上に振り上げる
  • 手を右から左へ払う

の2種類で構成しました。

出来た動画はこちらから

youtu.be

こんなこともできます

f:id:shop_0761:20151205113315p:plain

方囲と定礎の実装

これはLineTraceを使いました。Actorの右手から射出してます。 LineTraceするz座標を無理やり一致させてます。さらに無理やり-1000倍してます。これで正面になおりましたw

f:id:shop_0761:20151202233436p:plain

次に問題になるのが、当たったActorをどうやって箱に入れるかです。 こうなってほしいわけです。

f:id:shop_0761:20151202234135p:plain

動画からスクショしました。

つまりは、LineTraceで衝突したActorに応じて、サイズを変えた箱を生成して、その中に衝突したActorを入れなければなりません。

ここで

Actorを箱に入れるのではなくて、箱を生成してそこにActorを入れよう!!

と思いついたのでやってみた。

ClearBoxBPとして作ります。 外部からこのCreateイベントを発行することで箱を生成します。

f:id:shop_0761:20151203010235p:plain

引数にSkeletalMeshを指定してます。それで差し替えに対応してます。

次にCubeのLocationを設定します。Cubeはただの立方体でサイズが1辺200cmです。これはPivotを下にずらしたかったのでBlenderの起動時に出るあの箱を持ってきてます。

f:id:shop_0761:20151203004753p:plain

Offsetを用いることで箱内部に余裕を持たせます。

残った箱のScaleですが、Cubeのもとのサイズ200cmから倍率を求めてます。ActorSizeはPublicにして外から変えられるようにしてます。 今回はMannequinしか使ってないので初期値(144, 37, 187)に設定して、そのまま使ってます。 またActorSizeのyが小さいためにscaleも小さくなりすぎるのでx,y同じ値を使ってます。(原作も正方形の面があるはず

f:id:shop_0761:20151204195319p:plain 続きです。 さっき使ったScaleのz値をMAXとしてTimelineで処理してます。で、手頃なところでSE鳴らしたかったのでこんな形になりました。

で、このイベントを発行するのはActor側(カノちゃん)でやります。

f:id:shop_0761:20151204204904p:plain

さっきのLinetraceの後です。 全部説明すると長くなりそうなので肝になるところだけ。 どうやってActorを識別するかというと、この方法を使ってます。

pafuhana1213.hatenablog.com

Actorのphysics matでSkeletalMeshを判別します。それをselectノードで分岐させてます。これなら後々拡張できそうです。

あとはskeletalMeshを差し替えるところで、HitしたActorのモデルを引数として渡した後、Destroyすることで箱に入ったように見せてます。

ClearBoxBPのマテリアル

これらを参考にしました。

pafuhana1213.hatenablog.com

もんしょの巣穴blog [UE4] とりとめのないマテリアルネタ色々

テッカテカにならないかなーと淡い期待を込めながら作ったのがこちらです。

f:id:shop_0761:20151204200027p:plain

ただもんしょさんの記事にもある通りざわざわします。けどとりあえず目をつぶります。半透明っぽければよいです。

滅の実装

f:id:shop_0761:20151204200740p:plain

基本はさっきと同じTimeline処理です。個人的なポイントとしては2つあります。

  • AddRelativeLocationでz移動
  • Boxes(SceneComponent)にCube(透明な箱のStaticMesh)とSkeletalMeshを入れる

です。Cubeを破壊するときに真ん中に収縮していく形にしたかったのですが、ピボットをさっきずらしてしまったのでうまくいきません。 イメージを用意しました。

f:id:shop_0761:20151204202412p:plain

f:id:shop_0761:20151204202427p:plain

Pivotの位置が違うのでこんな感じでずれてしまいます。

なら無理やりScaleが落ちるときにz方向に上昇させよう!という脳筋的解決策です。

もう一つのポイントに行く前に、まずはBPの続きをば

f:id:shop_0761:20151204202943p:plain

Boxesの中身だけDestroyしてます。するといい感じに消えてくれるしエラーも出ないしで幸せになれました。 つまりはTimelineノードは途中から中身のないもののスケールを変えてるんですね。

でここで使ってるパーティクルはInfinity Bladeから持ってきて、Textureをいじって色を揃えました。

leap側の実装

さっきまではすべて箱の話でここからはActorつまりカノちゃん側の処理です。

といっても、イベントディスパッチャー使って、手の位置とってLinetraceしてskeletalMesh差し替えてるくらいです。

手の移動イベントを持つLeapAnimBodyConnectorはこのLeapAnimBodyChildActorから拾えるので内部で作ったイベントディスパッチャーがバインドできます。

f:id:shop_0761:20151204203846p:plain

で、Leapで手の座標を取るのはこうやってみました。

f:id:shop_0761:20151204205952p:plain

こちらの記事の手の位置の取り方を見る前にこれを作ってしまった…。

toorsoo.hatenablog.com

で、GateとSetTimerを使って、今と1s前の手の位置を格納した変数を比較することで分岐してます。

f:id:shop_0761:20151204210519p:plain

Then0が手の上下、Then1が手の左右の移動を取るようにしてます。Then1の方はなんか反応が良くなかったので緩めにして、xyのどちらでもいいようにしてます。

これでさっきの動画みたいになるはずです。(ちょいちょい省いたところもあるけど

まとめ

先人たちは偉大でした。特にアセット買いまくってる人(褒め言葉)の記事にはお世話になりました。 思ったよりUE4のLeap記事が少ない印象だったのでネタかぶりしなくて助かりました。

これoculus touchで出来たら楽しそうだなと思ってます!!(touch欲しい

Gateの閉じ忘れと手の位置を変数に格納し忘れがちょいちょいあって唸ってたときもありました。

明日はkiruroboさんのモーキャプネタだそうです。最近は2段ジャンプとか作ったので個人的にトレンディなネタなので楽しみです。 (もうLeapはつらいから違うデバイスにしたい…)