teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

追加の説明

2016/12/16 08:15

投稿

退会済みユーザー
answer CHANGED
@@ -100,3 +100,74 @@
100
100
 
101
101
 
102
102
 
103
+ 追加の回答です。
104
+
105
+ 二発目以降の弾が出ない原因はすみません、わからないです。
106
+
107
+ このエラーは初期化されていない変数を利用しようとしたときに出るものです。
108
+ Spaceshipのbulletが初期化されていないために発生したものと思われます。
109
+ このエラー自体初めて見たので対処方法はいまいちわからないのですが、
110
+ 念のため弾オブジェクトを新たに生成(Instantiate)しない方法で、あらかじめエネミーの子要素として弾を必要数配置し、プレハブ化すればそのエラーは出ないものと思います。
111
+ なので新たに弾を生成せずにすべての子要素にSetActive( false )を入れ、Listに登録するだけで済みます。
112
+
113
+ 具体的にはSpaceshipのスクリプトのStart()内の処理を
114
+
115
+ ```C#
116
+ void Start()
117
+ {
118
+ Transform t;
119
+ //Bullet bulleta;
120
+ // 最初に一定数の弾を備蓄しておく
121
+ // 子要素全てにアクセスし、弾オブジェクトだけをリストに登録する.
122
+ for (int i = 0; i < transform.childCount; i++)
123
+ {
124
+ // 弾の生成
125
+ //bulleta = Instantiate(bullet).GetComponent<Bullet>();
126
+ t = transform.GetChild( i );
127
+ if ( t.gameObject.name != "EnemyBullet" )
128
+ continue;
129
+ Bullet bulleta = t.GetComponent< Bullet >();
130
+
131
+
132
+ // 発射前は非アクティブにしておく
133
+ bulleta.transform.parent = this.transform;
134
+ bulleta.gameObject.SetActive(false);
135
+ // Listに追加
136
+ list_Bullets.Add(bulleta);
137
+ }
138
+ }
139
+ ```
140
+
141
+ に変更し、すでにあるEnemy以下の弾のプールから登録するだけになります。
142
+ 弾の名前がEnemuyBullet(Clone)ではないのはInstantiateしてないためです。
143
+
144
+
145
+ 弾がSetActive( false )で移動し続けるのも原因はいまいち判然としませんが停止処理を挟めば大丈夫かと思います
146
+
147
+ なのでDestroyAreaに当たったら別途弾を止める処理を入れる必要があるかと思います。
148
+ 例えば、Bulletスクリプトに停止用のメソッドを追加し以下のように呼び出してからSetActive( false )する等です。
149
+
150
+ ```C#
151
+ void OnTriggerEnter2D(Collider2D c)
152
+ {
153
+ if (c.tag == "Bullet(Player)")
154
+ {
155
+ c.GetComponent< Bullet >().stopBullet();
156
+ c.gameObject.SetActive(false);
157
+ }
158
+ else if (c.tag == "Bullet(Enemy)") {
159
+ c.GetComponent< Bullet >().stopBullet();
160
+ c.gameObject.SetActive(false);
161
+ }
162
+ else
163
+ {
164
+ Destroy(c.gameObject);
165
+ }
166
+ }
167
+ ```
168
+
169
+
170
+
171
+
172
+
173
+

1

ソース例を追加

2016/12/16 08:15

投稿

退会済みユーザー
answer CHANGED
@@ -6,4 +6,97 @@
6
6
  そもそもBullet自体が動いていない
7
7
  等...
8
8
 
9
- それとBulletGeneratorの動作を実装し、うまくいかなかったソースも載せていただけると答えやすいと思います。
9
+ それとBulletGeneratorの動作を実装し、うまくいかなかったソースも載せていただけると答えやすいと思います。
10
+
11
+ 僕の方でもそれっぽいものは作成ししてみました。
12
+ 実装の詳細は多少違いますが一応載せておきます。
13
+
14
+ まずはBulletGeneratorから、これは子要素にBulletオブジェクトを複数持つオブジェクトです。
15
+ 子要素の中からGetActive()でfalseのものを探し、あればtrueにし弾として動かします。
16
+ ```C#
17
+ using UnityEngine;
18
+ using System.Collections;
19
+ using System.Collections.Generic;
20
+
21
+
22
+ //------------------------------------------------------------------------------
23
+ //==============================================================================
24
+ // 弾プール.
25
+ public class BulletGenerator : MonoBehaviour {
26
+
27
+
28
+ [SerializeField] private GameObject[] bullets = null; // 子要素に入っている弾プール.
29
+
30
+
31
+ //------------------------------------------------------------------------------
32
+ void Start() {
33
+
34
+ // 子要素の弾たちを配列にしている.
35
+ Queue< GameObject > q = new Queue< GameObject >();
36
+ for ( int i = 0; i < this.transform.childCount; ++i ) {
37
+ q.Enqueue( this.transform.GetChild( i ).gameObject );
38
+ }
39
+ this.bullets = q.ToArray();
40
+ q.Clear();
41
+
42
+ }
43
+
44
+
45
+ //------------------------------------------------------------------------------
46
+ void Update() {}
47
+
48
+
49
+ //------------------------------------------------------------------------------
50
+ public void shot(
51
+ Transform origin ) {
52
+
53
+ // 子要素の配列の中から使えるものを探し、あれば使いまわす.
54
+ for ( int i = 0; i < this.bullets.Length; ++i ) {
55
+ if ( !this.bullets[ i ].GetActive() ) {
56
+ this.bullets[ i ].SetActive( true );
57
+ this.bullets[ i ].transform.position = origin.position;
58
+ this.bullets[ i ].transform.rotation = origin.rotation;
59
+ break;
60
+ }
61
+ }
62
+ }
63
+
64
+ }
65
+ ```
66
+
67
+ プレイヤーがショットを撃つ場合は以下のような感じです。
68
+ PCでAキーを押したらショットを撃ちます。
69
+ これでオブジェクトプール(BulletGenerator)にショットを依頼します。
70
+ 同様にエネミーのときもBulletGeneratorにショット依頼をすると弾が打てるようになると思います。
71
+ あとはBullet.csで何かに当たったときや画面買いに出たときにSetActive( false )でそのオブジェクトを無効にすれば弾オブジェクトの使いまわしができます。
72
+ ```C#
73
+ using UnityEngine;
74
+ using System.Collections;
75
+
76
+ public class Player : MonoBehaviour {
77
+
78
+ public BulletGenerator bg = null;
79
+
80
+ // Use this for initialization
81
+ void Start () {
82
+
83
+ }
84
+
85
+ // Update is called once per frame
86
+ void Update () {
87
+
88
+ if ( Input.GetKeyDown( KeyCode.A ) ) {
89
+ this.bg.shot( this.transform );
90
+ }
91
+
92
+ }
93
+ }
94
+
95
+ ```
96
+
97
+ 一応僕の環境ではうまくいきました。
98
+ ヒエラルキーの配置はこんな感じです。
99
+ ![イメージ説明](351ea16e442035e92123f2acca5a0e7e.jpeg)
100
+
101
+
102
+