重要なお知らせ:誠に勝手ながら当サイト(unityroom質問掲示板)は2021年10月31日をもちまして閉鎖させていただきます。ご利用誠にありがとうございました。

unityroom.com については引き続きご利用いただけます。

0 支持
273 閲覧

こんにちは。Unityでゲームを作っていますがまだ右も左もわからないペーペーです。

今回、ブロック崩しゲームを作成しているときにボールが水平方向や垂直方向に動き、壁を沿ってゲームにならない問題が発生しました。

初め、ボールに初速を持たせるために

void Start()
    {
        transform.eulerAngles = new Vector3(0, Random.Range(30, 120), 0);
        gameObject.GetComponent<Rigidbody>().AddForce(transform.forward * 500);   
    }

として、オブジェクトに力を加えました。
その次にRigidbodyコンポーネントを追加してから、SphereColiderで摩擦を消し、弾性力も1に直して、なんとかボールは絶えず動いています。

ここで、壁を沿う問題が発生するようになったため次のようにスクリプトを追加しました。

<以下現在のスクリプト>

public class StartShot : MonoBehaviour
{
    Rigidbody rb;

    float limitVerticalDeg = 10f;   // 垂直方向は 90 ± 10 度、270 ± 10 度の範囲の角度は近いほうに寄せる。
    float limitHorizontalDeg = 45f; // 水平方向は 0 ± 45 度、 180 ± 45 度の範囲の角度は近いほうに寄せる。

    // Start is called before the first frame update
    void Start()
    {     
        transform.eulerAngles = new Vector3(0, Random.Range(30, 120), 0);
        gameObject.GetComponent<Rigidbody>().AddForce(transform.forward * 500);
    }


    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            Vector3 playerPos = collision.transform.position;

            Vector3 ballPos = transform.position;

            Vector3 direction = (ballPos - playerPos).normalized;

            float speed = rb.velocity.magnitude;

            rb.velocity = direction * speed;
        }
    }

    private void FixedUpdate()
    {
        rb = this.gameObject.GetComponent<Rigidbody>();
        
        Vector3 velocityNormalized = rb.velocity.normalized;
        
        if (velocityNormalized.x >= 0f)
        {
            velocityNormalized.x = Mathf.Clamp(velocityNormalized.x, Mathf.Cos(Mathf.Deg2Rad * (90 - limitVerticalDeg)), Mathf.Cos(Mathf.Deg2Rad * (0 + limitHorizontalDeg)));
        }
        else
        {
            velocityNormalized.x = Mathf.Clamp(velocityNormalized.x, Mathf.Cos(Mathf.Deg2Rad * (180 - limitHorizontalDeg)), Mathf.Cos(Mathf.Deg2Rad * (90 + limitVerticalDeg)));
        }

        if (velocityNormalized.z >= 0f)
        {
            velocityNormalized.z = Mathf.Clamp(velocityNormalized.z, Mathf.Sin(Mathf.Deg2Rad * (180 - limitHorizontalDeg)), Mathf.Sin(Mathf.Deg2Rad * (90 + limitVerticalDeg)));
        }
        else
        {
            velocityNormalized.z = Mathf.Clamp(velocityNormalized.z, Mathf.Sin(Mathf.Deg2Rad * (270 - limitVerticalDeg)), Mathf.Sin(Mathf.Deg2Rad * (180 + limitHorizontalDeg)));
        }

        rb.velocity = velocityNormalized * rb.velocity.magnitude;
    }
}

いろいろ調べていると、こちらがよくとられている手法でしたので参考にさせていただいたのですが、成功せず、こんがらがってしまったので質問させていただきました。
わかる方がいらっしゃいましたらご回答よろしくお願いします。

初心者 (120 ポイント) | 273 閲覧

ログインまたはユーザー登録してから回答してください。

回答 1

0 支持

「Edit」→「Project Settings」→「Physics」より「Bounce Threshold」の値をできるだけ小さくしてはいかがでしょうか。

Unityの物理演算のデフォルトでは、絶え間なく跳ね続けるのを防ぐため跳ね返りの速度が規定値(2)以下になると、跳ね返りを止めます。

なのでその規定値を定める「Bounce Threshold」の値をできるだけ小さくすれば、複雑なコードを書かなくても自然と跳ね返ってくれると思います。

初心者 (440 ポイント)

関連する質問

0 支持
1 回答
0401 初心者 (140 ポイント) 5/18 質問 | 150 閲覧
0 支持
1 回答
tensaku 初心者 (440 ポイント) 2020 9/21 質問 | 174 閲覧
0 支持
1 回答
2021-02-08 質問・回答をMarkdownで入力できるようにしました。
2020-09-03 新たなスパム対策を導入しました。

181 質問

161 回答

165 コメント

221 ユーザー