質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.61%

MonoBehaviourのAwake、Start、Updateという関数が呼ばれる仕組み

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 9,924

score 37

MonoBehaviourを継承してAwake、Start、Updateという関数を作るとUnity側で勝手に呼んでくれますが、これはどういう仕組みで動いているのでしょうか?

最初、MonoBehaviour側にvirtualな関数、もしくはabstractな関数で定義されているのかとも思ったのですが、overrideしなくても書けますし、定義を書かなくてもコンパイルエラーにならないので、そういうわけでもないんですよね?

どういう仕組なのか、非常に不思議に思っています。

ご教授お願い致します。

ちなみに、私、C++にはある程度精通していますがC#歴は浅いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+3

いろいろ調べてみたところ、以下のようなことがわかりました。

スクリプティングランタイム(Mono・IL2CPP)によって Update()やStart()など特定のメソッドが定義されているかを調査され、MonoBehaviourが特定のメソッドを持っていたら所定のリストに組み込まれるようです。
ゲーム中はこのリストからメソッドが呼ばれている、というものだそうです。

この情報はUnity公式ブログに記載されていた情報なので信頼できるソースだと思います。
詳しくは以下のリンクを参考にしてみてください。
Update()を10000回呼ぶ

余談ですが、私自身この記事を見るまでSystem.Reflectionを使って何かしらしてるんじゃないかな、と思っていました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/01 20:12

    非常に的確なご回答ありがとうございます.とても勉強になりました.質問者ではありませんが感謝しています.

    キャンセル

  • 2016/06/02 08:56

    スクリプティングランタイムが、集めて回してくれているんですね。
    疑問に思っていたことがすっきり解決しました。
    ありがとうございます。

    ご紹介してくださった記事、面白いですね。
    やはり大したことしてなくてもイテレーションは遅いんですね。
    前職の時、頑張ってイテレーション数を減らそうと努力していたのを思い出しました。

    キャンセル

0

こんにちは.

私も同じ疑問を抱いていました.
調べても特に回答を得られなかったので,私の中で至った結論は
「Unityは独自のコンパイラを使用しているので,特定のイベント関数のみエンジンから呼べるようにしている」
ということです.
仮想関数はオーバーヘッドがかかりますからね.

C++ならまだしもC#ですし,エンジンの根幹部分で多大なオーバーヘッドによる負荷を生じさせてしまってはゲームどころではなくなってしまうため,コンパイラレベルで根本的に手を入れているのではないかと思っています.
さらに言うとpublicさえ付けさえない(付けなくて良い)のはイベント関数が不用意に他のクラスから呼ばれる事を防ぐためと,下記の点を実現するためではないかと.(長いので別段落にしました)

なお,継承した場合に基底クラスのイベント関数(例えばUpdate)にpublicを付けない場合は言語仕様通り継承されず,派生クラスでUpdateを定義しない場合は基底クラスのUpdateさえ呼ばれないので,クラスだけ継承してもオブジェクトの動作を決定するイベント関数は完全に別個になります.
それが Mono(単一の)Behaviour(動作)の名前の由来と考えると繋がります.
(BehaviourからではなくMonoBehaviourからイベント関数が定義されていますよね)
publicにすると言語仕様上必ず継承されてしまうので,子側で空の関数を定義しない限り親の動作を引き継いでしまい,このような動作は実現できません.
継承されようとも動作定義をクラス単位で別個にするには,publicを付けない状態で呼び出せる方法(=コンパイラ拡張)が必要になります.
前述のパフォーマンスのためか,MonoBehaviourの設計思想のためか,理由はどちらにせよ根本的に手を入れている線は間違いないのではないかと.

いまひとつ文章がまとまっていなくてすみません.
あくまで推測なので鵜呑みにしないで頂ければ幸いです.

※追記
誤った情報がありますが訂正しておりませんので,
後々ご覧になる方はコメント欄を見て補完して下さい.

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/01 13:44

    なるほど。丁寧な説明ありがとうございます。色々と参考になりました。

    試しに、
    基底クラスでpublicを付けずにStart関数を定義し、派生クラスではStartを定義しない。
    っとしてみたところ、基底クラスのStart関数は呼ばれているようでした。
    はて?

    キャンセル

  • 2016/06/01 13:50

    おや…これは失礼いたしました.
    別の方のブログでpublicを付けない場合継承されないという情報を目にしていた為,聞きかじった情報を交えてお答えしてしまいました.
    http://wannabe-jellyfish.hatenablog.com/entry/2015/12/13/221128

    申し訳ございません.もっと精進致します.

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る