【第16回】Sliderを使ってカメラの拡大率をゲーム画面から操作する

【第16回】Sliderを使ってカメラの拡大率をゲーム画面から操作する

前回のチュートリアルでは、ボールの動きに沿ってカメラが移動する処理を実装しました。

カメラが移動することでゲーム画面に描画される範囲が変わるため、より動きを感じられるようになります。

今回は、前回追加したカメラのズームイン・ズームアウト機能について、ゲーム画面から操作できるようにしてみます。

前回のチュートリアルはこちらから。

 

今回の目的

UIのSliderを使って、ゲーム画面からカメラのズームイン・ズームアウトを操作できるようにします。

プロジェクトの準備

前回のチュートリアルで作成したプロジェクトをそのまま使います。

このページに先にたどり着いた方は、チュートリアルの初回から追っていただけるといいかもしれません。

UIを追加する

現在のゲーム画面には、UIボタンとテキストが表示されています。

現在のゲーム画面
現在のゲーム画面

 

今回はここに新たなUIであるSlider(スライダー)を追加してみます。結構Unityでの操作が多くなるので、頑張って一緒にやっていきましょ。

親オブジェクトの作成

まずは『Canvas』オブジェクトを選択した状態で右クリックまたは二本指タップでコンテキストメニューを開きます。メニューから[Create Empty]を選択します。

空のオブジェクトを作成
空のオブジェクトを作成

 

作成された空のオブジェクトの名前を[ZoomParent]に変更します。今回追加するUIたちはこの子オブジェクトとして作成していきます。

ParentのTransform
名前を変更するのだポッター

 

『Slider』オブジェクトの作成

『ZoomParent』オブジェクトを選択した状態で、右クリックまたは二本指タップでコンテキストメニューを開き、[UI] -> [Slider]を選択します。

Sliderの作成
Sliderを作成する

 

『Slider』オブジェクトを作成すると、いくつかのパーツが一緒に作成されます。

Sliderのパーツ
いくつかのパーツがある

 

『Slider』オブジェクトのパーツは以下のようになっています。つまみの部分は『Handle』オブジェクトです。左側の青色になっている部分は『Fill』オブジェクト、右側のグレーの部分は『Background』オブジェクトです。

なお、『Fill』オブジェクトの色はデフォルトだと白色で、今回は分かりやすいように色を着けています。

Sliderの部位
Sliderの部位

 

『Slider』オブジェクトのカスタマイズ

ここからそれぞれのパーツをカスタマイズしていきます。

まずは『Slider』オブジェクトから。Scaleの値をそれぞれ[3]にします。WidthとHeightを直接いじらないのは、パーツの比率を維持したいためです。『Slider』オブジェクトは他のパーツの親オブジェクトなので、Scaleも子オブジェクトに適用され、バランスが崩れないんです。

SliderのRectTransform
Scaleを変更する

 

同じく『Slider』オブジェクトのSliderコンポーネント。ここではMin Valueを[50]に、Max Valueを[150]に設定します。この値は前回のスクリプトの中で、拡大率の最小値と最大値として設定した値です。

Whole Numbersは、値に整数のみを選べるようにするかどうかのチェックボックスです。チェックを入れると、取りうる値が整数のみとなります。スクリプトの中では拡大率をflaotにしていましたが、実際そこまで細かい値は必要ないため、整数にしましょ。スクリプトもあとで改修します。

OnValueChanged()はボタンの時にやったように、値が変わった時にスクリプトのpublicなメソッドを呼ぶことができます。ここもスクリプト改修時に設定を忘れずに。

また、Valueは初期値にもなるので、[100]にしておきます。実はこのValueが曲者で、『Inspector』ウィンドウからValueの値を変えるたびにWarningがコンソールに出るんですよね。

Sliderのカスタマイズ
Sliderのカスタマイズ

 

Valueを変えるたびに、

SendMessage cannot be called during Awake, CheckConsistency, or OnValidate
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

というWarningが。

Warning
Warningがズラリだぜ

 

この問題は、Unityで報告された問題やバグを追跡できる『Unity Issue Tracker』でも取り上げられていて、まだ治っていないようです。このチュートリアルと同じように、Sliderを追加してValueをいじったら出る、とコメントしている人もいるので、結構起こってる問題みたい。

幸い、ゲーム画面からSliderを操作し、スクリプトで値を拾う時にはこのWarningが出ません。なので、『Inspector』ウィンドウからValueを変えなければ、ひとまずは問題なさそうかな。Warningならゲーム実行は可能ですからね。

『Background』オブジェクト、『FillArea』オブジェクトは何もせず置いといて、『Fill』オブジェクトを選択して、色を変更します。Imageコンポーネント内にあるColorを選択し、[80C0FFFF](水色)に設定します。

Fillの色設定
Fillの色を設定

 

『Handle Slide Area』オブジェクト、『Handle』オブジェクトはそのままで大丈夫です。

 

拡大率表示用テキストを作成

次は拡大率を画面に表示するUIテキストを作成します。

『ZoomParent』オブジェクトを選択した後、右クリックまたは二本指タップでコンテキストメニューを開き、[UI] -> [Text]を選択します。

Textの作成
Textの作成

 

作成したオブジェクトを『ZoomText』にリネームし、Widthを[560]、Heightを[100]、Pos Yを[75]に設定。スライダーの少し上に来るようにします。

TextのTransform
WidthとHeightを変更

 

Textコンポーネントでは、Textフィールドに[Magnification : 100%]、Font Styleを[Bold]、Font Sizeを[48]、Alignmentを中央寄せで中段(両方真ん中を選べばOK)、Colorを[FFFFFFFF](白色)に設定します。

[Add Component] -> [UI] -> [Effects] -> [Outline]からOutlineコンポーネントを作成します。Effect DistanceのXを[2]、Yを[-2]に設定。

Textコンポーネントの設定
ハイスコアや飛距離のテキストと同様に装飾

 

ZoomParentの配置

今の状態だと画面中央に表示されているので、これらのパーツを一気に画面左下に持っていきます。親オブジェクトを作っておくと、複数のパーツがあっても一気に移動できるので便利です。

最初にZoomParentのアンカー設定。アンカーを選択し、[shift]キーと[alt(option)]キーを押しながら左下(bottom – left)を選びます。

アンカー設定
いつもの[shift] + [alt(option)]

アンカー設定後は位置を決めます。Pos Xを[250]、Pos Yを[25]にするのがちょうど良さそう。画面の大きさに合わせて適宜調整してくださいな。

Transformの設定
画面左下でちょうどいい位置に

 

設定が終わるとこんな感じになります。画面左下に無事配置できました。

ゲーム画面の様子
Sliderが配置された

 

スクリプトの編集

次はスクリプトを編集します。今回の方針は以下の通り。

  • Sliderを操作したことを検知するメソッドを作る
  • 上記メソッドから拡大率を操作
  • Sliderの値をテキストに表示
  • 拡大率をfloat型からint型に

これらを盛り込んで編集したのが以下のもの。変更点を紹介・解説します。

まずはusingの追加と、メンバ変数の追加です。『Slider』オブジェクトを操作するためにUnityEngine.UIを追加します。

『Slider』オブジェクトと『ZoomText』オブジェクトへの参照も忘れずに。また、操作したいコンポーネントをキャッシュするための変数も用意しています。

拡大率のテキストでは、数字以外の部分を文字列で宣言しています。拡大率そのものはint型に変更しました。なお、float型からint型に変えるときはおしりのfを忘れずに外します。

 

続いてStart()の中では、操作したいコンポーネントへの参照をキャッシュしています。『Slider』オブジェクトを操作する時に毎回GetComponentをするのはちょっと重いので、キャッシュして気持ち軽くしています。

 

次はGetMagnifiedOffset()です。3つ目の、拡大された距離を算出する計算を修正しました。実は前回の状態だと、拡大率150%でボールから遠ざかり、50%でボールに近づく仕様になってました。これは直感的じゃないので修正しましょ。

基準の距離はoffsetDistanceで、ここから拡大率に応じて距離を変えたいのですが、拡大率が大きい時に距離が短くなるように計算します。具体的には、拡大率100%を超えたらカメラの位置をボールの近くに、100%以下ならボールから遠い位置に配置します。

拡大率計算の考え方
拡大率計算の考え方

 

例えば、magnifyが150なら、カメラが基準の距離(赤色の線)から50%分ボールに近づく(青色の線)ことになり、その分カメラに映るボールが大きくなります。逆にmagnifyが50ならカメラが遠ざかる(オレンジ色の線)ためにボールが小さく映ります。

数直線での概念図
数直線での概念図

 

これを式変形したものが、スクリプトの記述です。200fは式変形の過程で出てきた数字なのでご安心ください。

最後にOnChangedMagnifyValue()です。これは『Slider』オブジェクトのValueが変わった時に呼び出されるメソッドです。『Slider』オブジェクトの値を拡大率magnifyにセットし、『ZoomText』オブジェクトにmagnifyの値を表示するようにしています。

 

これでスクリプトの準備ができました。変更点を記載しましたが、スクリプトの全文は『GitHub Gist』にあります。

 

オブジェクトのセット

スクリプトを保存してUnityに戻ったら、忘れずにUnity側の設定をしておきます。

まずはオブジェクト参照のセットから。『Main Camera』オブジェクトのCameraControllerを開き、Slider Objectフィールドに『Slider』オブジェクトをセットし、Zoom Text Objectフィールドに『ZoomText』オブジェクトをセットします。

『Hierarchy』ウィンドウからドラッグ&ドロップするか、フィールドの右にある丸ボタンからオブジェクトを選択します。

CameraControllerの設定
CameraControllerにオブジェクトをセット

 

続いて、『Slider』オブジェクトを選択し、SliderコンポーネントのOnValueChangedの設定を行います。イベントを通知するオブジェクトとして『Main Camera』オブジェクトをセットし、呼び出すメソッドとして[CameraController] -> [OnChangedMagnifyValue()] を選択します。

Sliderコンポーネント
OnValueChangedをセット

 

動作確認

んじゃ確認しましょ。(GIFは2倍速)

ズームイン・ズームアウト
ズームイン・ズームアウトがゲーム画面から操作可能に

 

ちゃんと拡大率が上がったらボールに近づいていますね。現在の拡大率もテキストとして表示されています。

いやー今回はなかなかのボリュームでした。『Slider』オブジェクト関連で設定項目が多かったので、その分盛りだくさんですしたね。

ズームイン・ズームアウトが実装できたので、次は……ボールに加える力の最大値を決めるために、ボールの飛距離予想を画面に表示するようにしましょうか。

まとめ

今回は『Slider』オブジェクトを使って、カメラのズームイン・ズームアウトを実装しました。

宝箱を開けた時や、ステージのゴールにたどり着いた時など、カメラを近づけてキャラクターを大きく映す演出はよく使われるので、スクリプトから自在にカメラを操れるようになると便利です。

次回はボールの飛距離予想とガイドを表示してみます。カービィボウルでよく見るアレっぽいのです。

アセット作ってます!

CTA-IMAGE

Unityでの開発に役立つアセットを作っています。

3DダンジョンRPGを開発するスピードを200%加速するAssetや、ファンタジーRPGのダンジョンを彩るパーツを取り揃えています。

特に3DダンジョンRPGのゲームを1から作るのは結構時間がかかります。ダンジョン部分の作成はこうしたアセットを使って、開発をブーストさせてみませんか?