【Unity】障害物を避けるように弾道を逸らす

投稿者: | 2020-12-09

障害物を避けるように、発射した球の弾道を逸してみました。

まずプレイヤーの正面へ球を飛ばします。

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

public class Gun : MonoBehaviour
{
    [SerializeField] GameObject ball;
    [SerializeField] float power;


    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            // 球を生成
            GameObject b = Instantiate(ball, transform.position + transform.forward * 2f, ball.transform.rotation);

            // 力を加える
            b.GetComponent<Rigidbody>().AddForce(transform.forward * power, ForceMode.Impulse);
        }
        
    }
}

そして、球のプレハブにつけたスクリプトで、コライダーのcontactOffsetを設定し、衝突する前にOnCollisionEnterが実行されるようにします。

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

public class BallScript : MonoBehaviour
{
    [SerializeField] float contactOffset;
    [SerializeField] float deflectPower;
    Collider coll;

    // Start is called before the first frame update
    void Start()
    {
        coll = GetComponent<Collider>(); // コライダーを取得
        coll.contactOffset = contactOffset; // contactOffsetを設定

        Destroy(gameObject, 8f); // 8秒後に削除
    }

    private void OnCollisionEnter(Collision collision)
    {
        // 障害物に衝突
        if (collision.gameObject.tag == "Obstacle")
        {
            // 力の方向
            Vector3 dir = Vector3.Normalize(transform.position - collision.collider.ClosestPoint(transform.position));

            // 力を加える
            coll.attachedRigidbody.AddForce(dir * deflectPower, ForceMode.Impulse);
        }
    }

}

その中で、障害物のコライダーの表面上で指定の位置から最も近い点(Collider.ClosestPoint)から、球への方向に力を加えて弾道を変えています。また、スタートでDestroy()を呼んで球が8秒後に破壊されるようにしています。

床以外の障害物をタグで判別しています。

逸らすときの力より発射するときの方が強いので、まっすぐ障害物に飛ばすと障害物に衝突しますが、横を通過するように飛ばすと障害物を避けて弾道が変わります。

コメントを残す

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