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

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

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

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

3回答

5501閲覧

[Unity] MoveTowardsAngle関数の回転

rituta

総合スコア41

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

0クリップ

投稿2016/05/31 12:32

編集2016/05/31 15:05

左が
MoveTowardsAngle関数で、x軸の回転(左の球)だけ90度地点で止まります。
右の球のような動きで、x軸に360度の回転をさせたいです。どうしたらいいですか?

【左の球】

C#

1using UnityEngine; 2using System.Collections; 3 4public class test01 : MonoBehaviour 5{ 6 public float target = 0.0F; 7 public float speed = 45.0F; 8 public float frame = 0.0f; 9 10 void Update() 11 { 12 frame++; 13 if (frame > 100) 14 { 15 frame = 0.0F; 16 target += 20.0F; 17 } 18 //360度超えたらリセット 19 if (transform.eulerAngles.x >= 360) 20 { 21 transform.eulerAngles = Vector3.zero; 22 target = 0.0F; 23 } 24 //回転 25 float angle = Mathf.MoveTowardsAngle(transform.eulerAngles.x, target, speed * Time.deltaTime); 26 transform.eulerAngles = new Vector3(angle, 0, 0); 27 } 28}

【右の球】

C#

1using UnityEngine; 2using System.Collections; 3 4public class test02 : MonoBehaviour 5{ 6 public float target = 0.0F; 7 public float speed = 45.0F; 8 public float frame = 0.0f; 9 10 void Update() 11 { 12 frame++; 13 if (frame > 100) 14 { 15 frame = 0.0F; 16 target += 20.0F; 17 } 18 //360度超えたらリセット 19 if (transform.eulerAngles.y >= 360) 20 { 21 transform.eulerAngles = Vector3.zero; 22 target = 0.0F; 23 } 24 //回転 25 float angle = Mathf.MoveTowardsAngle(transform.eulerAngles.y, target, speed * Time.deltaTime); 26 transform.eulerAngles = new Vector3(0, angle, 0); 27 } 28}

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

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

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

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

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

guest

回答3

0

こんにちは.

オイラー角での回転によってジンバルロックを起こしています.

ジンバルロックについての説明は質問内容から少し外れますので割愛しますが,これを回避するためにはクォータニオンを使用する必要があります.

Quaternion.Eulerを使えばオイラー角指定でクォータニオンが生成できるので,これで生成したクォータニオンをtransform.rotationに反映すると,停止することなく回転させられます.

参考になれば幸いです.

投稿2016/06/01 01:37

編集2016/06/01 11:15
shironegi

総合スコア119

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

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

rituta

2016/06/01 11:59

ご回答ありがとうございます。 ジンバルロックというのがあったんですね・・・。 申し訳ないのですが、左の球を正常に回転させられるコードを書いて頂けますでしょうか。。 お手数をお掛けして申し訳ありません。
shironegi

2016/06/01 13:48 編集

回転自体のコードは言葉通りで, transform.rotation = Quaternion.Euler(回転角, 0, 0); ですが,なめらかに回転させる部分も含めると補間が必要です. 元のコードで補間でangleを求めているところはオイラー角を元にしているためジンバルロックで値が不正なので使えません(意図通りに動作しない直接的な原因はここでした). なめらかな回転まで含めたコードをお求めなら,今は手元に環境がありませんので,私からの回答は明日までお待ち下さい. なめらかでない回転でよければ,上記の一文の回転角のところにtargetを入れてみて下さい.
shironegi

2016/06/02 04:28 編集

ここにはコード貼れないみたいなので別の回答として挙げました.そちらを見て下さい.
guest

0

C#

1//360度超えたらリセット 2if (transform.eulerAngles.y >= 360) 3{ 4 transform.eulerAngles = Vector3.zero; 5 target = 0.0F; 6}

のところを消せばなんとかなるかもしれません。

投稿2016/06/01 01:48

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2016/06/01 09:37

なんで低評価??
rituta

2016/06/01 11:20 編集

ご回答ありがとうございます。 360度超えたらリセットの部分を消してもかわりませんでした。 私は低評価なんてつけてませんよ? 評価あげておきました。
退会済みユーザー

退会済みユーザー

2016/06/01 13:41 編集

変ですね…確かめてみましたけど私のところでは普通に動きましたよ。 おそらく他のスクリプトが邪魔してると思いますが、スクリプトを複数追加してますか? 一応ちょっと変更しましたが、これでもう一度確かめてみてください。 using UnityEngine; using System.Collections; public class test02: MonoBehaviour { private float target = 0.0F; private float speed = 45.0F; private float frame = 0.0f; private Vector3 firstRotate; public void Start(){ firstRotate = this.transform.eulerAngles; } void Update() { frame++; if (frame > 100) { frame = 0.0F; target += 20.0F; } //360度超えたらリセット if (transform.eulerAngles.y >= 360) { transform.eulerAngles = Vector3.zero; } //回転 float angle = Mathf.MoveTowardsAngle(transform.eulerAngles.y, target + firstRotate.y, speed * Time.deltaTime); transform.eulerAngles = new Vector3(0, Mathf.FloorToInt(angle), 0); } }
rituta

2016/06/02 05:15

試してみましたがやはりダメでした・・・。 今回はshironegiさんのコードで解決致しました。 前回の質問からお付き合いいただき本当にありがとうございました。
guest

0

ベストアンサー

少し勘違いしてました.
補間なんて要りませんでしたね.(等速運動ですよね?)

元のコードを少しだけ変えました.

using UnityEngine; using System.Collections; public class test01 : MonoBehaviour { public float target = 0.0f; public float speed = 45.0f; public float frame = 0.0f; private float currentAngle = 0.0f; void Update() { frame++; if (frame > 100) { frame = 0.0F; target += 20.0F; } //回転 currentAngle += Time.deltaTime * speed; if (target < currentAngle) { currentAngle = target; } transform.rotation = Quaternion.Euler(currentAngle, 0, 0); } }

これでいかがでしょうか?

投稿2016/06/02 04:27

編集2016/06/02 04:29
shironegi

総合スコア119

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

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

rituta

2016/06/02 05:17

ありがとうございました。 このコードで完全に解決しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問