ゲーム化!tomo_manaのブログ

ゲーム化!tomo-manaのブログ

Unityでゲームを作る方法について紹介しています

Unity/C# 滑らかに移動するカーソル

手打ちでもすぐできそうですが、地味にこういうのがすぐ用意できるとプロトタイプの制作がはかどるかもと思ったので。

滑らかに移動するカーソル


DOTween 使用します。ChatGPT-4o で作成しました。

コード

以下のコードをコピペします。

using UnityEngine;
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;

// ChatGPT-4o
public class CursorMover : MonoBehaviour
{
    public RectTransform cursor; // カーソルとなるUIのRectTransform
    public List<RectTransform> targets; // 移動先のRectTransformリスト
    public float moveDuration = 0.18f; // カーソルの移動時間(秒)
    public float transparentAlpha = 0.3f; // 移動中のアルファ値
    public float normalAlpha = 1f; // 移動後のアルファ値

    private CanvasGroup cursorCanvasGroup; // カーソルのCanvasGroupコンポーネント
    private Queue<Vector3> moveQueue = new Queue<Vector3>();
    private bool isMoving = false;

    void Start()
    {
        cursorCanvasGroup = cursor.GetComponent<CanvasGroup>();
        if (cursorCanvasGroup == null)
        {
            Debug.LogError("Cursor does not have a CanvasGroup component.");
        }
    }

    // 指定されたインデックスの位置にカーソルを移動させる関数
    public void MoveCursorToTarget(int index)
    {
        if (index >= 0 && index < targets.Count)
        {
            EnqueueMove(targets[index].position);
        }
        else
        {
            Debug.LogError("Index out of range: " + index);
        }
    }

    // 移動をキューに追加
    private void EnqueueMove(Vector3 targetPosition)
    {
        moveQueue.Enqueue(targetPosition);
        if (!isMoving)
        {
            StartCoroutine(ProcessMoveQueue());
        }
    }

    // キューを処理するコルーチン
    private IEnumerator ProcessMoveQueue()
    {
        isMoving = true;
        while (moveQueue.Count > 0)
        {
            Vector3 targetPosition = moveQueue.Dequeue();
            yield return MoveCursor(targetPosition);
        }
        isMoving = false;
    }

    // カーソルを移動させる関数
    private IEnumerator MoveCursor(Vector3 targetPosition)
    {
        // カーソルを半透明にする
        cursorCanvasGroup.alpha = transparentAlpha;

        // カーソルを移動させる
        cursor.DOMove(targetPosition, moveDuration);

        // 移動時間を待つ
        yield return new WaitForSeconds(moveDuration);

        // カーソルを元の透明度に戻す
        cursorCanvasGroup.alpha = normalAlpha;
    }
}

オブジェクトと階層(Hierarchy)

カーソルの画像 と カーソルの選択対象を同じCanvas内に入れます。

オブジェクトと階層(Hierarchy/Sceneビュー)

コンポーネント(Inspector)

カーソル画像側のオブジェクトに、先ほどのコードを付けます。

作成されるコンポーネント(CursorMover)
定義ラベル オブジェクトの種類 説明
Cursor RectTransform カーソル(Image)
Target List カーソル選択対象
Move Duration float カーソルが移動する時間[秒]
Transparent Alpha float カーソル移動中のアルファ{0-1}
Normal Alpha float カーソル停止時のアルファ{0-1}


先ほどのCursorオブジェクトに、CanvasGroupをセットで付けて下さい。(見た目を良くするため)

Cursorオブジェクトのコンポーネント配置

CursorMover の Cursor には、カーソルの画像を、Target にはカーソルに移動対象となるアイコン(ボタン)をセットします。

作成されるコンポーネント(CursorMover)

ボタン側は、CursorMover::MoveCursorToTarget(int index) を呼びます。
この時、Target に並べた順番と、インデックス番号を一致させるようにして下さい。

インデックスの指定

動作例

カーソルが滑らかに動いて、カーソルがどこに行ったかちょっと分かりやすくなります。

滑らかに移動するカーソル


(以上)