Unity Cinemachineを使って、アートをクリックしたら、そのアートにフォーカスしてズームしていくカメラワークを作成しました。
これを実現するには以下の要素が必要です。
1.アート鑑賞用のCinemachine Virtual Cameraを作成する
2.アートオブジェクトにコライダーを設定する
3.コライダー上でクリックを検知したら、クリックされたアートオブジェクトのTransformを取得し、アート鑑賞用のVirtual CameraのBodyとAimにセットする
4.Virtual CameraのPriorityを変更し、通常用のVirtualカメラからアート鑑賞用Virtual Cameraにブレンドさせて切り替える
アート鑑賞用のCinemachine Virtual Cameraを作成する
まず、通常使うVitrual Cameraのほかに、以下のようなアート鑑賞用のVirtual Cameraを作成します。
Body はTransposer、Aim はComposerにしています。
Follow Offsetの Y, Zが1になっているのは何?と思われるかと思います。
本当は、汎用的に、どのアートに対しても自動的に正面から投影してくれるような設定にしたかったのですが、素人の私の技術ではうまく実現できませんでした。そのため、今回の記事には記載しませんが、実際には、アート毎にPivotの位置が異なったり、向きが異なったりしているため、BodyのFollow Offsetの値などもアート毎に変更するようにScriptで制御しています。
アートオブジェクトにコライダーを設定する
アートオブジェクトを選択し、Add Component →ボックスコライダーを選択して、適当な範囲を設定します。
コライダー上でクリックを検知したら、クリックされたアートオブジェクトのTransformを取得し、アート鑑賞用のVirtual CameraのBodyとAimにセットする
次に以下のようなスクリプトを作成し、アートオブジェクトにアタッチします。
OnMouseUpAsButton()でマウスクリックを検出すると、GameDirectorというインスタンスのSetTargetObjectというメソッドを呼び出し、そこに自分自身のtransformを渡す、というようなものです。
OnMouseUpAsButton()を使うために、4行目でusing UnityEngine.EventSystems; を宣言しています。
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.EventSystems;
- public class ArtViewController : MonoBehaviour
- {
- private void OnMouseUpAsButton()
- {
- GameDirector.instance.SetTargetObject (this.transform);//
- }
- }
↑アート側にアタッチするscript
なお、実際には、他のクリック操作等との排他制御が必要になるかと思います。
また、アートは複数配置するため、各アートに上記のスクリプトをアタッチすることになります。ですのでアート側のスクリプトは最小限にし、それとは別にGameDirectorを配置して、カメラはGameDirector スクリプトで制御することにします。
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using Cinemachine;
- public class GameDirector : MonoBehaviour
- {
- public static GameDirector instance = null;
- [SerializeField] CinemachineVirtualCamera virtualMainCamera;
- [SerializeField] CinemachineVirtualCamera artViewCamera;
- void Awake()
- {
- if (instance == null)
- {
- instance = this;
- DontDestroyOnLoad(this.gameObject);
- }
- else
- {
- Destroy(this.gameObject);
- }
- }
- public void SetTargetObject
- (Transform targetTransform)
- {
- // アートビューカメラにターゲットオブジェクトを指定
- artViewCamera.m_Follow = targetTransform;
- artViewCamera.m_LookAt = targetTransform;
- artViewCamera.m_Priority = 100;
- }
- }
↑ GameDirector側にアタッチするscript
空のGameObjectを作成し、GameDirector スクリプトをアタッチします。GameDirectorの virtualMainCamera にはメインで使うvirtualCamera、
ArtViewCameraにはアート鑑賞用のvirtualCameraを設定しておきます。
GameDirectorは、他にも色々なスクリプトから呼び出す想定のため、インスタンス化しています(8行目、15~26行目)。インスタンス化すると、いちいち他のスクリプトでGameDirectorをGetComponentする記載をしなくてよいため便利です。(なお、インスタンス化自体は今回やりたいカメラワークとは関係ありません)
30~31行目で、アートのTransform情報をアート鑑賞用カメラにセットしています。これで、アートをクリックするとアート鑑賞用のVirtual Cameraは以下のような状態になります。
Virtual CameraのPriorityを変更し、通常用のVirtualカメラからアート鑑賞用Virtual Cameraにブレンドさせて切り替える
上記scriptの32行目、 artViewCamera.m_Priority = 100; の部分になります。
(通常用のVitrual CameraのPriorityが100より小さい値になっていないとカメラが切り替わりませんので、前提として、通常用のVitrual CameraのPriorityは50とかにしておきます)
記事冒頭の動きをシーンビューで見ると以下のようになります。
Virtual Cameraの優先度が変更されたことが契機となってカメラのブレンド・切り替えが発生しています。
なお、上記のscriptは、アート鑑賞用のカメラに切り替わるところまでしか記載していませんが、その後、ダイアログを出してOKボタンをクリックしたら、 artViewCamera.m_Priority を50未満に変更するようにして動作を実現しています。この辺の一連の流れを実装するとなると、本当はTimelineを使うほうが簡単なようですが・・・使いこなせていません。
ちょっと長くなりましたが、今回は以上です。
“Unity CinemachineのBlendを使ってアートをクリックしたらそこにフォーカスして拡大するようにする” への1件の返信