【Unity】Unityと重力(指定した場所に重力をスクリプトで発生させる)
今回はUnityで重力を変更する方法を紹介したいと思います。
いきなりですがUnityってすごいですよね、たとえばリンゴのオブジェクトを空中に作ってRigidbodyコンポーネントを付けるだけで現実のように落下していきますもんね。
でもGameSceneは所詮はプログラムで動く世界、現実のように万有引力があり、地球の重力でリンゴが落ちているわけではないのですよね。
そうUnity上では下に向かって現実の重力と同じ力を常に発生させているだけです。(なぜか私がこのことが非常に面白いと思ってしまいました。)
Unityで重力の確認と変更
現実の重力はg=9.8m/s^2で表現されているわけですが、Unityではどうなっているかというと・・・
タブのEdit→ProjectSettingsを押下してみてください。
ここでは2DですがPhysics2DのGravityの部分でY:-9.81と表記されていることがわかると思います。(3Dの場合はPhysicsで確認できます)
Unity上では常にY軸に-9.81(マイナスなので下方向に)の加速度を発生させて擬似的に重力を再現しているのです。
(急に加速度って何って人もいるかと思いますが、重力は加速度のことです重力加速度とも聞いたことあると思います、単位はm/s^2です。)
つまりこのGravityの数値をいじると重力を変化させることができます。
ちなみに月の重力は1.62m/s^2なので-1.62に変更すると月を再現でき、すべて0にするとゼログラビティ・・・そう無重力を再現できるということです。
(私はこれを知ったときワクワクしました。)
また無重力に関してはオブジェクトにつけているRigidBodyのuse gravityのチェックをはずすことで各オブジェクト毎に重力を発生させるかどうかを決めることも出来ます。
上記の方法ではゲームシーン全体の重力を変更させることになるので、全体で重力を制御したいのか、個別に制御したいのかで使い分けることが出来ます。
重力をスクリプトで制御する
スクリプトで変更する方法は非常に簡単で以下でできます。
Physics2D.gravity = new Vector2(X,Y); //変数XとYに設定したい重力の数値を設定(2D) Physics.gravity = new Vector3(X,Y,Z); //変数XとYとZに設定したい重力の数値を設定(3D)
おまけ(任意の方向・力で重力を発生させる)
これだけだとあまり面白くないので指定した方向と力で重力を発生させるスクリプトを作ったので紹介したいと思います。まるでアニメのキャラのように・・・ちなみに2Dでのスクリプトになります。
スクリプトの詳細としてはシーン上のプレイヤーに対してマウスクリックした場所に向かって重力を発生させるというものです。
必要となるのは重力の方向と力の大きさです。今回のスクリプトでは
方向:プレイヤーの座標からマウスクリックした座標
力 :9.8(地球と同じ)
となります。
ソースコードは以下になります。
void Update() { //左クリックしたとき if (Input.GetMouseButton(0)) { //マウスクリックしたスクリーン座標を取得 Vector2 mousePos = Input.mousePosition; //マウスクリックしたスクリーン座標をワールド座標に変換 Vector2 mouseWorldPos = Camera.main.ScreenToWorldPoint(mousePos); //プレイヤーオブジェクトを取得 Player = GameObject.Find("Player"); //プレイヤーオブジェクトのワールド座標を取得 Vector2 playerWorldPos = Player.transform.position; //プレイヤーから見たクリック場所の方向を計算 Vector2 gravityvector = mouseWorldPos - playerWorldPos; //プレイヤーから見たクリック場所の方向の正規化 Vector2 normalizedGravityVector = gravityvector.normalized; //求めた方向のXに9.8の力を加える float GravityVector2X = normalizedGravityVector.x * 9.8f; //求めた方向のYに9.8の力を加える float GravityVector2Y = normalizedGravityVector.y * 9.8f; //計算した重力を設定する Physics2D.gravity = new Vector2(GravityVector2X,GravityVector2Y); } else { //クリックしないときは無重力にする Physics2D.gravity = new Vector2(0, 0); } }
みそとなるのは2点ありまして
①マウスクリックした場所はInput.mousePositionで取得することができるのですが、スクリーン座標で取得するということです。
つまりプレイヤーはワールド座標なので方向を求めたいときは基準とする対象2つの座標をスクリーン座標かワールド座標のどちらかにそろえる必要があります。
今回はワールド座標にそろえています。
②任意の力を発生させるために求めた方向を一度正規化し、その後任意の力を掛けるということです。
難しい書き方になるのですが、①で求めたものは、プレイヤーとクリック場所をつなぐベクトル(簡単に言うと矢印を思い浮かべるといいと思います)で取得されます。
ベクトルは方向と大きさを持つものです。(矢印で言うと方向はそのまま方向、大きさは矢印の長さ)
①の方法だと方向は問題ないのですが、ベクトルの大きさは大きくなったり小さくなったりします。(プレイヤーとクリックした場所によって距離が変わるのでベクトルの大きさが変わります)なので大きさを1に一回変換して任意の力を掛けます。なんで大きさを1にする必要があるかすごく簡単にいうと、1にするとベクトルは方向のみを持ちます。(単位ベクトルといいます、単位ベクトルに変換することを正規化するといいます)
つまり大きさを1に変更(正規化し単位ベクトルに変更)し、任意の力を掛ける必要があります。
以上のことを留意するとシーン上のプレイヤーに対してマウスクリックした場所に向かって重力を発生させることができます。
重力を操るってやっぱりなんかワクワクしますよね。
応用ではありませんが、ちょっと進んでUnityで万有引力とかやって見ましたので暇ならみてやってください。個人的にはおもしろかったのですが他にもやってる方が多かった・・・w