ガンズターン 公式サイト

楽しいことに、まじめです。 ——ガンズターンアプリ研究所公式サイト

Unity備忘録 #4 iTweenを使って1回転以上させる(超小ネタ)

Pocket

前置き長いので先に目次です。

0. 久しぶりに出前のピザを食べました

独立前は、二日酔いの休日とかに、一人でもよく出前のピザを頼んで食べていました。
今から考えると、とんでもない浪費ですね。

なんのイベントもない、普通の休日に、ただ家から出るのがめんどくさいという理由だけでなんの躊躇もなく出前のピザを頼むというダメな男の一人暮らし……。(徒歩1分以内にコンビニがあるというのに)

独立する直前からそういう浪費はしないように心構えを改めて、かれこれ半年以上、ピザの出前を取っていませんでした。
そもそも、そういう発想自体が生まれない体質(というかただのケチ)になってしまったという感じです。

……で、出前のピザの味なんてもう忘れたぐらいの気持ちでいたのですが、昨日、家族の誕生日でけっこう人が集まったので、久しぶりにピザを食べようという話になりました。

——正直、ぜんぜん期待してなかったんですけど……。

1枚食べたら、急に脳の食欲回路がピザの味を思い出して、よだれが止まらなくなってしまいました。

「——ヤバい! このピッツァ、超うまーい……!」

いやー……。まずいことになりましたよ。
このままでは、またいずれ、一人なのにピザを頼む生活に舞い戻ってしまいそうです。

……とここまで考えた時、わたしの頭に「ピコーン」という音を立てて豆電球が灯りました。

「そうだ! ピッツァを自分で作れるようになればいいじゃないか!」

これはなかなか、いいアイディアのような気がします。

成功しても失敗してもブログのネタになりそうなので、いずれピザ作りに挑戦してみようかと思います。

さて。久しぶりに前置き長くなりました。ガンズターンのRyosukeです。

実は最近、ぼちぼちとブログのアクセス数が増えてきました。(といっても微増ですが)
これも、Unity関係の記事を扱い始めた影響かもしれませんね。

というわけで、本日もUnity関係の記事を——といっても、これまで以上に小ネタになりますが、ご参考になれば幸いです。

1. iTweenは死ぬほど便利ですよ

はい。これ。
iTweenっていうのは、AssetStoreから無料で入手出来るAssetの一種です。
何かと煩雑なUnityにおけるオブジェクトの移動や回転をめちゃくちゃ楽にしてくれるので、まだ使ったことないかたは、試しにぜひダウンロードしてみてください。
iTween自体の基本的な使い方は色んなブログにすでに書かれているので、ここでは割愛しますね。
ちなみに自分は、以下のページを参考にして勉強を進めました。
(勉強といっても、10分かからずに大体使い方わかりました。それぐらい簡単です、iTween)

[iTween参考ページ]
ActionScript入門Wikiさん
ほぼiTweenの使い方を網羅して説明してくださってるので、ここだけ読めば大体わかると思います。

(ちなみに、英語が読める人はこちらから公式ドキュメントも見れますよ)

iTweenの魅力は、そのインターフェイスがわかりやすいことと、辞書形式の引数一つ渡せばほとんどの場合、事足りるっていうことですね。
イージングにも対応しているのはさらに嬉しいポイントです。
自前でやろうとしたらその実装だけで半日使っちゃいそう。(実際、Unity使う前に自前でイージング関数作りましたが1日作業でした……)

2. でも1回転以上させられない(iTween)

ひょっとしたらわたしの使い方が悪いのかも知れませんが、iTweenを使って1回転以上させる方法がすぐにわかりませんでした。

通常、回転させる時は以下のように書きます。

iTween.RotateTo(gameObject, 
    iTween.Hash(
        "x", angleX, 
        "y", angleY, 
        "z", angleZ, 
        "time", 1.0f,
    )
);

この時、各軸に設定する値(angleX〜angleZ)は、弧度法(radian)ではなく度数法(degree)ですので、お間違えなく。

これ、例えば1秒間で、y軸方向に対して時計回りに半回転させたい時は、以下のようにすればOKです。

iTween.RotateTo(gameObject, 
    iTween.Hash(
        "y", 180.0f, 
        "time", 1.0f,
    )
);

簡単ですね。y軸に対して180度を指定してあげるだけです。
ここまではわたしもすぐに理解できました。

……で、調子に乗って、「半回転できるんなら1回転もすぐにできるんじゃね?」と思ったんですが、無理でした。 orz

iTween.RotateTo(gameObject, 
    iTween.Hash(
        "y", 360.0f, 
        "time", 1.0f,
    )
);

一見すると、なんの問題もないコードのように思えますが、上記のように指定してあげたところで、オブジェクトは回転してくれません。(少なくともわたしの環境ではそうでした)

一体、何が間違いなのか?

……少し考えればすぐにわかりますね。
なにしろ、360度回転させてしまったら、元の位置に戻るだけです。
回転した結果、元の位置に戻るんなら、そもそも回転させる必要がないじゃありませんか。

……というのがおそらくiTween内部のロジック(どういう実装してるかまでは追いかけてませんが)なんだと思います。

「いやいやいや、回転した結果に差があろうがなかろうが、回転させることに意味があるんだよ」
というのが、わたしの意見なんですが、それをiTweenさんにうまく伝えることがどうしてもできない。

「ええい、それなら359度ならどうだ! ほぼ1周してくれるんじゃないか!?」

……そう思っていた時期がぼくにもありました。

しかしその結果……

オブジェクトは、反時計回りに1度傾いただけだった……!

そんな——!

まさかiTweenさんは、勝手に内部で、目標とする角度に到達するための最短経路を計算してそれに合わせてしか動けないというのか!?

……な、なんてことだ……!

これじゃあ、180度より大きい角度に、任意の回転方向で回転させること自体ができないじゃないか!?

……そうなんです。できないんです。

回転をもっと細かく制御したいなら、iTweenを使わずに自前でコードを書けということなのでしょうか……

しかし、なんだか悔しい(ビクンビクン)!

……というわけで、半ば無理やり、iTweenさんを使って1回転以上させるコードを書いてみました。

3. 1回転以上させるには oncomplete を使う(無理やり感)

結論から言うと、以下のようなコードを書きました。

public void StartRound ()
{
    //最初の半回転の呼び出し
    OnCompletionHalfRoundHandler();
}

private void OnCompletionHalfRoundHandler ()
{
    float angle = 180.0f;

    if (gameObject.transform.localRotation.y >= 1.0f)
    {
        angle = 360.0f;
    }

    iTween.RotateTo(gameObject,
        iTween.Hash(
            "y", angle,
            "time", 3.0f,
            "islocal", true,
            "easetype", iTween.EaseType.linear,
            "oncomplete", "OnCompletionHalfRoundHandler"
        )
    );
}

つまり、半回転ごとに oncomplete に設定したハンドラを呼び出してもらい、その中で、現在の角度に応じて、次の目標値となる角度を180度もしくは360度に設定してやってるというわけです。

一応、これでiTweenを使って、1回転以上させることができるようになりました。

あとは、このハンドラを呼び出した数をどこかに保持しておけば、1回転以上の任意の角度(といってもこのままでは180度刻みですが)をiTweenを使って回転させることができます。

……自分でも、かなり強引なやり方だと思います。
正直、ここまでするならiTween使わないで自力で回転させたほうがよっぽどスマートだと思います。
(ほかにいいやり方あったら教えてください)

……けれど、せっかくiTween使うんなら、移動と回転を全てiTweenを使う方式に統一したいと考えるのも、ある意味正しい感覚ではないでしょうか。

というわけで、ただiTweenを使って1回転以上させたいという小ネタのためだけに、こんなにもブログの紙幅を費やしてしましました……。

次回から、小ネタの時は小ネタにふさわしい文量になるよう気をつけたいと思います。

それでは本日はこの辺で。ガンズターンのRyosukeでした! m(_ _)m

(……とここまで書いて、そういえば前回Http通信のこと書くって予告してたこと思い出しました。……すみません、次に回します……)

Pocket

コメント

  • 1軸回転で良ければRotateAddが使えますよ。
    2軸以上の回転も可能ですが、完了時の向きが予測不能です。

  • > 通りすがり 様
    はじめまして〜!
    この度は、コメントありがとうございます!
    なんと、技術的な話題にコメント頂けたのは今回が初めてで、大変うれしいです! ^^

    RotateAdd ちょっと調べてみましたが、確かに使えそうですね〜!

    自分の場合、1回転以上させたい場合が多いので、最近は回転はiTween使わずに
    自前のコンポーネントをくっつけてやってます。
    いずれ、この記事の補完として、そのあたりのこともまとめてみたいな、と。。。
    その時は、回転の選択肢の一つとして教わったRotateAddについてももう少し調べてみますね。

  • お疲れです。エンドレスに回転させるのに、私の場合、以下で回転続けています。

    iTween.RotateTo(rotation_z_obj, iTween.Hash(“z”, 720, “looptype”, “loop”, “easetype”, “linear”, “delay”, 0));

  • > ユーリカ 様
    はじめまして & コメント承認遅くなり申し訳ありません。
    なるほど〜、iTweenを使ってそんな風にシンプルに回転を続けることもできるんですね!
    大変勉強になりました。

    最近は、単位時間あたりの回転角度を定義したQuternionを作って

    Quaternion quaternion;
    void Start(){
    quaternion = Quaternion.Euler( addXRot, addYRot, addZRot);
    }

    void Update(){
    transform.rotation *= quaternion * Time.deltaTime;
    }

    的な感じで書くのもそこまで手間じゃないな〜と思ってやっています。
    ……が、iTweenも便利なので教わった方法も実際に試してみます。ありがとうございました!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

トラックバックURL: http://gunsturn.com/2015/08/27/studying_unity_004/trackback/