VIDEO
Unityを使うとコードをあれこれ書かなくても2D/3Dゲームを簡単につくることができます。Rigidbody を使うと、ゲームオブジェクトを物理特性によって制御する事ができるようになります。重力の影響を加えたり、それ以外の力を与えることでどのように動くかをシミュレーションすることができるようになるのです。
ボールを地面におとすと反発します。反発係数が1.0であれば永久にボールは跳ね続けます。実際には反発係数は1.0よりも小さいのでボールは動かなくなってしまうのですが、どれくらいの反発係数でどれくらいボールは跳ね続けるのでしょうか? Unityをつかってシミュレーションするプログラムをつくってみました。
まずUnityのプロジェクトをつくり、ヒエラルキーで「空のオブジェクトを作成」。するとGameObjectが生成されます。つぎにassetsを右クリックして「C#スクリプトを生成」、名前は適当でかまいません。スクリプトの名前は「GameObjectScript1」に変更しました。
GameObjectScript1をダブルクリックするとVisualStudioが立ち上がります。このとき「public class GameObjectScript1」と書かれている部分、クラス名はファイル名と同じにしてください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System . Collections ;
using System . Collections . Generic ;
using UnityEngine ;
// スクリプトの名前を「GameObjectScript1」にしたらクラス名も「GameObjectScript1」にする
public class GameObjectScript1 : MonoBehaviour
{
void Start ( )
{
}
void Update ( )
{
}
}
これをヒエラルキーのGameObjectにドラッグアンドドロップしましょう。
次にこのファイルをもう一度開いて編集します。
まず床をつくります。球体の落下実験をしたいのですが、床がないと球体はそのままどこまでも落下してしまいます。
次に球体をつくります。場所はY座標5、Z座標0、X座標は少しずつ変更させて10個表示させます。球の大きさはlocalScaleはnew Vector3(0.7f, 0.7f, 0.7f);として1よりも少し小さい値にします。これは10個横に並べると幅をとるからでそれ以外にたいした意味はありません。
球を作ったらコンポーネントでRigidbodyとSphereColliderを追加します。Rigidbodyを追加することで重力の影響をうけます。
そのあと自作メソッド SetBouncinessを呼び出します。これは反発係数を設定するためです。最初は10個の球体に0から1.0までの値を設定しています。
Update()メソッドはとくに書くことはありません。これで実行してみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class GameObjectScript1 : MonoBehaviour
{
void Start ( )
{
// 床をつくる
GameObject plane = GameObject . CreatePrimitive ( PrimitiveType . Plane ) ;
plane . transform . position = new Vector3 ( 0 , 0 , 0 ) ;
plane . transform . rotation = Quaternion . Euler ( 0 , 0 , 0 ) ;
plane . transform . localScale = new Vector3 ( 1.7f , 1 , 1 ) ;
for ( int i = 0 ; i < = 10 ; i ++)
{
// 球をつくる
GameObject sphere = GameObject . CreatePrimitive ( PrimitiveType . Sphere ) ;
// 球の場所はY座標5、Z座標0、X座標は少しずつ変更させて10個の球を表示させます。
// 球のlocalScaleはnew Vector3(0.7f, 0.7f, 0.7f);を指定
float x = -5 + i * 1 ;
sphere . transform . position = new Vector3 ( x , 5 , 0 ) ;
sphere . transform . rotation = Quaternion . Euler ( 0 , 0 , 0 ) ;
sphere . transform . localScale = new Vector3 ( 0.7f , 0.7f , 0.7f ) ;
sphere . AddComponent < Rigidbody > ( ) ;
Rigidbody rigidbody = sphere . GetComponent < Rigidbody > ( ) ;
sphere . AddComponent < SphereCollider > ( ) ;
SetBounciness ( sphere , i ) ;
}
}
void SetBounciness ( GameObject sphere , int i )
{
SphereCollider sphereCollider = sphere . GetComponent < SphereCollider > ( ) ;
sphereCollider . material . bounceCombine = PhysicMaterialCombine . Maximum ;
// 0.0-1.0
sphereCollider . material . bounciness = i * 0.1f ;
}
void Update ( )
{
}
}
VIDEO
上記のコードを実行すると反発係数が0.6まではほとんど反発しないことがわかります。反発係数が1.0にすると永久に跳ね続けますが、ちょっとおかしな部分があります。だんだん跳ね上がる高さが高くなっていきます。これは物理学的にはありえないことです。物理学的現象に忠実再現することができるわけではないようです。
SetBouncinessメソッドを変化させれば反発係数の違いがどのように影響するかだいたいであればわかります。
0.6まではほとんど跳ねなかったので0.8から0.02刻みで実験してみましょう。SetBouncinessメソッドを以下のように書き換えます。
void SetBounciness ( GameObject sphere , int i )
{
SphereCollider sphereCollider = sphere . GetComponent < SphereCollider > ( ) ;
sphereCollider . material . bounceCombine = PhysicMaterialCombine . Maximum ;
// 0.80-1.00
sphereCollider . material . bounciness = 0.8f + i * 0.02f ;
}
0.8から0.02刻みの実行結果
VIDEO
これなら0.9から0.01刻みで検証することができます。
void SetBounciness ( GameObject sphere , int i )
{
SphereCollider sphereCollider = sphere . GetComponent < SphereCollider > ( ) ;
sphereCollider . material . bounceCombine = PhysicMaterialCombine . Maximum ;
// 0.90-1.00
sphereCollider . material . bounciness = 0.9f + i * 0.01f ;
}
0.9から0.01刻みの実行結果
VIDEO
鳩でも分かるC#管理人からのお願い
できる仕事であれば請け負います。鳩でもわかるC#管理人はクラウドワークスに在宅ワーカーとして登録しています。お仕事の依頼もお待ちしております。
⇒ 仕事を依頼する
コメントについて
コメントで英語などの外国語でコメントをされる方がいますが、管理人は日本語以外はわからないので基本的に内容が理解できず、承認することもありません。それからへんな薬を売っているサイトやリンク先のサイトが存在しないというスパムコメントも多々あります。
Some people make comments in foreign languages such as English, but since the manager does not understand anything other than Japanese, he basically cannot understand the content and does not approve it. Please use Japanese when making comments.
そんななか日本語のコメントもいただけるようになりました。「○○という変数はどこで宣言されているのか?」「××というメソッドはどこにあるのか」「例外が発生する」「いっそのことソース丸ごとくれ」という質問ですが、管理人としては嬉しく思います。「自分が書いた記事は読まれているんだな」と。疑問点には可能な限り答えます。記事に問題があれば修正いたします。
そのうえでお願いがあります。「匿名」という味も素っ気もない名前ではなく、捨てハンでいいのでなにかハンドルネームをつくってほしいと思います。
管理人のモチベーションアップのために
よろしければご支援お願いします。
⇒ 管理人の物乞いリスト
だんだん跳ね上がる高さが高くなっていきます。これは物理学的にはありえないことです。物理学的現象に忠実再現することができるわけではないようです。
と書いていますがこれは恐らく重力で加速され続けているからではないでしょうか?
なので物理演算は正しい気がします