【Unity】Virtual Cameraの視点操作をスクリプトで行う 【Cinemachine】
この記事はユニティちゃんライセンス条項の元に提供されています
ユニティちゃん1.2.1
Unity2019.3.1
やりたいこと
ゲームパッドの左アナログスティックでキャラクターを動かし、右アナログスティックでカメラの視点(映し出す方向)を操作したい(アクションゲームとかでありがちなやつ)。
大まかな流れ
追従:Virtual CameraのFollowとLookAtに対象のオブジェクトをアタッチすれば勝手に追従してくれる。
視点の操作:Virtual CameraのBiasとFollow Offsetの値をスクリプトで変化させることで実現。
※視点を操作することによってプレイヤーが意識する座標系とワールド座標系が異なるため補正をしなければならない。
Virtual Cameraの設定
1.Virtual CameraをHierarchyに追加
Window>Package ManagerからCinemachineをインポートした後、Cinemachine>Create Virtual Cameraを選択。
2.Virtual Cameraがキャラクターを追従するように設定
Follow(追いかける対象)とLookAt(注視する対象)にオブジェクトをアタッチ。
3.Bodyを設定
Input Axis Nameを空にすることでマウスで勝手に視点操作されないようにする。
4.視点の角度などを良い感じに設定
5.BiasとFollow Offset
BodyのBiasとFollow Offsetをいじるとカメラの視点がキャラクターを中心に変化していることが分かります。
[Bias]
[Follow Offset]
このBiasとFollow Offsetをスクリプトから操作します。
スクリプトからVirtual Cameraを操作して視点を回転させる
using Cinemachine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class test : MonoBehaviour
{
[SerializeField] private Animator _animator;
private float moveSpeed = 7f;
private CharacterController _characterController;
[SerializeField] private CinemachineVirtualCamera _camera; //エディタでVirtual Cameraをアタッチ
private CinemachineOrbitalTransposer _transposer;
private Transform _transform;
private Vector3 _moveVelocity;
private Vector3 world_moveVelocity;
private Vector3 _cameraRotation;
void Start()
{
_characterController = GetComponent<CharacterController>();
_transposer = _camera.GetCinemachineComponent<CinemachineOrbitalTransposer>();
_transform = transform;
_moveVelocity = Vector3.zero;
world_moveVelocity = Vector3.zero;
_cameraRotation = Vector3.zero;
}
void Update()
{
world_moveVelocity = Vector3.zero;
_moveVelocity = Vector3.zero;
_cameraRotation.x = Input.GetAxisRaw("Horizontal2");
_cameraRotation.z = Input.GetAxisRaw("Vertical2");
if (_cameraRotation.magnitude >= 0.1)
{
_transposer.m_Heading.m_Bias += _cameraRotation.x * 3f; //Biasを操作
_transposer.m_FollowOffset.y -= _cameraRotation.z / 8f; //Follow Offsetを操作
}
_moveVelocity.x = Input.GetAxisRaw("Horizontal1") * moveSpeed;
_moveVelocity.z = Input.GetAxisRaw("Vertical1") * moveSpeed;
if (_moveVelocity.magnitude >= 0.01)
{
//座標系の補正
world_moveVelocity = Quaternion.AngleAxis(_transposer.m_Heading.m_Bias, Vector3.up) * _moveVelocity;
Vector3 targetPositon = _transform.position + world_moveVelocity;
//向かせたい方向
Quaternion targetRotation = Quaternion.LookRotation(targetPositon - _transform.position);
_transform.rotation = Quaternion.Slerp(_transform.rotation, targetRotation, 0.2f);
}
_characterController.Move(world_moveVelocity * Time.deltaTime);
_animator.SetFloat("Speed", new Vector3(_moveVelocity.x, 0, _moveVelocity.z).magnitude);
}
}
using Cinemachine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class test : MonoBehaviour
{
[SerializeField] private Animator _animator;
private float moveSpeed = 7f;
private CharacterController _characterController;
[SerializeField] private CinemachineVirtualCamera _camera; //エディタでVirtual Cameraをアタッチ
private CinemachineOrbitalTransposer _transposer;
private Transform _transform;
private Vector3 _moveVelocity;
private Vector3 world_moveVelocity;
private Vector3 _cameraRotation;
void Start()
{
_characterController = GetComponent<CharacterController>();
_transposer = _camera.GetCinemachineComponent<CinemachineOrbitalTransposer>();
_transform = transform;
_moveVelocity = Vector3.zero;
world_moveVelocity = Vector3.zero;
_cameraRotation = Vector3.zero;
}
void Update()
{
world_moveVelocity = Vector3.zero;
_moveVelocity = Vector3.zero;
_cameraRotation.x = Input.GetAxisRaw("Horizontal2");
_cameraRotation.z = Input.GetAxisRaw("Vertical2");
if (_cameraRotation.magnitude >= 0.1)
{
_transposer.m_Heading.m_Bias += _cameraRotation.x * 3f; //Biasを操作
_transposer.m_FollowOffset.y -= _cameraRotation.z / 8f; //Follow Offsetを操作
}
_moveVelocity.x = Input.GetAxisRaw("Horizontal1") * moveSpeed;
_moveVelocity.z = Input.GetAxisRaw("Vertical1") * moveSpeed;
if (_moveVelocity.magnitude >= 0.01)
{
//座標系の補正
world_moveVelocity = Quaternion.AngleAxis(_transposer.m_Heading.m_Bias, Vector3.up) * _moveVelocity;
Vector3 targetPositon = _transform.position + world_moveVelocity;
//向かせたい方向
Quaternion targetRotation = Quaternion.LookRotation(targetPositon - _transform.position);
_transform.rotation = Quaternion.Slerp(_transform.rotation, targetRotation, 0.2f);
}
_characterController.Move(world_moveVelocity * Time.deltaTime);
_animator.SetFloat("Speed", new Vector3(_moveVelocity.x, 0, _moveVelocity.z).magnitude);
}
}
Horizontal1とVertical1は左アナログスティック(移動)の軸で、Horizontal2とVertical2は右アナログスティック(視点)の軸。
1.BiasとFollow Offset
BiasとFollow Offsetは以下のように操作できます。
[SerializeField] private CinemachineVirtualCamera _camera;
_transposer = _camera.GetCinemachineComponent<CinemachineOrbitalTransposer>();
_transposer.m_Heading.m_Bias += _cameraRotation.x * 3f; //Biasを操作
_transposer.m_FollowOffset.y -= _cameraRotation.z / 8f; //Follow Offsetを操作
2.座標系の補正
Biasを操作して水平方向に視点を回転させると、プレイヤーが意識する座標系とワールド座標系にBias分の角度の差が生まれます。
プレイヤーが右移動を入力したとき、想定する挙動は赤色の矢印方向への移動なのに、
右上のワールド座標系のx軸(赤)方向への移動になってしまう。
移動入力ベクトルをy軸まわりにBias分だけ回転させることで解決できる。
//座標系の補正
world_moveVelocity = Quaternion.AngleAxis(_transposer.m_Heading.m_Bias, Vector3.up) * _moveVelocity;
参考リンク
Author And Source
この問題について(【Unity】Virtual Cameraの視点操作をスクリプトで行う 【Cinemachine】), 我々は、より多くの情報をここで見つけました https://qiita.com/vodef6/items/e107a110d16f02d6530a著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .