3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ApplibotAdvent Calendar 2020

Day 14

Unity開発におけるView構造規約の紹介

Last updated at Posted at 2020-12-13

Applibot Advent Calendar 2020」 14日目の記事になります。
前日は@16choさんのBLEで始める心臓の死活監視という記事でした!

はじめに

  • UnityのGameObjectの仕様
  • デザインや演出の問題

などのため、スッキリしたViewの構造/クラスを作る事はなかなか難しい事だと感じています。
そこで、UnityでアウトゲームなどのViewを組む際、チーム内で定めた規約をご紹介します。

(View構造と書いていますが、広くMonoBehaviour継承クラスが他のgameObjectとの関係性をどう持つか、というテーマになります。)

狙い

ヒエラルキーに配置されたGameObjectは様々な箇所からアクセスする手段があり、global変数のようなものです。
GameObject.Find()などで、どういった構造であっても参照を取得する事が出来てしまいます。
今回ご紹介する規約は、何らかのGameObjectにアクセスできる経路を出来るだけ少なく絞り込む構造とし、メンテナンス性を高める事が狙いです。

説明に使うサンプルについて

public class Qiita : MonoBehaviour
{
    // 自分以外のgameObject
    [SerializeField] private GameObject _go;

    public void PlayXxx()
    {
        _go.xxx();
    }
}

こういったプログラムで自分以外のgameObject(ここでは_go)を管理している、MonoBehaviour継承クラスに関する決め事になります。
ImageやTextのような自身だけを処理する物は含みません。

① inspecterで参照を持ったり、GetComponentで参照を取得できるのは、自身の子供要素に対してのみ

スクリーンショット 2020-12-11 18.21.35.png
こういった構造があるとします。

OKな例

  • AがA_1の参照を持つ
  • A_1がXを参照に持つ

NGな例

  • XがB_2の参照を持つ
  • B_1がBを参照に持つ

親要素・兄弟要素へのアクセスを禁止し、子供要素へのアクセスのみ許可しています。
これにより依存関係を分かりやすくします。また「再利用のためにprefab化したい」となった時に、子要素以外に参照があるとprefab化するのが困難になるためです。

② 管理しているコンポーネントを飛び越して参照しない

スクリーンショット 2020-12-11 18.21.35.png
NG

  • Aが、A_1 を挟まずにXの参照を取得するのはNG
public class A : MonoBehaviour
{
    public void Awake()
    {
        var x = transform.Find("A_1/X");
    }
}
  • A_1がXを公開し、A-1.X の用にアクセスするのはNG
public class A_1 : MonoBehaviour
{
    [SerializeField] private GameObject _x;

    // 自分の子要素を公開
    public GameObject X
    {
        get { return _x; }
    }
}

public class A : MonoBehaviour
{
    [SerializeField] private A_ _a_1;

    public GameObject Awake()
    {
        _a_1.X.SetActive(false);
    }
}

Xにアクセスできる存在を絞るための規約です。親の管理Componentだけが参照できる事とします。

①・②を踏まえて演出を考慮した構造を作ってみる

最後は規約というより、①と②を守りながら演出を考慮した際の構造を考えてみます。
アニメーション等の演出のため、各Viewパーツをプログラム制御する場面を考えます。
スクリーンショット 2020-12-11 18.44.33.png
パーツが色々な箇所に散らばっていると制御が困難になるため、共通の親を用意します。
例えばA_1とA_2が同時に動いたり、相互に影響しあうアニメーション演出が考えられる際、A_1とA_2の参照を持つ親のAnimationRootを作り、子要素達の動きを制御します。

スクリーンショット 2020-12-11 19.08.54.png
更にAnimationRootAとAnimationRootBが関連するアニメーションを作るには、AとBの参照を持つ親Rootコンポーネントを用意し、子要素のComponentへ指令を出してタイミング等を制御します。

最後に

規約により、分かりやすさ・メンテナンス性は上がりますが、記述は冗長になり面倒が増える側面もあります。
より良い構造設計があれば是非教えて下さい!

また、皆さんのチームのView設計規約があれば、合わせて紹介いただけると幸いです。

Applibot Advent Calendar 2020」 14日目の記事でした。
明日は @lokiunybg さんです。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?