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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

7726閲覧

イベントハンドラを別のオブジェクトにアタッチしているスクリプトで書く方法。

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

1グッド

0クリップ

投稿2016/08/20 11:24

編集2016/08/21 13:20

###前提・実現したいこと
通常、CubeのOnCollisionEnter( )の処理を書きたい場合、そのCubeにアタッチしているスクリプトファイルでOnCollisionEnter( )の処理を書くと思います。

C#

1using UnityEngine; 2using System.Collections; 3 4public class CubeScript : MonoBehaviour { 5 6 void OnCollisionEnter(Collision col){ 7 Debug.Log ("test"); 8 } 9}

しかし、他のゲームオブジェクト(下図ではGameObject)にアタッチしているスクリプトファイルから、CubeのOnCollisionEnter( )の処理を書きたい場合はどうすればよいのでしょうか?
それともそれは不可能なのでしょうか?

通常

他のオブジェクトから

###試したこと

GameObjectにアタッチしているスクリプトから、Cubeオブジェクトを取得。

C#

1using UnityEngine; 2using System.Collections; 3 4public class GameObjectScript : MonoBehaviour { 5 6 // Use this for initialization 7 void Awake () { 8 GameObject cube = GameObject.Find ("Cube"); 9 } 10}

これより先の記述がわかりません。
ご教授お願い致します。

###追記
ご回答いただいた方法で、まず値を渡さない方法で試してみました。
イベントを受け取るようになったのですが、受け取りの際(OnCollisionEnterEvent)、senderを利用してみたいと思いました。CubeScriptでthisを渡しているので、senderはCubeだと思うのですが、このsender(Cube)を操作することができません。sender(Cube)の操作方法のご教授お願い致します。

C#

1public class CubeScript : MonoBehaviour { 2 3 // 値を渡さない 4 public event EventHandler OnCollisionEnterEvent = delegate { }; 5 6 void OnCollisionEnter(Collision col) 7 { 8 // 値を渡さない 9 OnCollisionEnterEvent(this, EventArgs.Empty); 10 } 11 12}

C#

1public class GameObjectScript : MonoBehaviour { 2 3 void Awake(){ 4 5 // コンポーネント(CubeScript)を取得 6 CubeScript cubeScript = GameObject.Find ("Cube").GetComponent<CubeScript> (); 7 8 // イベントを設定 9 cubeScript.OnCollisionEnterEvent += delegate (object sender, EventArgs e) { 10 Debug.Log(sender); //Cube (CubeScript) 11 sender.transform.position = Vector3.zero; //senderはCubeのはず。ここでエラー。 12 }; 13 } 14 15}

キャストしてもエラーになりました。

C#

1 (GameObject)sender.transform.position = Vector3.zero; //senderはCubeのはず。ここでエラー。
narudesign👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

やり方はいくつかあるかと思いますが、自分がよく使うイベントによる方法を書きます。

CubeScriptのOnCollisionEnter()が呼ばれた際に、予め登録されているイベントハンドラーを呼び出すことで、CubeScript以外のコンポーネントへイベントが発生したことを伝えます。

CubeSciprtにイベントを用意します。値を渡したい場合は、EventArgsを継承したクラスを用意します。
OnCollisionEnter()からイベントを発生します。

C#

1using UnityEngine; 2using System; 3 4// イベントで値を渡したい場合はEventArgsを継承したクラスを用意する 5public class EventArgsCollision : EventArgs 6{ 7 public Collision col; 8} 9 10public class CubeScript : MonoBehaviour 11{ 12 // 値を渡さない 13 public event EventHandler OnCollisionEnterEvent = delegate { }; 14 15 // 値を渡す(EventArgsを継承したクラスを<>に指定する) 16 public event EventHandler<EventArgsCollision> OnCollisionEnterEventWithArgs = delegate { }; 17 18 // 予め用意しておく 19 EventArgsCollision args = new EventArgsCollision(); 20 21 void OnCollisionEnter(Collision col) 22 { 23 Debug.Log("CollisionEnter"); 24 25 // 値を渡さない 26 OnCollisionEnterEvent(this, EventArgs.Empty); 27 28 // 値を渡したい 29 args.col = col; 30 OnCollisionEnterEventWithArgs(this, args); 31 } 32}

GameObjectにアタッチするコードでCubeにアタッチしたCubeScriptを取得します。
そしてCubeScriptに用意したイベントを設定します。

C#

1using UnityEngine; 2using System; 3 4public class GameObjectScript : MonoBehaviour 5{ 6 CubeScript cubeScript; 7 8 void Awake() 9 { 10 // コンポーネント(CubeScript)を取得 11 cubeScript = GameObject.Find("Cube").GetComponent<CubeScript>(); 12 13 // イベントを設定 14 cubeScript.OnCollisionEnterEvent += delegate (object sender, EventArgs e) 15 { 16 // メソッド呼び出し 17 MyOnCollisionEnter(); 18 }; 19 20 // イベントを設定 21 cubeScript.OnCollisionEnterEventWithArgs += delegate (object sender, EventArgsCollision e) 22 { 23 // 直接記述 24 Debug.Log("MyCollisionEnter " + e.col.transform.name); 25 }; 26 } 27 28 void MyOnCollisionEnter() 29 { 30 Debug.Log("MyCollisionEnter"); 31 } 32}

senderを使う場合はCubeScriptにキャストすれば大丈夫だと思います。

C#

1using UnityEngine; 2using System; 3 4public class GameObjectScript : MonoBehaviour 5{ 6 CubeScript cubeScript; 7 8 void Awake() 9 { 10 // コンポーネント(CubeScript)を取得 11 cubeScript = GameObject.Find("Cube").GetComponent<CubeScript>(); 12 13 // イベントを設定 14 cubeScript.OnCollisionEnterEvent += delegate (object sender, EventArgs e) 15 { 16 // キャストしたものを変数に 17 CubeScript cube = sender as CubeScript; 18 cube.transform.localPosition = new Vector3(0, 3, 0); 19 20 // または直接キャスト 21 // ((CubeScript)sender).transform.localPosition = new Vector3(0, 2, 0); 22 23 // メソッド呼び出し 24 MyOnCollisionEnter(); 25 }; 26 27 // イベントを設定 28 cubeScript.OnCollisionEnterEventWithArgs += delegate (object sender, EventArgsCollision e) 29 { 30 // 直接記述 31 Debug.Log("MyCollisionEnter " + e.col.transform.name); 32 }; 33 } 34 35 void MyOnCollisionEnter() 36 { 37 Debug.Log("MyCollisionEnter"); 38 } 39}

投稿2016/08/21 05:01

編集2016/08/21 13:37
narudesign

総合スコア32

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/08/21 12:37

ご回答ありがとうございます。ご回答いただいた方法で、まず値を渡さない方法で試してみました。イベントを受け取るようになったのですが、senderが扱えません。ご教授いただけないでしょうか?詳細は質問に追記してあります。
narudesign

2016/08/21 13:39 編集

解答を編集しました。 CubsScriptへキャストすれば大丈夫だと思います。
退会済みユーザー

退会済みユーザー

2016/08/22 15:43

ご回答ありがとうございます。delegateを知らなかったので勉強になりました。ソース中のコメントでイベントを渡す手順も理解することができました。また、キャストの方法もご教授くださりありがとうございます。とても勉強になりました、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問