UnityのMoveTo

cocos2d-xならrunAction(MoveTo(2, Vec2(50, 0)))のような感じで簡単にスプライトを動かすことができますよね。

Unity使い始めたら、オブジェクトを動かすのに、きっとcocos2d-xのような組み込みのメソッドあると思い、いろいろと探してみました。
結局そのようなもの見つかっておらず、基本的にはUpdate()におけるフレームごとの操作による演出のようです。

いくつサンプルみた中、2Dチュートリアルアプリ「Roguelike」スプライト動かすスクリプトが一番分かりやすかったと思います。

その中のMoveObjectを参考にして以下の点を変更しました。

  1. UI.Imageにも使えるようにlocal positionが変動するように変更
  2. 決まった時間で移動ではなく、決まったスピードで移動するように変更
  3. 移動終了後のコールバックを追加

そして、こうなります。

using System.Collections;
using UnityEngine;

public class MoveObject : MonoBehaviour
{

    public delegate void MoveObjectDelegate();
    protected MoveObjectDelegate callback;

    public float speed = 500f;

    public virtual void move(Vector3 targetPosition)
    {
        StartCoroutine(SmoothMovement(targetPosition));
    }

    public virtual void move(Vector3 targetPosition, MoveObjectDelegate moveObjectDelegate)
    {
        callback = moveObjectDelegate;
        StartCoroutine(SmoothMovement(targetPosition));
    }

    protected IEnumerator SmoothMovement(Vector3 targetPosition)
    {
        //Calculate the remaining distance to move based on the square magnitude of the difference between current position and end parameter. 
        //Square magnitude is used instead of magnitude because it's computationally cheaper.
        float sqrRemainingDistance = (transform.localPosition - targetPosition).sqrMagnitude;

        //While that distance is greater than a very small amount (Epsilon, almost zero):
        while (sqrRemainingDistance > float.Epsilon)
        {
            //Find a new position proportionally closer to the end, based on the moveTime
            Vector3 newPostion = Vector3.MoveTowards(transform.localPosition, targetPosition, speed * Time.deltaTime);

            //Call MovePosition on attached Rigidbody2D and move it to the calculated position.
            transform.localPosition = newPostion;
            //rb2D.MovePosition(newPostion);

            //Recalculate the remaining distance after moving.
            sqrRemainingDistance = (transform.localPosition - targetPosition).sqrMagnitude;

            //Return and loop until sqrRemainingDistance is close enough to zero to end the function
            yield return null;
        }
        OnMoveDone();
    }

    protected virtual void OnMoveDone()
    {
        if (callback != null)
            callback();
    }
}

そしたら、obj.move(GetPositionOfTarget(), OnArriced);というように使えます。

コメントを残す

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