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

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

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

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

Unity

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

Q&A

解決済

1回答

2227閲覧

Unity2D 目的地へ移動出来ない

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Unity

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

0グッド

0クリップ

投稿2018/05/17 16:44

編集2018/05/17 16:47

foodsの配列で"Food"というタグがついたオブジェクトを取得し、自分自身と"Food"というタグがついたオブジェクトとの距離をVecotr3.Distanseで取得。
そのあと、"Food"タグがついたオブジェクトととの距離が5以下、もしくは15以下になったら、targetを距離内にあるオブジェクトに変更するようにしています。
距離が15より大きい場合は、ランダムで位置を指定して移動するようにしていますが、なぜか、少し動いたあと、その場所で立ち往生してしまいます。
移動しているときに、"Food"タグがついたオブジェクトの傍を通りかかっても、targetがそのオブジェクトに変更されません。
Enemyスクリプトがアタッチされているオブジェクトは別のスクリプトで30体、"Food"タグがついたオブジェクトは、100個から200個までランダムで生成しています。

どのようにすれば距離内にあるオブジェクトまで移動出来るようになるでしょうか?
オブジェクト近くを通りかかったとき、taegetをそのオブジェクトに変更する方法とランダムな位置に移動する方法も、もしよろしければ教えていただきたいです。
回答よろしくお願いします。

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 public float dis; 13 private bool OK; 14 public GameObject game; 15 16 // Use this for initialization 17 protected override void Start() 18 { 19 GameManager.instance.AddEnemyToList(this); 20 21 base.Start(); 22 23 empty = GetComponent<Statistics>(); 24 } 25 26 private void Update() 27 { 28 GameObject[] foods = GameObject.FindGameObjectsWithTag("Food"); 29 foreach (GameObject food in foods) 30 { 31 dis = Vector3.Distance(transform.position, food.transform.position); 32 if (dis < 6) 33 { 34 target = food.transform; 35 }else if(dis < 16) 36 { 37 target = food.transform; 38 } 39 if(dis > 15) 40 { 41 OK = true; 42 if(OK == true) 43 { 44 float x = Random.Range(4, 104); 45 float y = Random.Range(4, 104); 46 game.transform.position = new Vector3(x, y, 0); 47 target = game.transform; 48 OK = false; 49 } 50 } 51 if(dis == 0) 52 { 53 OK = true; 54 } 55 } 56 57 if (empty.HP <= 0) 58 { 59 GameManager.instance.RemoveEnemyToList(this); 60 Destroy(gameObject); 61 } 62 } 63 64 protected override void AttemptMove<T>(int xDir, int yDir) 65 { 66 empty = GetComponent<Statistics>(); 67 empty.HP--; 68 //Call the AttemptMove function from MovingObject. 69 base.AttemptMove<T>(xDir, yDir); 70 } 71 72 //MoveEnemy is called by the GameManger each turn to tell each Enemy to try to move towards the player. 73 public void MoveEnemy() 74 { 75 //Declare variables for X and Y axis move directions, these range from -1 to 1. 76 //These values allow us to choose between the cardinal directions: up, down, left and right. 77 int xDir = 0; 78 int yDir = 0; 79 80 //If the difference in positions is approximately zero (Epsilon) do the following: 81 if (Mathf.Abs(target.position.x - transform.position.x) < float.Epsilon) 82 83 //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). 84 yDir = target.position.y > transform.position.y ? 1 : -1; 85 86 87 //If the difference in positions is not approximately zero (Epsilon) do the following: 88 else 89 //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). 90 xDir = target.position.x > transform.position.x ? 1 : -1; 91 92 //Call the AttemptMove function and pass in the generic parameter Player, because Enemy is moving and expecting to potentially encounter a Player 93 AttemptMove<Food>(xDir, yDir); 94 95 } 96 97 private void OnTriggerEnter2D(Collider2D other) 98 { 99 if(other.tag == "Food") 100 { 101 Food food = other.gameObject.GetComponent<Food>(); 102 other.gameObject.SetActive(false); 103 if (food.apple == true) 104 { 105 empty.HP += food.pointsPerapple; 106 } 107 if (food.apricot == true) 108 { 109 empty.HP = food.pointsPerapricot; 110 } 111 if (food.banana == true) 112 { 113 empty.HP = food.pointsPerbanana; 114 } 115 if (food.choko == true) 116 { 117 empty.HP = food.pointsPerchoko; 118 } 119 if (food.pear == true) 120 { 121 empty.HP = food.pointsPerpear; 122 } 123 } 124 } 125 126 protected override void OnCantMove<T>(T component) 127 { 128 129 } 130 131} 132

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

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

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

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

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

guest

回答1

0

ベストアンサー

このコードだと毎フレーム(の更にforeachの中で)ターゲットを切り替えます。

Food-1:範囲内ならtarget=Food-1。範囲外ならtarget=game。 Food-2:範囲内ならtarget=Food-2。範囲外ならtarget=game。 Food-3:範囲内ならtarget=Food-3。範囲外ならtarget=game。 ... 以下「全てのFoodタグが付いたオブジェクト」に対し行われる。

上記が毎フレーム実行されることになり、MoveEnemyの呼ばれるタイミングが不安定なら1フレーム毎にターゲットが切り替わることになります。移動するにもその余裕すら無く、結局立ち止まっているものかと。
(逆にMoveEnemyが毎回Updateの最後で呼ばれているなら、「foodsの末尾のオブジェクト or gameオブジェクト」がターゲットになるので比較的安定しそうではある)

ほぼ確実に呼ばれない行if(dis == 0)(disはfloatなのできっかり0になる可能性は非常に低い)や
意味の無いif文if(dis > 15)の中のOK=true; if(OK == true)もあるので、
今一度全体的に見直してみた方がいいと思います。

投稿2018/05/18 04:23

編集2018/05/18 04:26
sakura_hana

総合スコア11425

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

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

退会済みユーザー

退会済みユーザー

2018/05/18 07:34

回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問