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

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

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

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

Unity

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

Q&A

解決済

1回答

2606閲覧

Unity-iTweenのRotateで複数の軸を回転させる

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Unity

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

0グッド

0クリップ

投稿2018/03/13 10:02

iTweenを用いてオブジェクトを複数の軸で回転させたいです。
以下のコードをcubeにアタッチしてプレイしたのですが、回転後の数値はhashに指定したものとまったく違う結果となってしまいました。

C#

1void Start () { 2 3 var hash = new Hashtable(); 4 hash.Add("time", 1); 5 hash.Add("amount", new Vector3(90, 90, 0));//xとyの2軸を設定しています。 6 hash.Add("easetype", iTween.EaseType.linear); 7 hash.Add("oncompletetarget", gameObject); 8 hash.Add("oncomplete", "DebugRotation"); 9 iTween.RotateAdd(gameObject, hash);//他のアニメーションと併用したいのでRotateAddにしています。 10 } 11 12private void DebugRotation() 13 { 14 Debug.Log(gameObject.transform.eulerAngles);//結果は(39.4,140.5,79.0)となった。 15 } 16

回転する軸が1つだけの時(例えばhash.Add("amount",new Vector3(90,0,0)))は、回転後の数値とhashの数値が一致しました。

そこで質問なのですが、
iTweenを用いて複数の軸でオブジェクトを回転させる場合、回転後数値をhashの値に一致させることはできますか?

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

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

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

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

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

guest

回答1

0

ベストアンサー

iTweenの仕様上、このような奇妙な挙動になっているようですね...
iTween.csファイル中のRotateAddの初期化部分、回転適用部分は下記のようになっていました。

C#

1 // 省略 2 3 void GenerateRotateAddTargets(){ 4 //values holder [0] from, [1] to, [2] calculated value from ease equation, [3] previous value for Rotate usage to allow Space utilization: 5 vector3s=new Vector3[5]; 6 7 //from values: 8 vector3s[0]=vector3s[1]=vector3s[3]=thisTransform.eulerAngles; 9 10 //to values: 11 if (tweenArguments.Contains("amount")) { 12 vector3s[1]+=(Vector3)tweenArguments["amount"]; 13 }else{ 14 if (tweenArguments.Contains("x")) { 15 vector3s[1].x+=(float)tweenArguments["x"]; 16 } 17 if (tweenArguments.Contains("y")) { 18 vector3s[1].y+=(float)tweenArguments["y"]; 19 } 20 if (tweenArguments.Contains("z")) { 21 vector3s[1].z+=(float)tweenArguments["z"]; 22 } 23 } 24 25 //need for speed? 26 if(tweenArguments.Contains("speed")){ 27 float distance = Math.Abs(Vector3.Distance(vector3s[0],vector3s[1])); 28 time = distance/(float)tweenArguments["speed"]; 29 } 30 } 31 32 // 省略 33 34 void ApplyRotateAddTargets(){ 35 preUpdate = thisTransform.eulerAngles; 36 37 //calculate: 38 vector3s[2].x = ease(vector3s[0].x,vector3s[1].x,percentage); 39 vector3s[2].y = ease(vector3s[0].y,vector3s[1].y,percentage); 40 vector3s[2].z = ease(vector3s[0].z,vector3s[1].z,percentage); 41 42 //apply: 43 thisTransform.Rotate(vector3s[2]-vector3s[3],space); 44 45 //record: 46 vector3s[3]=vector3s[2]; 47 48 //need physics? 49 postUpdate=thisTransform.eulerAngles; 50 if(physics){ 51 thisTransform.eulerAngles=preUpdate; 52 GetComponent<Rigidbody>().MoveRotation(Quaternion.Euler(postUpdate)); 53 } 54 } 55 56 // 省略

ApplyRotateAddTargetsの「apply:」の部分で、回転の差分をオイラー角の状態で求めて、それをRotateで適用しているのが怪しそうに思えたため、これをクォータニオンベースの回転に変えてみました。

C#

1 // 省略 2 3 void GenerateRotateAddTargets() 4 { 5 //values holder [0] from, [1] to, [2] calculated value from ease equation, [3] previous value for Rotate usage to allow Space utilization: 6 vector3s = new Vector3[5]; 7 8 // islocal判定を追加 9 if (tweenArguments.Contains("islocal")) 10 { 11 isLocal = (bool)tweenArguments["islocal"]; 12 } 13 else 14 { 15 isLocal = Defaults.isLocal; 16 } 17 18 //from values: 19 vector3s[0] = vector3s[1] = vector3s[3] = isLocal ? thisTransform.localEulerAngles : thisTransform.eulerAngles; // ローカルモードの場合、基準回転を親からの相対回転とする 20 21 //to values: 22 if (tweenArguments.Contains("amount")) 23 { 24 vector3s[1] += (Vector3)tweenArguments["amount"]; 25 } 26 else 27 { 28 if (tweenArguments.Contains("x")) 29 { 30 vector3s[1].x += (float)tweenArguments["x"]; 31 } 32 if (tweenArguments.Contains("y")) 33 { 34 vector3s[1].y += (float)tweenArguments["y"]; 35 } 36 if (tweenArguments.Contains("z")) 37 { 38 vector3s[1].z += (float)tweenArguments["z"]; 39 } 40 } 41 42 //need for speed? 43 if (tweenArguments.Contains("speed")) 44 { 45 float distance = Math.Abs(Vector3.Distance(vector3s[0], vector3s[1])); 46 time = distance / (float)tweenArguments["speed"]; 47 } 48 } 49 50 // 省略 51 52 void ApplyRotateAddTargets() 53 { 54 preUpdate = thisTransform.eulerAngles; 55 56 //calculate: 57 vector3s[2].x = ease(vector3s[0].x, vector3s[1].x, percentage); 58 vector3s[2].y = ease(vector3s[0].y, vector3s[1].y, percentage); 59 vector3s[2].z = ease(vector3s[0].z, vector3s[1].z, percentage); 60 61 //apply: 62 // thisTransform.Rotate(vector3s[2]-vector3s[3],space); // 回転のオイラー角差分をRotateに与えて回転させる代わりに... 63 var previousRotation = Quaternion.Euler(vector3s[3]); // 前回の回転のオイラー角からクォータニオンを求め... 64 var nextRotation = Quaternion.Euler(vector3s[2]); // 今回の回転のオイラー角からクォータニオンを求め... 65 var rotationToApply = nextRotation * Quaternion.Inverse(previousRotation); // 2つのクォータニオンを合成して回転差分を求め... 66 if (isLocal) 67 { 68 // ローカルモードなら... 69 if (space == Space.Self) 70 { 71 thisTransform.localRotation *= rotationToApply; // Selfの場合は差分回転をthisTransform.localRotationの前に適用する 72 } 73 else 74 { 75 thisTransform.localRotation = rotationToApply * thisTransform.localRotation; // Worldの場合は差分回転をthisTransform.localRotationの後に適用する 76 } 77 } 78 else 79 { 80 // ワールドモードなら... 81 if (space == Space.Self) 82 { 83 thisTransform.rotation *= rotationToApply; // Selfの場合は差分回転をthisTransform.rotationの前に適用する 84 } 85 else 86 { 87 thisTransform.rotation = rotationToApply * thisTransform.rotation; // Worldの場合は差分回転をthisTransform.rotationの後に適用する 88 } 89 } 90 91 //record: 92 vector3s[3] = vector3s[2]; 93 94 //need physics? 95 postUpdate = thisTransform.eulerAngles; 96 if (physics) 97 { 98 thisTransform.eulerAngles = preUpdate; 99 GetComponent<Rigidbody>().MoveRotation(Quaternion.Euler(postUpdate)); 100 } 101 } 102 103 // 省略

そして、下記のようにキューブのトゥイーン設定にspaceとislocalを追加してみるとどうでしょうか?

C#

1 void Start() 2 { 3 var hash = new Hashtable(); 4 hash.Add("time", 1); 5 hash.Add("amount", new Vector3(90, 90, 0));//xとyの2軸を設定しています。 6 hash.Add("easetype", iTween.EaseType.linear); 7 hash.Add("oncompletetarget", gameObject); 8 hash.Add("oncomplete", "DebugRotation"); 9 hash.Add("space", Space.World); // 追加 10 hash.Add("islocal", true); // 追加 11 iTween.RotateAdd(gameObject, hash);//他のアニメーションと併用したいのでRotateAddにしています。 12 } 13 14 private void DebugRotation() 15 { 16 Debug.Log(gameObject.transform.eulerAngles);//結果は(39.4,140.5,79.0)となった。 17 }

投稿2018/03/14 22:20

編集2018/03/15 01:16
Bongo

総合スコア10807

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

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

退会済みユーザー

退会済みユーザー

2018/03/17 02:35

回答ありがとうございます。 お陰様で両数値を一致させることができました。 ただ、アセットストアから得たスクリプトを一部改変するのは著作権的に大丈夫なんでしょうか? 公開しなければokなんですかね?
Bongo

2018/03/17 03:45 編集

https://code.google.com/archive/p/itween/ によると、iTweenはMITライセンスを採用しているそうです。 MITライセンスについて http://wisdommingle.com/mit-license/ などの解説を読むと、改造を加えることも許されているようなので大丈夫かと思います。ただし、iTweenに関する著作権情報とライセンス文を表示するべきでしょう。 [追記] iTween.csの先頭部分のコメントによると、内部で使っているイージングの式の部分はBSDライセンスに基づくようです。こちらも改変は許されるライセンスのようですね。 http://www.dragonquest.jp/dqmbs/license.html もiTweenを使用しているようで、ライセンス表示はこの例のようにiTweenとEASING EQUATIONSについて併記するのがいいかと思います。
退会済みユーザー

退会済みユーザー

2018/03/19 14:31

丁寧にありがとうございます、確認してきました。 assetstoreに別途ライセンス表記がなかったのでアセットストアの利用規約に沿うものと思ってたのですが、 他のサイトに書いてある場合もあるんですね。 勉強になりました、回答ありがとうございましたm(__)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問