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

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

ただいまの
回答率

90.51%

  • C#

    7137questions

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

  • Unity

    4018questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • Unity2D

    888questions

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

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 385

t2t21212

score 29

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

public GameObject obj;
public Transform target;
protected override void Start()
{
 int x = Random.Range(4,104);
 int y = Random.Range(4,104);
 obj.transform.position = new Vecotor3(x,y,0);
 target = obj.transform;
}


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

public Transform target;
protected override void Start()
{
 target = GameObject.FindGameObjectWithTag ("Food").transform;
}


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

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Enemy : MovingObject
{
    public Transform target;
    private Statistics empty;

    private Statistics statistics;

    public Vector3 enemypositoon;

    // Use this for initialization
    protected override void Start()
    {
        GameManager.instance.AddEnemyToList(this);

        base.Start();

        empty = GetComponent<Statistics>();
    }

    private void Update()
    {
        if (empty.HP <= 0)
        {
            GameManager.instance.RemoveEnemyToList(this);
            Destroy(gameObject);
        }

        enemypositoon = transform.position;
    }

    protected override void AttemptMove<T>(int xDir, int yDir)
    {
        empty = GetComponent<Statistics>();
        empty.HP--;
        //Call the AttemptMove function from MovingObject.
        base.AttemptMove<T>(xDir, yDir);
    }

    //MoveEnemy is called by the GameManger each turn to tell each Enemy to try to move towards the player.
    public void MoveEnemy()
    {
            //Declare variables for X and Y axis move directions, these range from -1 to 1.
            //These values allow us to choose between the cardinal directions: up, down, left and right.
            int xDir = 0;
            int yDir = 0;

            //If the difference in positions is approximately zero (Epsilon) do the following:
            if (Mathf.Abs(target.position.x - transform.position.x) < float.Epsilon)

                //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).
                yDir = target.position.y > transform.position.y ? 1 : -1;


            //If the difference in positions is not approximately zero (Epsilon) do the following:
            else
                //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).
                xDir = target.position.x > transform.position.x ? 1 : -1;

            //Call the AttemptMove function and pass in the generic parameter Player, because Enemy is moving and expecting to potentially encounter a Player
            AttemptMove<Food>(xDir, yDir);

    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        if(other.tag == "Food")
        {
            target = other.transform;
        }
    }

    protected override void OnCantMove<T>(T component)
    {

    }

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

 回答1

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

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

 回答2

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

using UnityEngine;

// Enemy オブジェクトにアタッチする
public class MoveToRandomTarget : MonoBehaviour
{
    // シーン上に配置されているすべてのFoodオブジェクト
    private GameObject[] foods;

    // 向かう先
    private Transform target;       

    private void Start ()
    {
        // シーン上の、"Food"タグの付けられたオブジェクトをすべて取得する
        foods = GameObject.FindGameObjectsWithTag ( "Food" );

        SelectRandomTarget ();
    }

    // ランダムにターゲットを選ぶ
    private void SelectRandomTarget ()
    {
        target = foods[Random.Range ( 0, foods.Length )].transform;
    }


    // 以下は移動の例

    private void FixedUpdate ()
    {
        GoToTarget ();

        // 左クリックで新たなターゲットを選択
        if ( Input.GetMouseButtonDown ( 0 ) )
        {
            SelectRandomTarget ();
        }
    }

    private void GoToTarget ()
    {
        transform.position = Vector3.Lerp ( transform.position, target.position, 0.01f );
    }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/19 00: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に、なにもアサインされていないためだと思います。

    キャンセル

  • 2018/05/19 00:33 編集

    そのとおりですね。
    target は public な変数だったので、インスペクターからでもセットしてあるのかなと推測していました。

    Hierarchyビュー上に空のゲームオブジェクトを作成し、インスペクターの target にそのオブジェクト(のTransform)をセットすればよいのではないでしょうか。

    キャンセル

  • 2018/05/19 00:48

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

    キャンセル

  • 2018/05/19 01:10

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

    キャンセル

  • 2018/05/19 01:19

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

    キャンセル

  • 2018/05/19 01:24

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

    キャンセル

  • 2018/05/19 01:32

    https://unity3d.com/jp/learn/tutorials/s/2d-roguelike-tutorial

    ↑Unity2D Roguelike tutorialというチュートリアルのスクリプトを、自分の作りたいゲームに合うように書き換えたり、書き加えたものです。

    キャンセル

  • 2018/05/19 01:58

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

    キャンセル

  • 2018/05/19 03:24

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

    キャンセル

  • 2018/05/19 14:53 編集

    Foodが複数あるのですね。GameObject.FindWithTagではそのなかのひとつしか見つけないため、同じFoodに向かうことになります。
    まずは

    GameObject[] foods = GameObject.FindGameObjectsWithTag("Food");

    のようにしてシーン上のすべてのFoodを取得し、その後ターゲットに割り当てる際に

    target = foods[Random.Range(0, foods.Length)].transform;

    のようにしてランダムに選ぶ、というのではどうでしょうか。

    キャンセル

  • 2018/05/19 15:49

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

    キャンセル

  • 2018/05/19 17:30

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

    キャンセル

  • 2018/05/19 17:35

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

    キャンセル

  • 2018/05/19 17:52 編集

    Foodは一応残っているのですが……。回答ありがとうございました。

    キャンセル

  • 2018/05/19 18:00

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

    キャンセル

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

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    7137questions

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

  • Unity

    4018questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • Unity2D

    888questions