開発では必須!Gitを使いこなすには

目次

はじめに

初めまして!

去年新卒で入社したサーバーサイドエンジニアのOHです。

今回はGitについての記事を書いていきます。 具体的な内容は以下になります。

  • Gitの概要

  • Gitの学び方

これからGitの勉強を始める方や「Gitをどう学べばいいかわからない」と迷っている方のお役に立てるような記事になれば嬉しいです。

Gitの概要

Gitとは?

Gitとはソースコードなどのファイルのバージョン管理をしてくれるシステムの1つです。 Gitを使う事でソースコードなどファイルに対しておこなった変更を複数人で共有し開発を円滑に進めることが可能です。

テキストでは伝わりづらい部分もございますので、具体的にどういった流れで開発していくのか図にしてみました。

まずGitにはリポジトリというものがあります。

リポジトリとはファイルなどを格納、保管する場所になります。

f:id:rf-blog-sagyo:20210521145829p:plain
リポジトリ

サーバー上、インターネット上に置いてある(例 GitHubなどで作成した)リポジトリリモートリポジトリと呼びます。

リモートリポジトリから自身のPCのローカル環境にファイルをコピーしてきます。

このローカル環境に持ってきたリポジトリローカルリポジトリと呼びます。

f:id:rf-blog-sagyo:20210521150035p:plain

リポジトリの用意ができたら、自分が作業する為のブランチを作る必要があります。

ブランチとは作業した履歴を枝分かれさせ記録していくためのものです。 リモートリポジトリで区切られているブランチの例は以下です。

バージョン1.2で機能追加する際は、バージョン1.2から自分が作業するブランチを切ります。

f:id:rf-blog-sagyo:20210524160355p:plain
ブランチの例

例えば作業者Aが新規ファイルを追加したいとなった場合

ブランチを作ってファイルを追加しただけでは、リモートリポジトリには反映されません。

リモートリポジトリに反映させるには、Gitクライアントツールを使ったり、ターミナルにGitコマンドを入力して反映します。 反映すると、自分で作ったブランチがリモートリポジトリに追加されます。

f:id:rf-blog-sagyo:20210524174246p:plain

リモートリポジトリに反映された自分のブランチを、マージ対象のブランチにマージします。

そうなった場合でも作業B、Cのブランチには影響はありません。その為続けて作業する事が可能です。

f:id:rf-blog-sagyo:20210524175645p:plain

ただ安全に開発をするために自分のブランチをリモートリポジトリに反映する際には、最新の状態のファイルなどを取ると良いでしょう。

f:id:rf-blog-sagyo:20210521165446p:plain

このようにしてGitでは同時に複数人で並行して開発することが可能です。

Gitの学び方

自分が学んだ方法

私が初めてGitを学んだのは学校の授業です。 TortoiseGitというGitクライアントツールを使いGitの基本を学びました。

これからGitを学ぶ人は、Gitクライアントツールから入ることをオススメします。 最初はGitの設定で手こずってしまったりするので、ツールを使えばGit設定なども一緒にやってくれます。 そのためすぐ使うことができるし、簡単操作、わかりやすいUIでGitをストレス無く学ぶことができます。

Gitクライアントツールっていっぱいあるからどれがいいかわからない人はとりあえずForkを使うといいですよ、 WindowsMacに対応しており、対応言語は英語しかありませんが使い勝手の良いさまざまな機能ありオススメです。

git-fork.com

ただしForkは評価に関しては無料ですが、長期に渡る利用は有料になりますので
もし気に入って長く使いたいと思った場合は、購入をお願いいたします!

git-fork.com

余談を挟みましたが、私がGitをしっかりと学んだのは入社してからになります。 それまではコミット、プッシュなど基本的な動作しかわかりませんでした。

入社後初めてターミナルでGitコマンドを使いましたが、最初はコマンドを覚えれるかとても心配でした。 そんな中、どのようにしてGitコマンドを学んだのかというと、『実際に1つずつコマンドを打ち挙動を確認して、どういう挙動だったかを1つずつまとめて理解を深める』という方法です。

f:id:rf-blog-sagyo:20210524181732p:plain

上記のように実行、その内容、結果をまとめる事で自分が何をやっているのかがわかります。

基本的なコミット、プッシュなどの動作を学びたい人はGitクライアントツールの方が学びやすいと思いますが、 慣れてきたり、もっと理解を深めたい人はGitコマンドで学ぶことをオススメします。

ちなみに現在私が開発をする時はターミナルでGitコマンドを使用しています。 「なぜ便利なGitクライアントツールを使わないの?」と思いますよね。会社からGitクライアントツールを禁止されている訳とかではないですよ。

確かに便利なのですが、GitクライアントツールではGitコマンドの細かい操作がしづらい為、ターミナルでGitコマンドを使っています。

Gitクライアントツールも全てが便利という訳ではないのでそこも考慮してどちらで学ぶか考えてみてください。

Gitを学ぶための準備

学び方を書いただけでは具体的な準備がないとできない!となりますので、リポジトリ作成まで記載していきたいと思います。

Gitを学ぶためにはまず一番大事なGitを自身のPCにインストールします。 これがないと何も始めることができないです。

MacはデフォルトでGitが入っていますが、最新のものにすることをオススメします。

インストール方法は下記のGit公式に書いてあります! git-scm.com

次にGitを学ぶ為に必要なリポジトリについてです。 自分のPC内でリポジトリを作ってもいいのですが、GitHub・GitLabを使った方が簡単にリポジトリを作ることできます。 実際の開発ではGitHub・GitLab使うことがあるので、学んでおくと良いでしょう。

github.com

about.gitlab.com

簡単にGitHubでのリポジトリの作り方を説明します。 と、その前に!GitHubのアカウントを作成しておいてください。

まずGitHubのトップ画面に行きます 赤枠で囲まれている、『new』というボタンを押してください。

f:id:rf-blog-sagyo:20210610170936p:plain

次にリポジトリの名前を決めます。ここではtestとしています。 descriptionはあっても無くても平気です。

Gitの学習のために使うのでpublicでもprivateでもどっちでもいいのですが、他の人に見られるのと困る場合(恥ずかしさ的に)があるのでprivateにしています。

下のチェックはAdd a README fileだけつけています。 (リポジトリと一緒にブランチを作成してくれて、READMEファイルをGitの練習として使うこともできるのでつけています。)

Create repositoryを押せばリポジトリの完成です。

f:id:rf-blog-sagyo:20210610170931p:plain

完成したリポジトリ画面になります。

f:id:rf-blog-sagyo:20210610170924p:plain

完成したリポジトリをGitコマンド、Gitクライアントツールを使う事でローカル環境にリポジトリを持ってくることができます。

覚えて損のないGitコマンド

ここからは自分がGitコマンドを使っていて便利だな、これ覚えないの損だなと思うGitコマンドを紹介したいと思います。

そのコマンドが rebase です。

今回はこのrebaseを使ってコミットメッセージを変えたいと思います。

テストリポジトリを作成し、indexファイルを追加しました。 f:id:rf-blog-sagyo:20210524182914p:plain

コミットメッセージをミスしてコミットします。

f:id:rf-blog-sagyo:20210524182923p:plain

git logで確認してみるとコミットメッセージをちゃんとミスしてますね。

f:id:rf-blog-sagyo:20210524183703p:plain

続いてgit rebaseにオプション -iを指定します、コミットメッセージを失敗したコミットを選択して実行。

実行をするとこのような画面に行きpickの部分を変えることで様々なモードに変えることができます。

今回はコミットメッセージなのでrのrewordを選択

f:id:rf-blog-sagyo:20210524182930p:plain

そしてコミットメッセージを整形

コミットメッセージを保存し、テキストエディタを終了させます。

f:id:rf-blog-sagyo:20210524182902p:plain

このように整形されたコミットメッセージに変わります。

とても簡単にコミットメッセージを変える事ができます。

git rebase をする事で複数のコミットメッセージを変えることも可能です。

f:id:rf-blog-sagyo:20210524183717p:plain

そのほかにも複数のコミットを1つにまとめることができるsquash、コミットを内容(ソースコード)などを編集することができるeditなどがあります。 ぜひ覚えて頂きたいです!

まぁコミットメッセージだけならgit commit --amend -m "コメント"で編集することできるんですけどね...

まとめ

コマンドの動作検証を行い、自分が理解しているか確認をするために実行結果を見て何かに書くことは大事だと思います。 自分がどこで詰まって理解ができないかの確認もする事ができるので、今Gitを理解できずに悩んでいる人、これから勉強する人はぜひ試してみてください!

プランナーの腕の見せどころ!「レベルデザイン」について

目次

ごあいさつ

はじめまして。

株式会社アールフォース・エンターテインメント プランナーの横角です。

好きなダメージは「高高度攻め継300ダメージ」です。

今回の記事では、プランナーの業務の中でも、
学生の方にはあまり馴染みがない「レベルデザイン」について、
具体例を交えてご紹介させていただきます。

就活生、特にプランナーを目指している人向けに、
実際の業務をイメージする助けになれれば幸いです。

レベルデザイン」とは?

f:id:rf-blog-sagyo:20210303152814j:plain
レベルデザインってなんだ?

まずはじめに、「レベルデザイン」とはなんなのか?
よく略して「レベデザ」というものですね。

これは非常に幅広く使われる言葉で、
 ・RPGにおける、キャラの強さや使うわざ
 ・アクションゲームにおける、マップの広さや宝箱の場所
 ・リズムゲームにおける、ノーツの位置
  などなど………

本当に、とてもとても多岐にわたって使われます。

それもそのはず、上記では「RPG」「アクション」「リズムゲーム」と例を挙げましたが、
ゲームの内容によってデザインしなくてはならない項目がガラッと変わるから」というのが大きな理由です。

また、プレイステーションなどのハードで遊ぶ買い切りのゲームなのか、
スマートフォンで運営されているアプリゲームなのかによっても、
ゲーム性は大きく異なり、デザインしなくてはならない項目は変化してしまいます。

なので今回は「スマートフォンアプリゲーム、コマンド選択式RPG、ある1バトルのデザイン
という条件を設けたうえで、具体例を挙げて、実際にレベデザを行ってみましょう。

某F●O的なものを想像して頂ければ分かりやすいかと思います。)

難易度という意味でのレベデザについて、例を挙げて考えてみる

さっそく、難易度についてデザインしていきましょう。
ここはプレイヤーのストレスに直結する部分で、
絶対に失敗できない最重要なポイントといっても過言ではありません。

ドラ●エの最初の敵はスライムですし、ポ●モンの最初の敵は同レベルのライバルです。
これがダークド●アムだったり、ミュ●ツーだったりしたら
そこでゲームを辞めてしまいますよね。冒険終了!

ここで重要となるのは、「難易度」というものを観測するのは誰なのかです。
それはレベルデザインをしている自分ではなく、
もちろんそれを指示、監督しているリーダーでもディレクターでもなく、
そのゲームを遊ぶプレイヤーひとりひとりです。

ですが、スマートフォンで運営されているアプリゲームの場合には、
始めた時期やプレイの頻度、課金の量で、プレイヤーごとに立場が違います

そして、
全プレイヤーに等しく同じ体験をしてもらえる「難易度」をデザインすることは、
基本的には不可能です。

(某ファイナルファン●ジー8などで採用されている、
 自分のパーティのレベルに応じて敵の強さが変化するシステムなんかでは、
 理論上はこれを実現させることも可能です。
 しかし「よりプレイしたから強くなれた」「より課金したから強くなれた」という感情は
 アプリゲーム運営の上で不可欠なため、この部分を疎かにする場合がある前述のシステムは、
 今回は考慮から外します。)

では一体どうするのか、ということですが、
先述した「プレイヤーひとりひとり」というのものを可能な限り想定したうえで、
ターゲットユーザーを仮想して設定します。
マーケティング用語に「ペルソナ」というものがありますが、
 それを調べていただくとわかりやすいかと思います。)
それに基づいて、いくつかの段階分けをしたうえで、
バトルを設計していきます。
この段階分けが、いわゆるアプリゲームでよくある
「初級・中級・上級・超級」といった難易度分けになります。

では、実際にレベデザをする際の考え方や、作業をご紹介します。

■CASE.A「初心者向けクエストの1バトル」

f:id:rf-blog-sagyo:20210224172534j:plain

■CASE.B「上級者向けクエストの1バトル」

f:id:rf-blog-sagyo:20210224172547j:plain

世界観からくるレベデザについて、例を挙げて考えてみる

さて、上記の工程を踏むことで、強さはちょうどよくなります。

ですが、レベルデザインとは、
ただ「プレイしててストレスを感じないように数値をいじること」ではありません。

プランナー、ひいてはゲームクリエイターの仕事は、
ゲームに入り込んでいるプレイヤーの体験・感情」をデザインすることです。
 ・そこで現れる敵は、どんな見た目の敵なのか
 ・その敵は、どんな行動をとるのか など、よりプレイヤーをゲームに没入させるための工夫を凝らす必要があります。
(本来であれば、これは強さのレベルデザインより前にやらなくてはならない工程ですが、
 あくまで1バトルをデザインするということで、わかりやすいように順序を逆にしています。)

では、さっそくこちらもやっていきましょう。

■CASE.C「世界観設定がはっきりしている場合」

f:id:rf-blog-sagyo:20210224172557j:plain

■CASE.D「世界観設定が曖昧な場合」

f:id:rf-blog-sagyo:20210224172606j:plain

総括

f:id:rf-blog-sagyo:20210303152902j:plain
すっきり

今回は、いくつかの条件付けをしたうえでのレベルデザインの方法と
その際の思考についてご紹介させていただきました。
CASE.AとBでの強さのデザインと、CASE.CとDでの世界観からくるデザインを
うまくミックスさせることで、レベルデザインを成り立たせる方法です。

ただ、あくまで条件を絞った上での、ミクロな視点での話になっているので
例えば、クエストを周回させるようなイベントをデザインする場合には
「どれくらいのパーティがあればどれくらいの速度で周回出来るのか」
「どれくらいの周回で、どんな報酬が得られるのか」
など、デザインのための要件や領域は拡がっていきます。

上記の理由から、条件やゲームジャンルを限定しない形でまとめますと、

  • プレイヤーは、挑戦する時点でどのような状況、状態なのか

  • プレイヤーは、どのような欲求からそのゲームに挑戦するのか

  • ゲームにプレイヤーを没入させるためには、どのような工夫を凝らせばよいのか

これらを意識することが重要となります。

この記事が、ゲームプランナーを目指している方、特に学生や就活生の皆様にとって
レベルデザインについての知見を広げるきっかけになれれば幸いです。
以上、ありがとうございました。

Pychromecastって何?サイネージ配信で四苦八苦した話

目次

自己紹介

 かれこれ10年以上サーバーエンジニアをやっている、でわnです。
 弊社R-FORCEではバックエンドエンジニア一員としてゲーム開発に携わっております。
 趣味を列挙していくと身バレするので、メイド喫茶に通うことが趣味とだけ。
 ただメイド喫茶といってもジャンルがありまして、コンセプトカフェ、コスチュームカフェなどがある上に、にぎやかわいわい系、まったり系、伝統的系などあります。
 でわnはメイド喫茶が趣味と話しても社内でも誤解されっぱなしなので、いつかライトニングトークやろうかなと画策中・・・
趣味の話は一旦おいておき、今回そんな私がサイネージシステムを作ったところ、なかなか思うような結果を出せず、四苦八苦したので記事に残すことにしました。

サイネージってどんなもの?

 これです。
f:id:rf-blog-sagyo:20201022202341j:plain  正式名はデジタルサイネージ。インターネットを介して映像を投影させるシステムのことを指します。
f:id:rf-blog-sagyo:20201022220833g:plain

概要

 『R-FORCEの社内にてサイネージ配信システム作れない? 』  2020年3月頃その一言から始まり、Chromecast内蔵の機器を幾つか購入しました。
store.google.com

 Googleにて検索して、Google Cast API を使えばサイネージ出来ると知り、Chromecast機器とのソケット接続まわりの通信を変わりに行なってくれるPythonのプログラムPychromecastライブラリを発見。

 簡単というGoogle検索結果見出しに惹かれて始めること数ヶ月、苦労した点困った点を何かに残そうってことで記事にしました。

 これから中心に話す内容は Pychromecastライブラリを使用した開発メインの話になりますので予めご理解の程よろしくお願いします。

Pychromecastって何?

 概要にてサラッと記載しましたが、Pythonで動かすことが出来るサイネージ配信ライブラリになります。
 github.com

 ネットワークの知識をそこまで必要とせず、Python言語が扱える人がChromecast内蔵の機器をネットワークにつないで、わずか30行あまりのPythonプログラムを書くことでサイネージ配信出来るという代物になります。

 ではなぜ苦労することになったのか。それは30行あまりのPythonプログラムでは実現不可能なことをこのPychromecastライブラリを使って実現しようとしたから苦労する羽目になってしまいました。

システム構成図

f:id:rf-blog-sagyo:20201126163042p:plain
システム構成図
 Googleドライブ上にあるメディアファイルを配信サーバーへダウンロードし、同一ネットワーク上に存在するChromecast機器に対し配信を行なっています。

Pychromecastライブラリのバージョン

これからお話するPychromecastライブラリのバージョンは次になります。

7.5.1 (GitTag: 7.5.1、コミットハッシュ: 7c2bec4af3eedd236c4295a750ea60d3798e1313)

https://github.com/home-assistant-libs/pychromecast/commit/7c2bec4af3eedd236c4295a750ea60d3798e1313

苦労点・困った点

マルチキャストを予定していたつもりがユニキャストだった

理想

f:id:rf-blog-sagyo:20201005164640g:plain
マルチキャスト

現実

f:id:rf-blog-sagyo:20201005164712g:plain
ユニキャスト
 作る当初はブロードキャスト送信が出来、全Chromecast機器へ一斉に信号を送れるマルチキャストとばかり考えていたが、Chromecast機器を検出し、その1台1台にメディアの再生命令を出すユニキャスト送信しか出来ず、少し物悲しいものが完成しました。

配信サーバーと同一ネットワーク上しか再生出来ない

 Zeroconfと呼ばれるネットワーク機器検出サービスを利用しているライブラリであり、中身を変えずそのまま利用すると同一ネットワークのChromecast機器検出として動作するため、同一ネットワーク上に存在するChromecast機器のみに配信可能と制約を受けてしまう。

 R-FORCEでは当初サーバー群とChromecast機器群を別々のネットワークにて管理を予定していたが、Zeroconfサービスをそのまま利用しているシステムである故に、同一ネットワーク上に配信サーバーが存在することを余儀なくされてしまいました。

 異なるネットワーク上への挑戦は他の方も挑戦されているが、どうすれば成功するのか未だ不明のまま・・・ hogehiga.hatenablog.com github.com

再生メディアへはWebアクセスが必須とされている

 Chromecast機器にメディアの再生命令という表現を使っておりますが、正確にはChromecast機器にメディアURIを送信しChromecast機器に対しメディアURIにアクセスし再生してという命令になります。

 サポートメディアとしては公式にて幾つも挙げておりますが、 developers.google.com メディアを再生するにはChromecast機器がアクセス出来るURIである必要があり、さらにURIがサポートメディアである必要があります。
 弊社R-FORCEではこの問題を解決するために、サポートメディアを配信サーバー上にダウンロードし、配信サーバー兼HTTPアクセス可能なWebサーバーとすることで、Chromecast機器は配信サーバーからメディアを取得することで解決しました。
 Googleドライブ上のメディアを直接再生など計画はあったのですが、Google認証はChromecastが行なうことが出来ないなど問題が浮上し断念しました。

Webサーバーにホスト名および固定IPがオススメ

 弊社R-FORCEではプライベートIPにて配信可能なものを作成しましたが、運用保守に関してはネットワーク知識が必須となってしまいました。
 理由については、先に述べたようにChromecast機器にてメディアを再生するには同一ネットワークである必要があるからです。
 配信サーバーのネットワークインターフェースが複数ある中で、Zeroconfサービスにより見つかった同一ネットワーク上のChromecast機器、これがどのネットワークに属しているのか分からなければなりません。これがもし分からなければ、Chromecast機器からみた配信サーバーのプライベートIPが分からず、配信サーバーからメディアを取得することが不可能に陥ってしまいます。
 これを解決するためにChromecast機器ホストのプライベートIPから、同一ネットワーク上の配信サーバーのネットワークインターフェースを特定し、配信サーバーに割り当てられたプライベートIPアドレスを取得。これにより各Chromecast機器に対しプライベートIP指定による配信サーバーへのHTTPアクセス、つまりメディアへのHTTPアクセスを可能としています。

 このネットワーク構成について、予め社内にて固定のIPアドレス(グローバルorプライベート)又は、ホスト名を配信サーバーに割り当てた方が作成時間を短縮することができます。Zeroconfサービスによる同一ネットワーク上の制限と配信サーバーのメディア取得は切り離すことが出来、Chromecast機器は固定のIPアドレス又はホスト名を指定しての再生が可能となります。
 ネットワーク環境を制限化することで、開発コストが変わってきますのでぜひご提案してみることをオススメします。

配信サーバーの再生命令はChromecast機器のスリープモードを解除してしまう

 Chromecast機器の電源がOFF、言い換えるとテレビの電源をリモコンでOFFにしてあっても、配信サーバーから再生命令を送信すると電源がONに切り替わりメディア再生を始めてしまいます。
 これにより24時間稼働させるには再生命令を送信しない時間帯制御を行なう実装をする必要となりました。
 弊社R-FORCEでは、配信サーバーにCron設定を行ない自動で配信システムの起動と停止の制御を行なっております。

配信サーバーの再生命令はChromecast機器の状態を上書きしてしまう

 スリープモード解除と似た話ですが、Chromecast機器にて何かしら利用していたとしても上書きしてしまいます。

f:id:rf-blog-sagyo:20201008154617p:plain
再生
 弊社R-FORCEではChromecast機器に再生命令を発信する前に、配信停止命令を受けているChromecast機器か判別を行ない再生除外を可能としています。

Chromecast機器との接続周りの内部実装が分かりにくい

 Chromecast機器とのソケット周りの接続実装。README.rst の How to Use を読んで実装は出来ました。
 しかし、弊社R-FORCEでは複数のChromecast機器が存在するため定期的にChromecast機器の検索が必要でした。
 実装当初Pychromecastライブラリのバージョン 6.0.1 にて実装していたget_chromecasts()関数、今の Pychromecastライブラリのバージョン 7.5.0 の How to Use では記載ないがないものの、このget_chromecasts()関数を利用して接続を行なっておりました。*1
 この関数は同一ネットワーク上すべてのChromecast機器をZeroconfサービスを通して検出し、ソケット接続まで行なってくれるため大変ありがたい機能です。
 これを利用してメディアを再生して次のメディア再生に進む時に、get_chromecasts()関数を使ってすべてのChromecastを検索、もしChromecast機器が追加されている場合はここで新たに再生するChromecastとして追加して再生という実装を施しました。

 しかし、これには大きな問題がありました。
 それは数回メディアを再生するとChromecast機器との接続エラーで100%再生不能に陥るという現象です。

 この接続エラー問題に対し再接続を試みましたが何をやっても解決に結びつかずもがき苦しみました。
 Pychromecastライブラリのバージョン v6.0.1 から v7.5.0 にバージョンアップしたり、Pychromecastライブラリ周りのインスタンスをメディア再生の度に全て削除(デストラクタ)して再接続したりと、再接続の失敗の度に悩むに悩まされ別の手法別の手法と数回に渡り修正実装に着手。
 そして、あまりにも失敗続きであることからネットワーク通信の監視ソフトWiresharkを導入し調査するまでに発展。
 このWiresharkによるとPychromecastライブラリが利用しているZeroconfサービスを通して、マルチスレッドにてChromecast機器へソケット接続。メディアの再生の度に、Pychromecastライブラリ側で新たな接続を行ない、あるところでChromecast機器との接続失敗が始まっていることが確認出来るようになりました。
 これもしかして、一度接続に成功したChromecast機器とのソケット接続、この接続が生きたままメディア再生の度にget_chromecasts()関数によってChromecast機器とのソケット接続を新しく確立してはいないかと。そしてこのことがChromecast機器との接続最大数の上限に達してしまい切断を引き起こしていないかと疑惑が浮上しました。
 この疑惑のキッカケとなったのは次のissueより github.com  issue情報を元に、実装をPychromecastライブラリのバージョンv7.5.0の How to Use を参考にしながら、discover_chromecasts()関数にて同一ネットワーク上のChromecast機器を探し、切断検出したChromecast機器を検出した場合、または新しくChromecast機器を検出した場合に接続を行なうように変更しました。
 このように処理を切り替えたところメディアが一定回数再生してもChromecast機器との切断がなくなり、ようやく安定的な配信が可能となりました。

Chromecast機器のステータス判断種類が少ない

 弊社R-FORCEではPychromecastライブラリ利用時から拡張しています。
 その理由としてはChromecast機器のステータスPychromecastライブラリが標準で実装しているのが、
   * 再生中か?(PLAYING*2またはBUFFERING*3か?)
   * 一時停止中か?(PAUSED*4か?)
   * 何も再生していないか?(IDLE*5か?)
 この3パターンを提供しているものの、Chromecast機器のステータスのIDLEBUFFERINGPLAYINGPAUSEDの4種類のステータス遷移が上記3パターンだけでは要望を満たせないため拡張を行ないました。
 「再生中のBUFFERINGとPLAYINGを分けたい」「PAUSEDは再生中だけれど例外として扱いたい」「IDLEは再生前後で分けたい」といった条件分けを行ないたかったために、Chromecast機器のステータスについてはPychromecastライブラリ標準のものはほぼ利用せず、Pychromecastライブラリの外部から直接Chromecast機器のステータスを確認するように独自実装を行なっています。

Chromecast機器の拡張ステータスの取得部分を独自実装

 Chromecast機器の再生ステータスとして

IDLE ⇛ BUFFERING ⇛ PLAYING(PAUSED) ⇛ IDLE

大まかにはこのようなステータス変化をメディア再生の度に繰り返していました。

 弊社R-FORCEでは上記の流れからChromecast機器のステータスを調べIDLEというステータスを軸に、再生命令からIDLEというステータスに切り替わったとき再生終了と見なし次のメディア再生という遷移を行なっておりました。
 しかし、メディア再生途中で次のメディアの再生を開始してしまうというバグ報告を受けて調査を行なったところ、実際には次のステータス遷移を行なっておりました。

IDLE ⇛ BUFFERING ⇛ IDLE ⇛ PLAYING(PAUSED) ⇛ IDLE

 BUFFERINGの後にまさかのIDLEというステータスを稀に使用しており、この稀の現象を引き当てるとメディアのBUFFERINGが完了し、PLAYINGに切り替わる途中で次のメディア再生命令を配信サーバーから受け取ってしまい、メディア再生途中で次のメディアの再生という現象を引き起こしておりました。
 稀という表現行ないましたが、一度BUFFERINGされたメディアを再度再生している時に起こしており、Chromecast機器にて同一メディアを複数回再生していると発生するように感じました。ただ、この現象について原因を確定し現象を必ず再現させるまでは至れず稀という表現を行なっております。
 バグの調査を続けるに当たり、BUFFERINGの後のIDLEの場合は

{..., 'playerState': 'IDLE', ..., 'extendedStatus': {'playerState': 'LOADING', ...}}

というextendedStatusというパラメータを使ってChromecast機器のステータスplayerStateを返却しているため、Chromecast機器のステータスplayerStateがIDLEでもextendedStatusというパラメータが返却されたら、extendedStatus内のステータスplayerStateを優先するという処理をPychromecastライブラリを拡張させることで解決をさせました。

結論

 

参考にした記事を書いた人と実現したい要望(実装する環境)が必ず一致するのか確認しよう
 今回ネット上にあるPychromecastを利用した簡単に配信という記事からスタートしましたが、開発着手よりかれこれ半年・・・
 確かに1台だけの配信や1メディアだけの1回だけ再生であれば非常にかなり簡単に実装が出来ました。
 しかし要望は再生リストを作成してループ再生や複数のChromecast機器へ配信などetc...

 GoogleCastApiを利用したライブラリはPychromecast以外にも存在していました。

 ネットにある情報を鵜呑みにせず、ライブラリの比較や検証を正しく行なっていれば違った結果に行きつけたのかも知れません。
 この記事を読んだ人が私と同じようなまだトゲが残っている茨の道を歩むことが無いよう心よりお祈り致します。

*1:バージョン6.0.1の How to Useバージョン7.5.0の How to Use

*2:PLAYING: 再生中

*3:BUFFERING: 再生に備えて再生メディアデータを取り込んでいる状態

*4:PAUSED: 一時停止中(再生メディアが画像の場合はPLAYINGとならずPAUSEDの一時停止となる。動画メディアなどの場合はPLAYINGのあと再生中のメディアを一時停止するとPAUSEDの一時停止した状態となる)

*5:IDLE: 何も再生していない

Unityで作るDissolveShader

目次



自己紹介

初めましてクライアントエンジニアのK.Kです。

主にクライアントの作業をしている者ですが、 より見た目を綺麗にしたい、より製品のクオリティを自分の力で良くしたいなどの理由から1年ちょい前からシェーダーの勉強をしています。

まあシェーダーで何が出来るかイメージつかないかもなので、私が勉強がてらに作成したものを紹介します。

地面を塗ることができるシェーダー

f:id:rf-blog-sagyo:20201016160337g:plain

キャラクターを炭で書いたように表現するシェーダー

f:id:rf-blog-sagyo:20201016160825p:plain

塗るシェーダーと炭シェーダーを掛け合わせたもの

f:id:rf-blog-sagyo:20201016163500g:plain

そして今回ちょっとおしゃれな遷移を作りたかった!

f:id:rf-blog-sagyo:20201015200802g:plain

シェーダーとは

シェーダーとは簡単に考えるとCPUがGPUに表示方法を教えるための物です。 ではなぜCPUがGPUに表示方法を教える必要があるのでしょうか?

1920x1080のモニターで一度考えてみましょう。 1920x1080この数字はピクセル数を表しています、なので画面を一度描画するためには2,073,600ピクセルを処理しなければいけません。 CPUは難しい計算を淡々とこなしていくことが得意です。 ですが200万近くもしくはそれ以上の単純処理を一度にお願いしてしまうと突然処理が間に合わなくなります。 そこでGPUの登場です。 GPUは複数の単純処理を一度に行うことが得意で、200万近くの処理を行うにはもってこいです。 そのためにシェーダーが存在しています。

Unityでシンプルなシェーダーを見てみる

UnityでのShaderはShaderLabを使用しています。 ShaderLabは普通 Cg/HLSL プログラミング言語で書かれています。 Unityは自動的にDirect3D 9、OpenGLDirect3D 11、OpenGL ES 等にコンパイルしてくれるため、シェーダーはすべてのプラットフォームで動作します。 そこで画像をそのまま表示する一番シンプルなシェーダコードがこちらです。

Shader "Simple"
{
    Properties
    {
    }
    SubShader
    {
        Tags {"Queue"="Transparent" "RenderType"="Transparent"}
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            sampler2D _MainTex;

            fixed4 frag (v2f_img i) : COLOR
            {
                fixed4 col = tex2D(_MainTex,i.uv);
                return col;
            }
            ENDCG
        }
    }
}

いきなり見ても分かりづらいのでかみ砕いてこのシェーダーコードを簡単に説明していきます。

Shader

Shader "Simple"
{
    // シェーダーの中身
}

こちらがシェーダーの名前を指定する箇所です。

Properties

Properties
{
    // 追加パラメータ
    _NoiseTex ("Noise",2D) = "white"{}
}

シェーダー外部から入れるパラメータです。 ここで画像や値を入れることができます。また外部のコードからアクセスする事が出来る箇所です。 f:id:rf-blog-sagyo:20201015195935p:plain

構造が シェーダーで使う変数名("外部から見たときの名前",変数の種類) = デフォルト値になります。

ですのでこちらは_NoiseTex ("Noise",2D) = "white"{} シェーダー内では_NoiseTexという変数名で扱う Unity内ではNoiseという名前になる パラメータ自体は2D画像の物になる 最後のデフォルト値は"white"{}とあります。 こちらは画像が設定されていない場合白い画像が使われます。

SubShader

SubShader
{
    // 共通な設定やTagなどの指定
    Pass
    {
        // passのコード
    }
}

SubShaderとはPassで共通使用する設定、Tagなどを指定できる場所です。

#pragma

#pragma vertex vert
#pragma fragment frag

#pragmaとありますがこちらは何を利用するかを指定する場所です。
#pragma vertex name はnameに値する関数で頂点プログラムを含むことです。
#pragma fragment name はnameに値する関数でフラグメントプログラムを含むことです。

FragmentShader

fixed4 frag (v2f_img i) : SV_Target
{
    return fixed4(1,1,1,1);
}

fragはフラグメントシェーダーのコード部分です。 フラグメントシェーダーは描画される各ポリゴンに対して行う処理です。 フラグメントシェーダー色々ありますが画像編集ツールでよくある効果やマスクをイメージしてもらえると良いかもしれません。 f:id:rf-blog-sagyo:20201015212532p:plain

DissolveShader

今回はここからフラグメントシェーダーのみを利用して画像が消える演出、DissolveShaderを作っていきます。 f:id:rf-blog-sagyo:20201015200109g:plain

DissolveShaderは色々な物に使われており、使い方次第で敵が倒され、黒くなりつつ消えていく演出もできます。f:id:rf-blog-sagyo:20201015200144g:plain

まずはノイズのテクスチャーのパラメータとエフェクトがかかる強さを表すRateを用意します。

Properties
{
    _NoiseTex ("Noise",2D) = "white"{}      // 追加
    _Rate ("DissolveRate",Range(0,1)) = 0   // 追加
}
SubShader
{
//...
    Pass
    {
        //...
        
        sampler2D _MainTex;
        sampler2D _NoiseTex;    // 追加
        FLOAT _Rate;            // 追加
    
        //...
    }
}

DissolveShaderはノイズの画像を利用してDissolveをかけるRateに応じて画像のα値を抜いていくものになります。 使用するノイズの画像ですが基本的には白黒の画像を使用します。
f:id:rf-blog-sagyo:20201015212747j:plain

さてこちらのグラデーションの画像を見て一般的にはどこから消えるべきでしょうか? こちらの画像をフラグメントシェーダー内で見る場合はピクセル単位の色を見ることになります。

シェーダの色はfixed4(r,g,b,a)で0から1の間で値を持っているのですが、 左上のピクセルの場合色がfixed4(1,1,1,1)、右下のピクセルの場合色がfixed4(0,0,0,1)になります。

マスクなどでもそうですが1が表示すべき、0が隠すべきといった考え方になります。 よって、黒い部分から消えていくのです。

この二つのパラメータを準備した後にノイズテクスチャーの色の値を取る関数を用意します。

FLOAT NoiseValue(sampler2D tex, half2 uv)
{
    fixed4 col = tex2D(tex, uv);
    return (col.r + col.g + col.b) * 0.3333; 
}

sampler2Dは画像でuvはピクセルの座標になります。 その後にrbgの色値を平均させた値を返します。

ノイズの値を取る関数を用意したのでフラグメントシェーダーに反映させ、以下のようにします。

fixed4 frag (v2f_img i) : COLOR
{
    fixed4 col = tex2D(_MainTex, i.uv);
    
    FLOAT noise = NoiseValue(_NoiseTex, i.uv);
    col.rgb = lerp(col.rgb ,1 ,step(col.a ,0));
    
    return col;
}

こちらが実行結果です。 f:id:rf-blog-sagyo:20201015212933g:plain

Rateのパラメータを変えても変わりません。

これはシェーダーに正しい設定が出来てないからです。

SubShader
{
    Tags {"Queue"="Transparent" "RenderType"="Transparent"}
    Blend SrcAlpha OneMinusSrcAlpha  // 追加
    ZWrite Off  // 追加
    Pass
    {
        //...
    }
}

Blend設定に SrcAlphaとOnMinusSrcAlphaを追加 Blend設定を簡単に考えると描画されている物の色の混ざり具合の設定です。 こちらではα値を見て不透明にする設定の追加です。

ZWrite Off でポリゴンの裏側の描画をし、無くしています。

こちらが実行結果 f:id:rf-blog-sagyo:20201016133944g:plain

おまけ

”DissolveShaderは色々な物に使われており、使い方次第で敵が倒され、黒くなりつつ消えていく演出もできます。”

α抜きを行う直前に指定した色に変更すれば結構おしゃれになります。

そのためには指定したい色、色のしきい値のパラメータを追加し反映します。

Properties
{
    _NoiseTex ("Noise",2D) = "white"{}
    _Rate ("DissolveRate",Range(-1,1)) = 0
    _Color ("AcidColor",Color) = (1,1,1,1)              // 追加
    _Threshold ("DissolveThreshold",Range(0,1)) = 0.5   // 追加
}
SubShader
{
//...
    Pass
    {
         //...
         
         sampler2D _MainTex;
         sampler2D _NoiseTex;
         FLOAT _Rate;
         fixed4 _Color;         // 追加
         FLOAT _Threshold;      // 追加
         
         //...

         fixed4 frag (v2f_img i) : COLOR
         {
             fixed4 col = tex2D(_MainTex, i.uv);
             
             FLOAT noise = NoiseValue(_NoiseTex, i.uv);
             col.rgb = lerp(col.rgb ,1 ,step(col.a ,0));
             col = lerp(col, _Color, step(noise, _Rate + _Threshold));  // 追加
             col.a = lerp(1,0,step(noise, _Rate));
             
             return col;
         }
         
         //...
    }
}

これが実行結果になります。

f:id:rf-blog-sagyo:20201015200802g:plain

さいごに

シェーダーは何処から始めればいいか、何を勉強すればよいかと敷居が高い分野ですが、 サンプルコードなどはたくさんネットに散らばっています。 色々なサンプルを作っていく際に確実に身につくものはあります。

様々なシェーダーを作っていけば、これが出来るのでないか、あれが出来るのでないかと想像や可能性を実感できるので興味があるならば諦めずに挑戦し続けてほしいです。
難しいけどシェーダーは楽しいからいっぱい書こう!!

参考

docs.unity3d.com

docs.unity3d.com

qiita.com

© UTJ/UCL

学生時代ほぼ自己流で学んでいた専門卒3Dアニメーターが、入社して1年間で得られたことふりかえり

目次



はじめに

こんにちは!3DアニメーターのS.Kです。

今回は入社して丸1年が経ち
・学生の時と何が違うのか。
・そして技術的、精神的にどう成長できたか
という記事を書こうと思います。
まだ二年目ということもあり、学生さんに近い目線でお話ができると思うので、3Dアニメーターを目指す皆さんのお役に立てると嬉しいです!

学生時代にしていたこと

僕は元々アニメが好きでこの業界を目指していました。
しかし、自分が在籍していた学校にはアニメーションに関する授業がほとんどなく
ネットでなんとなく調べたり、創りたいな!と思うものを独自で創っていました。
この、「ちゃんとアニメーションの技術を調べず創りたいものをなんとなく創っていた」ということが、今でも後悔している反省点の一つです。

しっかりとした「知識をインプットし、作品へアウトプット」という工程をしていなかったことが 今でも本当に悔やまれます。
最低限の「12原則」などは何となく理解していましたが、
アニメーションはとても奥が深く、知識、経験がなくても仕事として提出できるものを創れるほど甘い世界ではありませんでした。


*アニメーションにおける12原則とは
・SQUASH&STRETCH ・ANTICIPATION
・STAGING
・STRAIGHT AHEAD&POSE TO POSE
・FOLLOW THROUGH&OVERLAPPING
・SLOW IN&SLOW OUT
・ARCS
・SECONDARY ACTION
・TIMING
・EXAGERATION
・SOLID DRAWINGS
APPEAL
上記からなるアニメーションの考え方です

昔と違い、今では大事な基礎もネットで調べれば膨大な知識を得ることができる時代なので、学生の皆さんにはしっかりとアニメーションの知識を吸収し
得た知識、技術を作品に反映するということを実践して欲しいです。
最初のうちは退屈かもしれませんが
・重心を意識したポーズ
・アニメーション(一歩前に出る、椅子に座るなど)を創り
体の動かし方、重心の移動を徹底して勉強することをお勧めします。
これができず会社に入ってから僕はとても苦労しました。
本当に大事ですので、是非日々の勉強に取り入れてくださいね!

現在の勉強法

現在は、仕事と並行して時間を決めてポーズやアニメーションを作っては先輩へ提出し、
「なぜこの時はここがこう動くのか」などを教えて頂いています。
↓の画像は実際にポーズ作り、FBをもらい修正した際のデータで、
気を付けるべきことや教えて頂いたことを記載したメモになります。
f:id:rf-blog-sagyo:20200828172122p:plain

時間を決めてと書きましたがここが結構重要で、
時間を決めないと結局だらだらと作業してしまい、無駄になってしまうことがあります。時間を区切ることで終わりが必然的に決まるので、作業にもメリハリがつきます。
また、「時間内でどう完成させよう」と自然に効率化が図れます。

集中力も鍛えられるので一石四鳥な作業法です。

また、アニメーションの勉強とは別に美術解剖の勉強もしています。
アニメーションを創る上で骨や筋肉の可動域を理解することは、
とても大切なことです。
最近では 毎日10分は必ず美術解剖の本を読むようにしています。
こういう時には体はこう動く、男女の骨格の違いなどある程度ルールや法則性があるので
知識としてそこを知っていれば、男性らしいポーズ、女性らしいポーズなども
あまり悩まず創ることが出来ます。
僕が読んでいる「ソッカの美術解剖学ノート」という本ですが
アニメーター、モデラーイラストレーターなど職種に限らず、1冊は持っていて欲しい!と感じる本です。
値段は少し張りますが、イラストも多く、わかりやすく説明してくれているのでサクサク読めますよ!

ソッカの美術解剖学ノート | ジョンヒョン, ソク, ジニ, チャン |本 | 通販 | Amazon

f:id:rf-blog-sagyo:20200828172929p:plain

今の仕事に関して

ゲームのストーリー部分のシネマや必殺技のカットインなどを
メインに作業をしています。
最近では、社内で制作しているゲームの
インゲーム部分のモーションを手伝っていました。
カットシーンの制作はアニメーションだけではなく、カメラワークも加わってくるので
モーションだけを作るよりも難易度は高くなりますが、
やりがいをもって仕事と向き合い
先輩たちに助けてもらいながらも精進しています。

入社から一年が経ち、かわった心境の変化など

学生の時は自分が好きだから、創りたいから作品を創っていましたが、
会社に入るとそうはいきません。
必ずしも自分がしたい仕事、創りたいものだけが創れるわけではないからです。
ですが、そこでふてくされてはいけません。何事も勉強です。
最初の方でも書きましたが、自分が苦手・気が進まない仕事でも必ず自分の経験値になります。
いざ自分がやりたいことができるとなった時、全力を尽くせず不完全燃焼よりも
自分の頭の中にある構想やイメージを全力で作品として具現化し
満足いくものが創れた方が良いし、楽しいですよね!

一番の心境の変化は、作品を見てくれる方々に満足してほしいと思うようになりました。
理由は、とある案件で携わらせていただいた作品の動画がYouTubeにあがり、親にそのことを話した時、とても喜び、褒めてくれたからです。
また、僕がアニメを見て感じたドキドキやワクワクを
今度は自分の作品を見てくれた人に感じてほしいと強く思いました。

会社に入ると、作業以外の業務は多く発生します。
業務に加えミーティングや、進捗会、その他雑務など一日はあっという間です。
そこで、なるべく時間を無駄にしないために最近では
一日のタイムスケジュールを作るようにしました。
「現在の勉強法」でも書きましたが、制約があるからこそ
作業の効率化を必死に行うし集中できるものです。
また、自分がいま置かれている状況を具現化することで、どうすればよいのか
作業が遅れてしまっていたら、どこで巻き取ればよいのか
なども見えてきます。
↓画像は実際に自分決めて行っていたタイムスケジュール表です。

*「用語集調べ入力対応」とは
カメラワークやアニメーションの用語をエクセルにまとめ、
重要度を決めたり参考サイトのリンク付けを行うなど、
エクセルに用語をまとめる作業の事です。

f:id:rf-blog-sagyo:20200828175521p:plain

おわりに

学生の皆さんにお伝えしたいのは、就職してもそこはゴールではなく
ようやくスタートラインに立ったということです。
就職したらそこには自分よりも知識、技術をもった方たちが多くいます。
その人たちの中で自分も対等、もしくはそれ以上の
パフォーマンスを発揮できる人にならなくてはいけないのです。
仕事である以上、作品に対し「新卒だからしょうがない」ということは通用しません。
作品がクオリティーラインに達していなかったり、
劣っていればそれだけダメ出しがあったり、リテイクとなります。
そうならないためにも、「内定をもらったから」「就職したから」とあぐらをかかず
勉強や技術を高めることを続けてほしいと思います。
最後にはなりますが、皆さんがこの業界に入り、
一緒に仕事ができることを楽しみにしています。
先輩方に負けないようともに頑張っていきましょう!

長文になってしまいましたが最後までご覧いただきありがとうございました。

ゲーム開発の最後の砦!? QAチームについて

はじめに
初めまして。QAのリードをやっているものです。
QAとはゲーム開発においてクオリティを担保するための重要な砦として存在する部署です。
今回アールフォースで行っているQAの流れを説明します。



アールフォースのQAについて
まず初めにQAとは何かについてになります。
「QA」とは「Quality Assurance=品質保証」の略称になります。
会社によってはQC(Quality Control=品質管理)と言ったりします。

一言で簡単に言うと「デバッグ」になります。

デバッグと言われてイメージするのは長時間壁に向かって走り続けるようなすり抜けのチェックを思い浮かべる方もいるかもしれません。
そのようなデバッグをやることもありますが、アールフォースではそのデバッグ作業をメインでは行っていません。


作業の概要を端的に説明しますと
・クオリティを担保する為に必要な調査/提案
・クオリティを上げるためにテスト計画を立て実行

などを行っています。

もっと具体的に作業を説明しますと以下のような順番で作業を行っています。


上記をざっくりとした説明ものが以下になります。

仕様書レビュー

f:id:rf-blog-sagyo:20200717183048j:plain 開発の初期から仕様書を確認し、仕様漏れやユーザビリティ、ユーザーエクスペリエンスについての指摘/提案を行っていきます。

テストプランの作成

f:id:rf-blog-sagyo:20200717183448j:plain 開発中期に作成する資料で、テストの計画書になります。
テスト範囲や環境、テストスケジュール、人員計画等をまとめ、どのようなテストが行われるか事前に確認してもらうものになります。

テストケースの作成

f:id:rf-blog-sagyo:20200717184124j:plain 開発中期に作成する資料で、チェックシートの設計書のようなものになります。
どの機能に対しチェックシートを作成するかをまとめます。

チェックシートの作成

f:id:rf-blog-sagyo:20200717184223j:plain テストケースに記載されてる機能に対して仕様通りの挙動になっているかチェックするための資料になります。
確認するための操作とその結果どうなるのが仕様通りか、データの数値がどうなっているのが正しいのかなどがまとめられています。
また組み合わせチェックでは無数にあるパターンを記載しテストプランで決めた範囲をチェックしていきます。

テストパスの作成

f:id:rf-blog-sagyo:20200717184524j:plain すべてのチェックシートの確認に必要な時間と作業者の人数をまとめた資料になります。
すべてのチェックシートの確認が終わる事で1回のテストパスが終了となり、テストパスを13回行えば、致命的なバグはすべて発見できると考えています。

テストスケジュールの作成

f:id:rf-blog-sagyo:20200717184347j:plain テストパスを基に、13回すべてのチェックシートの確認を行うことができるスケジュールを作成します。
スケジュールは予定通り、想定外、理想など3通りほど作成し、プロジェクトに提案します。

BVT(Build verification test)の作成/実行

f:id:rf-blog-sagyo:20200717184707j:plain テスト用のアプリ作成時に必ず行う簡易的なチェックシートになります。
アプリの安定性向上やデバッグを行うための準備を目的として行います。

バグプロジェクション

f:id:rf-blog-sagyo:20200717184813j:plain 過去プロジェクトのデータを使用し、バグ報告のピークがいつになるか、報告件数はどれくらいになるか、修正可能件数は何件か、どのようなバグが多いかを予測します。
予測を基に、安定したリリースを行うためピークが来る時期を調整します。

バグトリアージ

f:id:rf-blog-sagyo:20200717184904j:plain 残っているバグが多い場合に、対応すべきバグとそうでないバグを仕分けます。
対応すべきものを明確化することで、やるべき作業に注力し、スケジュールの延期またはクオリティが低いゲームをリリースしてしまうことを防ぎます。

ポストモーテム

f:id:rf-blog-sagyo:20200717184957j:plain 開発終了後に行う反省会のようなものになります。
次回の開発の際に同じ轍を踏まないように、問題点に対し改善策を出していくものになります。
各セクションでまとめたものをリーダーたちで共有することで開発の度に成長していく組織を作っていきます。


まとめ
結構発言を軽視されがちなQAですが、最初にも言ったように実は最も大事な部署だと思っています。
QAやデバッガーがいないプロジェクトは開発を行いながら自分でデバッグを行い、バグを直しきれず、ユーザーに発見してもらうという状態になってしまいます。
そのような状態でリリースしたゲームはユーザーの皆さんに長く遊んでもらえない事が多く、そうならないための砦としてQAは存在していると思っています。
f:id:rf-blog-sagyo:20200717185050j:plain

就活生の必須科目? プランナーこそ「コミュ力」を磨くべき

目次


はじめに

お疲れ様です、プランナーのT2と申します。

好きな三国志の武将は鄧艾です。

 

さて。

今回は、就活生の間でよく取沙汰される、「コミュ力」についてのお話です。

f:id:rf-blog-sagyo:20200625152147p:plain

 

コミュ力」とは何か

略さず言うと、「コミュニケーション能力」。

アルファベットで書くと"communication"。

コミュニケーションと、ネットで検索してみると、

英単語の1つで、「伝達」「通信」「意思疎通」などの意味。 言語、身ぶり、画像などの物質的記号を媒介手段とした、精神的交流のこと。通じ合い。

といった意味の言葉であることがわかります。

 

たまに間違った解釈をしている人がいますが、「コミュ力」というのは、ただ会話ができたり、自分の意見を一方的に通す能力のことではありません。

自分の意見を伝え、かつ相手の意見を聞き、自分を含めた複数の人の声を正しく理解する力のことなのです。

f:id:rf-blog-sagyo:20200625152236p:plain

 

ゲーム開発に「コミュ力」は必要なのか

一般企業の就職活動において、「コミュ力」の高さを求められる、という話をよく耳にします。

それでは、ゲーム業界ではどうなのでしょうか?

 

 

 

 

結論から言うと、めっちゃ必要です。

ゲーム業界に対して、

「高い技術力」や「センス」のある人材が求められる

といったイメージを抱いている人も多いかもしれませんが、

それらと同等か、あるいはそれ以上に、「コミュ力」は重要視されます。

f:id:rf-blog-sagyo:20200625152351p:plain

 

なぜ「コミュ力」が必要なのか?

コミュ力」が重要視される理由は明白で、

ゲーム開発イコール「チーム仕事」だからです。

極端に小規模なゲームや、時間的制約が少ない自主制作タイトル、そして数少ない天才クリエイターを除いて、スタッフ1人のできる仕事の範囲は限られています。

例えば私は、プログラムコードは書けませんし、絵も描けません。 仕様書は書けますし、シナリオも書いた経験がありますが、両方を並行作業するのは、すごく時間が掛かってしまいます。

ところが、商業作品の制作には、往々にして納期・締め切りが伴います。

1人のスタッフによる開発には、限界があるのです。

そのため、チームを結成し、プロジェクトとしてゲーム開発に取り組んでいくのが、一般的なやり方となります。

 

しかし、複数のスタッフが同時並行で作業を進めている途中で、

それぞれが思い描く「できあがり」のイメージにズレが出る

ことがあります。

それも、かなりの頻度で。

 

抽象的な例を挙げると、

プログラマーが5mmのネジを作っているのに、デザイナーは5cmのネジ穴を作ってしまい、それぞれ出来上がったものを合わせてみたら、全然サイズが合わない!

みたいなことが起こったりします。

(なお、こういう時にプランナーは、仕様書の単位記載漏れのミスを、把握していなかったりします)

こうした事態が延々と発生すると、開発が遅々として進まなくなり、スケジュールが遅れるハメになります。

お互いに不信感が生まれてしまうと、これはもう最悪ですね。

 

f:id:rf-blog-sagyo:20200625152643p:plain

プランナーの仕事

上記のような、スタッフ間での連絡の齟齬・食い違いのことを、

ディスコミュニケーションと呼んでいます。

平易に言い直すと「コミュニケーションの不足」ですね。

 

はい。

ここで「コミュ力」という最初の話題にボールが戻ってきます。

上記したような認識の齟齬は、コミュニケーションを丁寧に行うことで、事前に回避可能です。

スタッフが「いま作ってるネジって、どのサイズだっけ?」ということを確認すれば、 「なんか作っているもの違っていない?」という疑問が生まれ、互いの認識を擦り合わせる機会を持つことができるわけです。

 

私の考えでは、プランナーの役割の1つに

「面白いゲームを構成する要素の1つ1つを、設計段階から検討し、責任もって完成まで遂行すること」

があります。

仕様書や設計書を書くのは、チームのスタッフに仕事をしてもらうための、手段の1つに過ぎません。

この役割を達成するにあたって、「コミュ力」はこの上ない武器になります。

「コミュニケーションの不足」によって問題が引き起こるならば、「コミュニケーション」によってその問題を解消、もしくは未然に防ぐことができる、というわけです。

チームの仕事を停滞させず、開発を円滑に進めるために、プランナーには「コミュ力」が必要なのです。

f:id:rf-blog-sagyo:20200625152725p:plain

 

求められる「コミュ力」の正体

それでは、プランナーを志望する皆様に向けて、

私の考える「どんなコミュ力があれば、ゲーム制作に役立つか」を特別大公開。(ジャーン)

 

1. ポジティブな思考

コミュニケーションの第1歩は、人と気兼ねなく話ができることです。

吐き散らかされるネガティブに、人は心を開きません。

「なぜその機能の実装が必要なのか」 「なぜそのデザインでなければならないのか」

ポジティブな思考と話を心がけ、相手の心のドアを優しくノックしましょう。

2. 軽妙なフットワーク

開発スケジュールは常に動き続けます。

わからないこと・不安を抱えたまま、居付いて押し黙ることは時間の無駄。

軽い足取りで出かけて、意思の疎通を図って、あなたを覆う不安の雲を晴らしましょう。

3. 相手の気持ちをよく考え、推し量る

上に挙げた1と2の例ですが、行き過ぎると失礼なコミュニケーションになることも…

人はそれぞれ異なる意見や考え方を持っていますし、プライドだってあります。

そもそも仕事がすごく溜まっていて、聞く耳を持つ時間すらないかもしれません。

そうした時は、慎重に考えて、コミュニケーションの内容を選ぶことも、重要になるのです。

4. 最終目的は常に1つ!

私たちの最終目的は、最高のエンターテインメントを作り出し、お客様を喜ばせることです。

それは不変の事実であり、どんな仕事をしていても、それを決して忘れてはいけません。

もし、その目的に背くような類のコミュニケーションを取らなければならない…

そんな時は立ち止まり、もう一度考え直してみる時間が必要なのです。

 

 

まとめ

  • ゲーム開発者に「コミュ力」は必要。開発=チーム仕事だから

  • プランナーには特に必要。チーム仕事を遂行させるのが役割だから

  • ポジティブに、アクティブに。冷静さと情熱も忘れずに!