Sliderで水位表現

2021年9月2日

この記事で得られること

今回は、本サロンで解決した「Slider」での水位表現の方法を、復習を兼ねてアウトプットします!

youTubeからこのスタジオしまづのホームページに迷いこんだ人(初心者限定)に向けて

プログラムスキルそんなに高くなくても、サロンで解決できる参考例を提示したいと思います。

完成イメージ

※水面アセットはLux Waterを利用してますが、長くなるのでアセットの操作方法は記載していません。

Lux Water  $17.60

https://assetstore.unity.com/packages/vfx/shaders/lux-water-119244

やりたかったこと

プレーンオブジェクトを水面に見立てて、災害状態3つのオブジェクトを切り替えたい。
(平常時の水面「青」、その間の水面 「黄」 、洪水きた水面 「赤」 )

完成イメージ
手書きで考えた図

手順はこちらです

それではやっていきましょう。。

STEP1 まず動かすオブジェクトを作っていきます

・A,B,Cオブジェクトの生成(赤、青、黄色のオブジェクトです)

・水位調整を行うオブジェクト(Create Empty、、、空のオブジェクトです)

空のオブジェクトを作るのが最初違和感ありましたが、今は現場監督だと思って作業しています。

[SerializeField] でコードから下記の様に操作するオブジェクトを登録します

[SerializeField] でコードから操作するオブジェクトを登録しますの図

STEP2 Sliderオブジェクトを生成するよ

・ヒエラルキー右クリック>>UI>> Slider

・UIは別空間なので出来上がると、こんな感じになります。

Sceneビュー画面

Gameビュー 画面

STEP3 コードで扱うオブジェクトのことを書いていくよ

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//UI(Slider)を扱うので追加

public class GameManager : MonoBehaviour
{
    [SerializeField] GameObject maxObject;//赤いやつ
    [SerializeField] GameObject middleObject;//黄色いやつ
    [SerializeField] GameObject minObject;//青いやつ
   👆SetActiveで表示・非表示するのに必要

    [SerializeField] Slider slider;//スライダー
   👆値をマイフレーム調べて、位置を変えるのに必要

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

STEP4  登録作業をします

Main画面で、どのオブジェクトがどれのことなのかをunity(SerializeField)にお伝えします。

登録イメージ図

STEP5  黄色いやつをコードから動かすよ!

private void Update()
{
    Vector3 cPos = middleObject.transform.position; // Cの位置をゲット => cPosに入れる

    cPos.y = slider.value; 
  //cPosの高さ(y)を、スライダーの値に書き換える(ここは変数が変わっているだけ)

    middleObject.transform.position = cPos; //cPosの高さをエディターに反映する
}

ここでは、分かりにくいとこを検証してみます。。

変数が変わっているのに、なぜ自然に値を更新してくれないのか??

すごく違和感ありますよね。。

なのでここでは、、

これはUnityの仕様上、仕方のない事なのだと諦めをつけるためにも、最後のコードをコメントアウトして、 cPos.y の値をコンソールに出してみて「現実」が変わらない事を検証していきます。

private void Update()
{
    Vector3 cPos = middleObject.transform.position; // Cの位置をゲット
    cPos.y = slider.value; //yを書き換える
    Debug.Log(cPos.y);
    //middleObject.transform.position = cPos;
}

すると、、、

検証結果

cPos.y の値が変わっているのに、黄色いやつはうんともすんとも。

つまり、 Vector3 型cPos の変数の値は変わっているのに、エディターには反映されないことが確認できました。

これは、 Vector3 型 が、自然に変数の値を更新して反映してくれないことを表しています。

更に深めるために、、これを肉を焼くまでに例えます(しつこい)

1.まな板の上に、肉を置く(Vector3を宣言)

2.まな板の上で、肉を切る(Vector3の値を変更)

3.フライパンで、肉を焼く(Vector3を更新)

の手順になると思います。

まな板で切っただけでは、生肉で食べられない。

だから最後の行のtransform.position がいるんですね!!

完成と思いきやの図-1

transform.position の行を復活させると、この通り!!

残りは、表示/非表示(SetActive)の設定だけですね

STEP6 Sliderのvalueで出すオブジェクトを変える

水位の条件によって切り替えたいので、

・0m (最小値)

・10m(最大値)

・その間

各スライダー位置の時に、表示どうするのかを書きます。

private void Update()
{
    //「ぴったり0m」の時、、、
    if (slider.value == 0)
    {
        minObject.SetActive(true);//青いやつ【〇】
        middleObject.SetActive(false);//黄色いやつ
    }
    //そうではなくて「ぴったり10m」の時、、、
    else if (slider.value == slider.maxValue)
    {
        maxObject.SetActive(true);//赤いやつ【〇】、、、
        middleObject.SetActive(false);//黄色いやつ
    }
    //それ以外の時、全部
    else
    {
        minObject.SetActive(false);//青いやつ
        maxObject.SetActive(false);//赤いやつ
        middleObject.SetActive(true);//黄色いやつつける【〇】
    }

こう書くと、、、こうなります。

完成と思いきや-2

何か違います。

一瞬で分かりずらいですが初期表示は、黄色ではなく青色が「絶対」条件でした。

STEP7 最後に、Start関数にデフォルト値を設定します

正しく治していきましょう。。

    private void Start()
    {
        //最初はスライダーの値を0にしておく
        slider.value = 0;
        //青いやつを表示
        minObject.SetActive(true);
        middleObject.SetActive(false);
        maxObject.SetActive(false);
    }

これを書くと、、、

完成

おつかれさまでした。以上で完成です。

「共感出来る」ことあった方、「何かの役」に立った方ハートボタン押して頂ければうれしい限りです!

Unity

Posted by takase