渋谷ほととぎす通信

Unity・ゲーム開発 技術で一生食べていく情報発信

【初心者向け】Unityを使ったUI開発で大事にしている9つのTips🔰

f:id:esakun:20210508233842p:plain

こんにちわ、Unityエンジニアのオオバです。

ここ数年Unityを使ったUI開発に携わることが多く、
その知見は過去に何度か発信してきました。

今回は新規ゲーム開発でUIの設計をやったことがない初心者にフォーカスした内容です。 僕なりに10年前の自分にアドバイスする気持ちで執筆しています。

本記事で得られる内容

  • 10年以上のUI開発経験をもつ筆者が初心者に向けたノウハウ
  • いざUI開発を任された時のための知見

🚀 オオバ(筆者)の開発思想

ノウハウを共有する前に、そこに到る前提、僕オオバの思想について共有します。 僕がUI開発において大事にしている2つの開発思想です。

  1. 開発期間は短く抑えたい
  2. 軽量&サクサクで気持ちの良い手触りにしたい

1.開発期間は短く抑えたい

当たり前ですが開発にはお金(コスト)がかかります。
そしてコストは有限です。

コストの大半は人件費(人件費 × 開発期間)

人が少なく、開発期間が短ければ自然とコストは低く抑えられます。

「開発期間は短く抑えたい」を噛み砕くと、 人が少なく、開発期間の少ない環境を作るということがオオバの開発思想の根底にあります。

少人数で最大限パフォーマンスを上げる開発環境を作ることが自分の大きなミッションだと考えています。

2.軽量&サクサクで気持ちの良い手触りにしたい

「軽量&サクサクで気持ち良い手触り」を言語化すると以下です。

  1. ゲーム中にカクつかない
  2. ロードなどの待機時間が短い
  3. 洗練されたUI

最初の2つはエンジニアリング観点では当たり前。

「3.洗練されたUI」は一見デザイナーの領域だと思われがちです。

しかしそれは完全な間違いです。

デザイナーの頭の中にあるものを、現実的な設計でプロダクトに落とし込むためには、
Unityエンジニアのクリエイティブに対する視点の高さが重要になります。

「デザイナーはここでアニメーションを差し込みたいと思うはずだからトゥイーンを仕込んでおこう」

↑のような先回り。

直接デザイナーにUnityでアニメーションを作ってもらうための仕組みづくりなど。

また大抵のプロジェクトでは、機能開発が優先されUIアニメーションなどの演出は後回しになりがちです。

「🔰8.後乗せUIアニメーションは破綻する」で紹介をしていますが、 結論「UIアニメーションをあとから何とかしよう」という思想ではクオリティは上がりません。
(UIアニメーションと機能開発を切り分けて考えすぎてはダメ)

ある程度クリエイティブ・デザインに興味や関心を持ち、
デザイナーと考え方をシンクロさせていくことも
「3. 洗練されたUI」を実現させるためには必要になるわけです。
(※詳しくは後述)

もし機能開発を優先してUIアニメーションを
「後で一気に実装してクオリティアップしよう」
と思っている方がいらっしゃったら参考になるかもしれません。

僕の開発思想を踏まえた上でUI開発、
どういうことを大事にしているのか9つのTipsを紹介していきます。

📝 対象読者

新規ゲームのUI開発をやったことのないエンジニア向けに執筆しています。

実はUI開発は思わぬところに落とし穴があります。
それらを先に知り、今後アサインされた時の材料にしていただければと思います。

※本編はここから
※Tipsの順にあまり意味はありません

🔰 1.ボタン・テキストの独自コンポーネント作成のススメ

本章は「Button、Textはそのまま使わずプロジェクト独自のコンポーネントを作っておくべき!」 という持論を展開します。

Unityのデフォルトボタン使用は禁止からの独自ボタン作成

以前はNGUIを採用することもありましたが、
最近のUnity開発ではuGUIでUIを作っていくことが多いです。

UI開発で必ず登場する「ボタン」
どうやって実装していますでしょうか?

Unity本家が気を利かせて用意しているButtonコンポーネント
僕がメインのエンジニアとしてジョインする場合は100%使用禁止にします。

一番の理由はButtonコンポーネントだけでは対応できない状況が発生するからです。

経験的にボタンに求める機能を列挙してみます。

  • 長押し判定
  • タップ時のスケールアニメーションなどの独自インタラクション
  • タップ時のSE再生(複数種類 : OK時、キャンセル時など)
  • 各イベントに対する処理のセット
  • 複数の画像パーツの一括色変更
  • 画像付きボタン
  • テキスト付きボタン
  • ボタンに対応したタップエフェクトを切り替える

これらをButtonコンポーネントだけで作ることはできません。
(※厳密にはできないというより無理してButtonコンポーネントを使う理由がないという意味です)

経験上、結局独自ボタンを作ることになるため、
機能は少なめでも最初からプロジェクトの独自ボタンを作っておく方が良いでしょう。

専用のTextコンポーネントの作成

独自ボタンと同様でテキストも独自コンポーネントを作ります。

独自のテキストコンポーネントということですが、
Textをオーバーライドした形ではなくラッパーという位置づけです。

なぜテキストの独自コンポーネントが必要なのか?

理由は単純です。

「Textコンポーネントだけではフォローしきれない機能が開発中に大量発生するから」

独自ボタンと同じですね。

独自Textを作ってよかったこと

テキスト実装には必ず先の独自Textコンポーネントを使うというルールを敷きます。

👇以下の項目は開発中に発生したテキストの追加対応で、
独自コンポーネントにしておいてよかったな〜って思ったことです。
(※特段大きな工数がかからずに対応できたという意味で)

  • 禁則処理の追加
  • フォントの一括変更
  • UIレギュレーション (文字色、アウトラインの太さ・色など) の一括変更
  • 文字数による文字サイズの調整対応

テキストは至るところで使われ、数は膨大になります。
膨大なものこそ一括で管理できる仕組みがあるかないかで
開発工数は大きく変わるということが実感できるのではないでしょうか。

まとめると、ボタンもテキストもデフォルトのコンポーネントではサポートしきれません
最初からそうなる未来を想定した独自コンポーネントの開発が、
リスクを抑えた開発につながるのではないかと考えています。

🔰2.画面遷移基盤「戻る」実装のシンプル化

UI開発をする上で欠かせないのは画面遷移基盤の開発です。
同じような画面を大量生産しなければならないアウトゲーム。

大抵のプロジェクトで画面遷移基盤を開発しているのではないでしょうか。

👇ボタンを押して画面遷移する簡単なフロー図です。
(※画面の事をDisplayと呼称しています)

  1. ボタンAをクリック(Display Aに変更リクエストを送る)
  2. DisplayManagerはDisplayChangerにDisplay Aへの切り替えを依頼
  3. Display Aに切り替わる

※この図は以前執筆したコチラの記事で使用した図をリライトしています。

DisplayChanger「現在の画面と次の画面を切り替える」シンプルな設計にしています。

本章では「戻る実装のシンプル化」ということで、この基盤に対して戻る機能をどう実装するか?という話になります。

履歴リストの作成で解決

「画面遷移履歴リスト」というコレクションを用意します。

DisplayManagerが、画面遷移履歴リストに表示していた画面情報を追加します。

// 画面遷移履歴リスト
_displayStack.Push(displayInfo);

この設計によって特定の画面の戻り先を指定するといった画面の密結合を防ぐことができます。

ちなみに「戻る」を実行した際には画面遷移履歴リストから、
最新の遷移先画面情報を取り出し遷移を実行させます。

public void BackDisplay()
{
    // 履歴リストから取り出して遷移開始
    var info = _displayStack.Pop();
    Goto(info);
}

各画面を並列に扱うことで画面同士の依存を意識することがなくなりハッピー。

画面によって履歴をリセット

これ以上戻りたくない場合もあります。例えばホーム画面バトルリザルトです。

画面毎に履歴を保持する、削除するといった処理を画面遷移基盤に記述しています。

/// <summary>
/// 履歴リセットフラグの返却
/// </summary>
private bool IsClearHistory(DisplayType type)
{
    // 履歴をリセットする画面を定義
    switch (type)
    {
        case DisplayType.Home:
        case DisplayType.BattleResult:
            return true;
    }

    return false;
}

👇画面遷移シーケンスの中で必要があれば履歴を削除します。

// 画面遷移処理の流れで履歴リストのチェック
if (IsClearHistory(_currentDisplayType))
{
    // 履歴を削除
    ClearHistory();
}

重要なのは基盤に隠蔽することです。
ホーム画面のスクリプトにClearHistory()と書いてはいけません。

こういった共通処理は基盤に寄せる(責任を委譲する)ことで、
開発メンバーは特に意識することなく安心して開発できるのです。

この安心がとても重要です。

もちろん仕様によって履歴に従わない処理が必要になる場合もあります。

本当に必要かどうか議論はしつつも、
戻る処理をオーバーライド出来るような設計にしておくのがよいと考えています。

余談:Androidバックキー対応

ホーム画面からは「戻るボタン」がないゲームが多いのではないでしょうか。
なぜなら戻り先が無いからです。

戻るボタンがない異常、物理的に戻る処理は実行できません。
唯一戻ることが出来る手段、そうAndroidバックキーです。

Androidバックキーは常に意識する必要のある落とし穴のひとつ。

  • ホーム画面にいる場合はタイトルに戻す
  • タイトルだったらアプリを落とす(アプリを落とす確認ダイアログを開く)
  • Androidバックキーが反応してはいけないタイミングの考慮

こういった処理が必要になります。

これらを統合的に考え画面遷移基盤を作ることになるのです。

🔰3.どの画面でも直遷移できますか?

「🔰 2.画面遷移基盤「戻る」実装のシンプル化」と関連して画面遷移基盤についてです。

  • 仕様氏 : 「ステージ詳細画面にはクエスト選択画面からしか遷移しません」
  • オレ氏 : 「OK!それで実装します!」
  • 仕様氏 : 「CBTの結果、バトルを周回しやすくするためにステージ詳細画面に直遷移することになりました」
  • オレ氏 : 「マジか!!!」

あくまで過去の経験から、僕は初期仕様を無条件に受け入れるということはしません。
予め伝えておきますが、仕様を作った人を疑っているわけではないです。

理由は、さまざまな力で仕様は変わるからです。
(もちろんプロダクトを良くするために)

僕は以前ゲーム開発の比ではない頻度で仕様が変わる広告業界で働いていました。

その頃の師匠は僕にこう言いました。
「オオバくん、クライアントエンジニアにとって大事なのは想像力だよ」

その言葉と経験から想像力を大事にするようになりました。

想像力を働かせていれば「バトル周回」というブラッシュアップは必然だったのかもしれません。どの画面にも直遷移できる設計という初手を打っておくべきだったということになります。

ただし注意点はあります。

あくまで開発中期までの仕様がフワつきやすい時期での話。
その後、想像力を膨らませすぎて無駄な機能を作るのは危険!!

リリース後に使われない機能を保守するコストが発生するからです。

あくまで自然で無理のない設計の中で多様性を考慮した作りにしておくことをオススメします。

師匠、ムズイです。

🔰4.壊せるなら壊してしまえUI基盤

短期間開発に欠かせないのは基盤の充実化です。
基盤の存在は開発における「学習コストの低下」につながります。

学習コストが低いと何が良いのでしょうか?

  1. 作り方で迷わない
  2. 実装方法の統一性アップ
  3. 開発メンバーが本来の力を発揮する

良いことづくめ。

プロジェクトの初期メンバーは開発ルールの定義が大きなミッションですが、 これも学習コストを下げる一環。

増員時にワークするために学習コストを下げること、 つまり「基盤の整備」が重要になります。

前置きが長くなりましたが、 本章で話したいのは作り直せるタイミングであれば「積極的に作り直せと」いうことです。

人間誰しも一発で正解にたどり着くことは難しい。。。 僕にはできません。できないという自信があります。

開発を始めて最初の2ヶ月くらいは何度も作り直すことが多いです。

ポイントはどのタイミングで作り直すことを決断するのか?ということです。

「仕様に対して無理やりな部分が出てきた」 「やたらif文でごまかす部分が増えた」

これらが合図。

ソースコードを俯瞰して、こういった理にかなっていない実装が 顔をのぞかせたら「時が来た」ということです。

プロジェクト中期以前で、まだそんなに人が参画していないなら壊せるチャンス!!

こわしちゃえ!

これはUI基盤に限りません。

  • ダイアログ基盤
  • シーン遷移基盤
  • アセット基盤
  • API基盤
  • マスターデータ

などなど各種基盤同様です。

学習コストを下げるための「基盤作り直し」に躊躇しないことが大事です。
結果的にそれが完成までの道のりを最短にします。

🔰5.UIアニメーション処理を共通化しておく

UIアニメーションと一言で言ってもさまざまな種類がありますが、2つに大きく分けます。

  1. 再利用しないUIアニメーション
  2. 再利用するUIアニメーション

再利用しないUIアニメーションとは?

要は一点物です。

再利用するUIアニメーションとは?

複数の箇所で同じアニメーションを適用する必要のある、汎用性の高いものです。

ここでは汎用性を必要とする、 再利用するUIアニメーションの共通化の重要性について解説します。

👆の画像はyokohama.unityでの発表資料の一部です。
LT版クリエーターとUnityエンジニアの狭間でUIアニメーションを設計する3つのTips」より

UIアニメーションは情報整理

なぜUIアニメーションを実装するのかと言うと、 ユーザーに正しい情報を伝達するためです。

雑コラですが、以下のボタンの例を見てみましょう。

  • ホーム
  • クエスト
  • キャラ
  • メニュー

それぞれ同じレベルのボタンですが、 意味なくクエストボタンだけ大きいです。

この弊害はなんでしょうか? 「ユーザーに対して正しく情報が伝わらない」ということです。

ユーザー 「(大きいから)クエストはイベント中かしら?」

とか思われてはダメなのです。

僕らエンジニアが変数、関数を意味をもって定義するのと同様に、 デザイン(色、形、動きなど)にも意味があります。

これが本当かウソかお近くのデザイナーに聞いてみてください。 一つ一つのデザイン要素の意味を語ってくれるでしょう。

それはさておき、ここで何が言いたいのかと言うと、 UIにはルール(レギュレーション)が存在し、 それを守らなければいけないということです。

ソースコード上で共通化させておくと、 ルールを守りやすくなりますし同時に開発効率も上がります。

例えばスライド、拡大縮小、アルファなどよく使うアニメーションは共通化しておくと良いでしょう。

  • 時間
  • 移動距離
  • イージングの種類

これらの要素は共通になることが多いです。 もちろん特殊ケースも出てきますが、それは個別に対応でOK。

例えば横にスライドしながら表示するUIアニメーションは 👇のようなコードで共通化させます。

// 横スライドアニメーション
UITween.ShowSlideX(target);

※本質ではないため独自クラスUITweenの中身は割愛

大事なのは処理を共通化させて意識せずともUIレギュレーションを守る環境にしておくことです。

UIアニメーションの変更依頼は頻度高

さきほど例に上げた、時間移動距離イージングは、 開発やブラッシュアップの過程で変更依頼がちょくちょく発生します。

(例)「もう少し全体の画面遷移を早くしたい」 といった要望です。

共通メソッドにまとめていればUITween内のコードを変更するだけで対応は完了し、
高速なイテレーションを実現できます。
※開発中何度もパラメータを調整した記憶あり

以上のことから再利用するUIアニメーションは共通化しておくことをオススメします。

🔰6.文字列をソースコードに書くことなかれ

_confirmLabel.text = "タイトルに戻ってもよろしいでしょうか。";

とかソースコードに書いていませんか?

その行為は危険です。

_confirmLabel.text = Localize.Get("confirm.back.to.title");

👆のように文字列をソースコードに直書きしない工夫をしておくことをオススメします。

プロジェクト終盤の言い回し変更案件大量発生

"タイトルに戻ってもよろしいでしょうか。"
↓
"タイトルにもどってもよろしいでしょうか?"
  • 「戻る」→「もどる」
  • 「。」→「?」

このような言い回しの変更作業がプロジェクト終盤には大量に発生します。

結構な量を変更した記憶があります。

ただ幸いソースコードに直書きしていなかったため大きな問題にはなりませんでした。 しかしこの仕組がなかったとしたら。。。。

とりあえず、文字列をソースコードに直書きするのだけは止めておきましょう。

🔰7.UI人員増加タイミングの見極め

アウトゲームはその物量から開発期間を増員によって解決する事が多いです。
重要なのは増員のタイミング。

早すぎると開発ルールが整ってなくてやることがなく
追加人員がパフォーマンスを発揮できない状況が生まれます。

では、どのタイミングに増員すべきなのでしょうか?

あくまで持論ですが、以下の条件を満たしていれば安心して増員できると思っています。

  • シーン遷移基盤
  • 画面遷移基盤
  • ダイアログ基盤
  • アセット基盤
  • API基盤

これらの基盤が8割以上完成していれば増員しても問題ないと考えます。 指標として「作り方で迷わない状態であること」が重要かなと。

🔰8.後乗せUIアニメーションは破綻する

ボタンのタップやダイアログの開閉、画面遷移といったUIアニメーションはプロジェクトの終盤のブラッシュアップで一気に実装するのは不可能です。

「不可能」は言いすぎかもしれません。
ただクオリティの高い状態に持っていくのは限りなく不可能に近いと思います。

それを回避するためには、
プロジェクトの序盤からUIデザイナーと
すり合わせながら作っていくことをオススメします。

プロジェクト中盤も初期にすり合わせた内容を頭に入れながら実装するのです。
このプロセスを踏むことで終盤のブラッシュアップは現実的なものになります。

またよくある破綻の原因としては、大きめの仕様変更が入ったときです。
残り期間に対して機能開発を優先することになるためUIアニメーションのプライオリティがどうしても下がってしまいます。

優先度は下げても良いですが、そのUIアニメーションが後から入る余地を残した実装にしておかねばなりません。

完全にUIアニメーションのことを無視してしまうとこうなります👇

  • いざUIアニメーションを実装したときに設計から見直すコストが発生
  • 急いだつもりなのに逆に時間がかかってしまう

これを防ぐためにも設計者は「UIアニメーションがあとから実装される」という余白を作っておかねばならないのです。

本章で言いたかったのは2点。

  1. プロジェクトの序盤からUI演出のゴールをUIデザイナーと握りながら進める
  2. トラブルが起きたとしてもUIアニメーションを実装される隙間を残しておく

抽象的な表現になってしまいましたが、 最終的なクオリティを担保するために設計者はいつも心がけるべきことだと思っています。

🔰最終章 PSDでつながるKOIの物語

最後のTipsは今までとは毛色が変わります。

UIを組み込む際にPSDファイルを見ていますでしょうか?

PSDとは?

UIデザイナーが使うグラフィック編集ソフトのひとつPhotoshopの保存形式です。PNGやJPGと違い、レイヤーと呼ばれる画像の層が保存されます。

要はデザインの元データです。

デザイナーが実作業で使用したPSDを開いたことがない人はぜひ中身を見てもらいたいです。

何が言いたいのかというと、
PSDはUIデザイナーの苦労の結晶、0から1を生み出した奇跡がそこにはあるということです。

僕も昔印刷会社で3年デザイナーをやっていたので多少分かりますが、
0から1を生むというのは超〜〜〜〜シンドイのです。

引き出しからポイっと出るわけではなく、さまざまな検証の元、生み出されたもの。

その苦労がPSDには秘められています。

UnityにUIを組み込む際、パーツ化された素材(PNG)をデザイナーに納品してもらうことが多いかもしれません。
僕はあえてPSDを直接もらって自分でパーツを書き出して組み込むのが好きです。

よく以下のようなやり取りが発生します。

僕 : 「PSDもらえますか?」
デザイナー : 「PSDの中身を整理するので待ってください」
僕 : 「いや、むしろ大丈夫です!整理しなくても!」

どんなに汚いPSDでも書き出せる自信があるのと、
そもそもPSDを整理するデザイナーの時間がもったいないというのが大きいのですが、

一番の理由は0から1を生み出した苦労の共有を僕は尊重しているからです。

「なるほど、そういう検証もしたのか・・・リスペクト」みたいな。

職種間の良い連携が開発効率を向上させることは周知の事実。
良い連携を生みだすために他職種の苦労を知ることはかなり大事だと考えています。

デザインってマジ大変。それはエンジニアには分かりづらい感覚かもしれない。
ただ、PSDを見れば、氷山の一角を感じるきっかけになります。

書き出された小さなUIパーツの奥にはデザイナーの血と汗と涙の結晶が詰まっているわけです。

だからPSDを見てみましょう。

🚀 まとめ

ここまで読んでいただきありがとうございました。
若干テンションがブレブレで内容の粒度がまちまちでしたが、
重要だと思う9個のことを紹介してきました。

  1. ボタン・テキストの独自コンポーネント作成のススメ
  2. 画面遷移基盤「戻る」実装のシンプル化
  3. どの画面でも直遷移できますか?
  4. 壊せるなら壊してしまえUI基盤
  5. UIアニメーションは共通化しておく
  6. 文字列をソースコードに書くことなかれ
  7. UI人員増加タイミングの見極め
  8. 後乗せUIアニメーションは破綻する
  9. 最終章 PSDでつながるKOIの物語

僕的にはどれも常に意識しているテクニックでありマインドです。
何か1つでも今後のUI開発の参考になればと思います。

他にも過去にUI開発の発信をしていますので興味ある方は読んでみてください。

Twitterでは本ブログより高頻度にUnityや
UI開発について情報発信しています。

興味ある方はフォローしてみてください。
@ohbashunsuke

🚀 最後に宣伝

生まれて初めてソロで執筆した有料技術書「DOTweenの教科書」が今年の3月にリリースしました。 ※参考値 : 300冊以上売れています 教科書と言いつつ、今までの開発知見から引っ張り出した、 そこそこ突っ込んだ内容も書いています。 👉DOTweenの教科書 目次はコチラ

ソースコードと動画をセットで確認できるため、
「理解しやすい!」というお声をたくさん頂いております。

このブログを読んでいる方の中では「DOTweenは既に極めている」という方もいらっしゃるかもしれません。今さら教科書なぞ不要でしょう。

モノは使い方次第。

例えば以下のようなケースで組織の時間・開発効率を上げられるかもしれません。

  • 新卒エンジニア 「DOTweenワカリマセン」
  • トレーナー 「一旦DOTweenの教科書を読んでおいてね」

このようなトレーナー負担を下げるためのツールとして利用して頂くと良いかなと。
さらには無料エリアだけでも初心者を抜け出せる内容になっていますので一度読んでもらえたら嬉しいです。

以上。