ナビメッシュエージェントに玉を当てて物理的に吹き飛ばす

投稿者: | 2019-12-19

ナビメッシュエージェントは専用のコンポーネントを取り付けて、目的地の座標に向かって動かすので、Rigidbodyをつけたときは、isKinematicのチェックをオンにして、物理的に動かせないようにしておかないといけません。

このエージェントに玉を当てて物理的に動かす方法を考えてみました。
まずはエージェントをランダムで動かして、玉があたったときにNavMeshAgentコンポーネントを無効にして、RigidbodyのisKinematicをスクリプトからオフにしてみました。

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

public class agentScript2 : MonoBehaviour
{
    NavMeshAgent agent;
    Rigidbody rb;


    // Start is called before the first frame update
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        agent.destination = new Vector3(Random.Range(-25f,25f),0f,Random.Range(-25f,25f));

        rb = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        if (agent.enabled && !agent.pathPending && agent.remainingDistance < 0.5f)
        {
            agent.destination = new Vector3(Random.Range(-25f,25f),0f,Random.Range(-25f,25f));
            agent.speed = Random.Range(15,40);
        }
           
    }

    private void OnCollisionEnter(Collision collision)
    {
        agent.enabled = false;
        rb.isKinematic = false;
        
    }
}


最初に玉が衝突したときには、動きが止まるだけで、2回めで物理的に吹き飛ばされます。
1回めで吹き飛ばされてほしいです。

OnCollisionEnterでは Collision型の変数に衝突の情報が入っていますが、これには衝突時の相対的な速度や推進力を表すプロパティがあるようです。
参考:https://docs.unity3d.com/jp/current/ScriptReference/Collision.html

今回はCollision.impulseを使ってみます。

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


public class agentScript2 : MonoBehaviour
{
    NavMeshAgent agent;
    Rigidbody rb;

    bool hit;

    // Start is called before the first frame update
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        agent.destination = new Vector3(Random.Range(-25f,25f),0f,Random.Range(-25f,25f));

        rb = GetComponent<Rigidbody>();
        hit = false;
    }

    // Update is called once per frame
    void Update()
    {
        if (agent.enabled && !agent.pathPending && agent.remainingDistance < 0.5f)
        {
            agent.destination = new Vector3(Random.Range(-25f,25f),0f,Random.Range(-25f,25f));
            agent.speed = Random.Range(15,40);
        }

        if (Input.GetKeyDown(KeyCode.R))
        {
            SceneManager.LoadScene("Shoot");
        }

           
    }

    private void OnCollisionEnter(Collision collision)
    {       

        agent.enabled = false;
        rb.isKinematic = false;

        if (!hit) {
            rb.AddForce(collision.impulse, ForceMode.Impulse);

            hit = true;
        }
    }
}

エージェントに玉が衝突して、isKinematicをオフにした後に、collision.impulse の力をAddForceでエージェントに加えています。
念の為にAddForceが一度だけ使われるようにしています。

すると、エージェントが逆方向に吹っ飛びます。

collision.impulseを -collision.impulseにすると良くなりました。

コメントを残す

メールアドレスが公開されることはありません。