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

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

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

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

2回答

3774閲覧

【Unity】配列で取得したオブジェクトのスクリプトをまとめて実行したい

jum6948

総合スコア20

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

1クリップ

投稿2017/11/21 17:35

###前提・実現したいこと
配列を使って、オブジェクトを選択してまとめてスクリプトを実行させたい。
今回の場合だと、イベントフラグのあるコライダーに入った時、まとめてつららが4本落ちてくる。

###発生している問題・エラーメッセージ

今、書いているコードだと以下のエラーが出ます。

'Gameobject[]'に'GetComponents'の定義が含まれておらず、型'Gameobject[]'最初の引数を受け付ける拡張メソッドが見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足していないことを確認してください。

###該当のソースコード
C#で作っております。
【イベントフラグ】

public class EventBall_Turara : MonoBehaviour { [Header("反応時間")] public float t; public GameObject[] refObj; void OnTriggerEnter(Collider Collider) { //プレイヤーが範囲にいる間 if (Collider.gameObject.tag == "Player") { t = 0; } } void OnTriggerStay(Collider Collider) { t += Time.deltaTime; //プレイヤーが範囲にいる間 if (Collider.gameObject.tag == "Player") { AtackTurara a = refObj.GetComponents<AtackTurara>(); if (a != null) { a.TuraraOn(); Debug.Log("ざn"); } } } }

【つらら自身のプログラム】

public class AtackTurara : MonoBehaviour { [Header("Effect")] public GameObject IceHit; //つららが削れるエフェクト public GameObject IceBreak; //つらら爆破 public AudioClip BreakSe; protected GameObject clone; AudioSource aud; Rigidbody rb; GameObject GDirector; [Header("岩の能力")] public int HitPoint; public int HitPointMax = 50; public bool isDead = false; //つららはこわれていないか? public bool isZimen = false; public bool isTuraraOn = false; int damage; [Header("生存時間")] public float liveTime; public float t; [Header("足音")] public AudioClip foot_iwa; //土 public AudioClip foot_water; //水1 public AudioClip foot_sand; //砂 public AudioClip foot_snow1; //雪1 public AudioClip foot_snow2; //雪2 public Quaternion TuraraRote; //Yattackのエフェクトの角度 // Use this for initialization void Start() { rb = GetComponent<Rigidbody>(); this.aud = gameObject.GetComponent<AudioSource>(); GDirector = GameObject.Find("GameDirector"); HitPoint = HitPointMax; rb.isKinematic = true; } void Update() { //体力が0以下になったら消滅する if (HitPoint <= 0) { //死亡判定有効 isDead = true; Destroy(this.gameObject, 0.5f); } if (isTuraraOn ==true) { //重力 rb.AddForce(Vector3.down * 7000); } //clone = Instantiate(IceBreak, transform.position, Rote); } public void TuraraOn() { isTuraraOn = true; rb.isKinematic = false; } private void OnCollisionEnter(Collision collider) { int r = Random.Range(0, 2); //何かに触れたら? if (collider.gameObject.tag == "Zimen_Tuti" || collider.gameObject.tag == "Zimen_Isi" || collider.gameObject.tag == "Zimen_Wood" || collider.gameObject.tag == "Zimen_Kusa" || collider.gameObject.tag == "Zimen_Water"|| collider.gameObject.tag == "Zimen_Sand" || collider.gameObject.tag == "Zimen_Snow" || collider.gameObject.tag == "Player" ) { t = 0; isZimen = true; } //地面に刺さった時関連 if (collider.gameObject.tag == "Zimen_Tuti" || collider.gameObject.tag == "Zimen_Isi" || collider.gameObject.tag == "Zimen_Wood" || collider.gameObject.tag == "Zimen_Kusa" || collider.gameObject.tag == "Player" ) { this.aud.PlayOneShot(foot_iwa, 1F); } else if (collider.gameObject.tag == "Zimen_Water") { this.aud.PlayOneShot(foot_water, 1F); } else if (collider.gameObject.tag == "Zimen_Sand") { this.aud.PlayOneShot(foot_sand, 1F); } else if (collider.gameObject.tag == "Zimen_Snow") { if (r == 0) { // ランダムA this.aud.PlayOneShot(foot_snow1, 1F); } else if (r == 1) { // ランダムB this.aud.PlayOneShot(foot_snow2, 1F); } } //Playerと衝突したら消滅させる if (collider.gameObject.tag == "Player") { Destroy(this.gameObject, 0.5f); } //矢攻撃 if (collider.gameObject.tag == "Arrow" || collider.gameObject.tag == "WayArrow" || collider.gameObject.tag == "WayExArrow") {//矢攻撃の攻撃判定に当たった時 if (collider.gameObject.tag == "Arrow") { //ArrowMoveからダメージの値を取得する damage = collider.gameObject.GetComponent<ArrowMove>().damage; } if (collider.gameObject.tag == "WayArrow") { //ArrowWayMoveからダメージの値を取得する damage = collider.gameObject.GetComponent<ArrowWayMove>().damage; } if (collider.gameObject.tag == "WayExArrow") { //ArrowWayExMoveからダメージの値を取得する damage = collider.gameObject.GetComponent<ArrowWayExMove>().damage; } //判定が触れた所にエフェクト発生 foreach (ContactPoint point in collider.contacts) { //ダメージ量に応じてボイス変更 GameObject effect1 = Instantiate(IceHit) as GameObject; effect1.transform.position = (Vector3)point.point; Destroy(effect1, 1.0f); rb.velocity += ((Vector3)point.point * 5.1f) / rb.mass; } //攻撃判定衝突したらダメージ HitPoint -= damage; } //剣攻撃1 if (collider.gameObject.tag == "Blade_Hit1") { foreach (ContactPoint point in collider.contacts) { GameObject effect1 = Instantiate(IceHit) as GameObject; effect1.transform.position = (Vector3)point.point; Destroy(effect1, 1.0f); rb.velocity += ((Vector3)point.point * 25.1f) / rb.mass; } //ダメージをランダムで変える damage = Random.Range(100, 150); //攻撃判定衝突したらダメージ HitPoint -= damage; } //剣攻撃2 if (collider.gameObject.tag == "Blade_Hit2") { foreach (ContactPoint point in collider.contacts) { GameObject effect1 = Instantiate(IceHit) as GameObject; effect1.transform.position = (Vector3)point.point; Destroy(effect1, 1.0f); rb.velocity += ((Vector3)point.point * 25.1f) / rb.mass; } //ダメージをランダムで変える damage = Random.Range(200, 250); //攻撃判定衝突したらダメージ HitPoint -= damage; } //剣攻撃3 if (collider.gameObject.tag == "Blade_Hit3") { foreach (ContactPoint point in collider.contacts) { GameObject effect1 = Instantiate(IceHit) as GameObject; effect1.transform.position = (Vector3)point.point; Destroy(effect1, 1.0f); rb.velocity += ((Vector3)point.point * 25.1f) / rb.mass; } //ダメージをランダムで変える damage = Random.Range(500, 1000); //攻撃判定衝突したらダメージ HitPoint -= damage; } //バッシュ攻撃 if (collider.gameObject.tag == "Bash") { foreach (ContactPoint point in collider.contacts) { GameObject effect1 = Instantiate(IceHit) as GameObject; effect1.transform.position = (Vector3)point.point; Destroy(effect1, 1.0f); rb.velocity += ((Vector3)point.point * 25.1f) / rb.mass; } //ダメージ与える damage = 150; //プレイヤーの弾と衝突したらダメージ HitPoint -= damage; } } private void OnCollisionStay(Collision collider) { //地面に刺さったら? if (collider.gameObject.tag == "Zimen_Tuti" || collider.gameObject.tag == "Zimen_Isi" || collider.gameObject.tag == "Zimen_Wood" || collider.gameObject.tag == "Zimen_Kusa" || collider.gameObject.tag == "Zimen_Water" || collider.gameObject.tag == "Zimen_Sand" || collider.gameObject.tag == "Zimen_Snow" || collider.gameObject.tag == "Player" ) { t += Time.deltaTime; //地面に刺さってliveTime秒経過したら if (t > liveTime) { //時間とともに消滅 Destroy(this.gameObject); } } } //壊れる時、地面にささるか破壊された場合 void OnDestroy() { //死んでいると if (isDead == true || isZimen == true) { EDead(); } } //破壊時エフェクト表示 void EDead() { if (clone == null) { this.aud.PlayOneShot(this.BreakSe); Vector3 pos = transform.position; pos.y += 3.5f; transform.position = pos; clone = Instantiate(IceBreak, transform.position, TuraraRote) as GameObject; } } }

###試したこと
【1】
手段を選ばなければ【GameObject[] refObj】;を使用せずに【refObj0】、【refObj1】、【refObj2】、【refObj3】を作って、同じスクリプトを4回実行することで動作はしました。
でも、これは違う気がします。

【2】
public int x;
AtackTurara a = refObj[x].GetComponent<AtackTurara>();
で、inspectorで同じ数字を設定したものの、動作せず。

###補足情報(言語/FW/ツール等のバージョンなど)
【制作環境】
Unity5.6.1f1 personal
win10
MicrosoftVisualStudio
つららのコードじゃなく、おそらく、イベントフラグがおかしいと思って入るのですが、つららのコードにリストされるのを許可するコードが必要なのかな?とも考えてみたり・・・。
やり方がわからないので、見当違いな質問をしていたら申し訳ありません。
よろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

GameObject[]は「GameObjectの配列」です。
GetComponentsは「対象のGameObjectに付いた指定のコンポーネントを全て取得する」メソッドなので、配列に対しては使用出来ません。

AtackTurara a = refObj[x].GetComponent<AtackTurara>();
本来ならこれで動作するはずです。(エラーが出ているなら提示してもらえると解決しやすいです)

その他の方法として、全てのつららオブジェクトを1つの親オブジェクトの子としておき、
親オブジェクトに対してGetComponentsInChildrenをすることでも一括取得出来ます。
Unityのコンポーネントを一括で取得する | Unityを使った3Dゲームの作り方(かめくめ)
(リンク先のコードはJavascriptなので適宜C#に読み替えてください)

投稿2017/11/22 01:38

sakura_hana

総合スコア11425

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

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

jum6948

2017/11/22 03:02

つららの数が4なので、4にすると・・・ IndexOutOfRangeException: Array index is out of range. EventBall_Turara.OnTriggerStay (UnityEngine.Collider Collider) (at Assets/Scripts/EventBall_Turara.cs:31) 31行目 AtackTurara a = refObj[x].GetComponent<AtackTurara>(); プログラムの世界では、0が1だったのを思い出して、数字を変更して、動くには動いたのですが、xの指定した番号のみが落下するという結果になりました。 x=0 ツララ0、x=1 ツララ1、x=2 ツララ2、x=3 ツララ3・・・ MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object. UnityEngine.GameObject.GetComponent[AtackTurara] () (at C:/buildslave/unity/build/artifacts/generated/common/runtime/GameObjectBindings.gen.cs:38) EventBall_Turara.OnTriggerStay (UnityEngine.Collider Collider) (at Assets/Scripts/EventBall_Turara.cs:31) xが無いのにアクセスしてるぞって言ってるので、それを無理やり解決してみました。 //プレイヤーが範囲にいる間 if (Collider.gameObject.tag == "Player") { if (x > -1) { AtackTurara a = refObj[x].GetComponent<AtackTurara>(); a.TuraraOn(); if (a != null) { x -= 1; Debug.Log("ざn"); } } } 動作するようになりました! ・・・が、動作はしますが、この記述が正しいのかは、少し疑問は残ります。 最終的にはつららを同時には落とそうとは思っていないのですが、前段階として乗ったら全て同時に落ちてきてほしいので、この動作は理想ではありません。 (最終的にはつらら側のコードで落下までの時間を指定したい) お時間がよろしければいいので、sakura_hanaさんのご意見を賜りたいです。
jum6948

2017/11/22 03:03

ごめんなさい、後半の、インデントがおかしくなりました。
sakura_hana

2017/11/24 00:48

返答遅れて申し訳無いです。 配列の中身を操作する場合、通常はforかforeachを使います。 int size = refObj.length; for(int i=0; i < size; i++){ refObj[i].GetComponent<AtackTurara>().TuraraOn(); } foreach (GameObject item in refObj) { item.GetComponent<AtackTurara>().TuraraOn(); } 他、Linqという発展系もありますがプラットホームによってはエラーが出たりしますのでご自分で調べて頂けると幸いです。 なお、負荷的にはいちいちGetComponentさせるべきではないので、 可能ならGameObjectの配列ではなくAtackTuraraの配列にするとよいかと思います。
jum6948

2017/11/27 03:09

返答、ありがとうございます! いつも多角的な視点からの回答誠に感謝しております。 配列の数字を取得する方法が今回が「int size = refObj.length;」という方法というのが勉強できて大変感謝しております。 コードを持っているオブジェクトをそのまま配列することが出来るんですね。 回答していただいた foreach (GameObject item in refObj) { item.GetComponent<AtackTurara>().TuraraOn(); } をアドバイスしていただいたように書き換えたら動作しました。 public AtackTurara[] refObj; foreach (AtackTurara item in refObj) { if (item != null) { item.TuraraOn(); } } sakura_hanaさんの回答は、ただの回答じゃなく、いつもひとつふたつと、ステップアップできるすばらしい回答なので、大変感謝しております。今回もありがとうございました。 teratailは、返答にも高評価できる機能が欲しいです。とりあえず、ワタクシの心のスコアを+1させて頂きます。
guest

0

refObj配列が初期化されてないように思うのですが、どうでしょうか?
C#私的超入門#1 配列

投稿2017/11/22 00:06

nico29

総合スコア76

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

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

sakura_hana

2017/11/22 01:40

Unityの場合、publicな基本クラスの配列は勝手に初期化され、インスペクター上で初期値設定が出来ます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問