はかせのラボ

私の頭の中を書いていく雑記ブログです

Unity コンポーネントとは?クラスやスクリプトとは何が違うの?

あいさつ

どうも、はかせです。

昨日Twitterを眺めてたら
GetComponentがうまくいかないみたいな話があってですね。
ちらりと覗くとどうやらコンポーネント自体の理解が
あやふやなご様子でした。

どうやらその話自体は解決したみたいなんですが、
ネット上で調べても
「GetComponentの使い方」とか
コンポーネントを自在に操作!」とかばっかで
肝心のコンポーネントとはなんぞやって言う
記事や情報が無いように見えたんですよね。

もちろんその記事の中でしれっと紹介していたりもするわけですが、
コンポーネントについて知りたいって人が
いきなりコンポーネントの扱い方的な記事を見るかなーと。

ということでそういう方達に向けて
コンポーネントとはなんぞや?
っていうのと
クラスやスクリプトとは何が違うの?
っていうのを書いていきます

コンポーネントとはなんぞや?

まずComponentってどういう意味って話からですね。
Google翻訳にかけるとですね
「成分」「構成子」「構成要素」
こんな感じの意味だって教えてくれます。

あとプログラマーとかだと
「部品」「振舞」
みたいな意味合いで使うときもありますね。

つまりコンポーネントってのは何らかの成分、構成要素であり、
その何らかの振舞を定義するものであると
ぼんやり見えてきます。

ちなみにその何らかってのはUnity的に言えばGameObjectですね。
よくGameObjectは入れ物とか箱って言われます。
その箱の中に入れるのがコンポーネントってわけですね。
図にするとこんな感じ
f:id:hakase0274:20191110150800p:plain

Unityではこんな感じのGameObjectがたくさんあって
GameObject同士がコンポーネント使ってお互いにやりとりしたりして
ゲームの仕組みを構築していくわけです。

逆に言えばコンポーネントが無ければUnityでは何もできませんし、
そも論プログラマーが介入する場所がありません。
(厳密に言えばあるっちゃあるんですがここでは触れない方向で)

Unity的にはGameObjectが一番大事らしいですが、
実際問題コンポーネントが一番大事なんじゃないかと思う今日この頃です。

クラスやスクリプトとは何が違う?

よくUnity初心者向けの記事やら本やらでこんな記述を見かけます。

GetComponet<スクリプト名>();
GetComponet<クラス名>();

まぁ実際こう書けるんで書き方の説明自体は合ってるんですが、
意味の話をそういう記事や本って一切しないんですよね。

その結果
「他のクラスから値が取れない(´;ω;`)」
こんな感じの泣きを見せるわけですね。

なのでこの記事では意味の方もちゃんと書きます。
さてまずGetComponentという関数が何をするかですが、
これは先述のコンポーネントを取得する関数です。

Componentはさっきの図でも書いたようにGameObjectの中に入っています。
なのでニュアンス的にはこう書くべきです。

GameObject名.GetComponent<コンポーネント名>();

何のGameObjectの何のコンポーネントを取るのかってことですね。
動きとしてはこんなん
f:id:hakase0274:20191110152450p:plain

他のGameObjectが持つコンポーネントを取ってくる
これがGetComponentの動きなわけです。
ちなみにGameObject名を書かないと取ってくるのは
「自分についているコンポーネントとなります。
f:id:hakase0274:20191110152810p:plain
さて散々GetComponentの動きがコンポーネントを取るって話をしたとこで
コンポーネントとクラス、スクリプトって
何が違うのかって話に行きましょう。

まずスクリプトは何かというとこですね。
スクリプトってのはファイルです。
このファイルの中にC#やらJavaScriptやらで
プログラムを書いていくわけです。

じゃクラスは何かって言うと
機能の定義をしているものになります。
よく設計図って言われますね。
さっき書いたスクリプトソースコードの中に書かれるもので
変数は何があるとかどういう関数があるのかってのは書きます。

設計図ってなんで言われるかって言うとクラスそのものが
何かのアクションをするわけではないからです。

実際クラスを使うときはインスタンスっていうものを作って
そいつを使います。
(まぁstaticっていう例外はいますけど)

このインスタンスってのがさっきクラスで書いた定義を持つ実体になります。
工場とかでも何かを作る時はその作るものの設計図書いて
それをもとに製品を作りますよね。
その製品がここでいうインスタンスに該当します。

さて最後にコンポーネントとは何かという話です。
コンポーネントインスタンスです
コンポーネントはGameObjectの振舞であって
実際に動くものです。
クラスは実際に動かず動くのはインスタンスなのですから、
コンポーネントインスタンス以外ありえません。

つまりGetComponentってのは
クラスのインスタンスを取得する関数だったわけです。

そしてさらに言うならばGameObjectもクラスで
実際に動くのはインスタンスです。
つまりGetComponentの最終的に正しいのはこの形

取得したいクラスのインスタンス = GameObject型のインスタンス.GetComponent<取得したいクラス名>();

あとがき

今回はUnityのコンポーネントについてと
クラスやスクリプトとの違いについてでした。

なるべくわかりやすく書いたつもりではありますが、
いかんせん私自身はこの辺の違いをぬるっと理解していたので
どの辺がわかりづらいかがイマイチわかっておりません。
(元々JavaやらCやらっていう別の畑から来ていて基礎がわかっていたので)

なので
「この説明がわかりづらい」
「ここはこういう説明の方がイメージしやすい」

などあればコメント等いただけると助かります。

それでは今回はこの辺でノシ