3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Unity】Spritesでゲージを作る、成功ゾーンを添えて①【サンプル有】

Last updated at Posted at 2022-11-18

本実装のサンプルはこちらに用意しています。Unity Hubからプロジェクトとして立ち上げてみてください。
https://github.com/konbraphat51/GaugePrototype
ブラウザ上で動くデモ:https://konbraphat51.github.io/GaugePrototypeWEBGL/

次の記事:https://qiita.com/konbu9640/items/aa4696beb85a64854bbd

作りたいもの

ブラウザ上で動くデモ:https://konbraphat51.github.io/GaugePrototypeWEBGL/
Untitled.png
Untitled.png
上図のように、任意の形の図形が、片側から段々着色されていくようなゲージをspriteで作ります。

もしImageでの実装でよければ、こちらの記事の実装がとてもやりやすいです。
しかしImageでの実装となると、表示優先度(どちらが前でどちらが奥か)の管理がやりづらかったりして、Spriteでやれたらなと思い立ち、今回の記事に至りました。

ちなみに、応用として「成功ゾーン」も試みています。(上図、黄色の部分)
気分としてはドラクエ11の「不思議な鍛冶」のゲージですね。このゾーンに到達できなかったり超過してしまうと失敗してしまうやつ。

用意する画像(通常ゲージ)

このために、下記の画像を用意しました。(png透過処理済みです)

土台
Slot.png

緑の着色
Fill.png

右半分が透過されている長方形(マスク用)
LeftHalf.png

左半分が透過されている長方形(マスク用)
LeftHalf (1).png

作戦(通常ゲージ)

まずは土台の上に着色のスプライトをそのまま上乗せしちゃいます。
Untitled.png

そこで、先ほど用意した半分透過長方形をマスクとして使うと、なんとゲージっぽくなるではないですか。
Untitled.png

すなわち、我々がすべきことは、表示する割合に応じて、このマスクを移動していけばいいというわけです。

なぜわざわざ半分透過した画像を用意したかというと、下図のようにピボットがちょうど表示する部分と隠される部分の境界に位置するので、このマスク全体の座標がそのまま境界線の座標になり、指定がやりやすくなるからです。
Untitled.png

実装(通常ゲージ)

まずはスクリプト。これはどれにアタッチしても大丈夫です。私は土台スプライトにアタッチしました。

Gauge.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Must to call Initialize() first
/// </summary>
public class Gauge : MonoBehaviour
{
    //where Fill comes until
    private float showingRatio = 0f;

    [SerializeField] private GameObject rightEdgeObject;
    private float rightEdge;
    [SerializeField] private GameObject leftEdgeObject;
    private float leftEdge;

    [SerializeField] private GameObject reachedMovingMask;

    [Tooltip("Reverse")]
    [SerializeField] public bool goingRight;

    private void Start()
    {
        //set edge variable
        GetEdge();
    }

    /// <summary>
    /// this must be called
    /// </summary>
    /// <param name="showingRatio"></param>
    public void Initialize(float showingRatio)
    {
        //initialize variable
        this.showingRatio = showingRatio;

        //in case if this come earlier than Start()
        GetEdge();

        //Move to start point
        Animate();
    }

    /// <summary>
    /// Displaying gauge changes by here. 
    /// </summary>
    /// <param name="ratio"></param>
    public void SetRatio(float ratio)
    {
        showingRatio = ratio;

        //guard
        if (showingRatio < 0f) showingRatio = 0f;
        if (showingRatio > 1f) showingRatio = 1f;

        Animate();
    }

    //reached sprite move by here.
    private void Animate()
    {
        //where the mask position go
        float edgePosX = GetHorizontalPosition(showingRatio);

        //move the mask
        reachedMovingMask.transform.position = new Vector2(edgePosX, reachedMovingMask.transform.position.y);
    }

    private void GetEdge()
    {
        rightEdge = rightEdgeObject.transform.position.x;
        leftEdge = leftEdgeObject.transform.position.x;
    }

    protected float GetHorizontalPosition(float ratio)
    {
        float output = 0f;

        switch (goingRight)
        {
            case false:
                //going left
                output = rightEdge - (rightEdge - leftEdge) * ratio;
                break;
            case true:
                //going right

                output = leftEdge + (rightEdge - leftEdge) * ratio;
                break;
        }

        return output;
    }
}

ゲージのオブジェクト構成は下図のようにしています。
Untitled.png

一番親のGaugeが土台スプライト、
Right, Leftは空スプライト、
GaugeReachedが着色スプライト、
MovingMaskが先述の動かすマスクです。

Gauge:土台スプライト

Untitled1.png
RectTransformGaugeをアタッチ。
RectTransformをつけることによって、後述のRight, Leftの座標指定が楽になります。
Gaugeにはそれぞれ対応するオブジェクトをアタッチ。最後のGoing Rightは右向きに溜めていくならチェックをつけ、左向きなら外してください

Right, Left:空スプライト

Untitled2.png
これにもRectTransformをアタッチ。すると楽々にRightを右端に、Leftを左端に配置できます。

GaugeReached

着色スプライトはそのまま子オブジェクトとして上乗せ。元画像のサイズがあっていればPositionを(0,0,-1)にすることでキレイに重なります。(Z座標は上に乗せるため負数に)
これにSorting Groupをアタッチしてください。後述のMovingMaskの適用範囲がこのスプライトのみにするためです。

MovingMask

これは右向きに溜めていくなら左半分の長方形画像を、左向きに溜めていくなら右半分の長方形画像でSpriteMaskを作ってください。

これで通常ゲージは完成です!

成功ゾーンは続編の記事にて!

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?