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

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

ただいまの
回答率

87.61%

addRelativeForceの移動制限

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,494

score 350

前提・実現したいこと

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

該当のソースコード

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

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

試したこと

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

    void FixedUpdate()
    {

        float x = Input.GetAxis("Horizontal");
        float y = Input.GetAxis("Vertical");

        rigidbody.AddRelativeForce(x * Time.deltaTime * speed, y * Time.deltaTime * speed, 0);

        Vector3 viewport = Camera.main.WorldToViewportPoint(this.transform.position);
        Vector3 viewMin = new Vector3(0.0f, 0.0f,viewport.z);
        Vector3 viewMax = new Vector3(1.0f, 1.0f,viewport.z);
        Vector3 worldMin = Camera.main.ViewportToWorldPoint(viewMin);
        Vector3 worldMax = Camera.main.ViewportToWorldPoint(viewMax)

追記

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

    void FixedUpdate()
    {

        float x = Input.GetAxis("Horizontal");
        float y = Input.GetAxis("Vertical");

        rigidbody.velocity = new Vector3(x*speed, 0, 0);

        if(rigidbody.velocity.magnitude > 0){
            Debug.Log("-----");
            Debug.Log("Time.deltaTime:"+Time.deltaTime);
            Debug.Log("位置:"+ this.transform.position.ToString("G"));
            Debug.Log("算出:"+ (this.transform.position + rigidbody.velocity * Time.deltaTime).ToString("G"));
        }

追記2

加速度あり

    void FixedUpdate()
    {

        float x = Input.GetAxis("Horizontal");
        float y = Input.GetAxis("Vertical");

        Vector3 force = new Vector3(x * speed, y * speed, 0);
        Vector3 relativeforce = this.transform.TransformDirection(force);
        Vector3 acc = relativeforce/rigidbody.mass;
        rigidbody.AddRelativeForce(force);

        if(rigidbody.velocity.magnitude > 0){
            Debug.Log("-----");
            Debug.Log("位置:"+ this.transform.position.ToString("G"));
            Debug.Log("算出:"+ (this.transform.position + rigidbody.velocity*Time.deltaTime + 1f/2f*acc*Time.deltaTime*Time.deltaTime).ToString("G"));
        }
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/02 23: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を書き直して、ご教示いただいた公式に当てはめたつもりなのですが、
    コードで間違っている点があれば教えていただけませんか?

    キャンセル

  • 2019/08/03 00:31

    Console.WriteLine("{0}", 1/2);

    キャンセル

  • 2019/08/03 12: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

    キャンセル

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

  • ただいまの回答率 87.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る