5
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

【Godot】Tweenの使い方

概要

この記事では、Godot Engine での Tween の使い方を説明します。

Spriteの配置

Tweenで動かすオブジェクトとして、ここでは Sprite を使用します。
Godot_Engine_-_TestTween.png

素材の画像は以下のものを使います。
chabu.png

これを Sprite > Texture に割り当てます。
Godot_Engine_-_TestTween_-_Sprite_tscn____.png

Tweenノードを追加

Sprite ノードの下に Tween ノードをぶら下げます。
Godot_Engine_-_TestTween_-_Sprite_tscn____.png
このような構成としました。
Godot_Engine_-_TestTween_-_Sprite_tscn____.png

スクリプトからTweenアニメーションを制御

Sprite ノードに対してスクリプトをアタッチして以下のように記述します

Sprite.gd
extends Sprite

func _ready():
    # Tweenノードを取得する
    var tween:Tween = $Tween

    # アニメーションパラメータを設定
    tween.interpolate_property(
        self,             # 自分自身を登録
        "position",       # positionパラメータを制御
        position,         # 開始座標は現在地
        Vector2(200, 64), # (200, 64)に移動
        1,                # 1秒間で移動
        Tween.TRANS_EXPO, Tween.EASE_OUT # ExpoOutで移動
    )

    # ループ設定
    tween.repeat = true # 1回再生して終わる場合は指定不要

    # 再生開始
    tween.start()

Tween.interpolate_property() がアニメーションパラメータの設定となります。
確認しやすいようにループ設定を有効にしていますが、これは通常は設定しなくても問題ありません

パラメータを設定したら、Tween.start() でアニメーションの再生を開始します。

実行するとアニメーションを確認できます。
shot.gif

Tweenノードをあらかじめ作らずにアニメーションを使う

Tweenノードを配置せずに、動的に生成してアニメーションすることも可能です。
その場合は以下のように記述します。

Sprite.gd
extends Sprite

func _ready():
    # Tweenノードを生成する
    var tween:Tween = Tween.new() # ①

    # アニメーションパラメータを設定
    tween.interpolate_property(
        self,             # 自分自身を登録
        "position",       # positionパラメータを制御
        position,         # 開始座標は現在地
        Vector2(200, 64), # (200, 64)に移動
        1,                # 1秒間で移動
        Tween.TRANS_EXPO, Tween.EASE_OUT # ExpoOutで移動
    )

    # ループ設定
    tween.repeat = true # 1回再生して終わる場合は指定不要

    # ②どこかのノードにぶら下げる必要がある
    add_child(tween)

    # 再生開始
    tween.start()

変更点は二箇所です。var tween:Tween = Tween.new() でインスタンスを生成し、Tween.start() を呼び出す前 に、add_child() でシーンに追加します

パラメータ指定の注意点

アニメーションに指定可能なパラメータですが、オブジェクト直下のパラメータのみとなります。
そのため以下の指定だとうまく動作しません。

    # ■X座標のみアニメーションしたい
    # アニメーションパラメータを設定
    tween.interpolate_property(
        self,             # 自分自身を登録
        "position.x",     # positionパラメータを制御
        position.x,       # 開始座標は現在地
        20,               # x=200に移動
        1,                # 1秒間で移動
        Tween.TRANS_EXPO, Tween.EASE_OUT # ExpoOutで移動
    )

X座標のみ動かしたい場合でも、Vector2を渡して制御する必要があります。

カーブの種類について

カーブの種類は以下のものが指定可能です。

  • TRANS_LINEAR
  • TRANS_SINE
  • TRANS_QUINT
  • TRANS_QUART
  • TRANS_QUAD
  • TRANS_EXPO
  • TRANS_ELASTIC
  • TRANS_CUBIC
  • TRANS_CIRC
  • TRANS_BOUNCE
  • TRANS_BACK

カーブの一覧は以下のページが参考になります。
https://easings.net/ja

たくさんあって使い道に悩みそうですが、個人的によく使うのは以下のものです。

  • TRANS_LINEAR: 等速移動
  • TRANS_EXPO: 急激なカーブ
  • TRANS_ELASTIC: 激しく揺れる
  • TRANS_CUBIC: 緩やかなカーブ
  • TRANS_BOUNCE: バウンドする
  • TRANS_BACK: 開始または終点を少しはみ出る

TRANS_LINEAR: 等速直線移動

等速直線移動なので動きに面白みはないですが、目立たないアニメーションを行う場合に便利です
shot.gif

TRANS_EXPO: 急激なカーブ

イージング関数チートシート.png

個人的に最もよく使うカーブです。メニューのUIにこれを適用して、各項目をずらしながら入場させると良い感じの動きとなります。
picture_pc_e4ae1509978f49076a5ee1aa47015723.gif

このカーブだと少し鋭すぎる場合には、TRANS_CUBIC が緩やかなカーブなのでおすすめです。
イージング関数チートシート.png

TRANS_ELASTIC: 激しく揺れる

ELASTICは激しく揺れるカーブです。
picture_pc_836dda81ef6ad06a93898069684d4d31.png
拡大しながら表示されるオブジェクトに適用するとコミカルな感じの登場になります。

picture_pc_5c67f13685246e743be3dd4801d5c339.gif

TRANS_BOUNCE: バウンドする

TRANS_BOUNCEはバウンドする挙動です。
使い所はやや難しいですが、壁にぶつかったり落下しながら入場するようなUIに向いていると思います。
shot.gif

TRANS_BACK: 開始または終点を少しはみ出る

BACKは、少しはみ出るような動きとなります。
picture_pc_94ceeee14289cbb3bf93cd2f98938048-2.gif

picture_pc_052229ed1d1c9db4596df2cc72994ffd.png

IN/OUTと終了コールバックの設定方法

あと、IN/OUT の指定ですが、OUTは入場、INは退場する場合に使うのが、使いやすいと思います。

以下は、ExpoOutのアニメーションの終了時にコールバックでExpoInのアニメーションを行うコードです

Sprite.gd
extends Sprite

func _ready():

    # 開始を少し待つようにしてみる
    yield(get_tree().create_timer(2), "timeout")

    # Tweenノードを生成する
    var tween:Tween = Tween.new()

    # アニメーションパラメータを設定
    tween.interpolate_property(
        self,             # 自分自身を登録
        "position",       # positionパラメータを制御
        position,         # 開始座標は現在地
        Vector2(200, 64), # (200, 64)に移動
        1,                # 1秒間で移動
        Tween.TRANS_EXPO, Tween.EASE_OUT # ExpoOutで移動
    )

    # ループ設定
    #tween.repeat = true # 1回再生して終わる場合は指定不要

    # 終了時のコールバックを設定   
    tween.interpolate_callback(self, tween.get_runtime(), "tween_end")

    # どこかのノードにぶら下げる必要がある
    add_child(tween)

    # 再生開始
    tween.start()

func tween_end():
    # Tween終了時に呼び出されるコールバック
    # Tweenノードを生成
    var tween:Tween = Tween.new()

    # アニメーションパラメータを設定
    tween.interpolate_property(
        self,             # 自分自身を登録
        "position",       # positionパラメータを制御
        position,         # 開始座標は現在地
        Vector2(800, 64), # (800, 64)に移動
        1,                # 1秒間で移動
        Tween.TRANS_EXPO, Tween.EASE_IN # ExpoInで移動
    )
    add_child(tween)

    # 再生開始
    tween.start()

入場をOut、退場をInにすると良い感じのアニメーションとなります。

shot.gif

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
5
Help us understand the problem. What are the problem?