[Unity] ブロック崩しをあのアプリ風にする #10 細かい修正

前回までで一区切りつきましたと言ったけど、ボールの挙動に難ありなのでその修正をします。

現状

z方向(x方向)のverocityが小さくなりすぎて一方向にしか動かなくなる。それと反発するたび速くなっている。


ボールが右端に張り付いているのがわかると思います。
それと、上のgifでは分かりづらいけどボールは跳ね返るたびに速度が上がってます。physicMaterialBounciness(反発)は1(損失なし)にはしていますが、徐々に加速していくとは予想外です。宇宙が一巡する前になんとかしないといけません。

※追記
Edit -> ProjectSettings -> PhysicsManager BounceThreshold という項目があります。ここを0にするだけで今回の修正は不要となります。



BounceThreshold は相対速度をみているようで、デフォルトでは2になっています。上のgifだと右の壁に対するx方向の入射スピードが下回っていたために思うような動きになってません。

ここからは記事作成当初にBounceThresholdの存在を知らない僕が別の方法で解決策を考えた結果です。
無知な者がどんな珍解決を繰り広げたのか興味のある方だけにオススメします。

※追記ここまで

ボールの軌道修正

毎フレームやる必要はないので衝突した時に修正をかけます。
新しくBall_Scriptという名前のスクリプトをBallにアタッチします。


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

public class Ball_Script : MonoBehaviour {

    Rigidbody rig;
    float speed;
    void Start () {
        rig = GetComponent<Rigidbody> ();
    }

//玉が垂直or水平にしか動かなくなる時の対策と定速化
    void OnCollisionEnter(Collision col){
//定速化
        rig.velocity = rig.velocity.normalized * speed;
//水平対策
        if(3 > Mathf.Abs( rig.velocity.z )){
            float vec = rig.velocity.z > 0 ? 5:-5;
            rig.velocity += new Vector3(0,0,vec);
        }
//垂直対策
        if(3 > Mathf.Abs( rig.velocity.x )){
            float vec = rig.velocity.x > 0 ? 5:-5;
            rig.velocity += new Vector3(vec,0,0);
        }
    }
//補正用 BallManagerが呼び出す
    public void SetSpeed(float s){
        speed = s;
    }
}

16行目で速度をリセットしています。リセットに使うspeedは発射の時にBallManagerから受け取ります。

その下の水平対策と垂直対策では、現在の進行方向に対する絶対値をMathf.Abs()求めて3以下であればその進行方向に対して5を足しています。

BallManagerからSetSpeedを呼び出す追記をします。
IEnumerator shoot(Vector3 vec){
    foreach (GameObject obj in balls) {
        Rigidbody rig = obj.GetComponent<Rigidbody> ();
        rig.velocity = vec * speed;
        obj.GetComponent<Ball_Script>().SetSpeed(speed);
        yield return new WaitForSeconds (0.1f);
    }
}

またもやこれだけでは違いはわかりにくいと思いますが、何度か確認しても挙動は安定するようになりました。
修正量に関してはもう少し小さくてもいいかもしれません。

コメント