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

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

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

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

Unity

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

Q&A

解決済

2回答

699閲覧

オブジェクトがプレイヤーを追従してしまう。

YA87

総合スコア6

C#

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

Unity

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

0グッド

0クリップ

投稿2023/01/17 17:28

編集2023/01/17 18:41

前提

Unityで無限ランゲームを作っています。
プレイヤーの前に赤いゾーンがあり、その中に障害物がある時にキー入力を行って切ることでスコアが加算されるというゲームです。
動いているのはプレイヤーで地面や障害物は固定していて、カメラはプレイヤーを追従するようにしています。
赤いゾーンのオブジェクトはプレイヤーの子としてプレイヤーの前を同じ速度で動くようにしています。

障害物のうち、筍は切った後拾う動作を行いたいので、筍を切った後非表示にしてその代わりに倒れた筍の画像を同じ場所に表示しようとしているのですが、画像切り替え後に想定と異なる挙動が起きてしまいます。

実現したいこと

障害物(筍)を切った後、同じ場所に切られた後の筍の画像を表示したい。

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

筍を切った後に表示した倒れた筍の画像が、こちらに来ないでプレイヤーと同じ速度で前に進んでしまう。

該当のソースコード

LineDetector

1 using System.Collections.Generic; 2 using UnityEngine; 3 4 [SerializeField] ScoreManager scoreManager; 5 [SerializeField] private GameObject cutTakenokoPrefab, player; 6 [SerializeField] private List<GameObject> cutTakenokoPool; 7 8 private GameObject cutTakenoko; 9 10 private Vector3 takenokoPos = Vector3.zero; 11 12 private void Awake() 13 { 14 for (int i = 0; i < 10; i++) 15 { 16 cutTakenoko = Instantiate(cutTakenokoPrefab); 17 18 cutTakenoko.transform.SetParent(transform); 19 20 cutTakenokoPool.Add(cutTakenoko); 21 cutTakenoko.SetActive(false); 22 } 23 } 24 25 private void OnTriggerStay2D(Collider2D collision) 26 { 27 if (Input.GetKey(KeyCode.M) && collision.CompareTag("Bamboo")) 28 { 29 collision.gameObject.SetActive(false); 30 scoreManager.CutBamboo(); 31 } 32 else if (Input.GetKey(KeyCode.N) && collision.CompareTag("Takenoko")) 33 { 34 collision.gameObject.SetActive(false); 35 36 takenokoPos = collision.gameObject.transform.position; 37 38 for (int i = 0; i < cutTakenokoPool.Count; i++) 39 { 40 if (!cutTakenokoPool[i].activeInHierarchy) 41 { 42 cutTakenokoPool[i].SetActive(true); 43 44 cutTakenoko = cutTakenokoPool[i]; 45 46 break; 47 } 48 } 49 50 cutTakenoko.transform.position = takenokoPos; 51 } 52 } 53}

ObstacleSpawner

1using System.Collections.Generic; 2using UnityEngine; 3 4public class ObstacleSpawner : MonoBehaviour 5{ 6 [SerializeField] private GameObject bambooPrefab, takenokoPrefab; 7 [SerializeField] private float bambooPos_y = 1.1f, takenokoPos_y = -2.34f; 8 9 [SerializeField] private float minSpawnWaitTime = 0.3f, maxSpawnWaitTime = 1f; 10 11 private float spawnWaitTime; 12 13 private int obstacleToSpawn; 14 15 private Camera mainCamera; 16 17 private Vector3 obstacleSpawnPos = Vector3.zero; 18 19 private GameObject newObstacle; 20 21 [SerializeField] private List<GameObject> bambooPool, takenokoPool; 22 [SerializeField] private int initialObstacleToSpawn = 10; 23 24 private void Awake() 25 { 26 mainCamera = Camera.main; 27 GenerateObstacles(); 28 } 29 30 // Update is called once per frame 31 void Update() 32 { 33 ObstacleSpawning(); 34 } 35 36 void GenerateObstacles() 37 { 38 for (int i = 0; i < 2; i++) 39 { 40 SpawnObstacles(i); 41 } 42 } 43 44 void SpawnObstacles(int obstacleType) 45 { 46 switch (obstacleType) 47 { 48 case 0: 49 50 for (int i = 0; i < initialObstacleToSpawn; i++) 51 { 52 newObstacle = Instantiate(bambooPrefab); 53 54 newObstacle.transform.SetParent(transform); 55 56 bambooPool.Add(newObstacle); 57 newObstacle.SetActive(false); 58 } 59 60 break; 61 62 case 1: 63 64 for (int i = 0; i < initialObstacleToSpawn; i++) 65 { 66 newObstacle = Instantiate(takenokoPrefab); 67 68 newObstacle.transform.SetParent(transform); 69 70 takenokoPool.Add(newObstacle); 71 newObstacle.SetActive(false); 72 } 73 74 break; 75 } 76 } 77 78 void ObstacleSpawning() 79 { 80 if (Time.time > spawnWaitTime) 81 { 82 SpawnObstacleInGame(); 83 spawnWaitTime = Time.time + Random.Range(minSpawnWaitTime, maxSpawnWaitTime); 84 } 85 } 86 87 void SpawnObstacleInGame() 88 { 89 obstacleToSpawn = Random.Range(0, 3); 90 91 obstacleSpawnPos.x = mainCamera.transform.position.x + 20f; 92 93 switch (obstacleToSpawn) 94 { 95 case 0: 96 97 for (int i = 0; i < bambooPool.Count; i++) 98 { 99 if (!bambooPool[i].activeInHierarchy) 100 { 101 bambooPool[i].SetActive(true); 102 103 obstacleSpawnPos.y = bambooPos_y; 104 105 newObstacle = bambooPool[i]; 106 107 break; 108 } 109 } 110 break; 111 112 case 1: 113 114 for (int i = 0; i < takenokoPool.Count; i++) 115 { 116 if (!takenokoPool[i].activeInHierarchy) 117 { 118 takenokoPool[i].SetActive(true); 119 120 obstacleSpawnPos.y = takenokoPos_y; 121 122 newObstacle = takenokoPool[i]; 123 124 break; 125 } 126 } 127 break; 128 129 case 2: 130 131 break; 132 133 134 } 135 136 newObstacle.transform.position = obstacleSpawnPos; 137 } 138 139}

LineDetectorは前提に記した赤いゾーンオブジェクトに、ObstracleSpawnerは空のオブジェクトにそれぞれアタッチしています。
後者のコードで生成した障害物はちゃんとこちら側へ向かってきます。

試したこと

LineDetector内で座標を数値で指定してみましたが、ついてきてしまいました。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答2

0

ベストアンサー

赤いゾーンのオブジェクトはプレイヤーの子としてプレイヤーの前を同じ速度で動くようにしています。

LineDetectorは前提に記した赤いゾーンオブジェクトに、ObstracleSpawnerは空のオブジェクトにそれぞれアタッチしています。

と、いうことはLineDetectorもプレイヤーに追従して動いているということですよね。

で、LineDetectorのAwakeを見てみると

C#

1cutTakenoko.transform.SetParent(transform);

と書いてあるので、切られたタケノコ(cutTakenoko)たちはLineDetectorの子になってますよね。
ということはプレイ中、非アクティブのcutTakenoko達もLineDetectorと一緒に動いている訳ですよね。

でもタケノコを切られた後の処理に、cutTakenokoのparentを解消する処理が書いてありません。
なので

筍を切った後に表示した倒れた筍の画像が、こちらに来ないでプレイヤーと同じ速度で前に進んでしまう。

という感じになっているのではないでしょうか。

LineDetectorを見る限りは、cutTakenokoが子どもじゃないとダメな理由が見当たらないので、そもそもAwakeでsetParentしないか、もしくはcutTakenkoを表示した後にparentを解除すればいいと思います。

投稿2023/01/20 10:09

編集2023/01/20 10:10
UnchFullburst

総合スコア665

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

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

YA87

2023/01/20 19:12

わかりやすい説明をありがとうございます。 先に書いたObstacleSpawnerクラスの関数を何も考えずコピペしてしまった上に大事なポイントを見落としてしまうという、ひどいケアレスミスでした… それはともかく、回答いただきありがとうございました。
guest

0

cuttakenokoが切られた後の筍ですか?
筍が切られた時の処理は筍側に関数を作って赤いゾーンで呼び出す形にしたほうがわかりやすいと思います

赤いゾーンとcuttakenokoで親子関係を作る理由はなんでしょうか?

投稿2023/01/18 00:18

Sobasenbei

総合スコア132

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

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

YA87

2023/01/20 19:06

ObstacleSpawnerクラスから何も考えずそのままコピペしてしまって、赤いゾーンと親子関係ができていることを失念していました… 結局Sobasenbeiさんの言うように筍側に処理を作ることで解決しました。 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.45%

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

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

質問する

関連した質問