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

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

ただいまの
回答率

87.48%

2Dゲームにおける索敵が作動しない

解決済

回答 1

投稿

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

Unityで2DRPGゲームを作っております。今現在、普段は特定の地点を巡回し続けるが、視界判定内に主人公が入った場合、それを追いかける設定の敵キャラクターを製作しています。またその際、主人公が壁の裏に隠れれば、敵がこちらを見失う設定にしたいとも考えております。しかし、敵が追いかけるかどうか判別するためのプログラミングが上手く作動せず、困っております。追いかける条件として(1)特定の距離内(trackingRange)に主人公が入る(2)敵前方に広がる一定の角度内(ChaseRange)に主人公が入った場合(3)敵と主人公の間に障害物がない、この三つを設定しております。どこが問題なのか、ご教授いただければ幸いです。

using UnityEditor.UI;
using UnityEngine;
//NavMeshAgent使うときに必要

//オブジェクトにNavMeshAgentコンポーネントを設置
[RequireComponent(typeof(NavMeshAgent2D))]

public class OnlyFowardSsarch : MonoBehaviour
{
    GameObject seenGameObject;
    public Transform[] points;
    public float speedDown;
    public float speedUp;
    public float ChaseRange;
    // このキャラの進行方向
    public float chaseAngle;
    // プレイヤーの進行方向
    public float playerAngle;
    [SerializeField] int destPoint = 0;
    // 前回のベクトル
    public Vector2 prev;
    // 前回との差分
    public Vector2 diff;
    public Vector2 diffPlayer;
    private NavMeshAgent2D agent;
    Vector3 playerPos;
    GameObject player;
    float distance;
    [SerializeField] float trackingRange = 3f;
    [SerializeField] float quitRange = 5f;
    [SerializeField] bool tracking = false;
    GameObject[] fireUnits = GameObject.FindGameObjectsWithTag("Unit");

    // 向きベクトル
    public float AngleDir()
    {
        return transform.eulerAngles.z * (Mathf.PI / 180.0f);
    }

    // 角度からベクトルを算出
    public Vector2 GetVector(Vector3 center,float angle)
    {
        float x = Mathf.Cos(angle) + center.x;
        float y = Mathf.Sin(angle) + center.y;
        return new Vector2(x, y);
    }

    public float GetAngle(Vector2 start, Vector2 target)
    {
        Vector2 dt = target - start;
        float rad = Mathf.Atan2(dt.y, dt.x);
        float degree = rad * Mathf.Rad2Deg;

        return degree;
    }



    void Start()
    {
        agent = GetComponent<NavMeshAgent2D>();
        prev = transform.position;

        // autoBraking を無効にすると、目標地点の間を継続的に移動します
        //(つまり、エージェントは目標地点に近づいても
        // 速度をおとしません)
        agent.autoBraking = false;

        GotoNextPoint();

        //追跡したいオブジェクトの名前を入れる
        player = GameObject.Find("主人公");
    }

    void GotoNextPoint()
    {
        // 地点がなにも設定されていないときに返します
        if (points.Length == 0)
            return;

        // エージェントが現在設定された目標地点に行くように設定します
        agent.destination = points[destPoint].position;

        // 配列内の次の位置を目標地点に設定し、
        // 必要ならば出発地点にもどります
        destPoint = (destPoint + 1) % points.Length;
    }

    void Update()
    {
        float diffX = this.transform.position.x - prev.x;
        float diffY = this.transform.position.y - prev.y;
        diff = new Vector2(diffX, diffY).normalized;
        Debug.Log("敵の向き" );
        //Playerとこのオブジェクトの前回フレームを保存
        prev = this.transform.position;
        //Playerとこのオブジェクトの距離を測る
        fireUnits = GameObject.FindGameObjectsWithTag("Unit");
        playerPos = player.transform.position;
        Transform agentTransform = this.transform;
        Vector2 agentState = agentTransform.position;
        Transform playerTransform = player.transform;
        Vector2 playerState = playerTransform.position;
        distance = Vector2.Distance(this.transform.position, playerPos);
        RaycastHit2D hit = Physics2D.Linecast(agentState, playerState);
        chaseAngle = Mathf.Atan2(diff.y, diff.x) * 180.0f / Mathf.PI;

        if (hit)
        {
            seenGameObject = hit.transform.gameObject;
        }

        Debug.Log(seenGameObject);
        string seentarget = seenGameObject.name;

        if (tracking)
        {
            // 追跡の時、quitRangeより距離が離れたら中止
            // 目的地まで来たら一時中止
            if (distance > quitRange || seentarget != "主人公" && !seentarget.Contains("HumanSoul_0")
                || chaseAngle >= (ChaseRange + chaseAngle) && chaseAngle >= (chaseAngle + chaseAngle))
                tracking = false;

            //Playerを目標とする
            agent.destination = playerPos;
            agent.speed = speedUp;
        }
        else
        {
            //PlayerがtrackingRangeより近づいたら追跡開始
            if (distance < trackingRange && seentarget == "主人公" && (ChaseRange + chaseAngle) < chaseAngle && chaseAngle < (ChaseRange - chaseAngle))
                tracking = true;
            agent.speed = speedDown;

            // エージェントが現目標地点に近づいてきたら、
            // 次の目標地点を選択します
            if (!agent.pathPending && agent.remainingDistance < 0.5f)
                GotoNextPoint();
        }
    }

ヘディングのテキスト

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • Tto777

    2020/08/18 15:05

    https://teratail.com/questions/285403
    こちらのBAで解決出来たようなのでこちらの質問は自己解決などでクローズしておいて下さい。

    https://teratail.com/questions/284987
    こちらもお願いします。

    キャンセル

回答 1

check解決した方法

0

敵の向いている方向とプレイヤーとの差分に対して、一定距離内にいるか、内積して一定の角度内にいるかを判定するスクリプトを製作し、解決。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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