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

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

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

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

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

Q&A

解決済

3回答

1612閲覧

Unity C#  真っ直ぐ進まない

kakashi4310

総合スコア11

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

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

0グッド

0クリップ

投稿2021/08/20 14:15

ゲームを開始したら指定の位置(x, y, z) = (0f, 0f, 0f)まで進んで止まるという命令を書きたいのですが(画像1参照)、真っ直ぐ進まず何故かy軸方向にも移動してしまいます(画像2参照)。(画面端で止まっているのは他のスクリプトで移動範囲を制限しているからです)

何かヒントを頂きたいです。また、ほかにもスクリプトで間違っているところがあれば教えてほしいです。

C#

1public class FirstMovement : MonoBehaviour 2{ 3 private float speed = 800f; 4 private Vector3 destination; 5 private bool arrived; 6 7 // Start is called before the first frame update 8 void Start() 9 { 10 arrived = false; 11 destination = new Vector3(0f, 0f, 0f); 12 13 Rigidbody PlayerRb = this.gameObject.GetComponent<Rigidbody>(); 14 PlayerRb.AddForce(transform.forward * speed); 15 16 if (Vector3.Distance(transform.position, destination) < 0.5f) 17 { 18 arrived = true; 19 speed = 0f; 20 } 21 } 22}

イメージ説明
画像1

イメージ説明
画像2

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

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

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

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

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

guest

回答3

0

ベストアンサー

csharp

1using UnityEngine; 2 3public class FirstMovement : MonoBehaviour 4{ 5 [SerializeField] float speed = 10f; 6 [SerializeField] float stoppingDistance = 0.5f; 7 Vector3 destination = Vector3.zero; 8 Rigidbody rb = default; 9 10 void Start() 11 { 12 rb = GetComponent<Rigidbody>(); 13 rb.AddForce(this.transform.forward * speed, ForceMode.Impulse); 14 } 15 16 void Update() 17 { 18 if (Vector3.Distance(this.transform.position, destination) < stoppingDistance) 19 { 20 rb.velocity = Vector3.zero; 21 } 22 } 23}

ただし、原点に近づくことがなければそのまま飛んでいってしまいます。

投稿2021/08/20 14:46

bboydaisuke

総合スコア5275

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

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

kakashi4310

2021/08/20 15:03

やはり何故かy軸方向に移動してしまいます 結果的に飛んでいってしまいます
bboydaisuke

2021/08/20 16:40

Cube を作って 0, 0, -10 あたりに配置し、Rigidbody を追加して Use Gravity を無効にして、FirstMovement を追加して実行してください。きちんと動くはずです。 そうしたら、その「正しく動く Cube」と「正しく動かないそれ」を比較するとよいでしょう。 「this.transform.forward とはローカル座標系の Z 軸の正方向単位ベクトルである」ということが理解できていないんだろうと思いますが、Scene ビューでその辺を比較すれば理解できるかもしれません。
guest

0

スクリプトを拝借して確認したのですが、私の環境ではY軸の値は変化しませんでした。
その際のPlayerは単純なcubeです。
もしかしたらですが、インポートしたモデルが少し傾いているのかもしれません。
※transform.forwardはワールド座標を基準にしているのでそんなことないと思うのですが…

前者であった場合、Unity内でモデルデータのrotationをいじる術はないので、
すぐに思いつくものとしては、空のオブジェクトを用意して現在のPlayerを格納し、
空オブジェクトの方に現在のスクリプトを付ければ解決するのではないかと考えます。

根本的な解決にはなっていないのですが、目的は達成できるかと。

あと、すでに述べられていますがStart内のifは最初に判定が行われたきり呼ばれないので、
Update,LateUpdate内に仕込む必要があります。

投稿2021/08/20 16:23

編集2021/08/22 05:18
nstto12

総合スコア18

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

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

kakashi4310

2021/08/21 07:13

回答ありがとうございます。 取り敢えずその方法でやってみたら解決しました。
bboydaisuke

2021/08/21 20:58

> transform.forwardはワールド座標を基準にしている transform.forward: ローカル座標系 Vector3.forward: ワールド座標系 だと思います。
nstto12

2021/08/22 05:17

"Unlike Vector3.forward, Transform.forward moves the GameObject while also considering its rotation." 「Vector3.forwardとは異なり、Transform.forwardは、回転も考慮しながらGameObjectを移動します。」 フォーラム読み間違えて逆に覚えていました。 ご指摘ありがとうございます。 回答の方の余計な一文は消しておきます。
guest

0

どのような作り方をしているのか知りませんが、

Start is called before the first frame update

このコメントからすると FirstMovement の Start メソッドって開始時に1回だけ呼ばれるんですよね。

で、この(0, 0, 0)からの距離を取って停止させるためのこいつは、毎フレーム呼ばれるメソッドに入れるものですよね。

if (Vector3.Distance(transform.position, destination) < 0.5f) { arrived = true; speed = 0f; }

y方向に動いているのは、おそらくtransform.forwardのy成分に何か入っているからでしょう。

投稿2021/08/20 14:40

ishina_yum

総合スコア509

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問