質問: posTrMainCamera; } } ``` この上記2つのスクリプトを一つのGameManagerというオブジェクトにAdd Componentしてみました。 この時、Inspector上はこのような表示となっております。 ![アタッチなし](https://teratail.storage.googleapis.com/uploads/contributed_images/b016c9fd291a295f4299837f0a465f78.jpeg) 1つ目の質問です。 1なぜMain CameraはGameManagerとMoveManagerの両方に出現するのでしょうか。継承している場合、子クラスのInspectorにも表示されるのでしょうか 2つ目の質問です。 2オブジェクトをアタッチできるようにInspector上に表示していますが、GameManager のplayer がInspector上に表示されないのはなぜでしょうか。Inspector上にアタッチできるような状態でオブジェクト名を表示させる条件は何なのでしょうか?(publicでstaticではないGameObjectの型ならなんでも表示されるのでしょうか) この状態で、GameManagerのMainCamera にメインカメラをアタッチしてみましたが、MainCameraを取得できず実行時エラーとなってしまいました。 ![GameManagerにアタッチ](https://teratail.storage.googleapis.com/uploads/contributed_images/9958b2e253ae46c571670e236d4f830f.jpeg) しかし、以下のようにMoveManagerにアタッチしてみたところ、MainCameraを取得できたため、エラーが起こりませんでした。 ![MoveManagerにアタッチ](https://teratail.storage.googleapis.com/uploads/contributed_images/ab437b295817afd790cb5ae2c8fb9c86.jpeg) 3上記のように、MoveManagerにアタッチした時だけメインカメラを取得できた理由は何なのでしょうか?親クラスにオブジェクトをアタッチしているから、子クラスが参照できると思うのですが、なぜ親クラスでアタッチすると利用できず、子クラスでアタッチすると参照できるのでしょうか。そもそも子クラスにはGameObjectの宣言がないので、子クラス側でアタッチできるというのもよくわかりません。 4このように実装しているのも、よく利用するオブジェクトを一か所にまとめた設計にしたいというのが狙いなのですが、ほかに良い方法はありますでしょうか。 上記の1~4が質問です。 よろしくお願いいたします。
回答: (以下、継承元を「親クラス」、継承先を「子クラス」と称します) 1 そもそも継承というのは「あたかも親クラスのコードが子クラスにも存在するかのように振る舞う」というものです。 つまり(実際には書いてないけど)MoveManagerにも`public GameObject mainCamera;`が書かれているという扱いになります。 なので子クラスのインスペクターにもmainCameraが出現してます。 2 1と同様に、(実際には書いてないけど)MoveManagerにも`public static GameObject player;`が書かれているという扱いになっています。 が、static変数はインスペクター上に表示されません(継承とは関係無く常にそう)。 こいつはstatic変数が特殊な振る舞いをするからです。詳しくは「unity static」辺りでググってください。 ヒエラルキー上に表示されるのは、「private/static/constではない(要は普通のpublicな)変数」です。 型としてはGameObjectを始めとする各種のコンポーネント(Transform, Collider, Sprite等)、自作クラス、int/string/Vector3/配列/Listなど大抵なんでも表示されます。(よく使う中で表示されないのはDictionaryぐらい) 3 継承のルールその2として、「親クラスと子クラスは別の存在」です。 スクリーンショットの状態をイメージで言うと、 ・1個のGameObjectがGameManagerという箱と、MoveManagerという箱、2つの箱を持っている ・GameManager箱の中にmainCameraカゴがある ・MoveManager箱の中にmainCameraカゴがある という状態なので、「mainCameraカゴ」は同じ名前ですが全くの別物・別空間にある存在です。 (1で示したように、MoveManagerには実際には書いてないけどmainCamera変数を宣言したことになっている為) MoveManagerのソースコードにあるこの行 `trMainCamera = mainCamera.GetComponent();` この`mainCamera`は、「MoveManagerのmainCamera」を指してます。 なので「GameManagerのmainCamera」がアタッチされていようがいまいが、 「MoveManagerのmainCamera」がアタッチされていなければ、nullに対しGetComponentしているのでエラーになります。 4 継承の用途が間違っているように思います。一箇所にまとめるだけなら継承を用いる必要はありません。 継承を用いるパターンとして考えられるのは、「概ね同じ挙動だけど一部が違うクラス」が欲しい場合です。 この辺は「継承」や「ポリモーフィズム」をググると出て来るので参考にしてください。 超ざっくりした例) 親クラス:Animal/子クラス:Dog、Cat 子クラスにSay(鳴く)メソッドを実装:Dogクラスなら"Bow"、Catクラスなら"Meow"と返す 参照を取る:`Animal animal = DogかCatクラス as Animal;` 鳴かせる:`animal.Say();`(鳴かせたい側のスクリプトでは、対象がDogかCatかを考える必要が無い)