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

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

ただいまの
回答率

90.35%

  • Unity

    4413questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

thisとthis.gameObjectの違い

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 4,283

tkmnusr

score 177

前提・実現したいこと

thisとthis.gameObjectの違いは何なのでしょうか?
また、自身にアタッチしているコンポーネントを取得する際は、どちらで書くべきなのでしょうか?

下記のように出力をとったところ、

  Debug.Log (this);
  Debug.Log (this.gameObject);
ゲームオブジェクト名 (クラス名)
ゲームオブジェクト名 (UnityEngine.GameObject)


と表示されました。

どうやら、

this → クラス。
this.gameObject → そのクラスがアタッチしているゲームオブジェクト。


(↑合っていますか?)

ということらしいのですが、その使い分けがわかりません。

例えば、そのゲームオブジェクトにアタッチしているAnimatorを取得するとき、
GetComponentの呼び出しは、下記においてどちらを使うべきですか?
また、下記2つの書き方で違いはあるのでしょうか?
(どちらもコードは通りました。)

Animator animeData = this.GetComponent<Animator> ();
Animator animeData = this.gameObject.GetComponent<Animator> ();


thisとthis.gameObjectの違いや、使い分けのご教授をお願いします。

追記

ゲーム再生時にNullエラーが起きるのを検証しようとしました。

まず、ゲームオブジェクトにアタッチしているスクリプトを下記のようにしました。

using UnityEngine;
using System.Collections;

public class Sample: MonoBehaviour{

    void Start () {
        Hoge hoge = new Hoge ();
    }
}

次にゲームオブジェクトにアタッチさせないスクリプトも、MonoBehaviourを継承させて、下記のようにしました。

using UnityEngine;
using System.Collections;

public class Hoge: MonoBehaviour{

    void Start () {
        Debug.Log(this.gameObject);
    }
}

ゲーム再生時に発生したエラー(警告文)。
「MonoBehaviourを継承したクラスはnewできない」のでしょうか?

You are trying to create a MonoBehaviour using the 'new' keyword.  This is not allowed.  MonoBehaviours can only be added using AddComponent().  Alternatively, your script can inherit from ScriptableObject or no base class at all
UnityEngine.MonoBehaviour:.ctor()
Hoge:.ctor()
Sample:Start() (at Assets/Sample.cs:7)
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

checkベストアンサー

+6

既にベストアンサーが付いていますが、正確には
「普通に使う分には同じようなものだけど、本質的には別のもの」なので
特例を記載しておきます。

this → クラス。
this.gameObject → そのクラスがアタッチされているゲームオブジェクト。

これはその通りです。

Animator animeData = this.GetComponent<Animator> ();
Animator animeData = this.gameObject.GetComponent<Animator> ();

これも大体のケースにおいてどちらでも構いません。

但し、以下のスクリプトではどうでしょうか。

public class Hoge {

    GameObject gameObject;


    // Use this for initializationvoid Start () {

        this.GetComponent<Animator> ();    //エラー!this.gameObject.GetComponent<Animator> ();    //問題無い

    }

}



コメントにある通り、this.GetComponentはエラー(ビルドが通らない)になり、this.gameObject.GetComponentは正常に動きます。
何故かというとこのHogeクラスは「MonoBehaviourを継承していないから」です。

Unityの基本的なクラスは「MonoBehaviour」というクラスを継承して作られています。
public class Test : MonoBehaviour { }
とクラス宣言をした時、「:」の後ろが継承元のクラスです。
Hogeクラスではこの宣言が無いので、継承元が何も無いクラスということになります。

継承というのはオブジェクト志向のプログラムの考え方で、ざっくり言うと
「そのクラスは勝手に継承元の機能を持つ」という特性があります。
つまりMonoBehaviourで「GetComponent」というメソッドが実装されているので、
MonoBehaviourを継承した自作クラスではGetComponentを実装しなくてもGetComponentを使える、ということになります。

逆に言うと、MonoBehaviourを継承していないクラスではGetComponent(などのMonoBehaviourで実装されているメソッドやプロパティ)が使えません。
なので、
「thisがMonoBehaviourを継承しているのであれば、this.GetComponentでもthis.gameObjectでもどちらでもいい。継承していないならどちらも使えない(※)」
というのが正式な回答となります。

※「this.gameObject」もMonoBehaviourで用意されているプロパティなので継承するか、
上記HogeクラスのようにgameObjectという名前の変数を持つ必要があります。
GameObjectクラスはMonoBehaviourを継承しているので、Hogeクラスの中でもgameObject.GetComponentは正常に動作します。

まぁMonoBehaviourを継承していないとスクリプトをGameObjectにアタッチ出来ないので、滅多に無い事例ではあるのですが……
データを保存しておくだけのクラスやエディタースクリプト、プラグインスクリプトだったらあり得るかもしれないパターンなので記載しました。いつかどなたかの役に立てば幸いです。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/01/31 00:43 編集

    ご回答ありがとうございます。
    実際にコードを書いて、検証してみました。
    (ゲームオブジェクトにアタッチしたスクリプトの中で、アセットのHogeクラスをnewするという検証方法ですが、その検証方法で間違っていませんか?)
    違いがはっきりわかりました。ありがとうございます。
    「MonoBehaviourを継承していないとスクリプトをGameObjectにアタッチ出来ない」、というのも知りませんでした。

    ちなみに、データを保存しておくだけのクラスやエディタースクリプト、プラグインスクリプトでも、MonoBehaviourを継承させて問題はないですか?
    データを保存しておくだけのクラスやエディタースクリプト、プラグインスクリプトは、MonoBehaviourを継承する必要性がないという理由や、継承しない方が処理が軽くなるという理由で、MonoBehaviourを継承させないのでしょうか?

    キャンセル

  • 2017/01/31 10:13

    >ゲームオブジェクトにアタッチしたスクリプトの中で、アセットのHogeクラスをnewするという検証方法
    こちらで問題無いです。

    >MonoBehaviourを継承していないとスクリプトをGameObjectにアタッチ出来ない
    実は私も今回調べて初めて知りましたw

    >データを保存しておくだけのクラスやエディタースクリプト、プラグインスクリプトでも、MonoBehaviourを継承させて問題はないですか?
    特に必要性が無いならば継承させない方がいいかと思います。

    例えば継承させた状態だと「this.gameObject」はビルド時にはエラーになりませんが、そのスクリプトをシーン上のGameObjectにアタッチしていない場合、ゲーム再生時にNullエラーを吐きます。
    一方継承しない状態でgameObject変数を自作した場合、目的のGameObjectを変数に入れる処理も実装している筈なので、この手のエラーが起こりにくいです。
    まぁすぐに直せばいい話なのですが、たまに「ぱっと見正常なコードに見えるので原因箇所だと気付きにくい」「MonoBehaviourの仕様の所為でエラーになる」などのパターンもあるので出来るだけ可能性は減らしておいた方がいいかと。

    処理負荷の差が出るかは分からないで、気になるなら検証されてみるとよいかもしれません。
    (数万単位のクラスをインスタンスしない限り変わらないかなーとは思いますが)

    キャンセル

  • 2017/02/01 23:37 編集

    ご回答ありがとうございます。

    >例えば継承させた状態だと「this.gameObject」はビルド時にはエラーになりませんが、そのスクリプ
    >トをシーン上のGameObjectにアタッチしていない場合、ゲーム再生時にNullエラーを吐きます。

    上記、Nullエラーを検証してみようとコードを書いたのですが、
    他のエラーが出てしまい検証できませんでした(質問欄の追記に記述しました)。
    そのエラーなんですが、MonoBehaviourを継承したクラスはnewできないと書かれているように見えるのですが、
    「MonoBehaviourを継承したクラスはnewできない」のでしょうか?
    また、上記のNullエラーは、どのようなコードを書けば検証できますか?

    キャンセル

  • 2017/02/02 16:38

    >「MonoBehaviourを継承したクラスはnewできない」
    その通りです。そしてこの仕様をすっかり忘れていました……
    なので下記の現象は発生しないです。わざわざ検証頂いたのに申し訳ありません。

    >例えば継承させた状態だと「this.gameObject」はビルド時にはエラーになりませんが、そのスクリプトをシーン上のGameObjectにアタッチしていない場合、ゲーム再生時にNullエラーを吐きます。

    キャンセル

  • 2017/02/03 22:15

    ご回答ありがとうございます。
    MonoBehaviourを継承したクラスはnewできないんですね、ありがとうございます。

    thisとthis.gameObjectの違い、そしてMonoBehaviourとクラスの関係などが理解できました。
    ご教授くださりありがとうございました。

    キャンセル

+2

特に違いはないと思います。
ショートカットくらいの感じで使ってます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/01/28 00:55

    ご回答ありがとうございました。

    キャンセル

+2

destroy(this);   スクリプトのみ消える
destroy(this.gameobject); ゲームオブジェクトごと消える
あたりがわかりやすいんでないかな

子オブジェクトのパーティクルは残すがこのスクリプトは消したいとか

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/02/01 23:22

    ご回答ありがとうございます。検証してみようと思います。

    キャンセル

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

  • Unity

    4413questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。