障害物を避けるように、発射した球の弾道を逸してみました。
まずプレイヤーの正面へ球を飛ばします。
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秒後に破壊されるようにしています。
床以外の障害物をタグで判別しています。
逸らすときの力より発射するときの方が強いので、まっすぐ障害物に飛ばすと障害物に衝突しますが、横を通過するように飛ばすと障害物を避けて弾道が変わります。