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

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

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

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

Unity

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

Q&A

1回答

772閲覧

Unity2D Update関数以外でゲームオブジェクトを呼びたい

tomatoma...

総合スコア15

C#

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

Unity

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

0グッド

0クリップ

投稿2020/06/22 10:45

編集2020/06/22 11:17

初めに、私は現在Unity2Dでアンドロイドアプリを制作しております。

また、私自身プログラミング初心者ということもあり、ネット上で公開されているソースコードを参考にして作っているため、理解困難な箇所があるかも知れませんが、ご了承お願い致します。

制作中のアプリ内容としてはシューティングゲームを作っています。
また、『プログラム自体は正常に流れています』

しかしながら、実機のアンドロイドにてビルドしテストを行うと動作が重いことに気付きました。

幾つか自分で原因を考えてみたのですが、
『一番の原因はUpdate関数にGameObjectを大量に生成している』
からなのではないかと思っています。

そのコードを以下に記載させて頂きます。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5using UnityEngine.UI; 6using CompletedAssets; 7 8 9namespace CompletedAssets 10{ 11 12 public class boss1_move : MonoBehaviour 13 { 14 public GameObject boss0_bullet_prefab; 15 private int shot_time;//生存、発射時間 16 private float rad; //弾用角度 17 private float rad2; //弾用角度2 18 private float rad3; //弾用角度3 19 20 // ヒットポイント 21 public int hp; 22 23 // スコアのポイント 24 public int point = 100; 25 26 private Slider slider; 27 28 // Spaceshipコンポーネント 29 SpaceshipBoss spaceship; 30 31 //void Start() 32 IEnumerator Start() 33 { 34 // boss_t = 100; //ボス体力初期設定 35 shot_time = 0;//生存、発射時間初期設定 36 rad = 0f;//弾用角度初期設定 37 rad2 = 0f;//弾用角度2初期設定 38 39 slider = GameObject.FindGameObjectWithTag("EnemyHPSlider1").GetComponentInChildren<Slider>(); 40 41 slider.maxValue = hp; 42 43 // スライダーの現在値の設定 44 slider.value = hp; 45 46 47 // Spaceshipコンポーネントを取得 48 spaceship = GetComponent<SpaceshipBoss>(); 49 50 // canShotがfalseの場合、ここでコルーチンを終了させる 51 //if (spaceship.canShot == false) 52 if (hp <= 0) 53 { 54 yield break; 55 } 56 57 } 58 59 void Update() 60 { 61 62 if (shot_time > 1 && shot_time < 99) 63 { 64 transform.Translate(0, -0.018f, 0);//移動 65 } 66 67 if (shot_time > 100 && shot_time < 1200) 68 { 69 if (shot_time % 5 == 0) 70 { 71 Vector2 e0 = transform.position;//自機と敵の角度計算 72 float etx = Player.pos - e0.x;//自機と敵の角度計算 73 float ety = Player.pos - e0.y;//自機と敵の角度計算 74 rad = Mathf.Atan2(ety, etx);//自機と敵の角度計算 75 76 for (float ang = -7.8f; ang <= -5.4f; ang += 0.4f)//自機狙い6方向弾幕(1フレームに6発発射)青弾用 77 { 78 GameObject shot = Instantiate(boss0_bullet_prefab, transform.position, transform.rotation) as GameObject;//敵弾生成 79 boss0_bullet_move s = shot.GetComponent<boss0_bullet_move>();//boss0_bullet_moveスクリプトを取得 80 s.Create_rad_ds_bu_ex_ey(rad + ang + 0.1f, 0.1f, 0, 2.4f, -0.5f);//boss0_bullet_moveスクリプトのCreate_rad_ds_bu_ex_ey関数に弾の初期情報を渡す 81 } 82 83 for (float ang2 = -7.8f; ang2 <= -5.4f; ang2 += 0.4f)//自機狙い6方向弾幕(1フレームに6発発射)ピンク弾用 84 { 85 GameObject shot = Instantiate(boss0_bullet_prefab, transform.position, transform.rotation) as GameObject;//敵弾生成 86 boss0_bullet_move s = shot.GetComponent<boss0_bullet_move>();//boss0_bullet_moveスクリプトを取得 87 s.Create_rad_ds_bu_ex_ey(rad - ang2 - 0.15f, 0.1f, 1, -2.4f, -0.5f);//boss0_bullet_moveスクリプトのCreate_rad_ds_bu_ex_ey関数に弾の初期情報を渡す 88 } 89 } 90 if (shot_time % 16 == 0)//8方向回転弾幕(1フレームに8発発射) 91 { 92 for (rad = 0f; rad < 6.28f; rad += 0.8f)//弾発射角度が6.28になるまで発射、6.28で一回転(3.14の2倍)青弾用 93 { 94 GameObject shot = Instantiate(boss0_bullet_prefab, transform.position, transform.rotation) as GameObject;//敵弾生成 95 boss0_bullet_move s = shot.GetComponent<boss0_bullet_move>();//boss0_bullet_moveスクリプトを取得 96 s.Create_rad_ds_bu_ex_ey(rad + rad2, 0.1f, 0, 0, 0);//boss0_bullet_moveスクリプトのCreate_rad_ds_bu_ex_ey関数に弾の初期情報を渡す 97 } 98 rad2 += 0.5f;//発射角度プラス 99 for (rad = 0f; rad < 6.28f; rad += 0.8f)//弾発射角度が6.28になるまで発射、6.28で一回転(3.14の2倍)ピンク弾用 100 { 101 GameObject shot = Instantiate(boss0_bullet_prefab, transform.position, transform.rotation) as GameObject;//敵弾生成 102 boss0_bullet_move s = shot.GetComponent<boss0_bullet_move>();//boss0_bullet_moveスクリプトを取得 103 s.Create_rad_ds_bu_ex_ey(rad + rad3, 0.1f, 1, 0, 0);//boss0_bullet_moveスクリプトのCreate_rad_ds_bu_ex_ey関数に弾の初期情報を渡す 104 } 105 rad3 -= 0.5f;//発射角度マイナス 106 } 107 } 108 109 shot_time += 1; 110 if (shot_time >= 1300) shot_time = 100;//ボスの行動を8方向回転弾幕に戻す 111 112 } 113 114 void OnTriggerEnter2D(Collider2D c) 115 { 116 // レイヤー名を取得 117 string layerName = LayerMask.LayerToName(c.gameObject.layer); 118 119 // レイヤー名がBullet (Player)以外の時は何も行わない 120 if (layerName != "Bullet (Player)") 121 return; 122 123 // PlayerBulletのTransformを取得 124 Transform playerBulletTransform = c.transform.parent; 125 126 // Bulletコンポーネントを取得 127 Bullet bullet = playerBulletTransform.GetComponent<Bullet>(); 128 129 // ヒットポイントを減らす 130 hp = hp - bullet.power; 131 132 // ★(追加)この一行を追加しないとスライダーバーの目盛りが変化しません! 133 slider.value = hp; 134 135 // 弾の削除 136 Destroy(c.gameObject); 137 138 139 // ヒットポイントが0以下であれば 140 if (hp <= 0) 141 { 142 // スコアコンポーネントを取得してポイントを追加 143 FindObjectOfType<Score>().AddPoint(point); 144 145 // 爆発 146 spaceship.Explosion(); 147 148 // エネミーの削除 149 Destroy(gameObject); 150 151 Destroy(transform.root.gameObject); 152 153 } 154 else 155 { 156 // Damageトリガーをセット 157 spaceship.GetAnimator ().SetTrigger ("Damage"); 158 159 } 160 } 161 162 163 void OnTriggerEnter2D(Collider2D coll)//当たり判定 164 { 165 if (coll.tag == "ship_bullet")//自機弾が当たった時 166 { 167 Destroy(coll.gameObject);//自機弾削除 168 boss_t -= 1;//ボス体力マイナス 169 if (boss_t <= 0)//体力が0になったら 170 { 171 Destroy(gameObject);//ボス削除 172 for (int i = 0; i < 50; i++) 173 { 174 Instantiate(explosion_prefab, new Vector3(-4f + 8f * Random.value, 0f + 4f * Random.value, 0), Quaternion.identity);//爆破表示 175 } 176 // time_table.game_time = 0;//ゲーム時間を最初に戻す 177 Destroy(gameObject); 178 } 179 GameObject.Find("Canvas").GetComponent<UIcontroller>().AddScore();//得点プラス 180 } 181 182 } 183 } 184} 185

以上がコードとなります。

試したこと

・FPSのターゲットを60に設定
→効果はあったが、(shot_time > 100 && shot_time < 1200)の処理中にFPSが100を超える。

・クオリティ設定を低く変更
→効果の実感なし

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

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

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

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

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

guest

回答1

0

原因を見つけたい場合はMemory Profilerを使いましょう。
実機とつなげて確認すればどこで処理が跳ね上がっているか見ることができます。(スクリプト側の負荷なのか、グラフィック側の負荷なのかなど)
https://docs.unity3d.com/ja/2019.4/Manual/ProfilerMemory.html

もしくは一旦機能をオミットするのも手です。ボスが弾を撃ってこない設定で動かしたら軽くなるかを確認します。

ひたすらインスタンス化しているのが問題なようだったら
この手のゲームでまず思いつくのは弾のオブジェクトプールです。ひたすらインスタンス化するのではなく必要な分だけ作ってあとは使い回すやり方になります。
画面外に出たものや、なにかにあたったものはDestroyするのではなく非表示にして保管しておきます。弾をインスタンス化する際に保管してある弾があればそちらを再利用するという考え方です。

第01回 オブジェクトプーリング
https://github.com/unity3d-jp-tutorials/2d-shooting-game/wiki/%E7%AC%AC01%E5%9B%9E-%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%83%97%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0

投稿2020/06/23 00:33

hogefugapiyo

総合スコア3302

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問