質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

2903閲覧

CinemachineのVirtualCameraの感度をスクリプトから参照したい

退会済みユーザー

退会済みユーザー

総合スコア0

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

1クリップ

投稿2019/07/09 06:44

UnityでCinemachineというカメラAssetを使っています。
そのCinemachineFreeLookCameraというモードで、カメラ感度をスクリプトから参照したいのですが、調べてもわかりませんでした。カメラ感度を参照する方法をご教授いただきたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

マニュアルによれば、X軸、Y軸についてそれぞれ「Max Speed」、「Accel Time」、「Decel Time」のパラメーターがあり、「最大速度」、「目標速度まで達するのにかかる加速時間」、「入力がなくなったときに速度がゼロに戻るのにかかる減速時間」を意味するようです。

X軸パラメーターはm_XAxis、Y軸パラメーターはm_YAxisから一塊のAxisState構造体として取得および設定できるようでした。ここをいじってみてはいかがでしょうか?

C#

1using Cinemachine; 2using UnityEngine; 3 4[RequireComponent(typeof(CinemachineFreeLook))] 5public class SensitivityController : MonoBehaviour 6{ 7 [SerializeField] private float quickModeMaxSpeedX = 360.0f; 8 [SerializeField] private float quickModeAccelTimeX = 0.1f; 9 [SerializeField] private float quickModeDecelTimeX = 0.1f; 10 [SerializeField] private float quickModeMaxSpeedY = 2.0f; 11 [SerializeField] private float quickModeAccelTimeY = 0.2f; 12 [SerializeField] private float quickModeDecelTimeY = 0.1f; 13 14 [SerializeField] private float slowModeMaxSpeedX = 60.0f; 15 [SerializeField] private float slowModeAccelTimeX = 0.5f; 16 [SerializeField] private float slowModeDecelTimeX = 0.5f; 17 [SerializeField] private float slowModeMaxSpeedY = 0.2f; 18 [SerializeField] private float slowModeAccelTimeY = 1.0f; 19 [SerializeField] private float slowModeDecelTimeY = 0.5f; 20 21 private CinemachineFreeLook freeLook; 22 23 private void Start() 24 { 25 this.freeLook = this.GetComponent<CinemachineFreeLook>(); 26 } 27 28 private void Update() 29 { 30 if (Input.GetKeyDown(KeyCode.Space)) 31 { 32 // スペースバーを押し下げるともっさりモード 33 var xAxis = this.freeLook.m_XAxis; 34 var yAxis = this.freeLook.m_YAxis; 35 36 xAxis.m_MaxSpeed = this.slowModeMaxSpeedX; 37 xAxis.m_AccelTime = this.slowModeAccelTimeX; 38 xAxis.m_DecelTime = this.slowModeDecelTimeX; 39 40 yAxis.m_MaxSpeed = this.slowModeMaxSpeedY; 41 yAxis.m_AccelTime = this.slowModeAccelTimeY; 42 yAxis.m_DecelTime = this.slowModeDecelTimeY; 43 44 this.freeLook.m_XAxis = xAxis; 45 this.freeLook.m_YAxis = yAxis; 46 } 47 else if (Input.GetKeyUp(KeyCode.Space)) 48 { 49 // スペースバーを離すときびきびモード 50 var xAxis = this.freeLook.m_XAxis; 51 var yAxis = this.freeLook.m_YAxis; 52 53 xAxis.m_MaxSpeed = this.quickModeMaxSpeedX; 54 xAxis.m_AccelTime = this.quickModeAccelTimeX; 55 xAxis.m_DecelTime = this.quickModeDecelTimeX; 56 57 yAxis.m_MaxSpeed = this.quickModeMaxSpeedY; 58 yAxis.m_AccelTime = this.quickModeAccelTimeY; 59 yAxis.m_DecelTime = this.quickModeDecelTimeY; 60 61 this.freeLook.m_XAxis = xAxis; 62 this.freeLook.m_YAxis = yAxis; 63 } 64 65 // m_XAxis、m_YAxisはプロパティではなくフィールドなので、内部のメンバーに 66 // 直接アクセスしてもいいでしょう 67 // AxisStateのサイズは少し大きめ(88バイト)のようですので、頻繁に書き換えるなら 68 // 直接アクセス方式の方が効率的なような気がします 69 /* 70 if (Input.GetKeyDown(KeyCode.Space)) 71 { 72 this.freeLook.m_XAxis.m_MaxSpeed = this.slowModeMaxSpeedX; 73 this.freeLook.m_XAxis.m_AccelTime = this.slowModeAccelTimeX; 74 this.freeLook.m_XAxis.m_DecelTime = this.slowModeDecelTimeX; 75 76 this.freeLook.m_YAxis.m_MaxSpeed = this.slowModeMaxSpeedY; 77 this.freeLook.m_YAxis.m_AccelTime = this.slowModeAccelTimeY; 78 this.freeLook.m_YAxis.m_DecelTime = this.slowModeDecelTimeY; 79 } 80 else if (Input.GetKeyUp(KeyCode.Space)) 81 { 82 this.freeLook.m_XAxis.m_MaxSpeed = this.quickModeMaxSpeedX; 83 this.freeLook.m_XAxis.m_AccelTime = this.quickModeAccelTimeX; 84 this.freeLook.m_XAxis.m_DecelTime = this.quickModeDecelTimeX; 85 86 this.freeLook.m_YAxis.m_MaxSpeed = this.quickModeMaxSpeedY; 87 this.freeLook.m_YAxis.m_AccelTime = this.quickModeAccelTimeY; 88 this.freeLook.m_YAxis.m_DecelTime = this.quickModeDecelTimeY; 89 } 90 */ 91 } 92}

動かしてみた感想としては、操作感度調整目的でパラメーターを書き換えるならm_MaxSpeedだけでもいいかもしれませんね。カメラが操作しにくくなる...みたいな特殊な演出をするのでしたらいいでしょうが、もし精密エイミングモード的な位置づけでカメラを遅くするのでしたら、加速時間・減速時間を長くしすぎるともっさり感が強すぎるかもしれません。

#追記
まず、プレイヤーによる視点操作を無効化する件については単にX軸・Y軸の入力ソース名...m_InputAxisNameを空欄に変えるだけでよさそうでした。

※ご注意いただきたいのですが、デフォルトでは「Save During Play」がオンになっています。何らかのパラメーター...たとえば今回の入力ソース名の場合、それらを空欄に書き換えたままプレイモードを終了させると、変更が元に戻らず保存されていますので次回プレイモードにしたときに最初からカメラが動かせなくなってしまうでしょう。
プレイモード終了タイミングでパラメーターを復元するようなコードにしてもいいと思いますが、正しく復元するにはスクリプト実行順の調整も必要そうだったりで少々面倒そうに感じました。ですのでプレイモード中にパラメーター調整を行いたい場合以外は、素直に「Save During Play」をオフにした方がいいかと思います。

あとはスクリプトからの操作ですが、こっちはちょっとやっかいそうです。下記コードのコメント内でも言及しましたが、手動操作の時と同様のイメージで現在の向きから相対的に動かすのでしたらm_InputAxisValueに入力量を入れてやればよさそうでした。さらにm_MaxSpeed書き換えも併用すれば回転速度を正確にコントロールできそうです。この動作で問題なければシンプルで済みますのでおすすめかと思います。

C#

1using Cinemachine; 2using UnityEngine; 3 4[RequireComponent(typeof(CinemachineFreeLook))] 5public class CameraLocker : MonoBehaviour 6{ 7 private CinemachineFreeLook freeLook; 8 private string xAxisName = string.Empty; 9 private string yAxisName = string.Empty; 10 11 private void Start() 12 { 13 this.freeLook = this.GetComponent<CinemachineFreeLook>(); 14 15 // X軸、Y軸の設定を覚えておく 16 this.xAxisName = this.freeLook.m_XAxis.m_InputAxisName; 17 this.yAxisName = this.freeLook.m_YAxis.m_InputAxisName; 18 } 19 20 private void Update() 21 { 22 if (Input.GetKeyDown(KeyCode.Space)) 23 { 24 // スペースバーが押し下げられたら入力元の名前をを空にする 25 this.freeLook.m_XAxis.m_InputAxisName = string.Empty; 26 this.freeLook.m_YAxis.m_InputAxisName = string.Empty; 27 28 // 入力値も消去して、ロック後に余力で回り続けてしまうのを防ぐ 29 this.freeLook.m_XAxis.m_InputAxisValue = 0.0f; 30 this.freeLook.m_YAxis.m_InputAxisValue = 0.0f; 31 } 32 else if (Input.GetKeyUp(KeyCode.Space)) 33 { 34 // スペースバーが離されたら設定を復元する 35 this.freeLook.m_XAxis.m_InputAxisName = this.xAxisName; 36 this.freeLook.m_YAxis.m_InputAxisName = this.yAxisName; 37 } 38 39 if (Input.GetKey(KeyCode.Space)) 40 { 41 // ロック中(スペースバーが押されている間)... 42 43 // プレイヤーの手動操作をシミュレートするイメージでm_InputAxisValueに 44 // 値を入れてやれば、現在の角度から相対的に回転すると思います 45 // たとえば下記のようにすると、垂直位置はゆっくり上リグへ移動していき 46 // 水平位置はゆっくり時計回りに回転するでしょう 47 // (ただし各軸の「Invert」を切り替えている場合は向きが逆になるはずです) 48 this.freeLook.m_XAxis.m_InputAxisValue = -0.1f; 49 this.freeLook.m_YAxis.m_InputAxisValue = 0.1f; 50 51 /* 52 // しかし相対値ではなく絶対値で向きを指定するのはやっかいそうです 53 // Y軸については意図通り操作できそうでしたが... 54 this.freeLook.m_YAxis.Value = 0.75f; // 上リグと中リグの中間位置 55 56 // X軸で同じことをやろうとしても、Binding ModeがSimple Follow With World Upだと 57 // くるくる回り続けて使い物にならないでしょう 58 this.freeLook.m_XAxis.Value = 90.0f; // 基準方向に対して90°の位置にしたつもり 59 */ 60 } 61 } 62}

やっかいなのは相対値ではなく絶対的に向きを指定したい場合で、Y軸についてはm_YAxis.Valueに0~1の値(0で下、0.5で中央、1で上のリグ)を代入すればいいので楽そうでしたが、X軸はFreeLookCameraの「Orbits」→「Binding Mode」の設定によって挙動が変化するようです。
「World Space」とかでしたらY軸と同様にm_XAxis.Valueに代入することで操作できますが、デフォルトの「Simple Follow With World Up」ではそうはいかないようでした。「World Space」だとキャラクターをカメラに対して横に走らせても角度が変わらないのに対し、「Simple Follow With World Up」はカメラの移動量が最小限になるためいい感じに移動方向へパンして自然なカメラワークになり魅力的ですが、スクリプトからのコントロールをするには面倒ですね。

バインディングモードもスクリプトから切り替えてやることで何とかできるのかもしれませんが、モード切り替わり時に視点が飛んでしまうのを防ぐにはカメラ位置調整が必要で、やはり一筋縄にはいかなそうです。
そこまでするぐらいならこの際もう1基バーチャルカメラを作成してキャラクターに追従させ、自由操作モードではFreeLookをアクティブに、強制視点モードでは追加のバーチャルカメラをアクティブにする...みたいなアプローチの方がCinemachineの流儀に合っていそうでいいんじゃないかと思うのですが、いかがでしょうかね?

投稿2019/07/09 12:17

編集2019/07/11 20:34
Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/07/11 02:14

返信が遅れてすいません!無事設定することができました。今回は操作感度目的だったので、m_MaxSpeedだけでも全然いい感じでした。もう一つ質問したいのですが、FreeLookCamera自体のポジションをスクリプトから設定できるようにしたいのですが、どこにプロパティがあるのでしょうか?もしくはMainCameraのポジションを直接いじって設定する感じになってしまうのでしょうか?
Bongo

2019/07/11 03:42

なるほど、後で調べてみようと思いますが(今はUnityが手元にないためすみません)、ポジションを設定したいとおっしゃるのは「プレイヤーが操作することで視点を回すのを一時的に禁止し、スクリプトから強制的に回したい」といった感じでしょうか?あるいは「FreeLookCameraの上・中・下の旋回軌道リグ半径をスクリプトから調節し、キャラクターとカメラの距離を変えたい」ということでしょうか。
退会済みユーザー

退会済みユーザー

2019/07/11 04:14

説明不足ですいません。プレイヤーが操作することで視点を回すのを一時的に禁止し、スクリプトから強制的に回したいということです。視点操作は一時的に無効になります。
Bongo

2019/07/11 20:52 編集

検討してみましたが、ダイレクトな角度指定までは達成できずすみません。追記の最後で言及したような、バーチャルカメラをもう一つ増やして、それをスクリプトでコントロールした方が楽な気がしてきました。
退会済みユーザー

退会済みユーザー

2019/07/11 21:53

ご検討ありがとうございました。バーチャルカメラをもう一つ増やす方が確かに楽ですね。カメラを事前にもう一つセットしておく形で今回は行きたいと思います。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問