今回はスタンダードアセットのCarの速度をUIに表示する機能を作成していきます。
以前の記事でスタンダードアセットのCarを使って台地を走らせました。
今回はスタンダードアセットのCarの速度をゲーム画面右下にメーターと数値で表示する機能を作成したいと思います。
今回の機能を作成すると以下のようなものが出来上がります。
スタンダードアセットのCarを配置する
機能を作成する前に予め車が走る地面とスタンダードアセットのCarプレハブをヒエラルキー上に配置しておきます。
ヒエラルキー上で右クリックからCrate→3D Object→Planeを選択し、TransformのScaleのXYZを5000に設定します。
このPlaneが車が走る地面になります。
次にAssets/StandardAssets/Vehicles/Car/Prefabs/Carをヒエラルキー上にドラッグ&ドロップします。
Carはそのままキーボードの十字キー等で操作出来るようになっています。
速度表示用のUIの作成
速度表示用のUIを作成していきます。
ヒエラルキー上で右クリックからUI→Panelを選択し、Panelの左上の矢印をShiftキーを押しながらドラッグし右下に小さく表示するようにサイズを調整します。
Panelは車の速度表示に関するUIの大枠として使用するだけなのでコンポーネントのImageの横のチェックを外し透明にしておきます。
Panelを選択した状態で右クリックからUI→Panelを選択し、名前をSpeedMeterPanelとします。
SpeedMeterPanelのAnchor Presetsではstretch stretchを選択し、親要素のPanelに合わせてサイズが変わるようにします。
SpeedMeterPanelのインスペクタのAdd ComponentからUI→Maskを選択しSpeedMeterPanelの子要素のUI要素をマスクするようにします。
SpeedMeterPanelのImageのSource Imageには速度メーターの画像を設定するようにします。
今回は以下のような画像を設定しました。
スタンダードアセットの画像だったかもしれないですが、どこで入手した画像かはわかりません・・・・・。
SpeedMeterPanelにもAdd ComponentからUI→Maskを選択し子要素のUIをマスクするようにします。
次に速度メーターは0キロ~最高速度までのメーターを表示させるようにしますが、そのメーターは下からくるっと回って360度回転するのではなく0キロの時は左下、最高速度の時は右下ぐらいまでにメーター表示を制限します。
なので速度メーターの範囲として使用する画像を作成します。
上のように下がハの字になるような画像を作成します。
赤い部分以外は透明になるようにしています。
上の画像はご自由にお使いください。
作成したらUnityに取り込みインスペクタのTexture TypeをSpriteに変更します(ファイル名はspeedmeterとしました)。
次にSpeedMeterPanelを選択した状態で右クリックからUI→Panelを選択し、名前をBackgroundColorPanelとします。
BackgroundColorPanelのインスペクタのImageのSource Imageに先ほど取り込んだspeedmeterを設定します。
ImageのColorでRGBを0、Aを100とします。
BackgroundColorPanelは速度メーターの背景となります。
次にBackgroundColorPanelを選択した状態で右クリックからUI→Imageを選択し、名前をSpeedMeterImageとします。
ColorはRAを255、GBを0とします。
SpeedMeterImageのAnchor Prestsはstretch stretchにし、親要素のBackgroundColorPanelのサイズに合わせます。
ImageのSource Imageに先ほど取り込んだspeedmeterを設定します。
Image TypeをFilleddにし、Fill Methodを360とし、Fill Amountが1の時に360度回転するようにします。
Fill OriginはBottomにし下から回転するようにします。
Clockwiseにチェックを入れ時計回りに回転させます。
SpeedMeterImageを実際の速度のメーター表示に使います。
次にSpeedMeterPanelを選択し右クリックからUI→Textを選択し、名前をSpeedTextとします。
SpeedTextのAnchor Presetsはstretch stretchを選択し、親のSpeedMeterPanelのサイズに合わせます。
TextのFont Sizeを調整し、速度メーターの中に速度のテキストが表示されるようにします。
ParagraphのAlignmentを真ん中に設定します。
ここまでの速度表示用UIのヒエラルキーは以下のようになります。
速度表示メーターは以下のようになります。
これで速度表示用UIの作成が終わりました。
車の速度を取得しUIに表示する
車の速度表示用UIが出来たので、後は車の速度を取得してそれをUIに表示するだけです。
新しくOutputCarSpeedスクリプトを作成し、ヒエラルキー上に配置したCarオブジェクトに取り付けます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityStandardAssets.Vehicles.Car; public class OutputCarSpeed : MonoBehaviour { // スタンダードアセットのCarの速度を保持しているスクリプト private CarController carController; [SerializeField] private Image speedImage = null; [SerializeField] private Text speedText = null; [SerializeField] private float percentage = 22f; // Start is called before the first frame update void Start() { carController = GetComponent<CarController>(); } // Update is called once per frame void Update() { // Imageの表示率を最大速度に対する現在の速度で計算する var ratio = Mathf.InverseLerp(0f, 1f, Mathf.Abs(carController.CurrentSpeed) / carController.MaxSpeed); // 速度用のImageの最小と最大を補正した値で計算 speedImage.fillAmount = Mathf.Lerp(percentage / carController.MaxSpeed, (carController.MaxSpeed - percentage) / carController.MaxSpeed, ratio); // 現在の速度をテキストに表示する speedText.text = Mathf.Abs(carController.CurrentSpeed).ToString("000") + "km/h"; } } |
車の速度を保持しているのはCarオブジェクトに取り付けられたCarControllerなので、フィールドでcarControllerを宣言し、Startメソッドで同じオブジェクトに取り付けられているCarControllerを取得し入れておきます。
CarController.CurrentSpeedで現在の速度、CarController.MaxSpeedで最大速度が得られます。
Updateメソッドで行っていることは速度メーターのImageのFill Amountの量の調整です。
Fill Amountは0~1の間の数値を渡す必要があるので、最大速度に対する現在の速度の割合を与えると最低速度で0、最大速度で1の値が返ってきて、それをそのままFill Amountに設定すると良さそうです。
ですが、ハの字型の表示にしたので、単純にcarController.CurrentSpeed / carController.MaxSpeedとすると0~1の値が返ってきてしまって最低速度や最高速度付近の画像表示がおかしくなります。
そこで0の時は左下、最高速度の時は右下となるように調整する必要があります。
なので、Mathf.InverseLerpを使ってまずは最低が0、最高が1の時の最高速度に対する現在の速度の割合を求めratioに入れておきます。
Mathf.InverseLerpは第1引数が最低値、第2引数に最大値、の時の第3引数の値の割合を求める事が出来ます。
次にMathf.Lerpで補正した最低値と補正した最大値の時のその割合ratioでの値を求めています。
percentageは作成したspeedmeterの画像の位置と合わせる為の調整値です。
percentageの値はUnityを実行した後にOutputCarSpeedのインスペクタのpercentageの値を調整しスピードが0の時に速度メーターの左下付近をメーターが動くように調整します。
速度の調整が分かり辛いですが・・・・要は
元の速度メーターImageの範囲を0~10としていた時の現在の速度が2であるとすれば
1 2 3 | var ratio = Mathf.InverseLerp(0f, 10f, 2f); |
で帰ってくる値ratioは0.2になります。
それを速度メーターの範囲に収める為に2~8の間に調整したいので
1 2 3 | Mathf.Lerp(2f, 8f, ratio); |
とします。
返ってくる値は3.2となります。
Fill Amountには0~1の間の値を設定する必要があるので先ほどのようにcarController.MaxSpeedで割る必要があります。
このように最小値と最大値を指定した範囲の修正しています。
最後に現在のスピードの絶対値をMathf.Absで計算し、3桁で速度を表示しています。
1 2 3 | speedText.text = Mathf.Abs(carController.CurrentSpeed).ToString("000") + "km/h"; |
これで機能が出来ました。
CarオブジェクトのOutputCarSpeedのインスペクタのSpeedImageにSpeedMeterImage、SpeedTextにSpeedTextを設定し確認してみてください。
終わりに
車の速度メーターってバックの時はどういう表示をするんですかね?
一応免許持ってますが、ペーパーなのでわからないです・・・・・。
バックの時は0km/hならばスクリプトはそのように改造してみてください。(._.)