質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

1回答

625閲覧

addRelativeForceの移動制限

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2019/07/28 05:35

編集2019/08/03 01:42

前提・実現したいこと

addForceでの移動制限(画面外への移動不可)はどういった処理で実装できますか?
検索してもなかなか記事が見つからなかったです。
望ましいのは移動前に、addForceの移動後を計算して制御することですが、
おそらくそれは不可能と考えていて(可能でしたら教えていただきたいです)、
移動後に制御するしかないと思っています。
また、スクリプトでの制御法を知りたいです(オブジェクト配置での移動制限は考えていません)。
ご教示お願いします。

該当のソースコード

カメラのローカル軸の向きがワールド軸の向きと一致していなくて、
ゲームオブジェクトのローカル軸の向きもワールドと一致していない、
かつカメラのローカル軸とも一致していない想定です。

ここで、ゲームオブジェクトが例えば、addRelativeForceでゲームオブジェクトのローカル軸のX方向に動く場合、
画面外への移動を不可にしたいです。

試したこと

Rigidbodyの動き、画面の境界の取得は考えることができました。
もし、画面の境界の取得が間違っていたらご指摘ください。
thisがRigidbodyで動かすゲームオブジェクトです。
カメラは動くRigidbodyを追いかけることを想定しているので、常に画面の境界を更新しています。

C#

1 void FixedUpdate() 2 { 3 4 float x = Input.GetAxis("Horizontal"); 5 float y = Input.GetAxis("Vertical"); 6 7 rigidbody.AddRelativeForce(x * Time.deltaTime * speed, y * Time.deltaTime * speed, 0); 8 9 Vector3 viewport = Camera.main.WorldToViewportPoint(this.transform.position); 10 Vector3 viewMin = new Vector3(0.0f, 0.0f,viewport.z); 11 Vector3 viewMax = new Vector3(1.0f, 1.0f,viewport.z); 12 Vector3 worldMin = Camera.main.ViewportToWorldPoint(viewMin); 13 Vector3 worldMax = Camera.main.ViewportToWorldPoint(viewMax)

追記

加速度0のコードのはず。

C#

1 void FixedUpdate() 2 { 3 4 float x = Input.GetAxis("Horizontal"); 5 float y = Input.GetAxis("Vertical"); 6 7 rigidbody.velocity = new Vector3(x*speed, 0, 0); 8 9 if(rigidbody.velocity.magnitude > 0){ 10 Debug.Log("-----"); 11 Debug.Log("Time.deltaTime:"+Time.deltaTime); 12 Debug.Log("位置:"+ this.transform.position.ToString("G")); 13 Debug.Log("算出:"+ (this.transform.position + rigidbody.velocity * Time.deltaTime).ToString("G")); 14 }

追記2

加速度あり

C#

1 2 void FixedUpdate() 3 { 4 5 float x = Input.GetAxis("Horizontal"); 6 float y = Input.GetAxis("Vertical"); 7 8 Vector3 force = new Vector3(x * speed, y * speed, 0); 9 Vector3 relativeforce = this.transform.TransformDirection(force); 10 Vector3 acc = relativeforce/rigidbody.mass; 11 rigidbody.AddRelativeForce(force); 12 13 if(rigidbody.velocity.magnitude > 0){ 14 Debug.Log("-----"); 15 Debug.Log("位置:"+ this.transform.position.ToString("G")); 16 Debug.Log("算出:"+ (this.transform.position + rigidbody.velocity*Time.deltaTime + 1f/2f*acc*Time.deltaTime*Time.deltaTime).ToString("G")); 17 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

addForceってのは加速度で、画面端は位置です
単位が違いますので比較することすらできません

ちゃんと加速度や速度がどういうものなのか理解していれば、
次のフレームの予測位置というのは計算できます

加速度が1m/ss → 速度が1秒ごとに1m/s増えていく
速度が1m/s → 位置が1秒ごとに1m増えていく

つまり1フレーム後の位置は加速度が0なら、transform.position + rb.velocity * Time.deltaTimeです
※time.deltaTimeは前フレームから現在のフレームの時間なので、次のフレームが等間隔でくるのが前提です

投稿2019/07/28 17:02

izmktr

総合スコア2856

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/07/29 14:09

ご回答ありがとうございます。 質問の追記に書いたように、 実際、ご教示いただいたように算出通りの位置に来るのか検証してみたのですが、 ズレが生じますね。 誤差でしょうか? ただ、Time.deltaTimeは毎フレーム0.02で固定されていたので、そこが不思議です。
izmktr

2019/07/30 01:03

加速度が0なら、の部分をちゃんと理解していますか?
退会済みユーザー

退会済みユーザー

2019/07/31 14:06

追記のコードに、他の余計なコードが混ざっていて、削除して追記通りのコードにしたら、 算出通りの位置に来るようになりました。 追記のコードは加速度が0のコードで合っているのではないでしょうか? (間違っていたらご指摘お願いします。) 今度は追記2のように、 加速度ありのコードで移動場所を算出しようとしたのですが、 ログで位置と算出が一致しませんでした。 正しいコードを教えていただけませんか?
izmktr

2019/08/01 01:40 編集

x=1/2at^2+vt です 高校の物理の教科書に載っています あと、AddRelativeForceで与えるのはFであり、F=maですから、質量で割った値が加速度となります
退会済みユーザー

退会済みユーザー

2019/08/01 13:51 編集

ご回答ありがとうございます。 質問の追記2を書き直して、ご教示いただいた公式に当てはめたつもりなのですが、 算出と次のフレームの位置にズレが生じます。 コードで間違っている点があれば教えていただけませんか?
izmktr

2019/08/01 15:21

まず、1/2が0になることを理解していますか? そして、t^2に0.016を入れたら極小の値になるので、加速度の影響は殆どありません どの程度ずれているのか、本来ならどの位置にあるのが正しいのか、 そのためにどこで計算誤差が出ているのか、自分の手でノートなりエクセルなりで計算してみてください
退会済みユーザー

退会済みユーザー

2019/08/02 14:42

>1/2が0になることを理解していますか? 理解できてないです。1/2は0.5ではないのですか? >t^2に0.016を入れたら極小の値になるので、加速度の影響は殆どありません 以前のコメントで、「Time.deltaTimeは毎フレーム0.02」と書いたのですが、 0.02*0.02=0.0004‬なので、0.016という数字はどこから来たのでしょうか? 例えば、下記のような誤差になりますね。 算出:(5.251351, 6.770001, 0.4497643) 位置:(5.251924, 6.770001, 0.4496632) X成分の誤差:0.000573 Y成分の誤差:なし。 Z成分の誤差:0.0001011 追記2を書き直して、ご教示いただいた公式に当てはめたつもりなのですが、 コードで間違っている点があれば教えていただけませんか?
izmktr

2019/08/02 15:31

Console.WriteLine("{0}", 1/2);
退会済みユーザー

退会済みユーザー

2019/08/03 03:05

0と出力されました。 int型同士の割り算は0になってしまうということなのですね、理解できました。 追記2で書き換えたように、1f/2fに書き直しました。 再び、検証してみたところ、前回よりズレの値が小さくなりました。 これは誤差でしょうか? それとも、まだ追記2のコードにおいて、間違っている点があればご指摘お願いします。 算出:(11.29195, 6.770001, -0.6153572) 位置:(11.29169, 6.770001, -0.6153107) 誤差 X成分:0.00026 Y成分:なし Z成分:0.0000465
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問