『D×2 真・女神転生リベレーション』でのビッグバナー画像制作事例

はじめまして。セガ 第4事業部・第4開発1部・TAセクションの村上です。

アーケード向けのゲーム開発におよそ10年間携わった後、現在ではスマートフォン用ゲーム『D×2 真・女神転生リベレーション』(以下、『D×2(ディーツー)』)に3D背景チームリーダー兼テクニカルアーティストとして参加しています。

『D×2』の3D背景制作に携わる一方で、制作工程における技術的なサポートも行っています。 

 

『D×2』は悪魔召喚・交渉・悪魔合体・3Dダンジョンなど『真・女神転生』シリーズが持つ醍醐味を踏襲しつつ、スマートフォン向けとして最適化された戦略バトルRPGです。

2.5周年を記念した「超・感謝祭」キャンペーンとイベントを開催中ですので、ご興味がありましたら公式サイトをご覧ください。

d2-megaten-l.sega.jp

 

『真・女神転生』シリーズとは皆様ご存知の通りアトラスさんが開発・販売されている25年以上の歴史を誇る「荒廃し、悪魔が跋扈する現実世界を舞台としたRPGシリーズ」です。

「メガテン」の愛称のほうが馴染み深いかもしれませんね。弊社の家庭用ゲーム機でもいくつものタイトルが発売されてきました。

 

つい最近「ゲームギア」が発売30周年になることを記念したミクロサイズの「ゲームギアミクロ」が発表されました。

全4色のうちの「レッド」には、なんと『女神転生外伝 ラストバイブル』と『女神転生外伝 ラストバイブルスペシャル』が同梱されます。

今まで上記タイトルをプレイする機会に恵まれなかったため、個人的に発売が待ち遠しいです!

60th.sega.com

 

さて少し時間を戻した2020年2月。『D×2』のファンミーティングが有楽町にて開催されました。

新型コロナウイルス対策にスタッフ一同細心の注意を払った上で、ご応募をいただいた皆様の中から抽選により約100名様にご来場いただきました。

app.famitsu.com

game.watch.impress.co.jp

 

当日会場にサービス2周年記念悪魔である英雄 マサカドと天魔 アスラおうを撮影できるビッグバナー(フォトスポット)をご用意したところ、ファンの皆様には大盛況でした。

この画像の制作工程を紹介したいとの依頼を受けまして、本記事では要点を絞り2部構成にしてお届けします。

前半

  • 画像の拡大変換ツールwaifu2x-caffeの使い方
  • waifu2x-caffeとAdobe Senseiの拡大性能を比較検証

後半

  • 拡大前の元素材画像のメイキング(UnityでのキャプチャーからPhotoshopでのレタッチまで紹介)

 

うーん、少し地味ですかね。知っていてもすぐに役立たない情報もあるかもしれません。

例えるなら弊社「メガドライブミニ」のヘッドホンボリュームは動かせますが、本体の音量は変わらないんです、ぐらい地味な話もあるかもしれません。

faq.sega.jp

 

それでもお1人でも役に立ったと言っていただけるように、作業効率が変わりそうなコツを取り揃えてみました!

前置きはほどほどに、地味~にお付き合いください。

 

 

フォトスポットってなに?

巨大なビッグバナーの前で撮影する場所

当日は『真・女神転生』シリーズの人気悪魔と一緒にファンミーティングの楽しい思い出を残せるフォトスポットができました。このフォトスポットに設置されている巨大な写真のことをビッグバナーと呼びます(スマートフォンでさっと撮影した写真で失礼いたします)。

f:id:sgtech:20200723200211p:plain

英雄 マサカド

f:id:sgtech:20200723200204p:plain

天魔 アスラおう

ビッグバナーの解像度はいくつなのか?

高さ2m、横幅4m

「えっ? 高さ2m? 横は4mもあるの!?」

最初にビッグバナーの大きさを聞いた時はビックリしました。

会場で見た実物は床から天井まで届く、文字通り「ビッグバナー」でした

 
ビッグバナーのスペック
  • 2m x 4m(高さ x 横幅)
  • 布地に印刷 ※ベルクロ(マジックテープ)で箱に貼り付け
  • 入稿はIllustratorフォーマット

 

「画像解像度いくつだろう・・・」と不安が頭をよぎりましたが、問題なく作業するには8K~16K解像度が限界ではないか?と予想しました。

※8K=7,680×4,320ピクセル

※16K=15,360 x 8,460ピクセル

 

印刷の密度表現としてはdpiが一般的ですが、ここではピクセルで考えてみます。

タイミング良くPhotoshopを起動していたので、数値入力欄で計算してみましょう。

f:id:sgtech:20200723200002g:plain

Photoshopの入力欄で数値の計算

例えば横幅を16,000ピクセルで作るとします。

横幅1m辺り約4,000ピクセル、横幅1mmだと約4ピクセルの面積となるでしょうか。

 

撮影対象となる悪魔モデルはビッグバナー画像の中央に大写しに立たせることになっていますので、撮影時のカメラまでの距離を考えるとなんとかなりそうです。

「きっと16Kでも大丈夫!」と自分を納得させることにしました・・・(ドキドキ)。

 

出力する画像解像度は16K

少し適当に決めた解像度に聞こえてしまいますが、それにしても16K・・・本当に大きいです。

拡大しても、拡大してもピクセルが見えない!

ちょっと大げさですが、普段はスマートフォン向けゲーム開発をしているだけにこんな気持ちになりました。

後でdpiを計算すると約100dpiでした。※一般的な印刷物は300〜400dpi。

 

PC用モニターは標準で72dpiなので、標準的なPC用モニターよりは細かくできました(Retinaディスプレイは除く)。16K解像度は結構妥当だったようです。

 

制作する画像解像度は8K

私の普段の業務は『D×2』の3D背景制作と技術サポートです。開発業務と平行してのビッグバナー制作のため、入稿締め切りギリギリのスケジュールでした。

『D×2』はアトラスさんの監修を経てリリースされていますので、監修に必要な営業日と修正にかかる時間も考慮する必要があります。
 
スピーディーなワークフローが求められるため「制作自体は8K解像度で作業し、入稿直前に16K解像度に拡大変換する」方法を選択しました。 
 
印刷される画像解像度を最終的に2倍に拡大することができれば、レタッチ面積を節約できるだろうと考えました。
また作業するPSDファイルサイズは8K解像度で経験上1GB~2GBになります。16K解像度で作業するよりも軽くできますね。
 

拡大変換ってなに?

例えばPhotoshopで画像の解像度を2倍に拡大してみます。おそらく拡大する前よりもボヤ~っとしていませんか?
 
数年前まではPhotoshopで拡大してもそれほど良い結果は得られませんでした。それはバイキュービック法やバイリニア法という簡単な補完方法による変換だったからです。
 
でも当時はそれが当たり前でした。
 
――――当たり前だったのですが、ここ数年のAdobe社の画像テクノロジーへの取り組みは目覚ましく、ついにはAdobe Senseiという新技術が生まれました。
 
現在はPhotoshopでもAIと機械学習によるキレイな拡大変換が可能となっています。
※拡大変換=アップスケーリングとも呼ばれます。
 
AI/機械学習による拡大変換は、縮小画像と解像度の高い元画像のペア(教師データ)を大量に学習した成果を生かして、ただ引き延ばすのではなく、不足情報を補っています。
 
機械学習の説明は、こちらの記事が大変参考になりました。

 

入稿前に拡大変換

waifu2x-caffeとは?

それではビッグバナー制作においては、どのように画像を拡大させたのでしょうか?
 
この流れだとAdobe Senseiを――――Photoshopを使う流れに見えますが・・・違うんです。
これからご紹介するツールwaifu2x-caffeを使用すると簡単に、かつキレイに拡大変換できます!
waifu2x-caffe
  • 画像変換ソフトウェア「waifu2x」のWindows用ツール
  • 「waifu2x」の変換機能のみをCaffeを用いて書き直した

「オレの嫁ね!」と、愛称で呼ばれて既に利用されている方もいらっしゃるかと思います。最近だとスマートフォン向けアプリにリリースされていたり、市販の画像最適化ツールにも搭載されていますね。

 

ゲーム開発の立場で考えると、Windows上で実行できるスタンドアローンツールというのが大変に嬉しいです(外部サーバーに開発データをアップロードするのは問題ありますから)。

 

この素敵なツールは下記からダウンロードして使うことができます。

github.com

 

waifu2x-caffeのダウンロードからインストールまで

Windowsへのインストールもとっても簡単です。

インストール方法
  1. lltcggie/waifu2x-caffeのダウンロードページを開きます。
  2. waifu2x-caffe.zipをクリックして保存します。 ※最新版を選びます

    f:id:sgtech:20200723203707p:plain

  3. ダウンロードしたZIPファイルを右クリック→「すべて展開」します。
  4. waifu2x-caffeフォルダ内のwaifu2x-caffe.exeを実行します。
    ※今回はGUI版を使用しますが、コマンドライン版も用意されています(waifu2x-caffe-cui.exe)。

    f:id:sgtech:20200723203710p:plain

  5. 「WindowsによってPCが保護されました」と警告が表示される場合は、「詳細情報」をクリックすると「実行」ボタンが押せるようになります。

    f:id:sgtech:20200723203715p:plain

  6. ウインドウが立ち上がったら、「cuDNNチェック」ボタンを押します。
    特にエラーがなければ、準備完了です。

    f:id:sgtech:20200723203727p:plain

 cuDNNについて

  • GPUを使って変換を行う(※Compute Capability 3.0 以上のNVIDIA製GPU)
  • 高速に画像変換できる
  • VRAM使用量を減らせる
以前のバージョンでは別途NVIDIAのサイトからdllをダウンロードする必要がありましたが、ver 1.2.0.3より同梱されることになりました。とっても便利になりましたね。

 

エラーが出たら?

もし「cuDNNチェック」で「GPUで変換できません」等のエラーが出た場合は、通常は指示に従いますが、ここではCPU変換にすることで解決してみます。

  1. 動作設定」ボタンを押します。

    f:id:sgtech:20200723203722p:plain

  2. 「使用プロセッサー」を「CPU」へ変更します。
    ※CPUは変換時間が遅くなりますが、確実に動作します。

    f:id:sgtech:20200723203719p:plain

 

便利なカスタマイズ

同じ「動作設定」にある「入力参照時固定フォルダ」 で入力パスを設定できます。起動のたびにデフォルトフォルダから変更するのが面倒になったら、カスタマイズしてみましょう。

f:id:sgtech:20200723203943p:plain

「入力参照時固定フォルダ」で入力パスをカスタマイズ

 

waifu2x-caffeの使い方

設定のポイントは2つだけ

詳しい使い方はフォルダ内の「README」ファイルを読んでいただくとして、今回のビッグバナー制作における設定をご紹介します。

f:id:sgtech:20200723203733p:plain

『D×2』ビッグバナー画像の変換設定

使い方

  1. 入力パスの「参照」ボタンを押して、変換する画像を選択します。
    ※出力パスは自動で設定されます。
  2. 「変換モード」はそのままにします。※「ノイズ除去と拡大」
  3. ノイズ除去レベル」を選びます。※今回は「レベル2」
  4. 「拡大サイズ」を選びます。
  5. モデル」を選びます。※今回は「写真・アニメ(UpPhotoモデル)」
  6. 「実行」ボタンを選んで、変換開始です。 

    f:id:sgtech:20200723203738p:plain

 

このように数クリックで変換できてしまうこともwaifu2x-caffeの魅力ですね。

「実行」ボタンを押してしばらく待つと拡大された画像が作成されます。8Kから16K解像度への拡大もGPU変換なら短い時間で終了します。

 

ノイズ除去レベル

ノイズの具合が、質感に大きく影響している印象があります。ここはしっかり設定したほうが良いですね。

まずは「レベル1」を選んで一度変換し、結果を確認することをオススメします。

「レベル1」の結果を見た上で
  • 質感が失われ過ぎていれば「レベル0」で変換する。
  • ノイズが強ければ「レベル2」で変換する。

適切なレベルを設定することで、さらに良い結果を得られると思います。

 

モデル

ビッグバナー画像では「写真・アニメ(UpPhotoモデル)」を選んでいます。
※「写真・アニメ(Photoモデル)」より高速かつ同等以上の画質で変換できます。

アニメやイラスト系の画像では「2次元イラスト」モデルを選びますが、目的に合わせて「UpRGBモデル」「Yモデル」など最適なモデルを選べると良いですね。

 

結局どれくらいキレイになるの?

「オレの嫁(waifu2x-caffe)」と「アドビ先生(Adobe Sensei)」を比較

ところでどれくらいキレイに拡大変換できるのか、気になりませんか?

そこでwaifu2x-caffeとAdobe Senseiをビッグバナー画像を使って比較してみました。いったいどちらの拡大変換がよりキレイな画像になるのでしょうか? 私も楽しみになってきました。

 Adobe Sensei (Photoshop)
  • 人工知能(AI)とマシンラーニング(機械学習)
  • 「イメージ」→「画像解像度」のダイアログにある再サンプルから「ディテールを保持 2.0」を選ぶ
    ※Photoshop CC 2018からの新機能

 

waifu2x-caffeとAdobe Senseiの検証

ベース画像(8K解像度)はそのままの大きさ、100%表示です。

比較画像(16K解像度)は見やすくするため実際よりも200%拡大表示しています。

それでは英雄 マサカドの口元から比較してみましょう。 

ベース画像

f:id:sgtech:20200723200040p:plain

100%表示

Adobe Sensei

ディテールを保持 2.0

(ノイズを軽減0%)

f:id:sgtech:20200723200044p:plain

化粧の質感は残っているが、エッジ処理に問題があり

200%表示

Adobe Sensei

ディテールを保持 2.0

(ノイズを軽減50%)

f:id:sgtech:20200723200049p:plain

エッジはスムーズ、化粧の質感はノッペリ

200%表示

waifu2x-caffe

写真・アニメ
(UpPhotoモデル)

ノイズ除去レベル2

f:id:sgtech:20200723200052p:plain

化粧の質感を保ちつつ、エッジをスムーズにするバランスが良い

200%表示

waifu2x-caffeの結果が一番良いですね。Adobe Senseiの挽回なるか?

次は天魔 アスラおうの鎧装飾を比較してみましょう。

ベース画像

f:id:sgtech:20200723200008p:plain

100%表示

Adobe Sensei

ディテールを保持 2.0

(ノイズを軽減0%)

f:id:sgtech:20200723200012p:plain

四角いドットが残ったまま

200%表示

Adobe Sensei

ディテールを保持 2.0

(ノイズを軽減50%)

f:id:sgtech:20200723200016p:plain

エッジはスムーズ、質感は若干失われた

200%表示

waifu2x-caffe

写真・アニメ
(UpPhotoモデル)

ノイズ除去レベル2

f:id:sgtech:20200723200019p:plain

エッジはスムーズ、質感も問題なし

200%表示

ここでもwaifu2x-caffeの結果が一番妥当ですね。Adobe Sensei頑張って!

 

最後は天魔 アスラおうの背景です。段差のエッジとピンク色の背景との境界を比較してみましょう。

ベース画像

f:id:sgtech:20200723200023p:plain

100%表示

Adobe Sensei

ディテールを保持 2.0

(ノイズを軽減0%)

f:id:sgtech:20200723200028p:plain

エッジの輪郭がにじむ

200%表示

Adobe Sensei

ディテールを保持 2.0

(ノイズを軽減50%)

f:id:sgtech:20200723200031p:plain

エッジのにじみは改善、あと一歩

200%表示

waifu2x-caffe

写真・アニメ
(UpPhotoモデル)

ノイズ除去レベル2

f:id:sgtech:20200723200036p:plain

エッジのにじみが一番抑えられている

200%表示

最後もwaifu2x-caffeの結果が一番でした。

 

以上で「口元」「鎧装飾」「背景」の3つの比較が終了しましたが、ビッグバナー画像を元に検証した拡大性能に関しては「オレの嫁」――――waifu2x-caffeとの相性が良い結果となりましたね!

※検証を行ったバージョン:waifu2x-caffe (1.1.8.3)、Adobe Sensei (Photoshop CC 2019)

 

上記検証ではwaifu2x-caffe一択ですが、Adobe Senseiの「ディテールを保持 2.0」が活かせるケースもあります。

例えば「テクスチャーデータを簡単に拡大できる」ところですね。数世代前のゲームを移植する際にテクスチャーがHD化されていないこともあります。

この機能をバッチ処理することで、テクスチャーのHD化を低コストで量産できるかもしれません(弊社内で事例があると聞きました)。

 

「ディテールを保持 2.0」が使えない場合は?

f:id:sgtech:20200723204004p:plain

おかしいぞ? 本来はここにあるはずなのに、選べない場合は・・・

f:id:sgtech:20200723203959p:plain

「ディテールを保持 2.0 アップスケールを有効にする」をオン

(Photoshop CC2018以降であれば)環境設定→「テクノロジープレビュー」の「ディテールを保持 2.0 アップスケールを有効にする」をオンにします。

 

前半まとめ

というわけで前半はビッグバナーの解像度、拡大変換ツールwaifu2x-caffeの紹介、Adobe Senseiとの比較を行いました。ここからは画像を拡大変換する前の「元素材ができあがるまで」のメイキングについてご紹介していきます。

 

メイキング:拡大前の元素材の作成手法

全体のワークフロー

それでは全体の工程を確認していきましょう。 1~5までの工程がありますが、このメイキングでは「1. Unity~」と「2. Photoshop~」にフォーカスした内容となります。

ビッグバナー制作全体ワークフロー 

f:id:sgtech:20200723200218p:plain

  1. Unityでキャプチャーする
    ・8K解像度
  2. Photoshopで作業をする
    ・合成
    ・レタッチ
  3. waifu2x-caffeで画像を拡大する
    ・8K→16Kに拡大変換
  4. Photoshopで入稿用画像を作成する
    ・RGB→CMYK変換
    ・色調補正
  5. Illustratorで入稿データを作成する
    ・印刷業者側から提供されたテンプレートファイルに入稿用画像を読み込む
    ・側面デザインや権利表記等などIllustrator上の作業を行う
 

まずはUnityから

Unityのキャプチャー環境

『D×2』はUnityをゲームエンジンとして採用し、開発が行われています。

悪魔モデルと背景シーンは3Dで作成されているため、Unityでカメラを作成することで色々な角度から悪魔モデルと背景シーンをキャプチャーすることができます。

 

用意するデータは

  1. 悪魔モデル
  2. バトルステージ用の背景シーン ※ゲーム中にロードされる
  3. キャプチャー用のシーン ※ゲームには含まれない

です。

シーン内にどのデータが入っているのかは、リストにして下記にまとめました。

背景シーン(バトルステージ用)

  • 背景モデル
  • (背景内の)バトル開始位置
  • バトル開始位置に付随するフォグやライト等の環境設定
  • 悪魔モデルの質感調整等パラメーター


 
キャプチャー用シーン

  • 悪魔モデル
  • キャプチャー用バトル開始位置
  • キャプチャー用カメラ
  • キャプチャー用ライト

 

シーン内のバトル開始位置と連動して背景環境を変更させる仕組みとなっています。そのため同じ背景シーンでも、バトル開始位置によってはガラリと雰囲気が変化します。

f:id:sgtech:20200723200426g:plain

バトル開始位置を切り替えるとシーンの雰囲気や見た目も変わる

この仕組みを流用してキャプチャーのためのカメラのポジションやライティング環境を作り、キャプチャー用シーン内に保存しています。

マメなセーブデータが大切だ!ということを『真・女神転生』シリーズのザコ敵に全滅させられた経験から学んでいますので、うっかりミスで「あの背景をキャプチャーし忘れた!」と問題が発生しても、すぐ同じ環境を復帰できるように備えています(ああ、当時のトラウマが・・・)。

 

キャプチャー

キャプチャー用カメラのベースはバトル時のカメラと同じなのですが、画面をキャプチャーするコンポーネント(スクリプト)がアタッチされています。

画面のキャプチャーはフリーツールが多数ありますが、『D×2』では独自の描画方式を用いているのでフリーツールや標準機能では正しくキャプチャーできません。そのためキャプチャーツールは独自実装となっています。

 

カメラの背景色ですが「Background」をPhotoshopで抜きやすい色に変更しているだけです・・・横着ですね。背景エフェクトをキャプチャーする場合は「Background」を黒色でキャプチャーしています。

f:id:sgtech:20200723203647p:plain

「Background」カラーを抜きやすい色に変更

 

動きのあるポーズはTimeline機能を使う

特定のポーズでキャプチャーしたい場合では、Timeline機能を使っています。

※Timeline機能=シネマティクスやカットシーンを作ることができる

f:id:sgtech:20200723203953p:plain

Timelineを利用したキャプチャー

Timeline機能を使うとライティング、パーティクルエフェクト発動のタイミングも自由に組み合わせることができます。

「再生開始から◯◯フレーム目のアニメーション」をキャプチャーすることで、同じポーズとカメラアングルを再現しています。 

 

猛将 マサカドのレタッチ画像の制作では、「カメラ」「猛将 マサカドのモデル」「攻撃のアニメーション」をTimeline機能で読み込んでキャプチャーしました。この猛将 マサカドの攻撃アニメーションは何度見ても迫力があってカッコイイですね!

f:id:sgtech:20200723200224p:plain

猛将 マサカド「マサカドチャレンジ」 ※クリックすると大きい画像で表示

 

撮影舞台の紹介

英雄 マサカドのビッグバナー撮影の舞台は専用の「チャレンジクエスト」ステージ(いわゆるボス戦)です。

海上の歌舞伎舞台をイメージしていて、奥には三重塔が英雄 マサカドを見守るように佇んでいます。

f:id:sgtech:20200723200153p:plain

英雄 マサカド専用の「チャレンジクエスト」ステージ

『真・女神転生Ⅲ-NOCTURNE』にマサカド公が登場する場面がありますが、アトラスさんからの提案により篝火と鳥居の要素をオマージュとして取り入れています。

 

ここからはPhotoshop

レタッチの方向性は?

Photoshop上にて、以下のように作業を進めていきます。

背景
  1. 空、遠景、近景、エフェクトの合成
  2. レタッチ
  3. 色調補正
キャラクター
  1. 影とライティングの合成
  2. レタッチ
  3. 色調補正

 

英雄 マサカドは「格式の高さ」、そして天魔 アスラおうは「壮麗さ」をキーワードとして写真に収めた際に格好よく見えるような、写真映えするような方向性となっています。

 

記事ボリュームの都合上、ここでは英雄 マサカドのレタッチ工程を中心に進めていきます。

まずはゲーム画面の背景だけのスクリーンショットを確認してみましょう。

f:id:sgtech:20200723200158p:plain

ゲーム画面の背景スクリーンショット(参考用)

ゲーム中は迫力ある背景だと思ったのですが、スマートフォンのカメラで撮影するにはやや物足りないですね。

 

空を高解像度化

屋外の背景で空が見えているようであれば、空から作業を始めます。

画像全体のトーンを空を見ながら決めやすいですし、光がどのように射し込むかイメージできます。

また、単純に絵としてのクオリティーが上がりやすい印象もあります。

実は空の元画像素材は8K解像度には足りていませんでした。

先程Photoshopでの作業と書きましたが、この空だけは先にwaifu2x-caffeを使って4倍に拡大します。

f:id:sgtech:20200723204013p:plain

異なるノイズ除去レベルで4倍拡大した画像を2枚用意

変換してみるとノイズ除去レベル2ではノイズが残り過ぎ、3だと完全にノッペリしていましたので、この2枚を合成して画質をコントロールすることにしました。

 

もし元画像の地平線が傾いていれば「切り抜きツール」の「画像上に線を引いて画像を角度補正」を使います。

f:id:sgtech:20200723203619p:plain

余白を自動的に補正する設定

自動で傾きを修正してくれるので便利ですね。

f:id:sgtech:20200723203623p:plain

「画像上に線を引いて画像を角度補正」で水平線に沿って線を引く

この時に「切り抜いたピクセルを削除」オフ、「コンテンツに応じる」オンに設定します。

本来であれば傾きを修正すると空白が生まれてしまいますが、Photoshopがいい感じに埋めてくれます。

ポイントになるのは「コンテンツに応じる」という機能です。

 

こうして拡大された空をレイヤーマスクを使ってゲーム中の空に合成していきます。

f:id:sgtech:20200723200057p:plain

ゲーム中の空

f:id:sgtech:20200723200101p:plain

合成した空

空を変えただけですが、ずいぶんと雰囲気が変わります。

 

遠景と画像の切り抜き

ここからは三重塔と橋を合成していきます。

三重塔の画像をPhotoshopで読み込み、塔の形状で抜く作業をしていきます。

f:id:sgtech:20200723203703p:plain

選択範囲から「色域指定」

 

選択範囲メニューから「色域指定」を選んで、抜きたい色を削除するのが一番簡単な方法ですが、フチに1ピクセルほど微妙に色が残る場合がありますので注意が必要です。

f:id:sgtech:20200723203654p:plain

フチに色が残ったケース(極端な例)

f:id:sgtech:20200723203650p:plain

フリンジ削除でフチを削除

レイヤーメニューから「マッティング」→「フリンジ削除」で1ピクセル削ってしまうと安心です。

 

背景だと上記で大抵は問題ないのですが、木々のある背景や複雑な形状のキャラクターでは繰り返し調整可能な「レイヤーマスク」を使う方がより良い結果を得られます。

選択レイヤーに「レイヤーマスク」を追加し、マスクの「属性」にある「色域指定」を使います(「反転ボタン」を押すと選択を逆転できます)。

f:id:sgtech:20200723203658p:plain

レイヤーマスク「属性」の「色域指定」と「選択とマスク」

次に「選択とマスク」を使いながらエッジの処理を調整することができます。※以前のバージョンでは「マスクの境界線」

f:id:sgtech:20200723203743p:plain

「選択とマスク」を使用してエッジを微調整

 

空気感の演出として、レイヤースタイルや修正を加えていきます。

「カラーオーバーレイ」は空気感を演出できる便利な機能ですね。

f:id:sgtech:20200723200318p:plain

三重塔を追加

f:id:sgtech:20200723204034p:plain

レイヤースタイルの「カラーオーバーレイ」を選んで、三重塔に空気感を追加

f:id:sgtech:20200723200323p:plain

フォグと橋を追加して遠景の完成

ゲームからキャプチャーした素材だけでは足りなかったので、雲ブラシでフォグを描き足しました。

 

近景と水面反射

歌舞伎舞台、鳥居を合成していきます。

遠景のレタッチによって鳥居のシルエットがハッキリしました。この状態であればキャラクターを追加しても背景に埋没する心配はいらなさそうです。

f:id:sgtech:20200723200328p:plain

歌舞伎舞台と鳥居を追加

8K解像度ではライトマップの精度が荒い箇所がいくつも見つかりました。またアンビエント・オクルージョンも物足りないと感じたため、地味な作業ですが修正します。

 

歌舞伎舞台中央には水面があります。映り込むと美しさが増しますので、三重塔と空の水面反射を追加していきます。

レイヤーを選択して、フィルターメニューから「スマートフィルター用に変換」します。これでフィルター効果を何度でも修正できるようになりました。

f:id:sgtech:20200723203630p:plain

フィルター→「スマートフィルター用に変換」

 

編集の「自由変形」→「垂直方向に反転」で上下反転させますが、若干タテに伸びるように変形させた後に、フィルター→「ぼかし」→「ぼかし(移動)」を実行します。ぼかし表現をタテ方向(90度)に加えていきます(「距離」はケースバイケースで調整します)。

f:id:sgtech:20200723203626p:plain

フィルター→「ぼかし」→「ぼかし(移動)」で90度のぼかし

f:id:sgtech:20200723203441p:plain

水面反射として三重塔を追加

水面への映り込みは若干暗くなるように「トーンカーブ」で暗めに調整します。

 

次に空の反射を追加しますが、水面がツルッとしてしまいました。

f:id:sgtech:20200723203445p:plain

空の反射も追加

 

手っ取り早く調整する方法として、レイヤースタイルの「ブレンド条件」を使っていきます。

下になっているレイヤー」のスライダーを左右に動かして、ピクセルの明るさを基準にしながら、選択中のレイヤーより下になっているレイヤーを合成します。

f:id:sgtech:20200723203450g:plain

「ブレンド条件」で明るい部分だけの反射を残す

このままだと合成が荒いままなので、一度「Alt(Windows)/Option(Mac)」キーを押しながらスライダーをクリックします。

1つだったスライダーが2つに分割されます。隙間を空けるようにスライダーを移動させると、スムーズに境界が合成されます。

※スライダーは左右両端にありますので、目的に応じて使い分けます。

 

さらにレイヤーマスクを追加して、合成する範囲をコントロールしても良いかもしれません。

f:id:sgtech:20200723200340p:plain

近景の完成

 

エフェクトと色調補正

Unityでエフェクトごとにキャプチャーした画像を基本的には描画モードを「スクリーン」で合成していきます。炎だけ、煙だけと要素に分けてキャプチャーするため、キャプチャー枚数は背景よりもずっと多くなります。

f:id:sgtech:20200723200149p:plain

エフェクトは描画モードを「スクリーン」で合成

f:id:sgtech:20200723200249p:plain

背景の完成
※クリックすると大きい画像で表示

それでも足りないエフェクトはブラシで描き足します。色調補正を重ねて背景の完成です。

 

リテイクに強いゴミを消す方法

少し脱線しますが、フォトバッシュやレタッチ作業をしていると画像から不必要なゴミを消したい場合もあります。

定番というと「スポット修復ブラシツール(修復ブラシツール)」「コピースタンプツール」が思い浮かびますが、今回はCC 2019から追加されたマイナー(?)だけど便利な方法をご紹介したいと思います。

スマートフォンで撮影した実物のビッグバナー写真からエフェクトやシミなどを削除してみます。

f:id:sgtech:20200723203530p:plain

火の粉や鳥、印刷のシミを削除するには・・・

f:id:sgtech:20200723203536p:plain

削除したい範囲を囲み・・・

 

メニューから編集→「コンテンツに応じた塗りつぶし」を選びます。
※CC 2019より以前のバージョンでは編集→塗りつぶし→「コンテンツに応じる」ですが、新規レイヤー作成はできません。

f:id:sgtech:20200723203543p:plain

「新規レイヤー」を選ぶと、修正箇所を別レイヤー化できて便利

 

CC 2019からはプレビューで確認しながら調整できるようになり、出力先として「新規レイヤー」が選べるようになりました。このままデフォルト設定で適用します。※意図した結果にならないケースでは、「サンプリング領域」をブラシで塗り直します。

「サンプリング領域」と選択範囲を調節するだけで結果が変わるため、一気に修正できてリテイクに強い便利な機能となりました。

f:id:sgtech:20200723203547p:plain

囲った箇所を一気に修正

 

一方でブラシのストロークで修正できる「スポット修復ブラシツール」も捨てがたいです。

ああ、元画像を直接修正しない方法があれば・・・スマートオブジェクトでも修正できれば・・・。分かります。

実は「スポット修復ブラシツール」の「コンテンツに応じる」を選んでから「全レイヤーを対象」にチェックを入れることで解決できます。

f:id:sgtech:20200723203616p:plain

「スポット修復ブラシツール」の「全レイヤーを対象」を選ぶ

新規レイヤーを作成すれば、ストロークした修正箇所のみ新しいレイヤーに分けることができます。

 

ここまでポイントなっているのは「コンテンツに応じて◯◯」という機能です。Photoshop CS4からバージョンが上がるごとに対応が増えている機能ですが、こちらで詳しく使い方をフォローされています。

blogs.adobe.com

 

キャラクターのライティング

ここからは背景に英雄 マサカドを立たせて、基本的にはキャラクターのライティング調整を優先していきます。

その理由として悪魔モデルはモデリングと質感のクオリティーが非常に高いレベルにあるため、大きい修正をする必要性を感じられないからです(アトラスさんの監修も通っていますし)。

ちなみに下記画像のポーズは元のイラストのマサカド公を再現しています。イラストと見比べても再現性バッチリで、モデリングチームとアニメーションチームの熱意が伝わってくるかのようです。

向かって左側に立っている英雄 マサカドがゲーム中のリアルタイムライトでキャプチャーした画像です

 

まずは影の調整をしてみましょう。

左側の画像をベースにブラシを使用してアンビエント・オクルージョンを追加していきます。

f:id:sgtech:20200723200304p:plain

ベースのキャプチャー画像(左側)

アンビエント・オクルージョン追加後(右側)

夕日のバックライトに合わせて手のひら、袖の下、洋服の重なり部分、足首周りにしっかりと影を落とします。

 

ここからはラィティングの調整をしていきます。作り込んだモデルの立体感とPBRマテリアルによる繊細な質感をさらに引き出すことを目標とします。

基本はキーライト、フィルライト、バックライト(リムライト)があれば対応できます。顔周りが暗かったり、余計な影が顔に落ちているケースではフェイス用ライトを何個か追加してキャプチャーしておきます。

 

最終的にPhotoshop上で合成するため、Unity上でのライト調整はそこそこで大丈夫です。

1ライトにつき1枚キャプチャーしておくと、調整がしやすくなります。

f:id:sgtech:20200723200308p:plain

フロントライト(左側)、フィルライト(右側)

ベースの画像を1枚目として数えると、フロントライト、フィルライトの追加を行ったので合計3枚キャプチャーしたことになります。

 

意外と少ないキャプチャー枚数なのは屋外だったからかもしれません。もし屋内であれば光源が多数あるケースが多いため、キャプチャー枚数も増えていたでしょう。

以前はMayaでディフューズ、スペキュラーなどレンダリング要素別に出力していたことに比べると、とってもシンプルな手法ですね。

 

英雄 マサカドを取り囲むように篝火が配置してありますので、照り返しを感じられるように「トーンカーブ」を使って色調補正します。

f:id:sgtech:20200723200313p:plain

ベース(左側)、レタッチ完了後(右側)

足元には水面反射と影を追加し、注目される箇所を優先して修正します。

顔は注目度が高いので、瞳や歯の辺りは丁寧に手を入れています(口の中までクッキリと映る解像度なんです)。

 

最後に背景とキャラクターをなじませ、全体のバランスを調整をしてレタッチの完成です。

f:id:sgtech:20200723200238p:plain

英雄 マサカドのビッグバナー完成画像
※クリックすると大きい画像で表示

新生ホーム画面背景にそびえ立つ天魔 アスラおうのビッグバナー画像も上記と似たような工程を経ています。

f:id:sgtech:20200723200138p:plain

天魔 アスラおうのビッグバナー完成画像
※クリックすると大きい画像で表示

この後の作業工程ですが、記事前半でご紹介したwaifu2x-caffeを使った拡大変換へとつながっていきます。ここまで長かったですね・・・長文にお付き合いいただきまして、ありがとうございました!

 

まとめ

というわけで『D×2』ビッグバナー制作事例いかがでしたでしょうか?

  • waifu2x-caffeを使って入稿用画像を拡大変換する。
  • waifu2x-caffeの方がPhotoshop (Adobe Sensei)よりもキレイな拡大結果を得られる可能性がある。
  • Photoshopの「コンテンツに応じる」機能はどんどん使ってみる。

辺りがポイントでした。

ちょっとしたツールの使い方の違いで作業効率が地味に変わることもあります。今回の記事が皆様にご活用いただける内容でしたら幸いです。

 

セガではこのような取り組みに興味のある方を募集しています。もしご興味を持たれましたら下記サイトにアクセスしてみてください。

www.sega.co.jp

 

最後は『真・女神転生』シリーズ定番のセリフでしめたいと思います。

『コンゴトモヨロシク』お願いいたします。

 

©SEGA/©ATLUS

セガ・セガロゴ、ゲームギア、ゲームギアミクロ、メガドライブミニは株式会社セガまたはその関連会社の登録商標または商標です。

記載されている会社名、製品名は、各社の登録商標または商標です。

在宅でチームの働き方改革!!

ごあいさつ

初めまして、株式会社セガ開発技術部の廣島です。

 

今回のBlogでは新型コロナウィルスの感染拡大防止のために弊社で実施されたリモートワークに関して、私達のチームで起きた問題やその問題に対してどう対応したのかを紹介します。 

リモートワークをしてみて、私たちのチームに発生した問題は、コミュニケーションが上手くいかず、チームとしての機能が低下していくことでした。

 

そして、その原因は距離でした。

 

チームの間に物理的な距離ができてしまったことで、雑談のような気軽なコミュニケーションが減り、心の距離までもが遠くなってしまったのです。そしてこれまで何事もなく回っていたチームの歯車が、少しずつ噛み合わなくなっていきました。

 

しかし、リモートワークなので当然、物理的な距離を近づけることはできません。

どうすれば良いのか?何をすればこれまでと同じように上手くチームが回るのか?

そういった試行錯誤をした記録とそこから得た知見を共有したいと思います。

 

どうぞ宜しくお願いします。

対象となる読者

  • リモート環境でチームとして何かに取り組んでいる

  • リモート環境でこれからチームとしての作業に取り組もうとしている 

そういった方たちの活動の参考になれば幸いです。

仕事の内容

前置きになりますが、私達が所属する開発技術部はゲームを開発している部署ではありません。

 Windows上で動作する開発支援ツールの作成や、UnityのPlugin開発などを行い、開発現場を支援しています。

f:id:sgtech:20200614231029p:plain

これは私達が制作している、企画さんやデザイナさん向けのGit のクライアントツール「Pengit」です。過去には第1回 GitHub Enterprise ユーザ会」などでも紹介させていただきました。

 

私達のチームにはエンジニアが4人いて、それぞれがツールを作ったりプラグインの開発をしたりと、2人から4人のチームを組んで仕事をしていました。

 4人が関わっているツール作成のプロジェクトに関しては2週間単位で業務の計画を立て振り返りを行うスタイルで開発をしていました。

 それ以外のプロジェクトではやり方はバラバラで必要になったときに都度情報を共有するスタイルで仕事をしていました。

 ビックリするかもしれませんが会社ではお互い席も近く振り向けばそこにチームメンバーがいる環境だったので、このような進め方でも問題ありませんでした。

 

しかしリモートワークではそう上手くはいかなくなります。が、その話はもう少しあとで紹介します。

 

リモートワーク開始準備  2月の中頃から

リモートワークを始めるにあたって、在宅で何をするのかを上司とすり合わせました。

まず、基礎研究や調査と言った案件は比較的個人でも進めやすいので、これを機に新しい技術を勉強することになりました。

 

リモートワーク期間が短期で終われば新技術の勉強だけで良いですが、問題が長期化することも考え、その場合は在宅でも通常業務を回すという方針を立てました。

 まだこの時点では、出社をする必要があるツールのサポート業務が続いていたため、チーム内で順番に出社する人を決めて週に2日ほど出社する半リモートワーク生活からスタートしました。 

当時はまだ緊急事態宣言も発令されていなかったので、出社している人が数多くいたのを覚えています。

 

リモートワーク開始  3月

リモートワークが始まるといくつか困ることが出てきました。 

毎日チャットで朝会を行っていたのですが、当初は文字のみでコミュニケーションをとっていたため、あまりにも効率が悪かったのです。

  • 一つの議論に多くの時間が掛かる
  • 情報が流れてしまうので、あとから情報を追うのが大変

そこで、文字のみのチャットは止めて音声チャットを導入しました。

f:id:sgtech:20200614231035p:plain

文字のみで行っていた朝会

しかしサポートのために出社しているメンバーは周りにも人が居るため音声によるチャットがしにくいなど、環境の不一致による問題が起こりました。

機材調達もまだだったのでマイクが無い人、音声チャットそのものに抵抗感がある人もいて、全員が気軽に使える状態ではありませんでした。

すると、音声チャットが気軽に使えないことから、あまり大きな問題が無い場合は朝会を短縮もしくは中止してしまうようになりました。それが重なり、徐々にそれぞれのプロジェクトが何をやっているかが見えづらくなっていきました。

これはちょっとマズい状態ですが、この当時はまだ基礎研究や調査が中心だったのでそこまで大きな問題にはなりませんでした。

そうしている間にも、新型コロナウィルスの情勢は一向に良くならず長期化が見込まれたため、4月からは完全にリモートワークへ移行することになりました。

完全リモートワークへ  4月

私たちのチームは4月から完全なリモートワークに移行したのですが、振り返って以下のような問題がありました。

  • 長期間一人で作業をすることで、孤立感が高まっていく

  • 行き詰まったときに解決に以前より時間が掛かる

 

f:id:sgtech:20200614231047p:plain

これは「チーム」としてあまり機能していないことが原因だと考えました。マズいと思い進め方を見直しました。

具体的には以下のように変えました

  1. リモート朝会を毎日やる!

  2. 時間が掛かっても全プロジェクトを対象に行う

  3. 計画、振り返りを1週間単位に見直す、これも全プロジェクトでやる

  4. 雑談も積極的にする

  5. 小さいことでも皆で褒めよう!

不定期になっていた朝会でしたが、全員がリモートワークに移行しマイクも無事到着したので、全プロジェクトを対象に音声チャットでやることにしました。

ダラダラしないようにルールを決めて進めることがポイントです。

朝会で設けたルールは以下のようなものです。

  • 前日の作業内容と今日の予定を事前にチャットに書き込んでおく

  • 共有したいことなども事前にチャットに書き込む

  • 書いた内容を読み上げるのではなく気になったことのみを報告する

  • 司会が順番に発言者を指名する

  • プロジェクトごとの詳細な議論は朝会の終了後にそれぞれ行う

このあたりのルールやWeb会議のノウハウは今や色々なところで紹介されているので、自分達の状況に合ったものを見つけてくると良いと思います。

また情報の共有が終わったあとはそれとなく雑談をするようにしました。時事ネタから技術ネタまで自由に話してOK。もちろん強制ではないので忙しい人は自由に抜けてOKです。

こういう空気はとても大事です、雑談を強制されてもツラいだけですしね。

あまり長時間にならないように、時間に気を付けながら進めることも大切です。

また褒められると嬉しいしハッピーに仕事ができるよね。というわけで、些細なことでも褒めるスタンスで進めていくというルールになりました。 

計画から振り返りの期間を1週間に短縮したのにはいくつか理由があります。

  • 2週間後どうなっているかわからない
  • 2週間分の振り返りをリモートで行うと時間が掛かる
  • プロジェクトに関わりの無い人を長時間拘束してしまう

 などです。

私のチームでは同時に複数のプロジェクトを抱えているという特徴もありこのような理由で期間を短縮しました。

 

ちなみに朝会を含めた私達のチームで行うWeb会議ではカメラはOFFでやっています。

f:id:sgtech:20200614231051p:plain

  • 会議の度に部屋を片付けたくない
  • 服を着替えたくない

など色々な理由があるのですが、Web会議に対する心理的なハードルを少しでも下げたかったのでカメラはOFFで運用しています。

メンドクセと思われたらアウトです。

f:id:sgtech:20200614231041p:plain

私の作業環境

在宅勤務なんだからパジャマで仕事したいと思っている人もいるかもしれません。

ただカメラをONにしたほうが臨場感は出るので、オンライン発表などするときはカメラがあった方が良いですね。

 

最初は時間が掛かって「もう昼じゃん」みたいなこともありましたが、進行の慣れやルールの見直しによって良い感じに進むようになってきました。

こりゃ駄目だなと思ったら柔軟にルールを変え改善していくことが大事です。

ルールの見直しの一例

例えば当初は各プロジェクトに対して一人ひとり発言していたのですが、関わりの無い人には無駄な時間なのでプロジェクトごとの確認は行わないようになりました。
その代わり各プロジェクトのリーダーが事前にプロジェクトの状況をチェックして問題がありそうであれば共有をするスタイルに変わりました。

発言に関しても、初めの頃は何か意見はありますかと呼びかけていましたが、これを司会が指名する方式に変更しました。
これは発言が被ることの防止や、会議の時間短縮に役立っています。

気軽に相談や質問ができる環境を作る

雑談や相談は非常に重要で、何か上手くいかない問題があった場合も誰かに相談した途端に解決することは良くあります。

雑談や相談がリモートではやりにくかったので、積極的に音声で質問や相談を行えるようにルールを作りました。

ルールと言っても話は単純で、事前にチャットで聞くだけです。

「今ちょっと良いですか?」

「5分待ってください」

「わかりました、待ちます」

みたいなやり取りをするだけです。

数回チャットでやり取りをしても解決しなければ音声チャットに移るルールも作りました。

f:id:sgtech:20200614231055p:plain

時間が掛かりそうだと思ったらすぐに音声チャットへ

こんな簡単なやり取りですがチームで意識を合わせることでお互いに相談して良いんだ、質問して良いんだという雰囲気ができました。

チャットでのやり取りに関しては、以下のことに気を付けようとチームで共有しました。

  • 対面の会話より意図が伝わりにくいので、質問するときは前提条件などを丁寧に書こう
  • 対面の会話より感情が伝わり辛いので指摘等はきつくならないよう・誤解を招かないように表記に注意を払おう
  • いいね 等のエモーションを多く使おう

雑談に関しては、雑談専用のチャットルームを作ったり、お昼休みに行うフリーインフリーアウトのビデオチャットルームを作るなどして交流していました。

結果どうだったか

毎日朝会を音声チャットでやることで心理的な負担や孤独感を軽くすることができ、音声チャットへの抵抗感も段々と軽減されていきました。

また各プロジェクトの状況もきちんと把握できるようになりました。

相談を積極的に行えるようなルール作り雰囲気作りによって相談や質問の頻度は格段に上がりました。

相手を褒める姿勢は計画の振り返りの際に、メンバーのファインプレーを挙げたり、フォローされて助かったことなどを相手に伝える行動に繋がりました。

リモートワーク開始当初に比べてチームとして機能するようになったと実感しています。

 

以下は週に一度行う振り返りの様子です。振り返りはKPT(Keep・Problem・Try)方式で行っています。継続したい良かったこと、抱えている問題、トライする項目を書き出し共有する方式です。

コミュニケーションに関してはポジティブな意見が多く出ていることがわかります。

f:id:sgtech:20200614231024p:plain

カンバンを使ったKPT方式の振り返りの様子

まとめ

チームで仕事をする上での強みは相互に補強できることにあると思っています。
チームが上手く回っていないときにそれを妨げている要因は何なのかを見極めることが重要です。

それぞれチームによって事情は違うと思いますが、私達の問題はコミュニケーションにあったので、コミュニケーションを改善することに力を入れました。

  • 仕事のやり方、進め方を変える
  • Web会議への心理的なハードルを下げる
  • 機材を調達する(マイクが無いと音声チャットは厳しい)
  • 当たり前のことでもルールとして周知する
  • チャットでのやり取りで気を付ける点を共有する

こうすることでリモートワークの良いところをそのままに、悪いところを解消できたのではないかと思います。

今後も状況は変わっていくと思いますが、問題を見極めチームの力が発揮できるように頑張っていきます。

 

セガではより良いチームを目指し、一緒に働いてくれる方を募集しています。

興味がある方は下記サイトにアクセスして下さい。

 

 

www.sega.co.jp

 

Pythonの勉強会(入門編)の事例紹介 ―― アプローチを変えてみる

特にこういった方によんでいただけたら・・・

今回のブログは主に次のような方に向けて、Python の社内勉強会を開催した事例を紹介します。

  • Python に興味があって学習したいと考えているが何から手をつけてよいかわからない
  • Python などプログラミング言語の勉強会をこれから開こうと考えている
  • TA(テクニカルアーティスト)やスクリプターなどに Python の使い手をもっと増やしたいと考えている

プログラミング言語を学ぶ側と教える側、両方の方にとって何か少しでもヒントになれば幸いです。

 

今回のブログで伝えたいこと

Pythonの勉強会(全4講演を予定)の入門編である第1回目の講演について予想以上に盛況となった自身の成功体験から得た知見を最初に共有させていただきます。

  • プログラミング(Python)を学びたいと思っているオトナでかつプログラミング経験ゼロないし初心者に対する入門としてはビジュアルプログラミング作業分解が教材としては有効である
  • いきなりPythonに手をつけることは一旦我慢して、まずはプログラミングの基本(順次処理条件分岐繰り返し)を学ぶことが近道である
  • 先にたっぷり自信をつけた上で少し困難なことにチャレンジして成功体験を得られるサイクルになるようになるべく交通整理することで挫折せず継続できる

 

それではPythonを学びたい方、教えたい方への入門の参考教材として、
勉強会当日の内容についてご紹介しようと思います。

第1回目の勉強会の内容とは

当日はワークショップ形式にて開催しました。ワークショップ形式にすることで、

  • グループ内での協力
  • 発想の違いの発見
  • 安心感の向上
  • チームメンバを意識することで集中力の向上

などの効果を期待して設定しました。

またパソコンは使わずに、運営側で鉛筆とプログラムを書くための用紙を準備して、手ぶらでも参加できるようにしました。

 用紙イメージ
f:id:sgtech:20200426204520p:plain

時間の使い方としては、

  • 事前説明に5分
  • 順次処理の学びに30分(ビジュアルプログラミング)
  • 順次処理+条件分岐+繰り返しの学びに25分(作業分解)

で設定しました。

順次処理の学びについて

最初はビジュアルプログラミングを通して、順次処理だけに集中して学んでいただきました。
ここでは、

  • 「自分はできるんだ」
  • 「プログラミングって想像してたより簡単かも」

などといった、自分に自信をつけていただくことが最大の目的です。後半の作業分解の課題の難易度が1段上がることがわかっているため、ここでどの程度自信をつけていただくかによって、後半の課題に対する印象がガラッと変わります。

あともう1つ大事な目的があります。それはプログラミングすることで課題を解決する力を高めることです。

 

教材としては、コマンドをつかってキャラクタを操作して宝箱まで導くといったプログラミングのアナログ的なゲームを準備しました。

それでは、コマンドから見ていきましょう。

コマンドの紹介

キャラクタは各コマンドの内容にしたがって動かすことができます。 

コマンド(記号) コマンドの内容

f:id:sgtech:20200426204457p:plain

向いている方向に1マス進む

f:id:sgtech:20200426204501p:plain

時計回りに90度回転

f:id:sgtech:20200426204505p:plain

反時計回りに90度回転

コマンド3つを理解したところで早速課題に移りたいと思います。

 課題その1

下図の青いキャラクタを先ほど学んだコマンドをつかって宝箱まで到着できれば、課題クリアです。参加者にはプログラムを書く用紙の縦1行を使って、コマンドを鉛筆で書き足してプログラムを完成させていただきます。

正解はたくさんあります。正解の1例としては、下図右側の「プログラム例」をご覧ください。

f:id:sgtech:20200426204509p:plain



またこの課題その1において難易度をあげたければ、以下のような条件を加えてあげましょう。

  • 課題その1-A:コマンド(どれでも構わない)を9つぴったり使って宝箱まで導いてください
  • 課題その2-B:3種類すべてのコマンドを使って宝箱まで導いてください
 課題その2

新しいルールとして「岩」を追加します。岩のあるマスはキャラクタは通ることができません。課題クリアの条件は課題その1と同じですが、参加者は岩をうまく避ける形でプログラムを作成する必要があります。ルールを追加することで課題の難易度をバランスよくあげていきます。

こちらも正解はたくさんあります。正解の1例としては、下図右側の「プログラム例」をご覧ください。

f:id:sgtech:20200426204514p:plain

マスを増やしたり、岩の位置や数を変える(必ず宝箱には到達できる並びにしました。)ことで、難易度を調整することもできます。その場合はよりプログラムが複雑になり、コマンドを書き込む枠を増やす必要があるかもしれません。

ぷちエピソード

勉強会当日、道を岩で完全に塞ぐように配置して宝箱への道を絶ったあとに参加者の皆様に「この場合、どういうプログラムを書けば、宝箱まで到達できますか」と無茶ぶりな質問をしてみました。

すると1人の優秀な方が、「マスの外は歩けないというルールは聞いてないので、マスの外に出て迂回して移動するようにコマンドを書けば良いと思います」という異次元の回答を出してくれました。

f:id:sgtech:20200426204524p:plain



「とっても素晴らしい正解です!」と賞賛させていただきました。

回答者の方が一枚上手でした。

わたしはまだまだプログラマとして、ルールの詰めの部分で修行が足りていなかったというわけです。。。

プログラミングの世界ではこういったルール抜け、欠陥のことをバグといいます。バグによってこちらが意図しないような想定外の問題を引き起こします。

色々な状況や問題を事前にすべてもれなく想像できるようになれることが最高です。

 

このブログを今よんでくださっているあなたも時間が許すようなら鉛筆と紙を準備して、今回の課題のプログラムをご自分の手で書いてみてください。

プログラミングと聞くとパソコンで何か作業をするイメージがとても強いですが、実はそうではないことがわかっていただけたのではないでしょうか。

順次処理がどういったものかイメージはつかめたでしょうか?

プログラミングって意外とカンタンではありませんか?

今回、記号(絵)を使ってプログラムを書きましたが、絵や図を用いるプログラミングを ビジュアルプログラミング といいます。ビジュアルプログラミングとして有名なものとして「ScratchJr(スクラッチジュニア)」、「Scratch(スクラッチ)」などがあります。無料のアプリケーションですので気になる方は調べて触ってみてください。

ちなみにPythonはというと、文字や数字、また記号を用いるプログラミングで テキストプログラミング といいます。


前半は以上となります。

順次処理に加えて、繰り返し、条件分岐の学び

後半では作業分解を行うことで、プログラミングの三種の神器である

  • 順次処理(シーケンスともいいます)
  • 繰り返し(ループともいいます)
  • 条件分岐

について学んでいただきました。

どんな作業でもこの3つを駆使すれば再現できます。

では、当日準備した教材についてご紹介します。

カレー作りの工程を作業分解して学ぶ

まずはカレー作りの工程の例をあげて、「作業分解する」ということがどんな感じなのか学んでいただきました。

わたしなりにカレー作りの工程を作業分解したものがこちらになります。

  1. 野菜の皮をむいて野菜やお肉を一口大に切る
  2. 野菜やお肉を油で炒めて鍋に入れて水を足す
  3. 煮込む
  4. 野菜がやわらかくなったか?
    Yesなら5へ、Noなら3へ
  5. ルゥを溶かして煮込む
  6. カレー完成(※作業ではないですがわかりやすくするために)

f:id:sgtech:20200426204528p:plain

基本的には1から順に行う順次処理となりますが、ポイントは4の作業です。
野菜がやわらかいのかそうでないかでその後の進むべき道が枝分かれすることが条件分岐の考えです。
そして「野菜がやわらかくなる」という条件が満たされるまでひたすら3→4→3→4→…を繰り返して野菜を煮込み続けることが繰り返しの考えです。

几帳面な方だと、3と4の間にアクをとる作業を追加で入れたりするかもしれません。

また人によっては2と3の間に隠し調味料を入れる作業を追加するかもしれませんし、野菜を水で洗ってないことには気づきましたか。あなたならどこに追加しますか?

「作業分解する」ことについて、なんとなくイメージは掴んでいただけましたでしょうか。

 

次は参加者に日頃よく行っているあることについて、実際に作業分解を行っていただきました。

お題は「洗濯」

当日はグループごとにメンバ全員で相談し合って「洗濯」の作業を分解していただきました。

複数人で考えることで、他のメンバの考えを聞いて何か発見があったり、あと前半よりも難易度が上がっている点にみんなで考えれば怖くないといったことなどに期待しました。

また自由に想像・発想してほしかったこともあって、あえてこちらからは条件はつけずに、どういう設定でどこまで細かく分解するかも含めて考えていただきました。

当日の回答を少しだけ

参考に勉強会当日に、あるグループが作成した洗濯の作業分解の回答を1つだけのせておきます。

f:id:sgtech:20200426204532p:plain



条件分岐と繰り返しをちゃんと理解して使っていることがわかります。
今回紹介した回答はブログで掲載するためにぱっとみてわかりやすいものを選びましたが、他の回答ではもっと複雑に作業分解されているものも多くあったり、どのグループも理解力の高さに驚かされるものがたくさんありました。
たまたま賢い方ばかりが勉強会に参加されていた可能性も十分に考えられます。

あなたが日頃無意識に行っている洗濯ではどういう手順で行ってますか?試しに書き出してみると、意外と色々なことを行っている自分(人)の優秀さに気づくかもしれません。

もしロボット(コンピュータ)に洗濯させるとなると一から十まですべて手とり足とり教えてあげないといけません。

 

以上が勉強会の内容となります。

日頃の業務において何か改善したいと思ったときに、どういう手順でどの作業を行って解決するか、その一連の流れを考えることがとても大事です。作業分解を実際に行うことで、この課題を解決するための力、すなわちプログラミング能力を高めることが大いに期待できます。

講師としての成功体験とは

Pythonの勉強会の講師を行っての成功体験をいくつかご紹介しようと思います。

  • 参加人数110人は過去最高を記録
  • アンケート結果がおおむね良好で、特に講演の理解についてはアンケート結果的に全員理解できた様子なのでわたし自身の目標としていた脱落者0についてはおそらく達成できた
  • アンケートの所感欄でも非常にポジティブな所感を多くよせていただいた
実際のアンケート結果

設問:当セッションの内容は如何でしたか?
f:id:sgtech:20200426204535p:plain

設問:講演の内容は理解できましたか?
f:id:sgtech:20200426204542p:plain

設問:講演は今後の業務に役に立ちそうですか?
f:id:sgtech:20200426204546p:plain

印象に残る所感として

60個程度の勉強会に対する所感をいただきましたが、どの所感もわたしにとってはありがたい内容ばかりで、その中でも特に印象に残るものをピックアップしました。 

  • グループの方と交流しながらできたのは楽しかったです。プログラミングへの難しそうという意識がなくなった気がします。

  • ムズカシいのを覚悟していたのですが、非常に楽しく参加できました!

  • 分かりやすかった。プログラミングに対する恐怖感が減った気がした

  • プログラミングに苦手意識があったので、絵を使った導入で、これなら自分でも続けられるかも・・・?と思いました。Pyson使える様になればよいな・・・最後ちょっと慌ただしかったかも?

  • プログラミングをしたことがなかったので、理解できるのか不安でしたが、理解することができました。ありがとうございます。

以上の所感からは参加者の中にはやはり苦手意識や不安などをお持ちの方がそれなりにいらっしゃって、そういった方がプログラミングに対して自信を持ってくれたことが自分としては一番の成功体験でした。

また「次回も楽しみ」といった次への前向きな所感も数多くよせていただいたことも講演者としては非常にありがたく、第2回目への準備にもさらに力が入るきっかけを与えてくれました。

 勉強会あとの反響として

今回はまだ第1回目ということもあって反響は少ないものの、資料に関するお問い合わせがあったり、別のグループ会社様からプログラミングの勉強会に関する相談の打ち合わせをさせていただいたりしました。とにかく評判がよかったことだけは確かなようです。 

そういえば。 Python勉強会の開催のキッカケについて

わたしがPythonの勉強会を企画するきっかけを与えてくださったのは何名かのTA(テクニカルアーティスト)の方の以下の声を拾ったからでした。
(声をあげていただいたTAの皆様にはこの場をお借りして心よりお礼申し上げます。)

  • TAをもっと増やしたい
  • Python使いを増やしたい

Pythonの勉強会を開くにしても、ふたをあけてみて需要がなければ開催の意味がないので先に本当に需要があるのかどうか裏をとるために各部デザインセクションのマネージャの皆様のご協力の元で、グループ内のデザイナーの方へのアンケート調査を行いました。
するとアンケート結果から、

  • Pythonの勉強会に参加したい割合は確かに多い(90%)
  • Pythonを触ったことがないもしくは少ししか触ったことがない方の割合が多い(76%)

という非常に興味深い傾向がわかりました。

今回のPythonの勉強会はまさにこの約76%をターゲットにした内容になっています。

またプログラミングの入門から行うのであれば、デザイナーだけに職種を絞る必要はないことなどから職種は問わないように最終的に変更しました。

職種を絞らなかったことが、結果的に参加人数100人を超える勉強会につながりました。
(アンケート結果:デザイナー62%、それ以外の業種38%)

最後はこのブログの「オチ」をあてようのコーナー

最後はこのブログのオチをあてようのコーナーです。

すでに過去のセガの技術ブログに足を運んでいただいた方や、他の企業様のエンジニアブログなどをよくご覧になっている方なら、すでにこのブログのオチがかんたんに予測できているのではないでしょうか?

まだオチがわからない方は、いくつか過去のブログをチェックしてみてください。この記事や、この記事や、この記事などにヒントが隠されてます。

そのまま行って帰ってこない可能性ももちろんありますが、そういったオチも正解の1つだと思います。

 
弊社ではPython勉強会以外にも、月例の勉強会としてグループ内の色々な立場の方が講師を行ってくださっています。社外からゲスト講師をお招きしてすることもあります。また月例の勉強会以外にも SDC各種イベント(GDCやCEDEC)の報告会、プロジェクト内の勉強会などグループ内には多種多様な勉強会があります。

弊社では、勉強会などを通じて自他共栄を行える人を求めています。

みんなで共に成長して感動体験をたくさん創造しあえたら幸いです。(開発技術部 菊川) 

www.sega.co.jp

©SEGA

スケジュール作成をもっと簡単に。内製アプリケーション「ScheduleCanvas」

早速ですが皆さん。

プロジェクトの計画を立てるとき、スケジュールの作成が面倒だと感じたことはありませんか?

汎用的なExcel等のツールを使って作成すると、まずは管理するためにフォーマットを決めなければならず、途中でのタスクの入れ替えやパスの変更はなかなか容易ではありません。

市販のツールを使おうにもただ試すだけにはハードルが高すぎたり・・・。

そういった悩みを解消するために社内開発に踏み切ったのが、内製アプリケーション「ScheduleCanvas(スケジュールキャンバス)」です。

f:id:sgtech:20200206212358p:plain

今回のBlogではこのツールの仕様と、スケジュール作成がどう変わったのかを紹介するとともに、ツール実装におけるノウハウの一部を少しだけ紹介します。

今回このブログを担当するのは、セガゲームス 第3事業部 第3開発2部 テクニカルサポートセクションの麓です。

まずは私からScheduleCanvasとはどんなアプリケーションなのかなど説明していきたいと思います。

ScheduleCanvasってどんなツールなの?

単体で使用できるアプリケーション

このツール開発は、スケジュール表の作成、タスクの入れ替えをExcelから脱却し、煩雑なフォーマットを統一するためにスタートしました。

また、WebサービスやDBを社内向けに作ってしまうと、外部協力会社との連携のときの障壁が多かったことと、とりあえずアプリケーションを作ってみることでどこまで効果があるのかを見てみるには大きなシステムは向かないということで、単体で動くexe、アプリケーションとして開発されました。

f:id:sgtech:20200206212540p:plain

アイコン

ガントチャートと各リストで構成

画面要素はガントチャートをベースにそこに表示されるデータがリスト形式になっています。

ガントチャートによって、スケジュールの可視化ができ、マウス操作を充実させることで、簡単にタスクの入れ替えや調整ができるように作られています。

主な動作をいくつか紹介します。

タスクの作成

f:id:sgtech:20200206213605g:plain



タスクをガントチャート上で簡単に登録でき、タスク名も即座に変更することができます。

担当者変更

f:id:sgtech:20200206215139g:plain

担当者の追加とタスクのアサイン変更もドラッグ&ドロップで手軽に行えます。

休日の自動調整

f:id:sgtech:20200207160420g:plain

タスクの長さは工数(日数)ベースで設定されていますので、休日を跨ぐと自動で長さを調節します。

オート整列機能

f:id:sgtech:20200207160951g:plain

複数のタスクを並べ直して総工数を確認する機能も充実しています。

 

また、ガントチャートに表示される情報は全てリスト形式で管理され、リストの編集性もできるだけExcelに近づくように(完全再現への道はまだ遠いですが)設計されています。

例えば、リスト項目のコピペや追加、削除、順番の入れ替えは簡単にできるように作られています。

リスト処理「タスク一覧」

f:id:sgtech:20200207185005g:plain

Excelのような外部アプリケーションのリストから、コピー&ペーストでタスク登録、一覧のセルの内容のコピーペースト、値も外部アプリケーションからコピーペーストで設定することもできます。

リストのフィルター機能

f:id:sgtech:20200207192447g:plain

各要素のフォーカスを切り替えられるようなフィルター機能は大量のタスクを管理するのには重要な機能です。

 

また、スケジュール作成の簡便化やフォーマットの統一等はScheduleCanvasを使ってもらうことで解決していますので、印刷や報告書などに活用できるようにExcel出力機能も用意しています。

f:id:sgtech:20200207193346p:plain

このように、主だった機能はゲーム開発者であるユーザーのニーズに常に答えるようにしてアプリケーションは開発されました。

外部連携

Excelの他にも各種チケット管理やバグトラッキングシステムなどと連携させて、ガントチャート視覚化も実装済みですが、今回は記事のボリュームを考慮して割愛させていたできます。

その効果は?

機能実装がある程度落ち着き、現在では多くのプロジェクトで試用してもらっています。

そこで今後の開発継続に向けて参考にするために、ちょっとしたアンケートをとって見ました。

集計結果は…。

質問:ScheduleCanvasを利用するメリットを感じますか?

f:id:sgtech:20200207194313p:plain

質問:ScheduleCanvasを利用して、効率化した部分はありましたか?

f:id:sgtech:20200207194316p:plain

ここでは概ねポジティブな印象です。

また、意見として以下のようにもいただいていますので、ひとつひとつを参考にさらに使いやすいツールにするために開発を続行していきます。

良い意見
  • スケジュールの入れ替え、パスの調整等にかかる時間が短縮した。
  • ユーザーのタスク負担度が一目でわかる。
  • 今までバラバラだったスケジュールのフォーマットが統一され、見やすくなった。
改善が必要な意見
  • タスクの検索がExcelの検索より一覧性がない。
  • 開発会社に委託する業務が多く、他社提出のスケジュール(Excel)との共存が難しい。
  • 動作をとにかく軽くしてほしい。

他にもアンケートとは別にExcelで管理してたときよりも確実に30%は効率化できているという声もありました。

社内ツールを開発する上で定期的なアンケートはとても有用で、現在主にどう使われていて、何が一番ボトルネックになっているのかのスコープを探るときに活用しています。

今後も・・・

内製アプリケーションということで、手軽なカスタマイズや要望に応じて機能実装を即時対応できるというのが大きなメリットとなります。

単純なスケジューラーは数あれど、ゲーム開発の現場でゲーム開発の状況に応じて作られているアプリケーションは他の会社だったとしても同じような問題に行き当たることが多いと思います。

こういったゲーム会社に特化した内製ツールだからこそ、会社の枠を超えていつか提供できるようにして、業界に貢献できたらという願いで製作しています。

ご興味ある方は…と言いたいですが、現時点ではそういった準備が整っていないので今しばらくお待ち下さい。

実装ノウハウをちょっとだけ

ここからは実装担当の清水から、このアプリケーションの実装について軽く触れてもらおうと思います。

 

というわけで本パートを担当させていただきます、セガゲームス 第3事業部 第3開発2部 テクニカルサポートセクションの清水です。

 

今回は、いろいろと応用ができそうなExcel出力に関する実装について紹介しようと思います。

 ScheduleCanvasのExcelファイルの出力にはClosedXMLというオープンソースライブラリを使用しています。(https://github.com/ClosedXML/ClosedXML

f:id:nobutoshi_shimizu:20200213162255p:plain

簡単なコードでExcelワークシートを作成することができ、Excelファイル(.xlsx)で保存することができます。

また、PCにExcelのソフトウェアがインストールされていなくてもExcelファイルを作成することができます。これは、スタンドアロンツールであるScheduleCanvasにとって、とてもありがたい特徴でした。

NuGetからインストールできるのでVisual Studioを使用しているならば、インストールも簡単にできます。 

 

ClosedXMLを用いてExcelファイルを作成するには以下のようなコードを書きます。

//新規ワークブックを作成
var workbook = new XLWorkbook();

//新規ワークシート「Sample Sheet」を作成し、先ほど作成したワークブックに追加
var worksheet = workbook.Worksheets.Add("Sample Sheet");

//作成したワークブックを"HelloWorld.xlsx"として別名で保存
workbook.SaveAs("HelloWorld.xlsx");

このコードでは、初めに新規ワークブックを作成し、そのワークブックに新たなワークシート「Sample Sheet」シートを作成、ワークブックを「HelloWorld.xlsx」として保存しています。

f:id:sgtech:20200223205604p:plain

作成されたHelloWorld.xlsx

では次に、ワークシートに何か値を入れてみましょう。

//新規ワークブックを作成
var workbook = new XLWorkbook();

//新規ワークシート「Sample Sheet」を作成し、先ほど作成したワークブックに追加
var worksheet = workbook.Worksheets.Add("Sample Sheet");

//「Sample Sheet」シートのA1セルの内容に"Hello World!"を記入
worksheet.Cell("A1").Value = "Hello World!";

//作成したワークブックを"HelloWorld.xlsx"として別名で保存
workbook.SaveAs("HelloWorld.xlsx");

このコードでは、初めに新規ワークブックを作成し、そのワークブックに新たなワークシート「Sample Sheet」シートを作成、「Sample Sheet」シートのセルA1に「Hello World!」を記入して、ワークブックを「HelloWorld.xlsx」として保存しています。

f:id:sgtech:20200223205713p:plain

A1セルにHello World!を入力した出力結果

//「Sample Sheet」シートのA1セルの内容に"Hello World!"を記入
worksheet.Cell("A1").Value = "Hello World!";

この部分がセルに値をセットする部分です。

セルの指定方法は、複数あります。
以下のコードはいずれもA1セルを指定しています。

//セルのアドレスの文字列で指定
worksheet.Cell("A1").Value = "Hello World!";

//セルの行と列の数字で指定 ※最小は1、0だとエラーになる
worksheet.Cell(1, 1).Value = "Hello World!";

//セルの行は数字、列は文字列で指定
worksheet.Cell(1, "A").Value = "Hello World!";

実際にプログラムを組む際は一番よく使うのは、行と列ともに数字で指定する方法になるかと思います。

 

セルには値だけでなく、背景色、フォント、文字列の配置位置、数値の書式、枠線のタイプ、枠線の色なども設定できます。

//「Sample Sheet」シートのA1セルを変数に入れる
var cell = worksheet.Cell("A1");
 

//セルの背景色(R=255,G=0,B=0)に設定
cell.Style.Fill.BackgroundColor = XLColor.FromArgb(255,0,0);

//セルの文字のフォントをHGS創英角ポップ体に設定
cell.Style.Font.FontName = "HGS創英角ポップ体";

//セルの文字の水平方向の配置位置を中央に設定
cell.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;

//セルの文字の垂直方向の配置位置を中央に設定
cell.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center;

//セルの数値の書式を"yyyy/mm"に設定 任意のフォーマットに指定可能
cell.Style.DateFormat.Format = "yyyy/mm";

//セルの周りの枠線を点線に設定
cell.Style.Border.OutsideBorder = XLBorderStyleValues.MediumDashDotDot;

//セルの周りの枠線の色を黒色に設定
cell.Style.Border.OutsideBorderColor = XLColor.Black;

 

//文字の配置位置をわかりやすくするためにセルの大きさを変更
worksheet.Column(1).Width = 50;
worksheet.Row(1).Height = 50;

f:id:sgtech:20200223205717p:plain

セルにいろいろ設定した出力結果

手作業でExcelを編集するときと同じように、セル単体ではなく範囲を対象に設定することもできます。

//「Sample Sheet」シートのA1セルからC5セルの範囲を変数に入れる
//範囲の指定は左上のセルと右下のセルを指定する
var range = worksheet.Range(worksheet.Cell("A1"), worksheet.Cell("C5"));
 
//範囲内の全てのセルの背景色を青色に設定
range.Style.Fill.BackgroundColor = XLColor.Blue;

f:id:sgtech:20200223205722p:plain

複数のセルを範囲指定して背景色を設定した出力結果

このほかにも、

複数のセルを一つのセルにする「セルの結合」

//結合したいセル範囲を指定して...
var mergerange = worksheet.Range(worksheet.Cell("B2"), worksheet.Cell("D4"));

//Merge()で範囲のセルを結合する
mergerange.Merge();

 

//値を設定してみる
mergerange.Value = "結合セル";
//文字の配置位置を中央に設定
mergerange.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
mergerange.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center;

f:id:sgtech:20200223205727p:plain

セルの結合を設定した出力結果

ワークシート上のデータを抽出して表示できるようにする「オートフィルタの設定」

//例示のために


セルにデータを入力

worksheet.Cell("B2").Value = "名前";
worksheet.Cell("C2").Value = "味";
worksheet.Cell("D2").Value = "知名度";
worksheet.Cell("E2").Value = "値段";
 
worksheet.Cell("B3").Value = "リンゴ";
worksheet.Cell("C3").Value = "甘い";
worksheet.Cell("D3").Value = "一般的";
worksheet.Cell("E3").Value = "500";

worksheet.Cell("B4").Value = "みかん";
worksheet.Cell("C4").Value = "甘い";
worksheet.Cell("D4").Value = "一般的";
worksheet.Cell("E4").Value = "300";
 
worksheet.Cell("B5").Value = "チリドッグ";
worksheet.Cell("C5").Value = "辛い";
worksheet.Cell("D5").Value = "低い";
worksheet.Cell("E5").Value = "700";

//オートフィルタを設定したいセル範囲を指定して...
var filterrange = worksheet.Range(worksheet.Cell("B2"), worksheet.Cell("E5"));

//SetAutoFilter()でオートフィルタを設定する
filterrange.SetAutoFilter();

 

//見やすいように範囲内のセルに枠線を設定
filterrange.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
filterrange.Style.Border.InsideBorder = XLBorderStyleValues.Thin;
//見やすいようにセルの幅を設定
worksheet.ColumnWidth = 20;

f:id:sgtech:20200223205732p:plain

オートフィルタを設定した出力結果

特定の行や列を固定表示したままシートをスクロールできるようにする「ウィンドウ枠の固定」

//固定するワークシートの1~2行目とA列B列をピンク色に設定
worksheet.Column(1).Style.Fill.BackgroundColor = XLColor.Pink;
worksheet.Column(2).Style.Fill.BackgroundColor = XLColor.Pink;
worksheet.Row(1).Style.Fill.BackgroundColor = XLColor.Pink;
worksheet.Row(2).Style.Fill.BackgroundColor = XLColor.Pink;

 

//行と列の数字を指定して「ウィンドウ枠の固定」を行う
//Freeze(2, 2)だとC3セルを指定して「ウィンドウ枠の固定」したときと同じ状態になる
worksheet.SheetView.Freeze(2, 2);

 

//セルの指定では0を指定するとエラーになったが、この処理は0が指定できる
//0を指定すると、行方向だけ、または、列方向だけにウィンドウ枠の固定ができる
worksheet.SheetView.Freeze(2, 0);

 

//行方向だけ、または、列方向だけウィンドウ枠の固定をするための別メソッドもある
worksheet.SheetView.FreezeColumns(2);
worksheet.SheetView.FreezeRows(2);

f:id:sgtech:20200223205738p:plain

ウィンドウ枠の固定を設定した出力結果

上記のとおり、Excel上で設定できるものは基本的にコード上で設定することができます。

 

ScheduleCanvasでは、これらを使ってツール上で表示している見た目と同じようなExcelファイルの出力を実現しています。

以下の2つの図はScheduleCanvas上での見た目と出力したExcelの見た目をそれぞれキャプチャしたものです。

f:id:sgtech:20200223205743p:plain

ScheduleCanvasの見た目

f:id:sgtech:20200223205750p:plain

ScheduleCanvasから出力したExcelファイルの見た目

なかなかの再現度ではないでしょうか。

ここまで見た目にこだわるとコードも結構複雑になりますが、データを出力する際に見出しの行に色を付けたり、オートフィルタを設定するだけならば簡単に実装できます。

皆さんも試してみてはいかがでしょうか。

 

ひとまずはツールの実装の一例としてExcelファイルとの連携をご紹介しましたが、ユーザーの要件に応えるために一つのツールには他にも多くの技術が盛り込まれて実装されています。

このようなゲームを作るための周辺ツールやワークフロー、ゲームエンジンのノウハウが豊富で、情報共有が盛んな職場で働いてみたいという方はぜひ、以下をチェックしてみてください。

 

www.sega.co.jp

(C) SEGA

ゲームジャムでUnreal Engine 4を使ってみよう

ごあいさつ

はじめまして、セガ・インタラクティブ 第三研究開発部の若井です。アーケードゲームのプログラマーをしています。携わったタイトルはえ~でる すなばWCCF FOOTISTA 2019 などです。Unreal Engine 4 (以下UE4)の活動としては昨年の「UNREAL FEST EAST 2019」にてWCCFシリーズのUE4移行について発表いたしました。スライド(リンク先の説明欄より、動画と台本付きの資料をダウンロードしてください。)

記事の対象

今回はゲームジャム(文章中は「ジャム」と略します)の定義を、会場へ集まって1、2日で制作するものから期間1ヶ月程度までのコンテストとします。期間が長いものは当てはまりません。当てはまらない例:期間が10年もあるジャム

また、記事内容はジャム特化の内容となっておりますので、製品開発に必ずしも役立つものではない(技術的負債になりえる)ことをご了承ください。

記事のモチベーション

今回は私がUE4を使用したジャムで実際に活用したノウハウの内、他のジャムにも転用できそうなものをご紹介します。全体の話もしますが、主にプログラマー向けの初歩的なものが多いです。

ジャムでは結果よりもプロセスを楽しむことや経験することが重要であります。とはよく言われるものの、躓きが多いと楽しくない印象で終わることもあります。記事内のコンテンツで皆さんのジャムを快いものにすることができれば幸いです。

f:id:sgtech:20200126210259g:plain思惑と違ってしまうジャムもしばしば

おまけで記事の末尾にこれまでに制作したジャム作品を羅列しておきました。

ジャム当日までの準備

前日の十分な睡眠の他に、開発環境など事前に用意できるものがあります。

開発PCや実行環境

UE4を用いた開発PCについて、公式の推奨環境があります。会場に集まるジャムの場合はノートPCを持ち込むことになります。ご自身のノートPCスペックを確認してみてください。ジャムの会場によってはPCの貸し出しを行っている場合があります。

経験上UE4を使用する場合は3Dゲームを作ることが多いので、グラフィックカードの搭載された「ゲーミングノートPC」を持ち込むことをおすすめします(プログラマーの場合は特に必須)。

ノートPCの例

私はMSIのノートPCを愛用しています。冷却性能が優れておりジャム中に安定稼働しています。MSIさんのPRではございませんが製品名を挙げさせていただきます。各PCのスペックを参考にしてください。

・PS63 Modern

ジャムに持ち込んだときにゲーミングノートPCとしての役割を持てます。コンパクトでバッテリーも多いので、ジャム以外にも長めの勉強会などでメモ取り用として持っていける機種です。スペックとしては最低限で、2日程度の期間内でも処理負荷が大きいとゲーム開発中のカクつきが見受けられます。

・GE75 Raider

スリムでありながらVRゲームの開発にも対応できます。MSIのノートPCにはボタン1つでクーラー出力が最大(プロファイルの変更)となる機種があり、私はこのボタンをとても気に入っています。

スペックが低い環境の極端な例

おまけの④では、コンパクト性のためシングルボードコンピュータ (Latte Panda)上でアプリケーションを動作させました。デフォルトの状態では処理速度が追いつかなかったため、ジャム中にゲームのプロファイリングをして重い処理を取り除いていく必要がありました。おすすめしません。

f:id:sgtech:20200126210128p:plain←FlyingTemplateで10FPS

マウスを使用する(重要)

テンプレートを使用したゲームではカメラ視点操作をマウスで行ったほうが楽な事が多々ありますので、用意しましょう。

ビジュアルスクリプト「Blueprint」を使って開発することになります。慣れた操作でBlueprintノードを組み立てるためにノートPCと一緒にマウスを持ち込みましょう。

特にプログラマーは短時間で大量のBlueprintノードを操作すると腕が痛くなります。湿布を用意するか軽いマウスを使用することをおすすめします。

↓ ノードの総量はこのグラフ(おまけの⑩のBlueprint)くらいの量になるのではないでしょうか。ジャム中は試行錯誤でノードの作成と移動、ワイヤー接続と切断を繰り返しますので、グラフの見た目以上に手を動かすことになります。

f:id:sgtech:20200126210317j:plain

おまけの⑩では、制作時のグラフ切り替えやクラス間の画面切り替え時間を減らすためにほぼ1つのグラフに処理が集約されています。

仕事では書かないグラフなので見せるのはちょっと恥ずかしいです。

USBメモリ

どのジャムでも、素材やプロジェクトを共有するための手段が必要になります。1人1つUSBメモリを持っておくのが吉です。

共有ドライブが整備されたジャムもありますが、多くの会場では貧弱な無線環境ですのでUSBメモリのほうが共有しやすいです。

チーム内の数が少ないとUSBメモリ使用のための待ち時間が発生することがあります。発生したことがあります。

コントローラ

XInput形式のものを持ち込む

UE4は標準でXInputに対応しており、UE4のテンプレートは最初からキャラクターやカメラ操作のインプットアクションがアサインされています。

ジャムで制作するゲームはXboxコントローラのようなインターフェースが適することが多く、キーボードが必須であるアイデアは稀です。

持っている人は持ち込んでみましょう。

f:id:sgtech:20200126210552j:plain

年季の入ったコントローラや自作のアーケードコントローラ

お気に入りのコントローラを持っていて、ジャムで使用したくなることがあります。しかしXInputに対応していないことがあります。

UE4はDirectInput形式に対応しておらず、実際にUSBで繋げてみたがUE4のゲームで認識されない場合は概ねこちらが原因でしょう。

DirectInput形式はXInputより古い形式であり、UE4で扱うにはコードを書く(OSSのPluginを導入するのが楽)必要があります。こちらの導入については後述します。

f:id:sgtech:20200126210612j:plain自作コントローラそれはロマン

やってみたいことの妄想

こんなゲームを作りたい、こんな技術を作りたいといった思いはジャムに反映されやすいです。アイデア出しの種にもなりますので、考えてみてください。末尾のおまけには私のジャム参加前のモチベーションを添えてみました。

ジャム当日:アイデア出し

アイデア出しの裏で、UE4がインストールされていない人はこの間にインストールしましょう。

ワードマップから始める

私がよく使う手法を紹介します。

ゲームジャムはテーマとして単語や文章が与えられることが多いです。与えられたテーマより連想するワードを付箋などに書き出し、ワードマップにします。

このとき、名詞・動詞・状態(ゴールや目的)などを意識します。

f:id:sgtech:20200126225159j:plain

出てきたマップについてみんなで議論することになります。ここでの強力な手法の1つに「EMS Framework Method」というものがあります。

EMS Framework Methodについて紹介されている記事

こちらを少し簡略化して、「プレイヤー(名詞)が〇〇して(動詞)、□□という結果になる(状態)」という枠にワードを当てはめます。名詞、動詞、状態のうち2つ当てはめれば、ワードマップに無い言葉も生まれてくることでしょう。 

例えばおまけ⑫では、「☆」というテーマが与えられて「ヒトデ」「流れ星」といったワードが出てきました。枠内の名詞・結果に当てはめてみると、「ヒトデが〇〇して(流れ)星になる」となるので、残りの〇〇を皆で考えた結果、ビッグなスターになるということで「巨大化」という動詞が生まれてきました。

f:id:sgtech:20200126210936p:plain

アイデアの大枠が決定した時、UE4のテンプレートが使えそうか考える

UE4の使用経験のあるプログラマーは、決定されたアイデアにUE4のテンプレートを流用できるか考えてみましょう。流用できる場合は制作が楽になります。

f:id:sgtech:20200126210623p:plain

流用しない場合は考える楽しみがあります。おまけ⑨ではテンプレートを使用しませんでしたが、未知のものを作れそうなワクワク感がありました。

末尾のおまけでは、各ゲームが使用したテンプレートを記載しました。

ToDoリストを作成する

ゲームに必要な機能、要素を分割して、やるべきこと・やっていることを可視化します。

f:id:sgtech:20200126210428p:plain

運用につきましては過去の記事に詳しく書かれておりますので、こちらをご覧ください。

techblog.sega.jp

 

ジャム当日:最初にやること

テーマ決めより使用するテンプレート(または空のプロジェクト)はプログラマーが判断すると思うので、その方がプロジェクトを作成して配布するといいでしょう。

バージョン管理システム(VCS)を決める?

今現在Blueprintは更新が衝突したときのマージをマージツールで実現することが難しいです。よって衝突を防ぐためにファイル単位で担当を決めて作業することになります。

もし衝突した場合はUE4プロジェクトを両方開いて、Blueprintグラフ上で作業することになります。幸いBlueprintグラフはコピペが効きます。

おまけの⑪では、画像↓のようにPlayerやEnemy、大砲(Cannon)から放たれるMEGA DRIVEなどに分けました。Playerと大砲を担当する人とEnemyを担当する人に分かれ、各々でクラスファイルを実装しつつ相手のクラスに処理を追加したい場合は相手に仕込んでもらうようにしました。

f:id:sgtech:20200126210419p:plain

では、どのVCSを選びましょうか。

VCSを使用せずにUSBメモリを使用する

私のオススメUSBメモリを使用することです。経験上これがベストでした。

最初にプロジェクトを共有した後は図のような手順でローカルからUSBメモリへの更新と、USBメモリからの更新をローカルに適用します。

 f:id:sgtech:20200126210424p:plain

②のUSBメモリにコピーする際、周りのメンバーに何を更新したのか共有することを忘れないようにしてください。

私のオススメは定期的に全員で進捗確認の時間を設け、確認後にUSBにコピーすることです。確認をしたので、どんな更新がマスタープロジェクトに入っているか把握することができます。もちろん、プランナーやレベルデザイナーが最新の状態を触るために細かくやり取りすることも大事です。

USBメモリ側でもバックアップをしてもいいですが、ジャムの後半になるとそんなことは忘れます。①の部分も忘れられ②と③になることでしょう。しかし、このファイル共有作業において自分の更新分がどこかで消滅するとモチベーションが結構下がってしまうものです。面倒でも自分のローカルでバックアップを取るようにしましょう。そうすれば手違いが起きてしまったときに担当者がバックアップから取り出して確認し復旧しやすいです。

私の主観ですがUSBメモリの受け渡し形式はコミュニケーションの機会が増えるので、実装内容や予定の相談を行いやすいと感じます。

VCSを使用する場合
  • 安定したネットワーク環境であること
  • VCSを全員が操作できて問題解決もできる

といったチームであれば問題ないと思います。また、チームのプログラマーが3人以上であれば検討してよいと思います。

私は無線環境での更新の遅さやSVNのCleanupに悩まされた経験があります。ジャムの後半に問題が起こるととても焦ります。

Content直下にゲームジャム用のフォルダを作成する

このとき、名前を「数字_ゲームジャム(プロジェクト)名」にします。記号や数字を頭に持ってくることで並びが一番上に来ます。フォルダ名をチームで共有して、作業フォルダを明らかにしましょう。

f:id:sgtech:20200126210121p:plain

ゲームジャム後半などで、作業フォルダを見失うことを避けることができます。

例えばテンプレートやスターターコンテンツまたはMarket Placeのアセットなどを導入すると、Content「コンテンツ」フォルダ以下が肥大化することが多々あります。

下図は過去のゲームジャム(おまけの③)フォルダ構成なのですが、主な作業フォルダである「SGJ201707」を見つけることに苦労します。

f:id:sgtech:20200126210125p:plain

ゲームジャム2日目などはフォルダ名がとっさに思い出せないことやアルファベット順に並んでいることも頭から抜けていることがあります。ぜひ一番上に表示されるような名前を付けてみてください。

「Debug」フォルダを作成するときも「00_Debug」などにすると探しやすくなります。

各々の名前のフォルダで作業する

個人名のフォルダを作成し、自分の名前のフォルダ以下で開発を行うで複数人が同じアセットに対して作業することを防ぐことができます。

デバッグフォルダと同様、先頭に数字を入れると探しやすくなります。

f:id:sgtech:20200126210940p:plain

外部デバイスや使用したいコードのプラグインがある場合は、C++プロジェクトを作成する

UE4の標準機能では実現できないために外部のOSSを使用するときは、プロジェクト作成時にブループリントベースではなくC++ベースのプロジェクトを作成する必要があります。

これまでジャムで使用したことがあるサードパーティのプラグインを紹介します。

UE4Duino:Arduinoとのシリアル通信

傾きや照度などセンサー情報の受け取りや、回路へシグナルを出力してLEDを点灯させる等の場合に使います。(おまけの④で使用)

GitHub - RVillani/UE4Duino: Unreal Engine 4 plugin for COM communication on Windows

使用方法はGitHubのREADMEに載っている画像がわかりやすいです。

OpenSerialPort関数で得たSerialObjectの参照を使用してメッセージ送受信の関数を呼びます。Arduinoからメッセージを受け取る場合はRead〇〇関数、メッセージを送る場合はPrint関数です。

f:id:sgtech:20200126210730p:plain

 

おまけ④では複数発のLEDを制御するため、やりとりするメッセージの形式を「LED_(インデックス)_(点灯か消灯か)」に決ました。

Arduino側では受け取ったメッセージを解釈してLEDを点灯(消灯)させる処理を書き、UE4アプリ側では形式に合ったメッセージの文字列を合成して送信する処理を書きました。

f:id:sgtech:20200126210734p:plain

 

おまけ④以外のジャムでもUE4Duinoを使用する機会があり、傾きセンサの情報の取得を試みましたが、期間中にうまくいかず挫折したことがあります。

2日間のジャムで1日目にUE4で挫折して2日目でUnityを使って1から作り直したという苦い思い出です。悔しくて家でUE4バージョンも作り直しました。

f:id:sgtech:20200126210133g:plain

DirectInput:Joystickの使用

XInput非対応のコントローラを接続したいときにOSSのPluginを導入します。

GitHub - Ikarus76/UEJoystickPlugin: Unofficial Joystick Plugin for the Unreal Engine

 フォーラム:Joystick Plugin - Unreal Engine Forums

 

UEJoystickプラグインではスティックの軸値関数とボタンのインプットイベントより、望みの値を簡単に取得できます。PluginのReadmeにもあるように、Input用のActorまたはComponentを配置することを忘れないようにしてください。

f:id:sgtech:20200126210619p:plain

 

おまけの④ではAmazonでアーケードコントローラのDIYセットを購入し、専用のコントローラを作成しました。よく売っているタイプのエンコーダ接続は下図のようになります(4ボタン)。

f:id:sgtech:20200126210615p:plain f:id:sgtech:20200126210946j:plain

スティックはAxis値が中途半端(1.0ではなく、0.999などの値)になっていることがありますので、0.0や1.0を計算のしきい値にするような場合は注意してください。

OceanProject:リアルな海と浮力のシミュレーション

おまけの⑪では、海と船を使用するためOSSのOceanProjectを使用しました。

GitHub - UE4-OceanProject/OceanProject: An Ocean Simulation project for Unreal Engine 4

f:id:sgtech:20200126210556g:plain

とてもリアルな海、浮力のシミュレーションなどが含まれています。

素早く自分の好きな物体へ浮力を適用するためのヒントとしては、OceanProject内で既に浮力が与えられているBlueprintのメッシュを差し替えて流用することです。

↑の動画で見えるように、オブジェクトへ◇型をした浮力シミュレーション用のテストポイントがアタッチされています。テストポイントの位置や、細かい浮力パラメータを調整することができます。

OceanProjectを初めて触る場合、導入して使い方を覚える時間を考慮すると2日のジャムでは時間が足りないかもしれません。三角関数の単純な浮き沈み処理を書いた方が早くて楽だと思います。

プロジェクト作成者が最初に配布する内容

以下のフォルダを共有します。

  • Configフォルダ
  • Contentフォルダ
  • DerivedDataCacheフォルダ
  • 〇〇.uproject ファイル
  • Pluginsフォルダ(追加した場合。中のIntermediateは除外)
  • Binariesフォルダ(C++プロジェクトの場合)
  • Sourceフォルダ (C++プロジェクトの場合)

また、大きなテンプレートやアセットを最初から導入していた場合、共有DDCを設定してあげると初回のシェーダコンパイルが走らず、親切です。こちらの記事を参考に、

[UE4] DDCを共有してストレスフリーな開発を!|株式会社ヒストリア

「Path=%GAMEDIR%/DDC」を記述、.uprojectと同じフォルダに「DDC」という名前のフォルダを作成してプロジェクトのエディタを起動しましょう。

エディタを起動し、シェーダのコンパイルが終了したらDDCファイルごと共有します。

おまけの⑪では、サイズの大きいOceanProjectというOSSを最初に導入しました。導入時の共有DDC設定をすることで、渡してすぐに実行を試してもらうことができました。

初めてUE4を触る方・初めての方に教える方

おまけ⑫のジャムではメンバー5人のうちUE4の経験者は私だけでした。教えながら・調べながらのスタイルもゲームジャムですので、やってみたいという気持ちだけで当日を迎えても大丈夫です。

操作方法を教わりながら、初めての方が間近で挑戦されているところを見てきたので、事例を紹介します。

書籍を見ながらコインを実装

おまけ⑥のジャムでは、学生のプログラマー(UE4やUnityの経験無し)が書籍を見ながら、プレイヤーが触れると消滅するコインを作成しました。

Unreal Engine 4 で極めるゲーム開発 | ボーンデジタル

f:id:sgtech:20200126210326p:plainf:id:sgtech:20200126210330p:plain

f:id:sgtech:20200126210349p:plain

具体的には15章3節の「ピックアップアイテムを作る」の部分です。

UIのチュートリアルを見ながらメニュー、ゲーム中UI、結果画面を作成

おまけ⑫のジャムでは、内定者学生のプログラマー(Unityの経験者)が公式webのチュートリアルドキュメントを見ながらUIを実装しました。

UMG UI Designer Quick Start Guide | Unreal Engine Documentation 

f:id:sgtech:20200126210334p:plainf:id:sgtech:20200126210338p:plain

f:id:sgtech:20200126210341p:plain

制限時間を表現する処理にも挑戦していました。

レベルデザインやランドスケープツールの利用

おまけ⑫のジャムでは、Unity経験者のプランナー2人がプレイヤーのパラメータ調整とステージ作成を分担や協力をしてレベルデザインや見た目の調整をしていました。

f:id:sgtech:20200126210949p:plain f:id:sgtech:20200126210954p:plain



Unity経験者は慣れるスピードが早いのだとは思いますが、右の画像の海感は素晴らしいです。パラメータ調整も小数点第二位の値までこだわっており、完成度の高いゲームができあがっていました。

わからないところは質問しよう、わからなさそうなところに気づいたら教えよう

エディタ操作方法やBlueprintの実装方法など、初めての方にはわからないことが沢山あります。UE4の経験者は都度補足してあげることが重要ですし、初心者の方はわからないことを都度経験者に伝えることが重要になります。

初心者の方はUE4エディタに慣れてきたら、次はwebで検索して試すことにチャレンジしてみましょう。

こちらの写真は前回記事の写真でして、↑のUIチュートリアルを進めている方に対してドキュメントの内容と自分たちのゲームを照らし合わせて補足しているときのものです。

f:id:sgtech:20200126210345p:plain

よく聞かれたもの

UE4初めての方よりどういった質問や回答が多かったかを挙げてみます。

ビューポートやアウトライナについて

レベルデザインにおいて物体の配置(移動や回転)や見たい位置へのカメラ移動のとき、操作に対して思ったより動きが小さい場合や大きすぎる場合があります。

ビューポートの上部にある設定項目をいじりましょう。特にカメラ速度とフィールドの大きさが噛み合っていないと移動に時間をとられます。

f:id:sgtech:20200126210756p:plain

 

アウトライナの中でフォルダ分けしたいときは、フォルダのアイコンを押します。

おまけの⑫では捕食対象の種類によってフォルダ分けし、パラメータ変更時に選択しやすくなっていました。

f:id:sgtech:20200126210759p:plain f:id:sgtech:20200126210825p:plain

 

フィールドが広大な場合は、オブジェクトをアウトライナで選択した状態で「F」キーを押すとカメラがオブジェクトの近くに移動してフォーカスされます。

f:id:sgtech:20200126210830g:plain 約1.5kmの距離を一瞬で移動

Blueprintの基本的な操作

隣に座って画面を操作してもらいながら口頭で説明することが多いです。ドキュメントを見て貰う場合はマウス操作の説明や、画像に赤い枠などの印をつけて説明されているものを紹介しましょう。 

 

さわりとして、マウスの操作方法や画面の説明をすることが多いです。

↓こちらのドキュメントと同様な話をします。

【UE4】ブループリント入門【第1回】 | TECH Projin

 

算術演算子や、変数の定義方法もよく聞かれます。

↓こちらのドキュメントと同様な話をします。

ブループリントの基本を覚えよう | Think IT(シンクイット)

 

Blueprintワイヤーの切断方法

Blueprintワイヤーの切断方法は質問率ナンバーワンです。しかし多くの入門ドキュメントでは接続方法の近くに切断方法が書かれておらず、「Blueprint 切断」といったキーワードで検索しなおすケースが多いです。

切断と、ついでに付替のショートカットを覚えましょう。

  • 切断:ワイヤー上でAlt+Click
  • 付替:ワイヤー(切断側)上でCtrl+Click

f:id:sgtech:20200126210803g:plain

ノードのピンから右クリックでも切断できますが、ショートカットの方が早く便利です。

プランナー、ゲームデザイナー向け(プログラマーも見てね)

アイデア出しが終わったあとには、プレゼン資料の作成や詳細仕様を考えることに頭を悩ませると思います。今まで一緒にジャムをした方の立ち回りについてプログラマーの目線からご紹介します。

レベルデザイン

動くものを触ってみることが重要です。触ってみた結果、当初考えていたイメージと異なっていることに気づき、改修や調整の判断ができます。レベルデザイン担当者の試行回数が多かったときほど、手触りのよいゲームになっていると感じます。

なので、プログラマーにお願いしてパラメータを調節できるようにしてもらいましょう。プログラマー向けTipsにヒントを書いておきました。

例えばおまけの⑫では、プログラマーがプレイヤーの成長率(ジャンプの高さや身体の大きさ、乗り越えられる段差の高さなど)を調節できるようにして、プランナーの2人が地形とパラメータの調整を進めました。↓の画像は地形の調整用マップと、見た目の最終マップです。

f:id:sgtech:20200126210404p:plain f:id:sgtech:20200126210408p:plain

 

待ち時間が発生したとき

まだ基本的な動きが完成しておらず、ゲームを実行しての確認ができず手が空いてしまうケースはよくあります。むしろ、動きを早期に確認できるジャムは稀だと思います。

仕様を簡略化できるか・どこまで削ってよいか考える

アイデア出しのとき、ゲームが単調にならない要素を考えると思います。ゲーム中のキャラクターや制限の種類を増やすと面白そうなものになるでしょう。しかし期間の短いジャム中にアイデアの全てを入れ込むことは至難です。

アイデア出しの部分で言及したToDoリストなど要素分けしてリスト化したものに優先度をつけて、最低限必要なものが何であるか考えましょう。

 

おまけの⑫において削った仕様の例を紹介します。

・ゲームの終了条件

アイデア段階では「ゴール地点にたどり着く」「制限時間に達する」「自分より大きい捕食対象より一定のダメージを受ける」でした。開発を進める中で、ダメージを受ける要素が無くてもゲームになることに加え、捕食対象の動作(ダメージを与えようとしてくる)実装と調整の時間が足りないと判断してダメージの仕様は無くなりました。

・キャラクターの種類

アイデア段階での捕食対象は大きく4種類、さらにカラー変更で見た目のバリエーションも増やす考えがありましたが、最終的には3種類(最低限、水中・陸上・空中に存在するもの)となりました。プログラマー側から提案して種類を減らさせていただきました。

チームにサウンドさんが居ない場合、音素材を集めましょう。

UE4で使用できるオーディオファイルの形式はWAV形式です。UE4.22以降ならAIFF、FLAC、Ogg Vorbis形式を使用できます。

フリーの音源など外部より取得したものは音量にばらつきがある可能性がありますので、確認して波形の正規化をしてあげると扱いやすくなります。

フリーソフトのAudacityを使用した正規化とWAV形式への変換を紹介します。

Audacityはこちらより入手します。https://www.audacityteam.org/

Audacityへ音源をインポートしたときに、波形の枠上下いっぱいになっていなければ音量が小さいです。右の画像は-1.0dbで正規化されたものです。右の画像のようになっていれば扱いやすいです。

f:id:sgtech:20200126210531p:plain f:id:sgtech:20200126210548p:plain

 

正規化をします。Ctrl+Aで波形を全選択したあと、「エフェクト」>「ノーマライズ」を実行します。出てくるウィンドウはそのままでOKです。

f:id:sgtech:20200126210535p:plain f:id:sgtech:20200126210540p:plain

 

WAVファイルのエクスポートは、「ファイル」>「書き出し」>「WAVとして書き出し」を実行します。

f:id:sgtech:20200126210544p:plain

UE4へのインポートは、フォルダを選択してインポートボタンです。右クリックからもできます。

f:id:sgtech:20200126210706p:plain f:id:sgtech:20200126210710p:plain

 

インポートされたアセットを右クリックし、キューを作成します。

f:id:sgtech:20200126210714p:plain f:id:sgtech:20200126210718p:plain

 

例えばBGMの場合はループさせたいので、キューアセットを開いてWave Playerノードを選択し、詳細パネルのLoopingにチェックを入れます。

また風の音や爆発音といったSEについて、アウトプットノードを選択したときの詳細パネルでピッチ項目を弄ってゲームの雰囲気と合わせます。

f:id:sgtech:20200126210726p:plain f:id:sgtech:20200126210721p:plain

プログラマー向けTips

タイトル→ゲーム→リザルト→タイトルのゲームシーケンスループを作成

ゲームに備わっているべきシーケンスだと思います。もちろん、ゲームの部分を作ることに熱中して作成できなかったとしてもOK。それもゲームジャムです。

このシーケンスがスムーズに作られていると、プレイする人の頭が準備されるだけでなく、試遊する方がプレイするときに制作者がいちいちスタートボタンや停止ボタンを押さなくても良くなります。

ゲームジャムでは試遊の時間が設けられていることが多いです。自分のゲーム近くで案内操作している時間が多いと、他のジャム作品を遊ぶ時間が少なくなります。それはもったいないので、ぜひ自立したゲームシーケンスを目指してください。

f:id:sgtech:20200126210252g:plain

↑おまけ⑥を制作したジャムで配布されたテンプレートにおける遷移動作です。

マップを分割し、遷移処理を作成

ゲームジャム中はメインとなるゲームのマップを繰り返し実行して開発するので、タイトルを切り離しておくべきです。

ゲーム中にリザルトを表示させようとなると、表示の裏で動く様々な処理を止める必要があるかもしれません。意外と手間である場合もありますので、リザルトも分かれていると悩まなくて良いです。タイトルやリザルトの表示は一瞬でも、それを遷移する時間がちりつもで嵩んでいきます。

分割することで、UI作成+表示+マップ遷移の役割としてゲーム部分の役割と切り離すことができます。これは重要なことで、プログラマーが2人以上の場合はプレイヤー+ゲーム部分担当と、UI+シーケンス(+他のキャラクター)担当に分かれることがとても多いです。同じマップファイルを触らなくなるので、更新が衝突することも無くなります。

 

レベルの遷移はOpenLevelノードで行います。正しく該当のマップに遷移するか、必ず確認するようにしましょう。

f:id:sgtech:20200126210437p:plain

実行時にLevel Nameの名前を持ったマップアセットの探索が走ります。ジャム規模のプロジェクトで探索時間が問題になることは無いと思いますが、Gameからのフルパスを指定しておけば転ばぬ先の杖です。指定方法は、マップアセットを右クリックして「リファレンスをコピー」を実行してペーストした結果より、「World'」から「.マップ名'」までの文字を抜き出します。例えば

「World'/Game/00_GameJam2020/Map/Result.Result'」がコピーされるので、「/Game/00_GameJam2020/Map/Result」を使用します。

f:id:sgtech:20200126210440p:plain f:id:sgtech:20200126210445p:plain

繰り返しになりますが、正しく該当のマップに遷移するか必ず確認するようにしましょう。

得点などをリザルトで表示したい場合はGameInstanceクラスを作成して情報を持たせる

Mapを遷移するとActorがベースクラスのBlueprintは破棄されます。プレイヤーのキャラクタークラス等に得点情報を持たせてしまうと、マップ遷移時に情報が失われてしまいます。

GameInstanceクラスはプロジェクトに1つだけ設定され、アプリケーション起動時より常駐となります。このクラスにリザルトの情報を持たせる実装が楽です。

GameInstanceクラスの作成

コンテンツブラウザ上の右クリックメニューよりブループリントクラスを選択し、親クラスの選択ウィンドウにて「すべてのクラス」を展開した中よりGameInstanceクラスを選択します。

f:id:sgtech:20200126210456p:plainf:id:sgtech:20200126210502p:plain

 

今回はBP_Jam_GameInstanceという名前にしました。

f:id:sgtech:20200126210506p:plain

 

「編集」 > 「プロジェクト設定」で開いたウィンドウより、左側の「マップ&モード」を選択、中の「ゲームインスタンス」に先程作成したクラスを設定します。

f:id:sgtech:20200126210512p:plainf:id:sgtech:20200126210509p:plain

 

作成したゲームインスタンスの参照を取得するには、GetGameInstanceノードのアウトプットをキャストします。関数ライブラリなどに取得関数を作成すると便利です。

f:id:sgtech:20200126210518p:plain

※技術的負債ポイントです。GameInstance参照が各所に飛び散ると、起動と同時に芋づる式に参照アセットがロードされるので、規模が大きくなるうちに気づけば初回起動にとても時間がかかる問題にぶち当たります。

回避策の1つに、BlueprintInterfaceを使用する方法があります。ジャムではおすすめしませんので、もしあなたがジャム中であれば読み飛ばしてください。

他のBlueprintクラスと同様に右クリックからクラスを選択します。

f:id:sgtech:20200126210849p:plain f:id:sgtech:20200126210852p:plain

 

ダブルクリックでクラスの編集画面に入り、「+」ボタンでインターフェース関数を追加します。続いて引数や返り値を定義します。

f:id:sgtech:20200126210855p:plain

 

次に今回プロジェクトのGameInstanceクラスを開き、「クラス設定」よりBlueprintInterfaceクラスを指定し、インターフェース項目に追加された関数の中身を実装します。

f:id:sgtech:20200126210900p:plain f:id:sgtech:20200126210905p:plain

 

使用するときは、GetGameInstance関数のアウトプットから呼び出すことができます。右上にメールが開封されたようなアイコンが付いているものがインターフェース関数です。

f:id:sgtech:20200126210910p:plain

ジャム中にこの方式を使用するデメリットとしては、ノードをダブルクリックしても実装した部分が開きません。BlueprintInterfaceクラスが開きます。実装内容を調整したいときは自分でBlueprintInterfaceクラスを実装したクラスを開いて該当の関数を見つけるい必要があります。ちょっとした手間が貴重な時間や精神を削ります。

もしジャムのGameInstanceに適用する場合、何度も調整する必要がないように変数のSet, Get程度にとどめましょう。

もう少しこの辺りの問題について知りたい場合、こちらの記事の「プログラム編」を読んでみてください。

特徴的なアートスタイルはこうして作られた。「OCTOPATH TRAVELER」開発秘話 - GamesIndustry.biz Japan Edition

 

UIのWidgetBlueprintをGameInstanceに持たせた例

おまけの⑫では、この図のような構成で作りました。

f:id:sgtech:20200126210433p:plain

WidgetBlueprintクラスをGameInstanceに持たせておくと、ゲーム中のUI情報をリザルト画面で流用することができて楽になります。リザルトのマップにおいて、ゲーム中に更新されたWidgetBlueprintを表示(AddToViewport)してUI上部のゲージを非表示にするだけで、スコアのリザルトを反映することができました。

f:id:sgtech:20200126210448p:plain f:id:sgtech:20200126210453p:plain


パラメータを調節してもらうようにする

例えば、Blueprint関数ライブラリにパラメータを取得する関数を作成して、ゲームデザイナーの役割の人にアウトプットの数値を弄ってもらうようにします。

f:id:sgtech:20200126210354p:plain f:id:sgtech:20200126210357p:plain

 

関数ライブラリではなくマクロライブラリにする場合は、FormatText(テキストをフォーマット)ノードなどに気をつけましょう。この場合、関数ライブラリの出力は正しく値が渡りますが、マクロライブラリの出力値はnullとなります。
f:id:sgtech:20200126210401p:plain

値を画面に表示し続ける

PrintTextやPrintStringノードにおけるDuration(表示時間)を0にすると1フレームだけ描画されるので、Tickで毎フレーム呼び出すことで常に1つ表示されているように見えます。

例えば以下のように残り時間、体力、得点といったパラメータを表示しておくことをおすすめします。FormatText(テキストをフォーマット)ノード内に{hoge}を記述することでInputピンを増やすことができます。

f:id:sgtech:20200126210608p:plain


ずっと左上に出続けます。
f:id:sgtech:20200126210116g:plain

見ながら動作確認やレベルデザインに活用できます。短い期間でも数値の扱いでバグが生まれやすいので、おかしいなと思ったときにすぐ気づくこともできるでしょう。

 

デバッグキーを用意する

「ゲームをクリアしたことにする」「アイテムを取得したことにする」「次のレベルへ飛ばす」といったショートカットはレベルデザインやデバッグ作業を高速化します。キーボードを押した時に呼ばれるイベントを作成しましょう。

f:id:sgtech:20200126210914p:plain

グラフ上で右クリックして任意のキーボードイベントを検索するときに、なかなか見つからず苦労している方をジャム中によく見かけます。

たとえば「a」キーの場合、日本語環境では「a キー」、英語環境では「a keyb」まで入力することでサジェストを絞り込むことができます。

f:id:sgtech:20200126210918p:plain f:id:sgtech:20200126210922p:plain

 

または検索窓に「@」を入力(サジェストにキーボードイベントしか出てこない!)してインプットイベントをとりあえず作成し、イベントノードを選択した状態の詳細パネルから、Input Key部分から対応するキーやボタンを変更します。グラフ上で右クリックするよりも探しやすいと思います。

f:id:sgtech:20200126210927p:plain f:id:sgtech:20200126210932p:plain


エディタで配置するか、外部ファイルで配置するか、ランダムに任せるか

エディタでの配置

ゲームプレイのイメージをしやすく、プレイの実行自体もすぐに行えるので思ったことをすぐ試せる強みがあります。

熱中しだすと時間を消費するので、レベルデザインの担当者が時間を区切って取り組む必要があります。

f:id:sgtech:20200126210653p:plain

プログラマー側では、調整してほしいパラメータを公開するようにしましょう。

ブループリント変数 | Unreal Engine ドキュメント

 

おまけの⑥ではコインのBlueprintに「BigCoin」フラグを設けて、レベルデザイナーがフラグをオンオフすることでサイズとスコアの異なるコインの使い分けができるようにしました。

f:id:sgtech:20200126210703p:plain f:id:sgtech:20200126210656p:plain

外部ファイルに記述

設定箇所が多くエディタ内の操作では時間がかかる場合には、外部ファイルでまとめて設定できるような方法を検討するといいでしょう。

おまけの⑩では、ステージの起伏設定箇所が100個以上有ったため、Excelに入力してcsvよりUE4のDataTableへインポートするようにしました。Excelを使用する場合は、「条件付き書式」> 「セルの強調表示ルール」を設定することをおすすめします。

f:id:sgtech:20200126210626p:plain

 

例えばゲーム中の見た目と同様な色の使用や、設定の種類によって色をアサインすることで入力の段階から動作イメージをしやすくなります。

f:id:sgtech:20200126210630p:plain f:id:sgtech:20200126210642p:plain

CSVのインポートや、どのようにCSVを記述したらよいかは、こちらの記事がわかりやすいです。

ランダムに任せる

限られた時間の中で、手が回らない場合はランダムな配置に任せるのも手です。

プレイごとに内容が変わるので、いままで判明していなかった面白い部分や面白くない部分が見つかります。またジャムの終了後、試遊のために並んでいる人や気になって近くで見ている人達が自分でプレイするまでに飽きないです。

ただし同じゲーム内容を再現できないので、バランスを担保することが難しいです。

おまけの⑨のゲーム設計は、プレイヤー進行方向より流れてくるアイテムを取り続けるというものでした。しかし、アイテムをステージ上に手動配置する時間が足りず、ランダムを使用することにしました。

f:id:sgtech:20200126210634p:plain f:id:sgtech:20200126210647p:plain

 

0.35秒ごとに前方の4箇所からランダムで出現させる処理(右の関数)を書きました。

f:id:sgtech:20200126210638p:plain

40秒程度のゲームで100個以上のアイテムを出現させています。プログラムは1時間以内で書けましたが、同じ量を手動で配置して調整するとなると2, 3時間必要でしょう。

「とりあえず爆発させましょう」

ジャムの終盤でよく聞く言葉です。

理由はどうあれ、もう爆発させるしかない。爆発は全てを解決します。

Content Examples(機能別サンプル)より爆発を持ってきてみましょう。

 

Epic Games LauncherのUnrealEngine(左側)より、ラーニング(上側)より「機能別サンプル」を探してプロジェクトを作成します。

f:id:sgtech:20200126210138p:plain

 

作成してプロジェクトを開いたら(シェーダコンパイルを待つ必要はありません)、コンテンツブラウザの検索窓に「explosion」と入力します。

f:id:sgtech:20200126210156p:plain

 

爆発アセット「P_Explosion_Bomb」を右クリック、「アセットアクション」→「移行」を選択します。(英語環境では「Asset Actions」→「Migrate」)

f:id:sgtech:20200126210144p:plain

 

下図のように爆発アセットに参照されているテクスチャやマテリアルが階層表示されます。OKを選択し、移行先プロジェクトのContentフォルダを選択してOKします。

f:id:sgtech:20200126210147p:plain

 

画面右下に移行完了のメッセージが出ます。

f:id:sgtech:20200126210152p:plain

 

移行先のプロジェクトを開き、アクターを作成します。コンテンツブラウザで右クリック→ブループリント→ブループリントクラスを選択。

f:id:sgtech:20200126210202p:plain

ウィンドウからActorを選択します。

f:id:sgtech:20200126210246p:plain

 

作成したActorは「BP_Explosion」としました。

f:id:sgtech:20200126210206p:plain

 

ダブルクリックで開き、コンポーネントタブの「コンポーネントを追加」をクリック、検索窓に入力して「ParticleSystem」を絞り込んで選択します。

f:id:sgtech:20200126210210p:plain

 

コンポーネントタブはこのようになります。このParticleSystemを選択した状態(色が黄色になっている状態)にします。

f:id:sgtech:20200126210214p:plain

 

同じ画面の詳細タブから、「Particles」の項目を探し、中の「Template」行にあるプルダウンエリアをクリック、出てきたサジェストより移行してきた「P_Explosion_Bomb」を選択してください。

f:id:sgtech:20200126210219p:plain

 

Templateに適応された状態です。

f:id:sgtech:20200126210224p:plain

 

ちょっとだけ余裕がある人は、イベントグラフタブに移動してください。ない人はこれで「BP_Explosion」での作業は終わりです。画像を2個飛ばして「爆発の起動」から読んでください。

f:id:sgtech:20200126210229p:plain

 

BeginPlayノードより、Delay(2秒を設定)、DestroyActor(self:自分自身)とノードを作成して接続します。これで2秒後に自分自身を破棄します。

f:id:sgtech:20200126210232p:plain

爆発の起動

「BP_Explosion」をSpawnActorするだけで起動します。例えばレベルブループリントのBeginPlayでSpawnしてみます。爆発させたい位置(Transform内のPosition)をステージ真ん中辺りに指定しました。

f:id:sgtech:20200126210236p:plain

 

実行するとすぐ爆発します。終わり。

f:id:sgtech:20200126210241g:plain




ジャム中の注意点など

巨大なアセットが本当に必要か検討する

UE4のMarketPlaceやラーニングコンテンツでは高品質なアセットが並び、中には無料で手に入るものがあります。

これらは使いやすいと思いきや、大きいリソースはジャム中のイテレーションを鈍化させる原因になります。

おまけの⑧では広大な3つのステージを同時に使用しました。

  1. シューティング ゲーム | Unreal Engine ドキュメント

  2. Infinity Blade: Fire Lands:Epic Games:Epic Content - UE4 マーケットプレイス

  3. Infinity Blade: Ice Lands:Epic Games:Epic Content - UE4 マーケットプレイス

ShooterGameのビル内に、Fire LandsとIceLandsを入れこむ贅沢な使い方をしました。入れこむための配置調整に時間がかかった上に、結果としてマップを開く時間がとてつもなく長くなり、アプリのパッケージング時間も膨大となりました。

結果として提出するための動画撮影時間が足らずに中途半端なコンテストのエントリーになってしまいました。

f:id:sgtech:20200126210412g:plain

ゲームの本質的に不要であれば、無理に入れない方が良いかもしれません。

ゲーム画面の発表時には電源を接続する

ノートPCがバッテリー動作の場合、充分な電力がグラフィックカードへ送られず3Dゲームの実行が不安定になることがあります。

発表場所近くで電源を使用できるよう運営に手配していただくようにしましょう。

f:id:sgtech:20200126210523j:plain

ゲームジャムでUE4チームを作るには

テンプレートの活用やBlueprint開発、エディタでの高速なイテレーションによって、UE4はジャムの強力な味方になります。

しかしUE4だけの制限をしていないジャムにおいて、UE4チームが生まれる機会は少ないです。Global Game Jam (毎年世界同時に開催される最も大規模なジャム)では、Unityに比べてUE4で制作されるゲームの数は10分の1程度です。世界中の比率と日本国内の比率は同じくらいです。

UE4を使いたいなと思っていても、チームではUnityを使用する場合が多いと思います。

ジャム運営の方へ

UE4チームが組まれるためには、ジャム運営側の協力が必要だと思っています。あらかじめ参加者に希望(リーダーや使用ツール)を募るケースが多いと思いますので、参加時にエンジンの希望を出してもらうようにしてみましょう。

次に参加者の希望を公開 (公開する旨は伝わるようにする)して、ジャムのwebページで見えるように並べます。UE4の希望者は他にUE4の希望者が居ると集まりやすいです。

または、ジャムの参加枠にUE4枠を作成してみてください。どこからともなく集まります。connpassなどのサービスで枠を作成できます。

ジャム当日のチーム決めの後に、選択肢として考えてみる

チーム内にUE4経験者が居る場合は、UE4チームになってみることを検討してみてください。UE4未経験者が経験者に教わりながら触り始めて、機能実装やレベルデザインを主体的に行っている様子を何度も見てきました。ここでの経験者は私以外であるパターンもいくつか知っています。

おわりに

今回は個人的な活動を書き起こしてみました。私が活用したことのないものは書いておりませんので、良さげなノウハウや苦労した話を持っているよ!という方は、ぜひブログやスライドにして公開していただけたらと思います。

セガではグループ内で定期的にゲームジャムを開催しており、私のように毎回UE4を使う人や、その時によってアナログゲーム制作や電子工作を絡める方など、やりたいことを試す機会に恵まれています。ご興味がありましたら、ぜひ採用情報をチェックしてみてください。

採用情報| 株式会社セガ・インタラクティブ

そして私とUE4のチームを組んでください。

 

おまけ:これまでの制作物

簡単な説明・期間・画像を載せてみました。

Sega Game Jamで制作したものは[SGJ]とつけました。

画像の下にジャム前のモチベーションを書きました。


①: [SGJ]超電磁的なコインを飛ばすVRゲーム:1日

f:id:sgtech:20200126210958g:plain

ジャム前は、VR元年ということもありVRゲームを作りたいモチベーションでした。

バーチャルリアリティのテンプレートを使用しています。


②: クレー射撃のようなVRゲーム:2日

f:id:sgtech:20200126205831g:plain

ジャム前はとにかくVRゲームを作りたいモチベーションと、オリンピック競技的なものを作りたいと思っていました。

バーチャルリアリティのテンプレートを使用しています。

 

③: [SGJ]巨大化して求婚するゲーム:2日

 ※Sega Game Jam内に限り、セハガールモデルの使用が認められていました

f:id:sgtech:20200126210107g:plain

ジャム前は特に何も考えずに挑みました。

サードパーソンのテンプレートを使用しています。

 

④:[SGJ]コントローラやLED連動システムごと作った宇宙探査ゲーム:2日

f:id:sgtech:20200126225439g:plain

ジャム前はアーケードゲーム筐体を作りたいと思っていました。

フライングのテンプレートを使用しています。


⑤: 爆弾の設置側と解除側のゲーム:1ヶ月程度

f:id:sgtech:20200126205856g:plain

ジャム前はUE4のリプレイ機能(DemoRec)を使いたいなと思っていました。

サードパーソンのテンプレートを使用しています。

 

⑥: 昼と夜を切り替え対応する足場を乗り継ぐゲーム:2日

f:id:sgtech:20200126205842g:plain

ジャム前はUE4のライトシナリオ機能を使いたいと思っていました。

ジャム専用のサイドスクロールテンプレートを使用しています。

 

⑦: [SGJ]おじさんが失った青春を取り戻すゲーム:2日

f:id:sgtech:20200126210112g:plain

ジャム前は特に何も考えずに挑みました。

サードパーソンのテンプレートを使用しています。

 

⑧: プリンがぷるぷるするゲーム:1ヶ月程度

f:id:sgtech:20200126205917g:plain f:id:sgtech:20200126210741g:plain

ジャム前は、ゲームにならなさそうなものを無理やりゲームにしたいと思っていました。

サードパーソンのテンプレートを使用しました。プリンの軟体シミュレーションにはNVIDIA FleXを使用しています。

 

⑨: つばめが綺麗な円を描くゲーム:2日

f:id:sgtech:20200126205932g:plain

ジャム前は特に何も考えずに挑みました。

テンプレートは使用していません。

 

⑩: 地形をリバースさせ、せり上がる衝撃でジャンプし続けるゲーム:5日

f:id:sgtech:20200126210004g:plain

ジャム前は、アプリケーション容量を小さく収めるチャレンジ枠に挑戦したいと思っていました。地形をランタイムで生成しています。(ProceduralMeshComponent)

テンプレートは使用していません。

 

⑪: [SGJ]大崎オフィスにグループ会社が集結するということで、各事業所を回ってグループシナジーを集めていくタイムリーネタだったゲーム:2日

f:id:sgtech:20200126210045g:plain

ジャム前は、メガドライブミニ要素をどこかしらに入れたいと思っていました。実際にプレイヤーの前方より発射されます。

テンプレートは使用せず、OSSのOceanProjectを使用しています。

 

⑫: [SGJ]ヒトデが魚や人を食べて大きくなって星になるゲーム:2日

f:id:sgtech:20200126210021g:plain

ジャム前は、チーム分けでUnityチームのプログラムリーダーになっていたのでUnityの復習をしていました。当日の話し合いでUE4を使うことになりました。

サードパーソンのテンプレートを使用しています。

 

以上です。ここまで見ていただき、ありがとうございました。

Powered by はてなブログ