HEXA BLOG

プログラム

HEXA BLOGプログラム2019.12.2

そうだ設計しよう

🔟年近く使っていた洗濯機🌀の洗浄モードの存在に最近気がついて、
ずっと間違った洗浄をしていたことに動揺😖を隠せないgood sun🌅こと山口です。

前回から大分時間が経ちましたが完全に怠けていた😴ので続編ではありません。
代わりにゲームプログラミングでは少し珍しいかもしれない設計を題材にしたいと思います。

個人的な感想ですが、
仕様変更も活発に行われる事もありゲーム🎮のプログラミングでは設計について軽視される😋傾向にあると感じています。
汎用ゲームエンジンの採用事例も増えてきたこともあり、その傾向はより強くなっていると思われます。

こうなってくると意地でも設計を滑り込ませたいと天邪鬼👹が顔を出してきます。
では早速設計を現場に持ち込むための方法を検討しましょう。

まず設計のメリットを上長🤴に訴えます。
1.意思疎通
作業が完全に閉じられている場合は全く不要ですが、
もしその作業が複数人で取り組んでいる場合は仕様書📃を共有しての作業になるでしょうか?
仕様書の精度や実装目標の種類によりますが、
この状態で複数のプログラマーが思い描く実装方法は人それぞれです。
前準備無しに共同実装を試みると噛み合わない現象が起きたりします。
設計をすることでこのリスクを少し削減出来ます。

2.コスト
個人的には規模によりますが設計は実装よりもコスト🤑が低いと考えています。
頭の中を整理しながら処理の流れ🎏を書き起こす過程で、
脳内計画の穴🕳をある程度潰すことも出来て作ってから直すコストが削減されます。
但し完璧を目指すと逆に高コストになってしまいますので程々に留める必要があります。

さぁメリットは伝えて上長の許可が得られました。
しかし、肝心の設計方法が分かりません🥺。
ここから先は実践あるのみです。
最初はうまく行かないかもしれませんが学習コストとして払いましょう。
世の中で一定数の支持があるものは学習コストを払ってしまえば便利なる傾向にあると信じています🛐。

では練習をしてみます。
3Dのアドベンチャーゲームで扉🚪を開ける流れを設計してみましょう。
一定距離にプレイヤーが近づくと開扉アイコンが表示され、
ボタン🎮を押したら扉を開けて物理制御に切り替える簡単な作りです。

今回の設計にはUMLを使用します。
UMLに拘る必要はありませんが一般的にルールが知れ渡っている事と
モデリングツールが色々あるので自分に合ったものを選べるので
導入コストを抑えられるのが魅力です。
ソフトはPlantUMLのVisual Studio Codeアドオンバージョンを利用します。
このソフトはチートシートを用意しておく程度の学習コストで悪くない図を生み出すのでお勧めです。
まずはユースケース図を書きます。
要素のつながりを抽象化して整理する事が出来ます。
個人的にはお気に入りです。
今回はプレイヤーキャラクターと扉の間を繋ぐ関係を挙げてみます。

@startuml
title 扉開閉ユースケース図
left to right direction
:プレイヤーキャラクター: — (センサー)
(センサー) -left- (開扉アイコン)
:プレイヤーキャラクター: — (開扉アイコン)
(センサー) — :扉:
:扉: -right- (物理エンジン)
@enduml


少し頭の中が整理出来ました。
次に開閉までのシンプル流れをシーケンス図を使って表します。
何が何を制御しているかの関係が整理出来ます。

@startuml
title 扉開閉シーケンス図
プレイヤー->センサー : 侵入
センサー->開扉アイコン : 活性化
プレイヤー->開扉アイコン : 決定ボタン
開扉アイコン->扉 : 物理有効&開扉ベクトル
扉->開扉アイコン : 非活性化
== ここから閉扉処理 ==
プレイヤー->センサー : 離脱
センサー->扉 : 閉扉通知
扉->扉 : 閉扉シーケンス&物理無効
@enduml

 

さらに中断処理を分かり易くするためにアクティビティ図を書きます

@startuml
title 扉開閉アクティビティ図
start
while(センサー内にいる)is(True)
if(開扉中?)then(True)
elseif (アイコン表示中?) then (True)
if(決定ボタン?)then(True)
:開扉処理;
:アイコン非活性化;
:センサーを閉扉に;
else(False)
endif
else(False)
:開扉アイコン表示;
endif
endwhile(False)
if(開扉中?)then(True)
:閉扉処理;
elseif(アイコン表示中?)then(True)
:アイコン非活性化;
else(False)
endif
end
@enduml

最後にセンサー等の関係性をクラス図を使って表します。
この段階では再利用性等を検討出来ます。
キャラクターは別途巨大な定義がある前提で扉の構造のみに注目します。

@startuml
title 扉開閉クラス図
class InteractionSensor{
+ float radius
+ delegate onSensorIn
+ delegate onSensorOut
}
class PhysicsHinge{
+ activate(bool)
+ setVelocity(vector)
}
class InteractionIcon{
+ image icon
+ vector displayOffset
+ setVisibility(bool)
+ setInputPriority(float)
+ delegete onDecide
}
class Door{
– InteractionSensor sensor
– PhysicsHinge hinge
– InteractionIcon icon
}
Door o–InteractionSensor
Door o–PhysicsHinge
Door o–InteractionIcon
@enduml

如何でしょう?
学習コストを払い終わるとこの程度であればかなり低コストでこのように書き起こす事が出来ます。
実際これらの図を書きながらチョコチョコ関係性修正が行われたので、実装に入る前に軽いリファクタリングが出来た事にもなります。
この程度の図であっても脳内🧠の漠然とした状態を共通言語にして具現がすると色々と見えてきます。

現場によっては高速なイテレーションを求められるので準備する時間がないかもしれませんが、
普遍的なコアになるものはしっかりと共有が出来ていると後々効いてきます。

少しの学習コストと少しの設計時間を取り入れる事で後の世を変えるかもしれない設計教にあなたも今日から入信しませんか❓
では👋‼

RECRUIT

大阪・東京共にスタッフを募集しています。
特にキャリア採用のプログラマー・アーティストに興味がある方は下のボタンをクリックしてください

RECRUIT SITE