Unityで〇×ゲームを作ろうぜ(^~^)?

読了目安:17分

教育目的

プログラミング・スキルの普及のために、 この記事の内容は 改変・転載許可

成果物: 📖 Tic tac toe
コード: 📖 Tic-Tac-Toe

📅2023-01-17 tue

📖 アマゾン創業者が部下に繰り返し続けた「過酷な一言」

202101__character__31--ramen-tabero-futsu2.png
「 👆 ジェフ・ペゾスは モックアップの時点で完成度高くないと 企画も通さないらしいぜ。迷惑だよな」

202101__character__28--kifuwarabe-futsu.png
「 どう迷惑を受けたんだぜ?」

202101__character__31--ramen-tabero-futsu2.png
「 モックアップ作りから妥協しない姿勢が Amazon の強さの秘訣だ、みたいな論調の記事を読むと
だったら もう モックアップ作るの いいかな、 弱くていいや、 と なにもかも 嫌になってしまう」

202108__character__12--ohkina-hiyoko-futsu2.png
「 個人サークルの1人が言う モックアップ と、
140万人ほどの社員がいる企業の社長が言う モックアップ を同じように扱おうとするのが 性格が意固地なのよ。
モックアップに完成度を求めていないケースだってあるのだから、
特定の社長に最適化せず もっと言葉を適当に使えばいいのよ」

202101__character__31--ramen-tabero-futsu2.png
「 これより Unity を使って 〇×ゲームの やっつけモックアップ を作る。
今回の趣旨は 技術 を何も説明せず、 雰囲気 で書く ヒカルの碁方式 だぜ」

202101__character__28--kifuwarabe-futsu.png
「 Qiita と Zenn で規約違反になるから Crieit でやるのか」

202101__character__31--ramen-tabero-futsu2.png
「 いや、思想違反」

202108__character__12--ohkina-hiyoko-futsu2.png
「 ガイドラインぐらい 程度は違えど どこにでもあるのだから 守ればいいのよ」

202301_unity_17-1925-unity-hub.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 これ、 Unity Hub (ユニティ ハブ)。
なんか並んでる1つ1つは レッスンの残骸とか、 手指の練習の残骸とか、 まあゲーム1個分の何かだぜ」

202101__character__28--kifuwarabe-futsu.png
「 なるほど 画面を見せていくわけか YouTube でやれだぜ」

202101__character__31--ramen-tabero-futsu2.png
「 嫌だぜ」

202301_unity_17-1948-unity-hub.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 最初は とにかく プロジェクト名 を付けろだぜ。
偉いさんは SEO や name conventions を考えた いい感じの名前を 付けたいと考えるかもしれないが
わたしの流儀は 『あの世に持っていけるものは何もなし』 だぜ。 ひねらず 付けて 進め」

202101__character__28--kifuwarabe-futsu.png
「 現世利益に興味を持てだぜ」

202108__character__12--ohkina-hiyoko-futsu2.png
「 墓碑銘は 『墓』 にしましょう」

202301_unity_17-2007-unity-editor-4k.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 プロジェクトを開くと Unity Editor(ユニティー・エディター)が出てくる。
わたしは 4K(よんけー)ディスプレイ を使っているので 大きな添付画像になってしまうから、
以降は 適当にウィンドウを縮めて スクリーンショットを貼っていくぜ」

202101__character__28--kifuwarabe-futsu.png
「 そこらへんの You Tube で ゲーム開発動画が たくさんあるから 読者諸君は 詳しくは勝手にググれだぜ」

202301_unity_17-2013-unity-editor.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 〇×ゲーム作るんだったら 盤が要るだろ。 平面(へいめん;Plane プレーン)を置こうぜ?」

202101__character__28--kifuwarabe-futsu.png
「 ぜったい Unity Learn で 企画書を書けだの、設計を練れだの レッスン受けたのにな。
プログラマー・スキル・レベル剥奪だぜ」

202108__character__12--ohkina-hiyoko-futsu2.png
「 設計を 信じて ないのよ。 プロジェクトは 崩壊 すると思ってるから」

202101__character__28--kifuwarabe-futsu.png
「 じゃあ お父んは何を信じて Unity Editor なんか開いたのか?」

202101__character__31--ramen-tabero-futsu2.png
「 あっ、そういえば 〇 も × も 素材が無いぜ!」

202301_unity_17-2029-paint.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 わたしには モデルを作るスキル無いので Windows Paint で描くぜ」

202101__character__28--kifuwarabe-futsu.png
「 行き当たりばったりだな」

202108__character__12--ohkina-hiyoko-futsu2.png
「 行動してから考える人 ですからね」

202101__character__28--kifuwarabe-futsu.png
「 お父んの頭の中に 効率戦略 が無いことは 分かった」

202301_unity_17-2042-texture.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 画像を プレーンに ドラッグ&ドロップ すれば テクスチャーを貼るの完了だぜ」

202101__character__28--kifuwarabe-futsu.png
「 Unity、 3Dが得意なのに ペラペラの平面に Windows Paint の画像 貼り付けるの
Unity の無駄遣いだよな」

202108__character__12--ohkina-hiyoko-futsu2.png
「 まだ 行動の途中 で、 考える ところまで 行ってませんからね」

202101__character__31--ramen-tabero-futsu2.png
「 そう言えば、盤に 黒くて太い線を引きたいけど、 黒い太線を引くのも めんどくさいんだよな。
それに 盤のマスをクリックしたかどうか 範囲を調べるのも めんどくさい……」

202301_unity_17-2103-board.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 そこで プレーンを9枚 置いて、マスの代わりとしようぜ!」

202101__character__28--kifuwarabe-futsu.png
「 お父んの優先順位の中で、 アートワーク の順位は下の方にあることが分かった」

202108__character__12--ohkina-hiyoko-futsu2.png
「 花より団子 の人ですからね。 〇×ゲームができれば なんでもいいのよ」

202101__character__31--ramen-tabero-futsu2.png
「 しかし どういう感じにすりゃ 〇×ゲーム を作れるのか よく分からんな」

202301_unity_17-2112-save.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 ここで一旦 プロジェクトを保存して Unity Editor を終了するぜ」

202101__character__28--kifuwarabe-futsu.png
「 考えるのをやめたか」

202301_unity_17-2118-git-hub.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 わたしの Git Hub を開くんだぜ」

202101__character__28--kifuwarabe-futsu.png
「 ソースを クラウドに保存するんだな」

202301_unity_17-2130-git-hub.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 クラウド上に リポジトリを作るぜ。 リポジトリというのは ファイル置き場 ぐらいの意味だぜ」

202301_unity_17-2132-git-hub.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 GitHub Desktop for Windows というデスクトップ・アプリケーションと連動するんで、
ローカルPCの さっきの Tic-Tac-Toe のファイルを、
いったんローカルPC側のリポジトリで コミットし、
続いて クラウド上のリポジトリへ プッシュするぜ」

202101__character__28--kifuwarabe-futsu.png
「 何を言っているか分からないが まあ がんばれだぜ」

202301_unity_17-2138-git-hub.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 リモートに ファイルが置かれたな」

202108__character__12--ohkina-hiyoko-futsu2.png
「 本当は コード・レビュー を入れて、コメントをちゃんと書いてコミットして使うものなんだけど、
やらないのよ」

202101__character__28--kifuwarabe-futsu.png
「 やらないだろうな」

202101__character__31--ramen-tabero-futsu2.png
「 ドカスカ プッシュしろだぜ」

202108__character__12--ohkina-hiyoko-futsu2.png
「 Git Hub にソースをプッシュしたから、
ソースを壊してしまったときは それより前のバージョンへ 巻き戻すことが可能になったわね」

202101__character__31--ramen-tabero-futsu2.png
「 適当に どこかに戻せれば 十分だぜ」

202101__character__28--kifuwarabe-futsu.png
「 戻してから考える んだろうなあ」

202301_unity_17-2148--script-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 マス(※英語でSquare スクウェア)をマウスでクリックしたときに 〇×を付けたいんだろ。
とりあえず Square という名前で C#(しーしゃーぷ)スクリプトを作ろうぜ?」

202101__character__28--kifuwarabe-futsu.png
「 Git Hub で、いつでもリセットできるから お父んの とりあえず進もうぜ、困ったら戻ろうぜ法 が完成だな」

202108__character__12--ohkina-hiyoko-futsu2.png
「 頼りない名前の法だなあ」

202301_unity_17-2156--visual-studio-2022.png

補足:📖Unity 2020でスクリプトの日本語が文字化けするのを修正する

202101__character__31--ramen-tabero-futsu2.png
「 👆 これが Visual Studio 2022 (びじゅある すたじお にせんにじゅうに)というデスクトップ・アプリケーションだぜ。
こんな画面出てきても、これから何かけばいいか分からないだろ」

202101__character__28--kifuwarabe-futsu.png
「 何でも書いたらいいんじゃないか」

202301_unity_17-2200--intellisense.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 そう!
何もないところのうち いい感じのところに mouse と打鍵すれば、
わたしが書きたいものを予測して候補が出てくる。 これが Visual Studio の利点である インテリセンス(IntelliSense) という AI だぜ。
1990年代後半にはすでにあった」

202301_unity_17-2203--intellisense-and-tab-key.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 そしてその候補で合ってたら、キーボード上の tab キーを1回押せだぜ。
スケルトン・コードを書いてくれる。
スケルトンというのは、穴埋め文章の穴じゃない方だな」

202101__character__28--kifuwarabe-futsu.png
「 適当の達人だな」

202108__character__12--ohkina-hiyoko-futsu2.png
「 いい感じのところ がどこなのか説明してくれないから 真似するの無理よ」

202301_unity_17-2211--debug-log.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 何書けばいいか分からないから、とりあえず Debug.Log("なんちゃら") を書けだぜ。
このテクは デバッグ・ライト(Debug write)と言う」

202101__character__28--kifuwarabe-futsu.png
「 とりあえず が多いな」

202301_unity_17-2216--attach-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 で、スクリプトは書いただけでは動かない。
マス(※画面上では Square 0 ~ Square 8)というゲーム・オブジェクトに Square スクリプトを持たせる。
この操作を アタッチ (Attach) と呼ぶ」

202301_unity_17-2221--main-camera.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 カメラの位置も あんまりだったので、 Main Camera の位置を調整する」

202301_unity_17-2223--play-button-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 ゲーム・ビューも好きなようにいじって、 Unity Editor の上の方に置いてある再生ボタンを押せだぜ」

202301_unity_17-2225--game-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 するとゲーム画面になる。
黄緑色のマスをクリックしたら、 Unity Editor の左下に 『マウスボタンを押しました』と出てきた。
これで動作確認完了だぜ」

202101__character__28--kifuwarabe-futsu.png
「 マスがクリックできることまでは 分かったな。
そこから どうするのか 分からんけど」

202108__character__12--ohkina-hiyoko-futsu2.png
「 クリックしたマスの上に 〇のカード が飛んでくりゃ よくない?」

202101__character__28--kifuwarabe-futsu.png
「 じゃあ 〇のカード 5枚、 ×のカード 4枚を予め作っておけばいいのかだぜ?」

202101__character__31--ramen-tabero-futsu2.png
「 めんどくさ……。 マスの表面のテクスチャーを貼り替えりゃよくないかだぜ?」

202108__character__12--ohkina-hiyoko-futsu2.png
「 あらゆる発想が めんどくささに 飲み込まれて 消えていくわね」

202101__character__28--kifuwarabe-futsu.png
「 お父ん ぜったい あらゆる企画マンと 会話 合わないよな」

202301_unity_17-2247--game-manager-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 とりあえず GameManager C#スクリプトをアタッチした Game Manager ゲーム・オブジェクトを作れだぜ」

202301_unity_17-2255--serialize-fields-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 GameManager C#スクリプトの いい感じのところに、 いい感じに マテリアルを3つ書くと」

202301_unity_17-2302--serialize-fields-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 マテリアルを ドラッグ&ドロップで 設定できる欄が できるから」

202301_unity_17-2304--drag-and-drop-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 がんばって ドラッグ&ドロップ しろだぜ」

202301_unity_17-2323--remove-game-object.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 Nought ゲーム・オブジェクトと、 Cross ゲーム・オブジェクトは 結局使わないので 消せだぜ」

202101__character__28--kifuwarabe-futsu.png
「 行き当たりばったりの ひずみ ここに出るの わらう」

202108__character__12--ohkina-hiyoko-futsu2.png
「 バーチャル空間だから 無駄な発注を やりたい放題よ 徒労が増えるだけで」

202301_unity_17-2329--game-manager-script-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 GameObject C#スクリプトに 実質5行ほど コードを書き足したぜ」

202301_unity_17-2331--square-script-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 Square C#スクリプトに 実質4行ほど コードを書き足したり、編集したりしたぜ」

202101__character__28--kifuwarabe-futsu.png
「 なんの説明もないところが 今回の記事の趣旨だな」

202301_unity_17-2335--game.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 だが、もう ○、× を交互に置けるぜ」

202301_unity_17-2336--illegal-move.png

202101__character__28--kifuwarabe-futsu.png
「 👆 もう印を置いてあるところを またクリックして 印を変えることができるぜ」

202101__character__31--ramen-tabero-futsu2.png
「 👆 イリーガル・ムーブ(非合法手)のチェックはしてないからな」

202108__character__12--ohkina-hiyoko-futsu2.png
「 しなきゃ いけなくない?」

202101__character__31--ramen-tabero-futsu2.png
「 プロフェッショナルなプログラマーなら 必ず 修正するし、
レッスン中なら 不具合の修正は ほっといて 後回しにしろだぜ。
不具合の修正は 気持ちが乗らないからな」

202108__character__12--ohkina-hiyoko-futsu2.png
「 不具合の修正より、気持ちがノるか ノらないかが 優先されるのね」

202101__character__28--kifuwarabe-futsu.png
「 ぜったい わらう」

📅2023-01-18 wed

202301_unity_18-1938--win.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 勝ったとき 『勝ち!』 って出てくれば 気持ちがノるだろ。
まずは その前に 勝ったかどうか判定するプログラムを書こうぜ?」

202101__character__28--kifuwarabe-futsu.png
「 プログラムらしい話に進むな」

📅2023-01-20 fri

202301_unity_20-1927--texts.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 テキストをまず作っておこうぜ。
普段は非表示にしておいて、必要な時に表示すればいい」

202101__character__28--kifuwarabe-futsu.png
「 仕込みだな」

202301_unity_20-1932--judge-manager-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 勝敗判定を どこに どういう風に書けばいいのか分からない。
分からなかったら なんとかManager C# スクリプトを作って、 なんとか Manager ゲーム・オブジェクトにアタッチすればいいぜ」

202101__character__28--kifuwarabe-futsu.png
「 お父んは『いいぜ』と言うが、 ダメだったら戻ればいいスタイルだからな」

202108__character__12--ohkina-hiyoko-futsu2.png
「 迷路をとりあえず進んでるだけよね」

202301_unity_20-1942--position-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 Position (ポジション) C# スクリプトもいるかもしれない。スケルトンを置いておこう」

202101__character__28--kifuwarabe-futsu.png
「 要るか 要らないか 分からなくても スケルトンを置くのが お父んの開発スタイルだよな」

202301_unity_20-1954--piece-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 Piece (ピース;駒)イナム(enum;列挙)型も作っとこ。 あとで使うだろ」

202101__character__28--kifuwarabe-futsu.png
「 どんどんタネを仕込んで あとで 組み合わせる やり方か」

202108__character__12--ohkina-hiyoko-futsu2.png
「 ちゃんと 組み合わさるか 事前に検討して 必要なものだけを洗い出すステップを やらないのよ、 ノらないから」

202301_unity_20-2003--position-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 ポジションに Piece 型の配列を持たせようぜ。
これ、 Unity Editor で いじれるようにしようかな、 [SerializeField] アノテーション付けたろ」

202301_unity_20-2008--position-manager-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 やっぱ Position Manager ゲーム・オブジェクトも作って Position C#スクリプトをアタッチしようぜ?
盤を編集でけて お得だろ」

202101__character__28--kifuwarabe-futsu.png
「 お得かどうかは関係ないんじゃないか? 損だったら戻ればいいのだから 進めば」

202108__character__12--ohkina-hiyoko-futsu2.png
「 最後に まとめ切れるかどうか 関係無いですからね、この開発手法」

202301_unity_20-2029--position-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 Position は Clear 関数や、 SetPiece 関数を使うだろ。
class の public 修飾子も消して internal アクセスにしておこうぜ。
Linq は パフォーマンスが心配なんで使わないぜ」

202101__character__28--kifuwarabe-futsu.png
「 それが 何かの説明は しないんだな」

202301_unity_20-2058--position-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 GameManager C#スクリプトに入ってた movesCount フィールドは、 Position クラスにあった方がいいので 移動した。
MovesCount アクセッサ―も追加したぜ」

202301_unity_20-2101--game-manager-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 movesCount フィールドを Position クラスに持っていかれた GameManager クラスの方には、
Position インスタンスにアクセスできるように プロパティを用意し、参照箇所も Position プロパティに変更するぜ」

202101__character__28--kifuwarabe-futsu.png
「 フーン」

202301_unity_20-2118--game-manager-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 Square 0 ゲーム・オブジェクトの 0 の部分だけ取るように 正規表現(せいきひょうげん;RegularExpression)を書き、
Position インスタンスにセットするように書いてみた」

202108__character__12--ohkina-hiyoko-futsu2.png
「 へぇ」

202301_unity_20-2124--game-1.png

202301_unity_20-2126--game-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 これで、マスをクリックすると、○と×が入っているのが分かるな」

202108__character__12--ohkina-hiyoko-futsu2.png
「 Cross (×)と Nought (○)が逆よ」

202101__character__31--ramen-tabero-futsu2.png
「 ぬぎぎぎぎ!」

202301_unity_20-2138--increment-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 インクリメントは最後にやれだぜ!」

202301_unity_20-2147--win-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 Position インスタンスが盤を表している。
Element 1Element 4Element 7Nought が入っていれば、3つの○が並んだということだぜ」

202108__character__12--ohkina-hiyoko-futsu2.png
「 タテ、ヨコ、ナナメに同じピースが3つ並んでいることを判定できる数式があるの?」

202101__character__31--ramen-tabero-futsu2.png
「 ○×ゲームぐらいの 盤サイズの小ささなら 全パターン網羅して ハードコーディングしたった方が早いぜ」

202301_unity_20-2205--getPiece-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 Position クラスに GetPiece メソッドが無いと 盤のマスを見れないので追加する」

202301_unity_20-2212--winPattern-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 例えば 3つ並んだケースの一覧とか 要るだろ。
要ると思ったものを 予め 作っておくんだぜ」

202101__character__28--kifuwarabe-futsu.png
「 要ると分かってから 作った方が良くないか?」

202108__character__12--ohkina-hiyoko-futsu2.png
「 ノらないから そんなこと しないのよ」

202301_unity_20-2224--gameResult-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 対局結果も要りそうだ。作っとこ」

202101__character__28--kifuwarabe-futsu.png
「 この開発手法では 工数の見積もりを取れないのでは?」

202108__character__12--ohkina-hiyoko-futsu2.png
「 設計してないんだから 見積もりがあるはずないじゃない」

202301_unity_20-2239--judge-manager-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 勝敗判定を書いている途中に思ったんだが、負けかどうかは判定してないな」

202101__character__28--kifuwarabe-futsu.png
「 じゃあ 『勝敗判定』ではなくて 『勝ったか判定』だぜ」

202301_unity_20-2242--game-results-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 対局結果から 負け を削除しとこ。
GameResult も こっそり GameResults に変えた」

202108__character__12--ohkina-hiyoko-futsu2.png
「 勝ち しか無かったら、どっちが勝ったのか 分からなくない?」

202301_unity_20-2247--nought-win-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 まさか Lose を使う必要がないとは 思わなかったぜ」

202101__character__28--kifuwarabe-futsu.png
「 ダメだったら戻ればいい の現場だな」

202301_unity_20-2259--judge-manager-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 JudgeManager で対局結果を見れたら デバッグが楽だと思ったから フィールドと プロパティ付けたろ。
winPatterns も こっそり static readonly 付けたろ」

202301_unity_20-2303--setup-judge-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 対局結果を返すのではなく、対局結果を フィールドに入れるように変更。
名前も DoJudge から SetupJudge に変更」

202301_unity_20-2313--game-manager-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 GameManager クラスの中で JudgeManager インスタンスの SetupJudge メソッドを使ってみよう」

202301_unity_20-2318--game-result-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 ちゃんと Win が入ってるな」

202301_unity_20-2323--draw-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 でも Draw 判定が 10手目にされたので 1 引いとこ」

202101__character__28--kifuwarabe-futsu.png
「 10手目なんか 無いんだけどな」

202301_unity_20-2326--disable-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 対局結果のゲーム・オブジェクトのアクティベートのチェックを外して、存在していないことにしよ」

202301_unity_20-2350--setActive-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 存在しないゲーム・オブジェクトだったら、 Unity は見つけられないので、
[SerializeField] アノテーションを利用して ゲーム・オブジェクトにアクセスする仕組みを 仕込むぜ。
ついでに SetActive( ) メソッドを使って、ゲーム・オブジェクトのアクティベートのチェックを入れるコードも書いておくぜ」

202301_unity_20-2353--drag-and-drop-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 ドラッグ&ドロップしておくぜ」

202301_unity_20-2357--draw.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 対局結果が出るようになったぜ」

202108__character__12--ohkina-hiyoko-futsu2.png
「 配色わる」

202101__character__31--ramen-tabero-futsu2.png
「 文字のような○×の上に 文字 出してるしな」

202101__character__28--kifuwarabe-futsu.png
「 他の 盤ゲームが 対局結果を どう表示しているか 見てこいだぜ」

202301_unity_21-0018--front-cover.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 わたしに美術はできないので、終局時に 半透明のフロント・カバーが かかるようにしよう!」

202101__character__28--kifuwarabe-futsu.png
「 確かに お父んは 企画 通らなさそう」

202301_unity_21-0025--front-cover.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 これで 十分 十分」

202108__character__12--ohkina-hiyoko-futsu2.png
「 ビデオゲームは 見た目のできが 内容のできだと 思われるのよ」

202101__character__31--ramen-tabero-futsu2.png
「 ノらないところは やらないでおこうぜ?」

202101__character__28--kifuwarabe-futsu.png
「 他の人はむしろ 目に付く 見た目を いじりたがるんだけどな」

202101__character__31--ramen-tabero-futsu2.png
「 次は リスタート・ボタン を付けようぜ?」

📅2023-01-21 sat 00:31 end

📅2023-01-22 sun 01:34 start

202301_unity_22-0139--button-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 2020年代の GUI というと Web クライアントや、 Windows デスクトップ・アプリケーションでは 進歩、淘汰の激戦区だが、
Unity に付いてる GUI は 1990年代かな、というぐらいクラシックなものなので あまり気合を入れずに使うぜ」

202301_unity_22-0149--restart-button.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 リスタート・ボタンの見た目は こんなんでいいんじゃないか?」

202108__character__12--ohkina-hiyoko-futsu2.png
「 美術の欠如している わたしたちは これでいきましょう」

202301_unity_22-0153--judge-manager-clear-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 JudgeManagerClear メソッドを付けるぜ」

202301_unity_22-0157--position-clear-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 PositionClear メソッドで moveCount フィールドを ゼロ初期化してなかったので するぜ」

202101__character__28--kifuwarabe-futsu.png
「 仕込みをしてるんだな」

202301_unity_22-0203--game-manager-clear-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 GameManagerClear メソッドを付けるぜ。
この中で Position インスタンスと、 JudgeManager インスタンスの Clear メソッドを呼び出すとともに、
対局結果のテキストと、盤に被せた半透明の幕のアクティベートのチェックを外して、ゲーム中に存在しない扱いにするぜ」

202101__character__31--ramen-tabero-futsu2.png
「 👆 また、 Start メソッドで Clear メソッドを呼び出した」

202101__character__28--kifuwarabe-futsu.png
「 それは要るのか?」

202101__character__31--ramen-tabero-futsu2.png
「 シーン・ビューで テキストの表示のアクティベートのチェックを外すの忘れたりしたまま リリース したくないだろ」

202301_unity_22-0210--restart-button-event-listener-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 ボタンを押したら、 Game Manager ゲーム・オブジェクトの持っている GameManager C#スクリプトの Clear メソッドが
呼び出されるように マウス操作で紐づけるぜ。
この技術の名前は イベント・リスナー(Event Listener)だぜ」

202301_unity_22-0220--restart-button-activate-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 リスタート・ボタン自体のアクティベートのチェックを オン/オフする仕組みを忘れてた 追加しよ」

202301_unity_22-0223--restart-button-attach-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 だんだん ごつく なってきたな」

202301_unity_22-0225--restart-button-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 でも リスタート・ボタンが出てきたぜ。押してみよ」

202301_unity_22-0227--restart.png

202101__character__28--kifuwarabe-futsu.png
「 👆 盤はクリアーされてないぜ? なぜだぜ?」

202101__character__31--ramen-tabero-futsu2.png
「 WPF (ダブリュー・ピー・エフ)の MVVM (エム・ブイ・ブイ・エム)の ViewModel (ビュー・モデル)に慣れた癖で忘れていたが、
Unity では データをクリアーしても、 シーンは連動していないのだった」

202108__character__12--ohkina-hiyoko-futsu2.png
「 これは ゲーム・プログラミングなのよ。
デスクトップ・アプリケーションのような 処理が重たい技術は 流行らないのよ」

202301_unity_22-0237--square-texture-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 マスの材質を 緑色の素材に貼り替えたろ」

202301_unity_22-0239--game.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 貼り替わったぜ」

202101__character__28--kifuwarabe-futsu.png
「 これで ○×ゲームは 卒業かだぜ?」

202108__character__12--ohkina-hiyoko-futsu2.png
「 まだ イリーガル・ムーブ を禁止していないわよ?」

202301_unity_22-0255--static-validator-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 じゃあ バリデーター(Validator)を作ればいいだろ。
そのマスに置けるかどうかだけ チェックすればいいのかだぜ?」

202301_unity_22-0303--square-number-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 あっ、 Square 0 みたいなゲーム・オブジェクトの名前しか取れね。 0 みたいなマス番号取れね」

202108__character__12--ohkina-hiyoko-futsu2.png
「 不便よねえ」

202301_unity_22-0316--static-helper-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 じゃあ ヘルパー関数 作ればいいんだぜ。
GameManager で 似たようなコード前に作ったから 引っこ抜いて 共通利用できるようにするぜ」

202301_unity_22-0319--static-helper-using-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 既存のコードは見やすくなるし」

202301_unity_22-0322--validation-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 新しいコードは書きやすくなる」

202301_unity_22-0325--validated.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 これで 非合法手 は防げたんじゃないか?」

202108__character__12--ohkina-hiyoko-futsu2.png
「 Nought win のあとに まだ X を置けるんじゃない?」

202301_unity_22-0327--front-cover-validated.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 半透明の青い膜が被っていて、 マスはクリックできないから
対局終了後に マスをクリックすることは でけないぜ」

202108__character__12--ohkina-hiyoko-futsu2.png
「 じゃあ いいかあ」

202101__character__28--kifuwarabe-futsu.png
「 これで 完成か?」

202101__character__31--ramen-tabero-futsu2.png
「 コード・レビュー しようぜ?
プログラミングの へたくそなところがある」

202301_unity_22-0338--code-review-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 例えば 『駒を置く』は入力だが、 『対局結果を表示する』は出力だぜ。
入力メソッドが 出力してるなんて イケてないぜ

202108__character__12--ohkina-hiyoko-futsu2.png
「 判断基準は イケてるか イケてないか なのね」

202101__character__28--kifuwarabe-futsu.png
「 プログラマーの気分 を 重要視してるんだな。 その点では Ruby に似ているな。お父んのポリシーが 分かってきたぜ」

202301_unity_22-0338--code-review-2.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 『出力』の部分を DoMove メソッドから外に出したいが、
piece 変数が DoMove メソッドに束縛されているから、 piece 変数を 自由変数に変える方法を考えようぜ」

202101__character__28--kifuwarabe-futsu.png
「 なんだか分からないが 任せたぜ」

202301_unity_22-0356--turn-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 Position クラスに 手番(Turn)を持たせようぜ。
初期値は Nought

202301_unity_22-0407--next-turn-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 手番を追加する NextTurn メソッドもいるや。追加しとこ」

202301_unity_22-0419--increment-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 インクリメントも NextTurn メソッドの中で やってまお。
MovesCount プロパティーのセッター(set)も要らなくなったから、短く書いたろ」

202301_unity_22-0424--doMove-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 これで DoMove の中から piece 変数が消えた。 代わりに Position に依存するようになったぜ」

202301_unity_22-0430--update-game-result-view-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 こうやって UpdateGameResultView メソッドに切り分けることがでけたな。
しかし DoMove メソッドを実行すると UpdateGameResultView メソッドまで 実行されてしまうのは イケてないな」

202301_unity_22-0435--increment-validation-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 あっ いけね!
対局が終了しているときは NextTurn しないように バリデーション・チェックしようぜ」

202301_unity_22-0455--setup-judge-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 JudgeManagement クラスの SetupJudge メソッドを、
変更があったかどうか返すように 変更するぜ」

202301_unity_22-0501--dirty-judgement-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 判定に変更があれば dirtyJudgement フラグを立て、
dirtyJudgement フラグが立っているときだけ UpdateGameResultView メソッドは働き、
働いたら dirtyJudgement フラグは下ろす、という風に作るぜ」

202101__character__28--kifuwarabe-futsu.png
「 めんどくさ」

202301_unity_22-0508--update-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 これで UpdateGameResultView メソッドの呼び出しを
DoMove メソッドの外に出して、
Update メソッドの中へ 引っ越すことがでけたぜ」

202301_unity_22-0511--game.png

202108__character__12--ohkina-hiyoko-futsu2.png
「 👆 そんなけ コードをいじっても ゲームは何にも変わらないじゃない。
コードを イケてるようにすることに 何の意味があんの?」

202101__character__31--ramen-tabero-futsu2.png
「 ワザを安定して出せるようになると、
もっと 大きなワザ を出せるようになる。大きなワザ を出せるようにするために コードを掃除してるんだぜ」

202301_unity_22-0523--clear-1.png

202101__character__28--kifuwarabe-futsu.png
「 👆 GameManager クラスの Clear メソッドの中で 画面表示を切り替えているのは 掃除しないのかだぜ?」

202101__character__31--ramen-tabero-futsu2.png
「 する」

202301_unity_22-0530--set-piece-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 Position クラスの SetPiece メソッドも、変更があったかどうか返すようにしようぜ?」

202301_unity_22-0541--dirty-squares-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 マスをクリックして、絵柄に変化があったときだけ dirtySquares セットに マス番号を追加することにするぜ」

202301_unity_22-0553--update-square-view-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 これで DoMove メソッドの中から 表示をコントロールするコードは 消えてなくなっただろ」

202101__character__28--kifuwarabe-futsu.png
「 入力メソッドの中では 出力はしないようにしたんだな」

202108__character__12--ohkina-hiyoko-futsu2.png
「 dirtyなんちゃら フラグが 入力メソッドと 出力メソッドの 橋渡しをしているのね」

202301_unity_22-0610--clear-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 GameManager クラスの Clear メソッドの中にあったコードも、 dirty フラグを立てるだけで よくなったぜ」

202101__character__28--kifuwarabe-futsu.png
「 これで 表示周りのコードの クリーンナップ は終わりか?」

202101__character__31--ramen-tabero-futsu2.png
「 まだある」

202301_unity_22-0615--update-square-view-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 GameObject.Find メソッドは 処理に時間がかかるらしい。
できれば Start メソッドで1回使ったあとは 使わなくて済むようにしたいぜ」

202101__character__28--kifuwarabe-futsu.png
「 やってくれだぜ」

202301_unity_22-0628--go-squares-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 GameManager クラスの Start メソッドが呼び出された時点で、GameObject.Find を先にしてしまって、
ゲーム・オブジェクトをメモリに入れておけばいいぜ」

202101__character__28--kifuwarabe-futsu.png
「 他に どこを クリーンナップ するんだぜ?」

202301_unity_22-0639--accessor-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 例えば get アクセッサ―で 変数をリターンしているだけのプロパティなんかは……」

202301_unity_22-0639--lambda-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 ラムダ式と同じなんだったら、書き方が短いラムダ式にするとかかな。
パフォーマンスに違いがでるのか 知らんけど」

202108__character__12--ohkina-hiyoko-futsu2.png
「 パフォーマンスの測定をするほどの 速度が必要なアプリケーションじゃないから
ちょっとぐらいパフォーマンスが違っても 違いは分かんないわねえ」

📅2023-01-22 sun 06:45

202301_unity_22-0650--webgl.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 WebGL 形式で 実行ファイルを出力してみようぜ?」

202301_unity_22-0655--live-server-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 Visual Studio Code に Live Server エクステンション入れてると ローカルWebサーバー起ちあがるんで、
Tic Tac Toe の index.html を開いてみようぜ?」

202301_unity_22-0657--unity-webgl-player.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 開けたな」

202301_unity_22-0659--nought-win.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 プレイできるぜ」

202101__character__28--kifuwarabe-futsu.png
「 ○×ゲームできても ビデオゲームって感じ しないけどな」

202108__character__12--ohkina-hiyoko-futsu2.png
「 2か月 Unity Lesson でビギナーコースを受けて、○×ゲームを作るのに 3日間かかるようでは 気が遠くなるわよね」

202101__character__31--ramen-tabero-futsu2.png
「 仕込みが なんにも無いからな。
重要なのは 制作進行を覚えて 素材の発注を見積もることだぜ」

202108__character__12--ohkina-hiyoko-futsu2.png
「 UI も タイトル画面も 何もかもがなくて ゲーム開発の全体像はまだ見えないわね」

202101__character__31--ramen-tabero-futsu2.png
「 まあ、先に進もうぜ」

📖 Unity Play

202301_unity_22-0708--unity-play.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 Unity Play という Web サイトがある」

202301_unity_22-0710--unity-play-upload.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 ここには、作ったゲームをアップロードするページがある」

202301_unity_22-0711--game-file-1.png

202101__character__31--ramen-tabero-futsu2.png
「 👆 というわけで、 WebGL のファイルが入ったフォルダーを .zip 圧縮し……」

202301_unity_22-0718--play-unity.png

📖 Tic tac toe

202101__character__31--ramen-tabero-futsu2.png
「 👆 アップロード完了。 Play Unity に置いたぜ」

202301_unity_22-0721--play-unity-game.png

202101__character__28--kifuwarabe-futsu.png
「 👆 まあ ○×ゲーム しかできないんだけどな」

📅2023-01-22 sun 07:22 end

<おわり>

ツイッターでシェア
みんなに共有、忘れないようにメモ

むずでょ@きふわらべ第29回世界コンピューター将棋選手権一次予選36位

光速のアカウント凍結されちゃったんで……。ゲームプログラムを独習中なんだぜ☆電王戦IIに出た棋士もコンピューターもみんな好きだぜ☆▲(パソコン将棋)WCSC29一次予選36位、SDT5予選42位▲(パソコン囲碁)AI竜星戦予選16位

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント