@hasegawadesu (hasegawa)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Unity C# ランゲーム:敵の攻撃の狙いをランダムにする方法について!!

こんにちは、連日 Qiitaで質問させて頂いてます。はせがわです。

また、皆さんのお力をお借りしたく質問させて頂きます。

今作っている物

Unityで
「盾一枚で依頼人を敵の攻撃から守りながらゴールまで送り届けるランゲーム」
を作っています。

aaaaa.png

プレイヤーは、自動前進で敵がPlayerまたは依頼人を狙って放物線上に飛んできます。
※現状は、playerのみをターゲットにしています。

実現したい事

敵の攻撃は、3パターン作り、そのパターンをランダムで実行したいと思っています
パターン1は、プレイヤーをそのまま狙ってくるパターン
パターン2は、依頼人を狙ってくるパターン
パターン3は、下記のペライチのような、ランダム範囲で攻撃してくる
無題のプレゼンテーション.jpg

しかし、現状 Z軸が動いてしまい、盾の後ろの方にターゲットが移動してしまいます。
※現在、ターゲットは、プレイヤーの前身移動速度を考慮して、盾の少し前に設定しています。
 Z位置は、そこで固定して YとX軸だけでターゲットがばらついてほしいと思っています。

【参考動画】
https://youtu.be/-LhvG5ULkfk

クリアしたい課題

・3つ目の ランダム攻撃が実装できません。
 どうか、お力を貸してください。。。

[Github]
https://github.com/hasegawadesu/ShieldRunner-VR-.git

[射出Code]

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

public class throwingscript : MonoBehaviour
{


    //☆
    private float InstantiationTimer = 0f;
    // ターゲットオブジェクトの Transformコンポーネントを格納する変数
    public Transform target;//☆
    // オブジェクトの移動速度を格納する変数
    public float moveSpeed;//☆
    // オブジェクトが停止するターゲットオブジェクトとの距離を格納する変数
    public float stopDistance;//☆
    // オブジェクトがターゲットに向かって移動を開始する距離を格納する変数
    public float moveDistance;//☆  

    //<summary>
    //testtest
    //射出するオブジェクト
    //</summary>
    [SerializeField, Tooltip("ThrowingObject")]
    private GameObject ThrowingObject=null;

    //<summary>
    //標的のオブジェクト
    //</summary>
    [SerializeField, Tooltip("TargetObject")]
    private GameObject TargetObject=null;

    //<summary>
    //射出角度
    //</summary>
    [SerializeField, Range(0F,90F), Tooltip("ThrowingAngle")]
    private float ThrowingAngle=0;

    // Start is called before the first frame update
    private void Start()
    {
     Collider collider = GetComponent<Collider>();
     if(collider != null)
     {
         //干渉しないようにisTriggerをつける 
         collider.isTrigger = true;
     }   
    }

    // Update is called once per frame
    void Update()
    {

     // ゲーム実行中に毎フレーム実行する処理

        //☆ 変数 targetPos を作成してターゲットオブジェクトの座標を格納
        Vector3 targetPos = target.position;//☆
        // 自分自身のY座標を変数 target のY座標に格納
        //(ターゲットオブジェクトのX、Z座標のみ参照)
        targetPos.y = transform.position.y;//☆
        // オブジェクトを変数 targetPos の座標方向に向かせる
        transform.LookAt(targetPos);//☆

        // 変数 distance を作成してオブジェクトの位置とターゲットオブジェクトの距離を格納
        float distance = Vector3.Distance(transform.position, target.position);//☆
        // オブジェクトとターゲットオブジェクトの距離判定
        // 変数 distance(ターゲットオブジェクトとオブジェクトの距離)が変数 moveDistance の値より小さければ
        // さらに変数 distance が変数 stopDistance の値よりも大きい場合



        if (this.transform.position.z-15 < target.transform.position.z)
        {
            Destroy(gameObject);
        }

        else if (distance < moveDistance && distance > stopDistance)//☆
        {
            ThrowingBall();
        }

    }
    //<summary>
    //ボールを射出する
    //</summary>
    private void ThrowingBall()
    {
        InstantiationTimer -= Time.deltaTime;
        if (ThrowingObject !=null && TargetObject !=null && InstantiationTimer <0)
        {
            //Ballオブジェクトの生成
            GameObject ball = Instantiate(ThrowingObject, this.transform.position, Quaternion.identity);
            InstantiationTimer =2f;

            //標的の座標
            float x = Random.Range(0.0f, 2.0f);
      float y = Random.Range(0.0f, 2.0f);
            float z = Random.Range(0.0f, 2.0f);
           Vector3 targetPosition = TargetObject.transform.position;
           TargetObject.transform.position = new Vector3(x, y, z);

            //射出角度
            float angle = ThrowingAngle;

            //射出速度を算出
            Vector3 velocity = CalculateVelocity(this.transform.position, targetPosition, angle);

            //射出
            Rigidbody rid = ball.GetComponent<Rigidbody>();
            rid.AddForce(velocity * rid.mass, ForceMode.Impulse);
        }


            }

    //<summary>
    //標的に命中する射出速度の清算
    //</summary>
    //<param name="pointA">射出開始座標</param>
    //<param name="pointB">標的の座標</param>
    //<returns>射出速度</returns>
    private Vector3 CalculateVelocity(Vector3 pointA, Vector3 pointB, float angle)
    {
        //射出角をラジアンに変換
        float rad = angle * Mathf.PI / 180;

        //水平方向の距離x
        float x = Vector2.Distance(new Vector2(pointA.x,pointA.z),new Vector2(pointB.x, pointB.z));

        //垂直方向の距離y
        float y = pointA.y - pointB.y;

        //斜方投射のこうしきを初速度について解く
        float speed = Mathf.Sqrt(-Physics.gravity.y * Mathf.Pow(x,2)/(2*Mathf.Pow(Mathf.Cos(rad),2)*(x * Mathf.Tan(rad)+y)));

        if(float.IsNaN(speed))
        {
            //条件を満たす初速を算出できなければVector3.zeroを返す
            return Vector3.zero;
        }
        else
        {
            return (new Vector3(pointB.x - pointA.x, x * Mathf.Tan(rad), pointB.z-pointA.z).normalized*speed);    
        }
    }
}


なにとぞ、よろしくお願いします。

0 likes

1Answer

分析

    float x = Random.Range(0.0f, 2.0f);
    float y = Random.Range(0.0f, 2.0f);
    float z = Random.Range(0.0f, 2.0f);

この3行では、乱数(各座標2未満)で3D(x, y, z)の変位(ずらす)量を生成していますね。

    Vector3 targetPosition = TargetObject.transform.position;

次の1行では、狙うべき標的の位置座標を取り出しています。

    TargetObject.transform.position = new Vector3(x, y, z);

そして、次の行では、標的自体の位置を「変位量」で書き換えています。
ここで、いくつかおかしなことに気付きます。

  • 標的そのものを移動してしまっています。
    • ずらすのは、「標的の位置(TargetObject.transform.position)」ではなくて、「狙う位置(targetPosition )」の方ですよね。
  • 変位量として生成した数値を、座標として使っています。
    • ずらす量なので、position += new Vector3(ではないでしょうか。
  • 固定するはずのZ座標も変更しようとしています。
    • Z座標を固定するなら、new Vector3(x, y, 0f);ではないでしょうか。

変更案

以下の部分に対して、下記のように変更するのはいかがでしょうか。

変更前
    //標的の座標
    float x = Random.Range(0.0f, 2.0f);
    float y = Random.Range(0.0f, 2.0f);
    float z = Random.Range(0.0f, 2.0f);
    Vector3 targetPosition = TargetObject.transform.position;
    TargetObject.transform.position = new Vector3(x, y, z);

変更後
    //標的の座標
    float x = Random.Range(0.0f, 2.0f);
    float y = Random.Range(0.0f, 2.0f);
    Vector3 targetPosition = TargetObject.transform.position + new Vector3(x, y, 0f);;
1Like

Comments

  1. @hasegawadesu

    Questioner

    毎度最速での回答ありがとうございます!
    +にしたところやりたいことに近づけました!

Your answer might help someone💌