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

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

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

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

Unity

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

Q&A

解決済

1回答

5296閲覧

Unity2D ランダムなTransformを取得する方法

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Unity

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

0グッド

0クリップ

投稿2018/05/18 15:11

編集2018/05/18 18:31

ランダムなTransformを取得して、targetに入れたいのですが、方法が分かりません。
試した方法は、

C#

1public GameObject obj; 2public Transform target; 3protected override void Start() 4{ 5 int x = Random.Range(4,104); 6 int y = Random.Range(4,104); 7 obj.transform.position = new Vecotor3(x,y,0); 8 target = obj.transform; 9}

をやってみましたが、多少は動くのですが、現在位置と隣のマスを行き来するだけで、きちんと動きませんでした。

C#

1public Transform target; 2protected override void Start() 3{ 4 target = GameObject.FindGameObjectWithTag ("Food").transform; 5}

もやってみました。ですが、30体生成しているオブジェクトのほとんどが、Foodオブジェクトを百個以上生成しているのに、みな、同一のFoodオブジェクトの所に向かってしまい、動きにランダム性が見られなくなってしまいました。
もしランダムなTransformを取得する方法があれば、教えて欲しいです。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.SceneManagement; 5 6public class Enemy : MovingObject 7{ 8 public Transform target; 9 private Statistics empty; 10 11 private Statistics statistics; 12 13 public Vector3 enemypositoon; 14 15 // Use this for initialization 16 protected override void Start() 17 { 18 GameManager.instance.AddEnemyToList(this); 19 20 base.Start(); 21 22 empty = GetComponent<Statistics>(); 23 } 24 25 private void Update() 26 { 27 if (empty.HP <= 0) 28 { 29 GameManager.instance.RemoveEnemyToList(this); 30 Destroy(gameObject); 31 } 32 33 enemypositoon = transform.position; 34 } 35 36 protected override void AttemptMove<T>(int xDir, int yDir) 37 { 38 empty = GetComponent<Statistics>(); 39 empty.HP--; 40 //Call the AttemptMove function from MovingObject. 41 base.AttemptMove<T>(xDir, yDir); 42 } 43 44 //MoveEnemy is called by the GameManger each turn to tell each Enemy to try to move towards the player. 45 public void MoveEnemy() 46 { 47 //Declare variables for X and Y axis move directions, these range from -1 to 1. 48 //These values allow us to choose between the cardinal directions: up, down, left and right. 49 int xDir = 0; 50 int yDir = 0; 51 52 //If the difference in positions is approximately zero (Epsilon) do the following: 53 if (Mathf.Abs(target.position.x - transform.position.x) < float.Epsilon) 54 55 //If the y coordinate of the target's (player) position is greater than the y coordinate of this enemy's position set y direction 1 (to move up). If not, set it to -1 (to move down). 56 yDir = target.position.y > transform.position.y ? 1 : -1; 57 58 59 //If the difference in positions is not approximately zero (Epsilon) do the following: 60 else 61 //Check if target x position is greater than enemy's x position, if so set x direction to 1 (move right), if not set to -1 (move left). 62 xDir = target.position.x > transform.position.x ? 1 : -1; 63 64 //Call the AttemptMove function and pass in the generic parameter Player, because Enemy is moving and expecting to potentially encounter a Player 65 AttemptMove<Food>(xDir, yDir); 66 67 } 68 69 private void OnTriggerEnter2D(Collider2D other) 70 { 71 if(other.tag == "Food") 72 { 73 target = other.transform; 74 } 75 } 76 77 protected override void OnCantMove<T>(T component) 78 { 79 80 } 81 82} 83

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

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

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

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

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

guest

回答1

0

ベストアンサー

回答1

1つめのコード、以下のようにしてみてみたらどうでしょうか。

C#

1public Transform target; 2protected override void Start() 3{ 4 int x = Random.Range(4,104); 5 int y = Random.Range(4,104); 6 target.position = new Vecotor3(x,y,0); 7}

回答2

全く別の物ですが、ランダムなターゲットに向かうスクリプトを書いてみました。ご参考まで。
参考動画

C#

1using UnityEngine; 2 3// Enemy オブジェクトにアタッチする 4public class MoveToRandomTarget : MonoBehaviour 5{ 6 // シーン上に配置されているすべてのFoodオブジェクト 7 private GameObject[] foods; 8 9 // 向かう先 10 private Transform target; 11 12 private void Start () 13 { 14 // シーン上の、"Food"タグの付けられたオブジェクトをすべて取得する 15 foods = GameObject.FindGameObjectsWithTag ( "Food" ); 16 17 SelectRandomTarget (); 18 } 19 20 // ランダムにターゲットを選ぶ 21 private void SelectRandomTarget () 22 { 23 target = foods[Random.Range ( 0, foods.Length )].transform; 24 } 25 26 27 // 以下は移動の例 28 29 private void FixedUpdate () 30 { 31 GoToTarget (); 32 33 // 左クリックで新たなターゲットを選択 34 if ( Input.GetMouseButtonDown ( 0 ) ) 35 { 36 SelectRandomTarget (); 37 } 38 } 39 40 private void GoToTarget () 41 { 42 transform.position = Vector3.Lerp ( transform.position, target.position, 0.01f ); 43 } 44} 45

投稿2018/05/18 15:24

編集2018/05/19 06:44
negitama

総合スコア943

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

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

退会済みユーザー

退会済みユーザー

2018/05/18 15:30

UnassignedReferenceException: The variable target of Enemy has not been assigned. You probably need to assign the target variable of the Enemy script in the inspector. 試してみましたが、 target.position = new Vecotor3(x,y,0);がエラーになりました。 targetに、なにもアサインされていないためだと思います。
negitama

2018/05/18 15:37 編集

そのとおりですね。 target は public な変数だったので、インスペクターからでもセットしてあるのかなと推測していました。 Hierarchyビュー上に空のゲームオブジェクトを作成し、インスペクターの target にそのオブジェクト(のTransform)をセットすればよいのではないでしょうか。
退会済みユーザー

退会済みユーザー

2018/05/18 15:48

Enemyスクリプトがアサインされているオブジェクトは全てプレハブなので、Unityの仕様上、オブジェクトのTransformをセットすることが出来ませんでした。
negitama

2018/05/18 16:10

では、空のゲームオブジェクトに何かタグを付けて、Start()内で target = GameObject.FindWithTag("TagName").transform; のようにして取得してみてはいかがでしょうか。
退会済みユーザー

退会済みユーザー

2018/05/18 16:19

やってみましたが、反復横跳びのように、同じ場所を行ったり来たりするだけでした。なぜ、そうなるのかはいまいち分かりません。
negitama

2018/05/18 16:24

target.transform を参照している行をひとつずつ // でコメントアウトするなどして、悪さをしている箇所がないかチェックしてみてはいかがでしょうか。 これは質問者さんが書いたスクリプトではなく、アセットか何かに含まれているものですか?
negitama

2018/05/18 16:58

・元のチュートリアルから書き換えた箇所はどこなのでしょうか ・「"Food"タグがついている同じオブジェクトの所に向かってしまい、動きにランダム性が見られなくなった」とありますが、どうなれば正解なのでしょうか。Foodに向かう動作とランダムな動作をどう両立させたいのでしょうか
退会済みユーザー

退会済みユーザー

2018/05/18 18:24

元のチュートリアルから書き換えた箇所は、主にPlayerのスクリプトで、それを生成しているFoodにアサインしています。Foodは動きません。FoodとEnemyのターンが交互に行われるようになっています。 ランダム性が見られなくなった、というのは、Foodを百個ほど生成しているのに、Enemyのほとんどが、同じFoodの元へ向かってしまうということです。
negitama

2018/05/19 06:20 編集

Foodが複数あるのですね。GameObject.FindWithTagではそのなかのひとつしか見つけないため、同じFoodに向かうことになります。 まずは GameObject[] foods = GameObject.FindGameObjectsWithTag("Food"); のようにしてシーン上のすべてのFoodを取得し、その後ターゲットに割り当てる際に target = foods[Random.Range(0, foods.Length)].transform; のようにしてランダムに選ぶ、というのではどうでしょうか。
negitama

2018/05/19 06:49

質問者さんの作られているものの全体像や各変数の位置づけなどが把握しきれていないため、回答2としてこちらで書いてみたスクリプトと参考動画を載せてみました。ご参考まで。
退会済みユーザー

退会済みユーザー

2018/05/19 08:30

やってみたのですが、Foodの数が少なくなってくると、その場で立ち止まってしまい、動かないという現象が出て来てしまいます。
negitama

2018/05/19 08:35

現在のtarget以外から次のtargetを選択するようにしたとしても、Foodがなくなれば行先がなくなるので当然そうなるのではないでしょうか。 それはタイトルの質問とは別の問題かと思います。
退会済みユーザー

退会済みユーザー

2018/05/19 08:53 編集

Foodは一応残っているのですが……。回答ありがとうございました。
退会済みユーザー

退会済みユーザー

2018/05/19 09:00

その場で立ち止まるのは、コライダー同士がぶつかっているからでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問