Cou氏の徒然日記(2022)

ほのぼの日記ブログです。

Unityで遊ぼう [ブロック崩し編 その2:摩擦・跳ね返り・移動制約・初速の設定]

前回の続き。

 

Rigidbodyを付けることで、物理運動が適用されるようになりますが・・・

そうなるともちろん、摩擦の影響も受け、スピードが落ちてしまいます。

ブロック崩しのボールは、止まってしまってはダメなので、そのあたりを回避する設定が必要です。

 

(1) Physical Material

Assetsで「Physical Material」を作成し、各項目を設定。

f:id:coublood:20210116021234p:plain

  • Dynamic Friction 動的摩擦力。0は摩擦力なし(無視)、1は摩擦力最大。
  • Static Friction静止摩擦力。0は摩擦力無し(無視)、1は摩擦力最大
  • Bounciness弾性力。0は跳ね返らない、1は100%の力で跳ね返る。

今回の場合は、摩擦力を無視、100%の力で跳ね返ってほしいので、上記のような設定でよさそうです。

 

(2) Rigidbodyの制約設定

また、ボールは、XZ平面上の移動のみで、Y方向への移動はしてほしくありません。

f:id:coublood:20210116022154p:plain

それはRigidbodyの中で制御できるようです。

f:id:coublood:20210116022303p:plain

ここで、固定したい方向、回転の向きを制限できるようです。

Y軸方向への移動と、ボールの回転は不要なので、上記のようにすればよさそう。

 

(3) Ballに初速を付ける

ここまででボールは、壁や物にぶつかれば跳ね返り、摩擦による影響も受けなくなり、Y座標(上下)に跳ねることもなくなりました。

 

ただ、初速がないと、ボールは動きません。

運動エネルギーが必要です。

 

ここでボールのスクリプトで初速を付けます。

初速の与え方は、Start() メソッドで、RigidboryAddForceを使えばよさそう。

docs.unity3d.com

f:id:coublood:20210116141707p:plain

public void AddForce (float x, float y, float z, ForceMode mode= ForceMode.Force)

 

ForceModeは、以下のようです。

f:id:coublood:20210116142243p:plain

  • Force 質量を使用して、リジッドボディへ継続的な力を加えます。
  • Acceleration その質量を無視して、リジッドボディへ継続的な力を加えます。
  • Impulse その質量を使用し、リジッドボディにインスタントフォースインパルスを追加します。
  • VelocityChange 質量を無視して、リジッドボディにインスタント速度変化を追加します。

 

今回は摩擦力がなく弾性力も100%なので、 瞬間的に与えればいいです。

(継続的に与えたら、加速しそう・・・)

ということで、VelocityChangeでよさそう。

 

ということで実装。

[Ball.cs]
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Ball : MonoBehaviour
{	
    public float speed = 10.0f;
    private Rigidbody rigid;

    // Start is called before the first frame update
    void Start()
    {
       // Rigidbodyオブジェクトを取得 //
       rigid = this.GetComponent<Rigidbody>();

       // AddForceで初速を与える (斜めにするために、x座標向きとz座標向きに力を加える) //
       rigid.AddForce(speed, 0, speed, ForceMode.VelocityChange);       
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 

これでいけそうかなとお試ししてみます。


ブロック崩し テスト2

 

お!跳ね返った♪ と思って見ていたら、まさかの事故…。

ボールがバーに当たったら、跳ね返らずに、その衝撃でバーが倒れました(笑)

 

原因は、プレイヤー用バーオブジェクトに、Rigidbody属性を付けてしまったこと。

そもそも、プレイヤー用バーオブジェクトには物理演算は不要である(ボールと当たっても、ボールの衝撃を受けるのではなく、ただのボールのエネルギーを全部跳ね返す壁であればよい)ため、つける必要がなかったんですよね。

 

ということで、プレイヤー用バーオブジェクトからRegidbody属性を削除したら、無事にうまくいきました。


ブロック崩し テスト3

 

続きます。