みくみくまうすについて&Unity で使えるコーディングノウハウ

114
みくみくまうすの紹介 Unityにおけるコーディングノウハウ とりすーぷ 12/20 プログラミング生放送勉強会

Transcript of みくみくまうすについて&Unity で使えるコーディングノウハウ

Page 1: みくみくまうすについて&Unity で使えるコーディングノウハウ

みくみくまうすの紹介&Unityにおけるコーディングノウハウ

とりすーぷ

12/20

プログラミング生放送勉強会

Page 2: みくみくまうすについて&Unity で使えるコーディングノウハウ

自己紹介

とりすーぷ (@toRisouP)

• 25歳

• 某Web企業でエンジニアやってる

• 趣味でいろいろ開発してる

– 一番得意な言語はC#

– 最近はずっとUnityいじってる

– あとUniRxが最近のマイトレンド

Page 3: みくみくまうすについて&Unity で使えるコーディングノウハウ

過去に作ったもの

交通事故・渋滞シミュレータ

(sm16238908)

NITORI BOX

(東方2次創作ゲーム)

ユニティちゃんゴーストマンション

(OculusGameJam2014)

Page 4: みくみくまうすについて&Unity で使えるコーディングノウハウ

今作ってるもの

みこバト~レ

• 東方2次創作ゲーム

• UnityとPhotonCloudを使ったネット対戦ゲーム

• プログラマは自分1人だけ(いろいろツライ)

Page 5: みくみくまうすについて&Unity で使えるコーディングノウハウ

本題

今回話すこと

• 「みくみくまうす」の紹介

•コーディングする上で意識すべきこと

•Unity開発で活用できるC#の機能

Page 6: みくみくまうすについて&Unity で使えるコーディングノウハウ
Page 7: みくみくまうすについて&Unity で使えるコーディングノウハウ

みくみくまうす

• ニコ生の配信支援ツール

• MMDモデルがニコ生のコメントを読み上げてくれる

• 配信ツールでクロマキー合成して映像に合成して使う

Page 8: みくみくまうすについて&Unity で使えるコーディングノウハウ

ゲーム配信で使ったり

Page 9: みくみくまうすについて&Unity で使えるコーディングノウハウ

プログラミング生放送で使ってみたり

Page 10: みくみくまうすについて&Unity で使えるコーディングノウハウ

たくさん配置してみたり

Page 11: みくみくまうすについて&Unity で使えるコーディングノウハウ

生放送を盛り上げるためのツールみんなニコ生しようぜ

Page 12: みくみくまうすについて&Unity で使えるコーディングノウハウ

機能

• コメントの読み上げ

– 棒読みちゃんの設定次第でボイスロイドも使用可能

• コメントの感情解析

– コメントの内容でキャラクタのリアクションが変わる

• 複数キャラの同時使用

– コメントカラーで読み上げのフィルタリングができる

• デスクトップマスコットモード

– ウィンドウからキャラクタが独立して表示される

Page 13: みくみくまうすについて&Unity で使えるコーディングノウハウ

作った経緯

知人同士でニコ生を配信し、

自身のニコニココミュニティのレベルを

目標値まで先に上げた人が勝ち(コミュニティレベルは自分をお気に入り登録した人の数で決まる)

※優勝者は鰻が奢りになるから「鰻レース」と呼んでた

Page 14: みくみくまうすについて&Unity で使えるコーディングノウハウ

作った経緯2

女性の方のコミュレベルがどんどん上がっていく

(ただ顔出し放送するだけで入れ食い状態)

おっさんがただ配信するだけでは華がなく絶対に勝てない

だったら画面に女の子がいれば華があって人がくる?

あと自分はエンジニアなのでそこは武器になるのでは?

MMDモデルがコメントを読み上げてくれるツールを作ろう

Page 15: みくみくまうすについて&Unity で使えるコーディングノウハウ

しくみ

コメビュ(やりますアンコちゃん/NCV)

棒読みちゃん

• みくみくまうす用プラグインを作成

• ニコ生からコメントを取得

• コメントのフィルタリング/解析

• 口パクと発声依頼

• 実際に読み上げる

• VoiceroidTalkPlusを使えばボイスロイドでも読み上げできる

TCP Socket

TCP Socket

Page 16: みくみくまうすについて&Unity で使えるコーディングノウハウ

つかったもの

• Unity Pro 4.6(βのころから使ってた)

• ユニティちゃん(とそのアニメーション)

• MMD4Mecanim

• MeCab(NMeCab)

• LitJSON

みくみくまうすは「ユニティちゃんライセンス」で提供されています

Page 17: みくみくまうすについて&Unity で使えるコーディングノウハウ

ここまでは概要

この場は「プログラミング生放送勉強会」

実装の話を少しします

Page 18: みくみくまうすについて&Unity で使えるコーディングノウハウ

実装について話すこと一覧

•MMDモデルのインポート

•コメビュとの通信

•口パク

•コメントの感情解析

•設定ファイルの読み書き

•デスクトップマスコットモード

Page 19: みくみくまうすについて&Unity で使えるコーディングノウハウ

実装について話すこと一覧

•MMDモデルのインポート

•コメビュとの通信

•口パク

•コメントの感情解析

•設定ファイルの読み書き

•デスクトップマスコットモード

Page 20: みくみくまうすについて&Unity で使えるコーディングノウハウ

MMDのインポート

• MMD4Mecanimを使用すると簡単にインポートできる

– 付属のスクリプトがかなり充実している

– ただしモデルの動的ロードには対応していない

• 後述のライセンスの問題もある

Page 21: みくみくまうすについて&Unity で使えるコーディングノウハウ

MMDモデルのライセンス

• ゲームで使用して良いかは作者への確認が必要

– 作者によってライセンスがバラバラ

– Readmeに明記されていないことが多い

Page 22: みくみくまうすについて&Unity で使えるコーディングノウハウ

実装について話すこと一覧

•MMDモデルのインポート

•コメビュとの通信

•口パク

•コメントの感情解析

•設定ファイルの読み書き

•デスクトップマスコットモード

Page 23: みくみくまうすについて&Unity で使えるコーディングノウハウ

コメビュとの通信

• コメビュ用プラグインを作って導入

– TCP接続で待ち受ける(コメビュ側がホスト)

– 複数クライアントの同時接続に対応

– コメント情報のデータフォーマットはJSON

• コメビュとの通信Componentも作成

– コメビュからコメントを取得する

– 実際の通信を行う機構はUnityと分離してある

Page 24: みくみくまうすについて&Unity で使えるコーディングノウハウ

Unityでニコ生のコメントを取得したいとき

• CommentViewer2Unity

– コメビュプラグインからコメントを取得するComponent

– 使用にはLitJSONが必要

– https://github.com/TORISOUP/CommentViewer2Unity

Page 25: みくみくまうすについて&Unity で使えるコーディングノウハウ

【余談】UnityでJsonを使う

• Unityでは標準ではJsonが扱えない

• Jsonライブラリを入れる必要がある

– MiniJSON

– JSONObject

– LitJSON ← 自分はこれを使ってる

Page 26: みくみくまうすについて&Unity で使えるコーディングノウハウ

そもそもJsonとは

• JavaScript向けに作られたデータ記述言語– 数値

– 文字列

– Boolean

– 配列

– 連想配列

– Null

※要するに各値をテキストデータに変換する時のフォーマットの一つ

Page 27: みくみくまうすについて&Unity で使えるコーディングノウハウ

LitJSONの使い方

•オブジェクトをJSON化する

Page 28: みくみくまうすについて&Unity で使えるコーディングノウハウ

LitJSONの使い方

•JSONからオブジェクトに変換する

ToObject<T>()を使えば良い

ただし

• 変換に失敗すると例外が飛ぶ

• floatは使えない(doubleを使うこと)

• 値の中身がnullだった時の扱い(null許容型を使う)

Page 29: みくみくまうすについて&Unity で使えるコーディングノウハウ

Jsonで値が送られてこなかった時の判別方法

•Null許容型構造体(値型)にnullが入ることを許容する

「Jsonの中身にNoの要素が無かった」

・非Null許容型int → 0で初期化(0が送られてきたのか判断不能)

・Null許容型int → Nullかどうかで値が送られてないと判断できる

Page 30: みくみくまうすについて&Unity で使えるコーディングノウハウ

実装について話すこと一覧

•MMDモデルのインポート

•コメビュとの通信

•口パク

•コメントの感情解析

•設定ファイルの読み書き

•デスクトップマスコットモード

Page 31: みくみくまうすについて&Unity で使えるコーディングノウハウ

口パク

• MMD4MecanimSpeechHelperで簡単にできる

– MMDモデルはこのスクリプトで口パクできる

– ただしこのSpeechHelperはMMDモデルにのみ使える

– ユニティちゃんは別にスクリプトを自作して対応

• クエリちゃんは対応できんかった……

Page 32: みくみくまうすについて&Unity で使えるコーディングノウハウ

口パク機構の管理

• インターフェースを用いて呼び出し元の処理を統一

SpeechTextController読み上げるコメントの

管理を行う

MMD4MecanimSpeechHelperMMD向け口パクComponent

インターフェースISpeechController

UnitychanLipControllerユニティちゃん専用口パクComponent

Page 33: みくみくまうすについて&Unity で使えるコーディングノウハウ

口パク用のコメントひらがな変換

• 口パクさせる為にコメントのひらがな化を行う

– NMeCabを使ってひらがな化

– KakasiはGPLライセンスだったので避けた

Page 34: みくみくまうすについて&Unity で使えるコーディングノウハウ

実装について話すこと一覧

•MMDモデルのインポート

•コメビュとの通信

•口パク

•コメントの感情解析

•設定ファイルの読み書き

•デスクトップマスコットモード

Page 35: みくみくまうすについて&Unity で使えるコーディングノウハウ

コメント感情解析

•コメントの内容に応じてリアクションが変化する

Page 36: みくみくまうすについて&Unity で使えるコーディングノウハウ

リアクションするキーワードの例

• 挨拶 (「わこつ」、「初見」など)

• 挙手 (ノ)

• 笑い (wを含むコメント、「吹いた」「ワロス」など)

• 絶叫 (あああああ! など)

• ツッコミ (「おまえが言うな」「やめてー><」など)

• 命令 (~しろ! など)

• 疑問 (語尾に「?」が付いているなど)

• 感動 (「泣けてきた」「切ない」など)

• 賛美 (「ありがとう」「才能の無駄遣い」など)

• 返答 (「おこ?」「ですよねー」など)

• 興奮 (「おおぉぉぉぉぉ!」など)

• 賞賛 (「すごい!」など)

※ただしそこまで精度はよくない

Page 37: みくみくまうすについて&Unity で使えるコーディングノウハウ

コメント感情解析の仕組み

• ニコニコ動画コメント@ばっちりサーチ.net

– こちらのnode.js用モジュールをC#に移植

• https://github.com/TORISOUP/CommentAnalyzerCSharp

– 中身は鬼のような正規表現

– 正直どのコメントが何に判定されるかわからない

Page 38: みくみくまうすについて&Unity で使えるコーディングノウハウ

実装について話すこと一覧

•MMDモデルのインポート

•コメビュとの通信

•口パク

•コメントの感情解析

•設定ファイルの読み書き

•デスクトップマスコットモード

Page 39: みくみくまうすについて&Unity で使えるコーディングノウハウ

設定パネル

Page 40: みくみくまうすについて&Unity で使えるコーディングノウハウ

設定ファイル

• パラメータをJsonでテキストに保存(.NETの機能)

– PlayerPrefsはレジストリに保存されるので使いたくない

– バイナリにシリアライズして保存すると後から変更しにくい

– 読み込み時にバリデーションを入れる必要がある(平文保存のため)

Page 41: みくみくまうすについて&Unity で使えるコーディングノウハウ

実装について話すこと一覧

•MMDモデルのインポート

•コメビュとの通信

•口パク

•コメントの感情解析

•設定ファイルの読み書き

•デスクトップマスコットモード

Page 42: みくみくまうすについて&Unity で使えるコーディングノウハウ

デスクトップマスコットモード

• こちらのAssetを使わせて頂きました

• オススメです

Page 43: みくみくまうすについて&Unity で使えるコーディングノウハウ

みくみくまうすのまとめ

• ニコ生配信支援ツール

• フリーソフトとして配布中

• 生放送を盛り上げるのに使ってね!!!

• プログラミング生放送でも使おう!!

• 使うときは「みくみくまうす」のタグを付けてくれるとエゴサしやすくて助かります

Page 44: みくみくまうすについて&Unity で使えるコーディングノウハウ

ステッカー

• 調子に乗ってステッカーも作りました

– 数に限りがあるので欲しい人は1人1枚お持ち下さい

– 割りと安い(100枚刷って4000円くらい)

Page 45: みくみくまうすについて&Unity で使えるコーディングノウハウ

くぎり

•みくみくまうすについての質問とかあれば

続いて「コーディングする上で意識すべきこと」→

Page 46: みくみくまうすについて&Unity で使えるコーディングノウハウ

コーディングする上で意識すべきこと

Page 47: みくみくまうすについて&Unity で使えるコーディングノウハウ

おしながき

•名前

•機能の分離

•SOLID原則

•MVCパターン

Page 48: みくみくまうすについて&Unity で使えるコーディングノウハウ

おしながき

•名前

•機能の分離

•SOLID原則

•MVCパターン

Page 49: みくみくまうすについて&Unity で使えるコーディングノウハウ

名前

わかりやすい名前をつけろ!!!!!

Page 50: みくみくまうすについて&Unity で使えるコーディングノウハウ

例)メソッド名

• メソッド名から処理内容が判断できるべき

– メソッド名が長くなるのは構わない(限度はあるが)

– 例)GetNearestEnemyFromPlayer

• 誤解される名前をつけるな

– Get*()なのに副作用がある

• 副作用=状態を変化させてしまう動作

• Get()は何度実行しても結果が同じになるべき(べき等性)

– GetSize()なのに計算量がO(n)

• GetSize()はO(1)であるべき

• O(n)なら「Count()」にしたほうがまだわかる

Page 51: みくみくまうすについて&Unity で使えるコーディングノウハウ

おすすめの本

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

Page 52: みくみくまうすについて&Unity で使えるコーディングノウハウ

おしながき

•名前

•機能の分離

•SOLID原則

•MVCパターン

Page 53: みくみくまうすについて&Unity で使えるコーディングノウハウ

機能の分離

• Unityに依存しないコードを書こう

– なんでもかんでもMonoBehaviourを継承させない

– Unityからゲームロジックを分離する

– Unity以外でもそのまま使えると良い

– 単体テスト書きやすくなる

Page 54: みくみくまうすについて&Unity で使えるコーディングノウハウ

おしながき

•名前

•機能の分離

•SOLID原則

•MVCパターン

Page 55: みくみくまうすについて&Unity で使えるコーディングノウハウ

SOLID原則

• オブジェクト指向開発を行う上での5つの原則

– 単一責任の原則(SRP)

– オープン・クローズドの原則(OCP)

– リスコフの置換原則(LSP)

– 依存関係逆転の原則(DIP)

– インターフェース分離の原則(ISP)

• あくまで原則である

– 必ず守る必要はない

– 守ったほうが良い場合の方が多い

– Unity開発も例外ではなく守った方が良い

Page 56: みくみくまうすについて&Unity で使えるコーディングノウハウ

SOLID原則

• 単一責任の原則(SRP)

• オープン・クローズドの原則(OCP)

• リスコフの置換原則(LSP)

• 依存関係逆転の原則(DIP)

• インターフェース分離の原則(ISP)

Page 57: みくみくまうすについて&Unity で使えるコーディングノウハウ

単一責任の原則

「クラスを変更する理由は1つ以上存在してはならない」

「一つのクラスに複数の責務を持たせるな」

• 馬鹿でかいクラスは管理しにくい

• 1つのクラスにあれこれ機能を詰め込むな

• クラス名以上の責務は負わせるな

Page 58: みくみくまうすについて&Unity で使えるコーディングノウハウ

悪い例

• PlayerController(プレイヤキャラクタの制御)– Inputの受け付け

– キャラクタの移動処理

– キャラクタの攻撃処理

– キャラクタの体力の管理

– アニメーション再生の管理

– エフェクト再生の管理

– 効果音再生の管理

– カメラの制御

処理多すぎィ!!!!!だが初心者はやりがち

Page 59: みくみくまうすについて&Unity で使えるコーディングノウハウ

適切に分離しよう

• PlayerInputManager

– Inputの受け付け

• PlayerController

– キャラクタの移動処理

– キャラクタの攻撃処理

– キャラクタの体力の管理

• PlayerView

– アニメーション再生の管理

• CameraController

– カメラの制御

• EffectManager

– エフェクト再生の管理

• SoundManager

– 効果音再生の管理

Page 60: みくみくまうすについて&Unity で使えるコーディングノウハウ

SOLID原則

• 単一責任の原則(SRP)

• オープン・クローズドの原則(OCP)

• リスコフの置換原則(LSP)

• 依存関係逆転の原則(DIP)

• インターフェース分離の原則(ISP)

Page 61: みくみくまうすについて&Unity で使えるコーディングノウハウ

オープン・クローズドの原則

「モジュールの振る舞いの拡張に対してオープンである」

「モジュールの振る舞いの修正に対してクローズドである」

• 機能追加は簡単にできる

• 機能追加によって他のコードを書き換える必要はない

• 要するに「ポリモーフィズム」となるようにしろ

Page 62: みくみくまうすについて&Unity で使えるコーディングノウハウ

オープン?クローズド?

• あとから簡単に機能追加できるようにしろ

– インターフェースを実装すれば機能追加できる(オープン)

– 実クラスが増えても元のコードに変更はなし(クローズド)

SpeechTextController読み上げるコメントの

管理を行う

MMD4MecanimSpeechHelperMMD向け口パクComponent

インターフェースISpeechController

Page 63: みくみくまうすについて&Unity で使えるコーディングノウハウ

オープン?クローズド?

• あとから簡単に機能追加できるようにしろ

– インターフェースを実装すれば機能追加できる(オープン)

– 実クラスが増えても元のコードに変更はなし(クローズド)

SpeechTextController読み上げるコメントの

管理を行う

MMD4MecanimSpeechHelperMMD向け口パクComponent

インターフェースISpeechController

UnitychanLipControllerユニティちゃん専用口パクComponent

Page 64: みくみくまうすについて&Unity で使えるコーディングノウハウ

オープン?クローズド?

• あとから簡単に機能追加できるようにしろ

– インターフェースを実装すれば機能追加できる(オープン)

– 実クラスが増えても元のコードに変更はなし(クローズド)

SpeechTextController読み上げるコメントの

管理を行う

MMD4MecanimSpeechHelperMMD向け口パクComponent

インターフェースISpeechController

UnitychanLipControllerユニティちゃん専用口パクComponent

ユニティちゃんを簡単に追加できる(オープン)

Page 65: みくみくまうすについて&Unity で使えるコーディングノウハウ

オープン?クローズド?

• あとから簡単に機能追加できるようにしろ

– インターフェースを実装すれば機能追加できる(オープン)

– 実クラスが増えても元のコードに変更はなし(クローズド)

SpeechTextController読み上げるコメントの

管理を行う

MMD4MecanimSpeechHelperMMD向け口パクComponent

インターフェースISpeechController

UnitychanLipControllerユニティちゃん専用口パクComponent

呼び出し側に修正不要(クローズド)

Page 66: みくみくまうすについて&Unity で使えるコーディングノウハウ

SOLID原則

• 単一責任の原則(SRP)

• オープン・クローズドの原則(OCP)

• リスコフの置換原則(LSP)

• 依存関係逆転の原則(DIP)

• インターフェース分離の原則(ISP)

Page 67: みくみくまうすについて&Unity で使えるコーディングノウハウ

リスコフの置換原則

「派生クラスは基底クラスで定めたルールを破ってはいけない」

• 基底クラスで定義された部分は派生クラスと置換可能である

• 派生クラスは基底クラスと全く同じ仕事ができなくてはいけない

Page 68: みくみくまうすについて&Unity で使えるコーディングノウハウ

リスコフの置換原則に違反した例

例)移動メソッドMove(Vector3 direction)

基底クラス:引数に方向ベクトルを与える(長さ1のベクトル)

移動速度は内部の状態に基づいて決まる

派生クラス:引数に速度ベクトルを与える

移動速度は与えられたベクトルで従う

基底クラスと派生クラスで振る舞いが違う

Page 69: みくみくまうすについて&Unity で使えるコーディングノウハウ

SOLID原則

• 単一責任の原則(SRP)

• オープン・クローズドの原則(OCP)

• リスコフの置換原則(LSP)

• 依存関係逆転の原則(DIP)

• インターフェース分離の原則(ISP)

Page 70: みくみくまうすについて&Unity で使えるコーディングノウハウ

依存関係逆転の原則

「上位モジュールは下位モジュールに依存してはならない。

どちらのモジュールもインターフェースに依存すべきである」

• インターフェースを使え

• 実クラスへの参照を無くしてインターフェースに依存させろ

Page 71: みくみくまうすについて&Unity で使えるコーディングノウハウ

関係の逆転?

• 上位から下位に依存した関係(ダメな例)

– 上位モジュールが下位モジュールに依存

– 実クラスそのものを参照してしまっている

– 実クラスの変更の影響を上位モジュールが受けやすい

InputManager入力を管理する

PlayerReimuプレイヤ(霊夢)

PlayerMarisaプレイヤ(魔理沙)

Page 72: みくみくまうすについて&Unity で使えるコーディングノウハウ

関係を逆転させる

• 下位から上位に依存させる

– 上位のレイヤにインターフェースを作成

– 上位モジュールはインターフェースを参照する

– オープン・クローズドの原則も同時に満たされる

InputManager入力を管理する

PlayerReimuプレイヤ(霊夢)

PlayerMarisaプレイヤ(魔理沙)

PlayerYoumuプレイヤ(妖夢)

インターフェースIPlayerInput

Page 73: みくみくまうすについて&Unity で使えるコーディングノウハウ

SOLID原則

• 単一責任の原則(SRP)

• オープン・クローズドの原則(OCP)

• リスコフの置換原則(LSP)

• 依存関係逆転の原則(DIP)

• インターフェース分離の原則(ISP)

Page 74: みくみくまうすについて&Unity で使えるコーディングノウハウ

インターフェース分離の原則

「クライアントにクライアントが本来依存しないメソッドへの依存性を強制して

はならない」

• 不必要なメソッドまでクライアントに提供しない

• インターフェースを適切に分割して提供しろ

Page 75: みくみくまうすについて&Unity で使えるコーディングノウハウ

インターフェース分離の原則に違反した例

InputManager入力を管理する

PlayerReimuプレイヤ(霊夢)

PlayerMarisaプレイヤ(魔理沙)

PlayerYoumuプレイヤ(妖夢)

インターフェースIPlayerInput

Move()Attack()Jump()

Move()Attack()Jump()

Move()Attack()Jump()

Move()Attack()Jump()

• IPlayerInputインターフェースを各クラスが実装

– PlayerMarisaに「盗む Steal()」を増やしたい

Page 76: みくみくまうすについて&Unity で使えるコーディングノウハウ

• IPlayerInputインターフェースを各クラスが実装

– PlayerMarisaに「盗む Steal()」を増やしたい

– IPlayerInputに追加してしまった

インターフェース分離の原則に違反した例

InputManager入力を管理する

PlayerReimuプレイヤ(霊夢)

PlayerMarisaプレイヤ(魔理沙)

PlayerYoumuプレイヤ(妖夢)

インターフェースIPlayerInput

Move()Attack()Jump()Steal()

Move()Attack()Jump()

Move()Attack()Jump()Steal()

Move()Attack()Jump()

Page 77: みくみくまうすについて&Unity で使えるコーディングノウハウ

• 関係の無い他のクラスまで影響を受けてしまう

– 使わないのに実装しないといけない

インターフェース分離の原則に違反した例

InputManager入力を管理する

PlayerReimuプレイヤ(霊夢)

PlayerMarisaプレイヤ(魔理沙)

PlayerYoumuプレイヤ(妖夢)

インターフェースIPlayerInput

Move()Attack()Jump()Steal()

Move()Attack()Jump()Steal()

Move()Attack()Jump()Steal()

Move()Attack()Jump()Steal()

Page 78: みくみくまうすについて&Unity で使えるコーディングノウハウ

インターフェースを分離する

InputManager入力を管理する

PlayerReimuプレイヤ(霊夢)

PlayerMarisaプレイヤ(魔理沙)

PlayerYoumuプレイヤ(妖夢)

インターフェースIPlayerInput

• IStealインターフェースを新しく作る

– 必要としているクラスだけがそのインターフェースを実装する

インターフェースISteal

Page 79: みくみくまうすについて&Unity で使えるコーディングノウハウ

SOLID原則のまとめ

• 機能は分割して作れ

• インターフェースを使え

• モジュールの依存関係を疎結合にしろ

Page 80: みくみくまうすについて&Unity で使えるコーディングノウハウ

UnityとSOLID原則

• Componentは機能単位で分割して作るべき

– クラス名以上の責務は負わせるべきではない

– コードの記述量は増えるが、わかりやすくなる

• Componentはインターフェースを介してやりとりするべき

– Componentが複雑に関係しあう時は特に意識すべき

– Componentの差し替えが楽になる

• SOLID原則をいちいち守ってると逆に非効率なこともある

– 小さい規模なら無視して作ったほうがぶっちゃけ早い

– 大規模開発になった時はSOLID原則は重要になる

Page 81: みくみくまうすについて&Unity で使えるコーディングノウハウ

おしながき

•名前

•機能の分離

•SOLID原則

•MVCパターン

Page 82: みくみくまうすについて&Unity で使えるコーディングノウハウ

MVCパターン

• Model View Controller

– GUIを持つアプリケーションで用いられるデザインパターン

– 機能を以下の3つに分離する

Controller(ユーザからの入力)

Model(実データやロジック)

View(描画処理)

Page 83: みくみくまうすについて&Unity で使えるコーディングノウハウ

UnityとMVC

• プレイヤの制御がMVCパターンと相性がいい

– プレイヤ制御を以下のMVCに分離してしまう

Controller(ユーザからの入力)

Model(実データやロジック)

View(描画処理)

Input周りの処理• キーボード入力• マウス入力

メイン処理• 移動• ダメージ判定• 攻撃

出力系の処理• アニメーションの再生• エフェクトの再生• 効果音の再生

Page 84: みくみくまうすについて&Unity で使えるコーディングノウハウ

プレイヤ制御とMVC

• MVC分割のメリット

– Componentの責務が明確になる(単一責任の原則)

– 入力機器の差異をControllerの差し替えで対応できる

– ネットワーク同期も簡単になる

Page 85: みくみくまうすについて&Unity で使えるコーディングノウハウ

MVC分割でSOLID原則を満たすなら

• インターフェースを切ってそこに依存させる

Controller(ユーザからの入力)

Model(実データやロジック)

View(描画処理)

インターフェースIPlayerController

インターフェースIPlayerStatus

Move()Attack()Jump()

OnGroundIsRunningIsDead

Page 86: みくみくまうすについて&Unity で使えるコーディングノウハウ

実例

• ユニティちゃんゴーストマンション– MVCが分離されているのでそれぞれ個別に開発できる

– ゲームジャムで役に立った

←Controller

←Model

←View

←ネットワーク同期用スクリプト

Page 87: みくみくまうすについて&Unity で使えるコーディングノウハウ

「意識するべきこと」まとめ

• わかりやすさ最優先でコードを書くべき

• Unityへの依存は断ち切ろう

• SOLID原則を意識した設計にしよう

• インターフェースを活用しよう

• MVCパターンは割りと使えるかもしれない

Page 88: みくみくまうすについて&Unity で使えるコーディングノウハウ

Unityで活用できるC#の機能

Page 89: みくみくまうすについて&Unity で使えるコーディングノウハウ

おしながき

•拡張メソッド

•LINQ

•UniRx(※ C#の機能では無い)

Page 90: みくみくまうすについて&Unity で使えるコーディングノウハウ

おしながき

•拡張メソッド

•LINQ

•UniRx

Page 91: みくみくまうすについて&Unity で使えるコーディングノウハウ

拡張メソッド

• クラスに外からインスタンスメソッドを追加する

– staticメソッドを「あたかもそのクラスが持っているメソッド」を呼び出す

かの様に記述できるようになる機能

– 実際はただのstaticメソッドの呼び出し

static class ExtensionMethods

{

public static 返り値の型 メソッド名(this 追加対象の型,引数1…)

{

処理…

}

Page 92: みくみくまうすについて&Unity で使えるコーディングノウハウ

拡張メソッドを使うと便利な例

• Vector3のy成分を無視した水平面での方向を計算

– 進行方向にプレイヤを向かせるときに使うことが多い

• y成分を含ませると身体が傾く

進行方向

鉛直方向を無視した水平面での方向ベクトル

Page 93: みくみくまうすについて&Unity で使えるコーディングノウハウ

拡張メソッド)水平面での方向ベクトルを取得

• Vector3型への拡張メソッドとして定義する

– 拡張メソッドを収めるstatic classを定義

– その中にstaticメソッドを追加

– 第一引数のVector3にthisを付ける

Page 94: みくみくまうすについて&Unity で使えるコーディングノウハウ

拡張メソッド)実際に使ってみる

• Vector3に最初から生えているメソッドとして振る舞う

– Vector3を継承することなく、Vector3をカスタマイズできた

Page 95: みくみくまうすについて&Unity で使えるコーディングノウハウ

拡張メソッドまとめ

• 標準で足りない機能をガンガン追加していこう

– Vector3とかMomoBehaviourとかに追加すると便利になる

– 自分なりにカスタマイズしてしまおう

• 拡張メソッドの定義はわかりやすくしておく

– どこに定義したかわからなくなる事態は避ける

– 作った拡張メソッド群は資産として再利用可能

Page 96: みくみくまうすについて&Unity で使えるコーディングノウハウ

拡張メソッド

• 自分が追加した拡張メソッド群(一部)– Vector3

• ベクトルの要素ごとの積

• 2点間の距離の計算

• 水平面での距離の計算

• 水平面での方向ベクトルの計算

• x,y,zそれぞれの上書き

– Transform• Photon ViewIDの取得

• Photon IsMineの取得

• キャラクタの中心座標を補正して取得

• CharacterControllerから速度を取得

– Animator• 値オブジェクトからAnimatorのパラメータに反映

• Animatorパラメータ書き換えと同時に差分を保存(ネットワーク同期用)

Page 97: みくみくまうすについて&Unity で使えるコーディングノウハウ

おしながき

•拡張メソッド

•LINQ

•UniRx

Page 98: みくみくまうすについて&Unity で使えるコーディングノウハウ

LINQ

• 統合言語クエリ(LINQ)

– 様々なデータソースに対する操作を統合的に記述するもの

– 特にLINQ to Objects(コレクション)がよく使われる

– せっかくのC#なのになぜLINQ使わないのか!?!?!?!?

Page 99: みくみくまうすについて&Unity で使えるコーディングノウハウ

LINQ to Objectで何ができるか?

• コレクションに対する操作を簡単に記述できる

– コレクション(配列、リスト、ディクショナリとか)

– 複雑な処理をわかりやすく記述できる

LINQメソッドの例 処理の内容

Where 条件を満たす要素のみにフィルタリング

Select 要素を別の形式に変換

Any 条件を満たす要素が1つもであるか

All 全ての要素が条件を満たすか

First 最初に見つかった条件を満たす要素を返す

Count 条件を満たす要素の数を数える

Page 100: みくみくまうすについて&Unity で使えるコーディングノウハウ

例)LINQを使わずに書く

• TagがEnemy

• 指定座標から半径10m未満

• Transformのリスト

をGameObject配列から取得するメソッドをLINQを使わずに定義

Page 101: みくみくまうすについて&Unity で使えるコーディングノウハウ

例)LINQを使わずに書く

• TagがEnemy

• 指定座標から半径10m未満

• Transformのリスト

をGameObject配列から取得するメソッドをLINQを使わずに定義

本当に正しいかの確認が大変これを毎回読み解くのか?

Page 102: みくみくまうすについて&Unity で使えるコーディングノウハウ

例)LINQを使った場合

Page 103: みくみくまうすについて&Unity で使えるコーディングノウハウ

例)LINQを使った場合

1. gameObjectArrayに対して2. TagがEnemyのものだけ3. 指定座標から10m未満のものだけ4. Transformに変換して5. List形式にまとめて返す

• 順番に上から読むだけで処理の内容が理解できる

– 単純に「やりたい事だけ」を記述すれば良い

– ループやif文が無く、バグが入り込む余地がない

Page 104: みくみくまうすについて&Unity で使えるコーディングノウハウ

LINQまとめ

• C#を使ってるなら是非使うべき機能

– ちゃんと使えばコード中からfor文を無くせる

– LINQを使わずして何がC#か

• 普通にループを書くより処理速度は落ちる

– LINQによって実行速度が問題になるようなことはほぼ無い

– コードの読みやすさ>>>>>速度

– 下手に凝ったループを書いてバグを生むのとどっちが良いか?

• iOSでのLINQは不具合がある

– 詳しくはショートセッションで

Page 105: みくみくまうすについて&Unity で使えるコーディングノウハウ

おしながき

•拡張メソッド

•LINQ

•UniRx

Page 106: みくみくまうすについて&Unity で使えるコーディングノウハウ

Rx(UniRx)

• ReactiveExtensions(Rx)

– LINQの概念を「非同期」「イベント」に拡張したもの

– 時間を跨いだ処理を簡単に記述できる

– UniRxはRxのUnity移植版(neueccさん作)

• ちゃんと解説すると1時間はかかる

– 今回は説明を放棄

Page 107: みくみくまうすについて&Unity で使えるコーディングノウハウ

UnityでRxを使う

Page 108: みくみくまうすについて&Unity で使えるコーディングノウハウ

Rxの概念

• イベントをストリームとして扱う

– イベントって時間軸に並んだコレクションじゃね?

– コレクションならLINQで扱えるんじゃね?

Page 109: みくみくまうすについて&Unity で使えるコーディングノウハウ

Rxの使い道

• イベントの代わりに使う(ストリームを作る)

– Subject<T>を使えばストリームが作れる

– 既存のEventの上位互換(むしろEventはレガシー)

• ストリームの終了、エラーを通知できる

• イベントの複雑な処理

– 特定のイベントのみ処理する

– 前のイベントの値と組み合わせる

Page 110: みくみくまうすについて&Unity で使えるコーディングノウハウ

UniRxの例

• マウスのダブルクリックの検知

– 普通に書くと煩雑な処理がたった数行で終わった

– 状態の一時保管用のフィールドの定義不要

Page 111: みくみくまうすについて&Unity で使えるコーディングノウハウ

Rxのまとめ

• 時間やフレームを跨いだ処理を簡単に記述できる

• 使いこなすとUpdate()の中身が短くなる

• 学習コストは高め

とにかく便利なので使ってみるべし

Page 112: みくみくまうすについて&Unity で使えるコーディングノウハウ

「C#の機能」まとめ

• C#には便利な機能がたくさんある

– C#っぽくない書き方のコード多くて悲しい

– 使いこなすと強力な武器になるので使うべし

• Rx楽しい

– 本当に便利なのでもっと流行るべき

Page 113: みくみくまうすについて&Unity で使えるコーディングノウハウ

最後にまとめ

• みくみくまうす使ってね

– みんな生放送やろうぜ

– せっかく作ったんだから使って欲しい

• Unityの開発力は最終的にコーディング能力に行き着く

– 複雑なことやるには結局スクリプトを書かないといけない

– プログラミングスキルは高めるべき

• 動き続けるプログラムが正義

– 「動けばいいや」ではダメ

– Unityは特に適当に書いても動くので注意が必要

– 保守性やメンテナンス性も考えた開発をやろう

Page 114: みくみくまうすについて&Unity で使えるコーディングノウハウ

ありがとうございました