Unity C#: управление камерой с помощью автоматического позиционирования и мыши
Я обычно не пишу здесь, но мне потребовались часы, чтобы понять это, и я уже искал в сети, но не смог найти ответ. Я желаю, чтобы кто-то мог помочь мне здесь. Я новичок, и я впервые пытаюсь объединить два типа управления камерой от третьего лица, которые следуют за движением игроков в Unity C#:
- Камера перемещается в предопределенную позицию и поворачивается при движении игрока (без мышки)
- Мышь Look активируется, когда удерживается кнопка мыши, и поэтому камера вращается в соответствии с движением мыши, независимо от того, изменяется позиция игрока или нет
Это почти работает, за исключением того, что я не могу сбросить Mouse Look к его первому предустановленному значению. После того, как проигрыватель отпускает кнопку мыши, начинает действовать код для #1, и камера, похоже, возвращается к своему виду по умолчанию. Но, продолжая смотреть с помощью мыши, я заметил, что камера всегда возвращается в последнюю позицию и вращение было отключено. Мне нужно, чтобы он вернулся в исходное заранее заданное положение и вращение еще до того, как Игрок активирует свой первый Мышь, так что это не слишком дезориентирует Игрока.
Я попробовал несколько кодов, но не смог заставить его работать, поэтому я удалил нерабочие строки и просто разместил те, которые, я думаю, применимы. Пожалуйста, обратитесь к моему коду ниже. Был бы признателен, если кто-то может мне помочь. Заранее спасибо!
Изменить: Обновил код, чтобы иметь два метода управления камерой и добавил предложенный код для сброса текущих значений X и Y. Комментарий / раскомментируйте каждый вызов метода для проверки. Но у меня все еще есть проблема с невозможностью сгладить масштабирование мышки.
Окончательное редактирование: я снова обновил приведенный ниже код, очистил его и включил предложенные изменения. Код должен теперь быть полностью работоспособным и не иметь дрожания. Спасибо за помощь!:-)
Последнее финальное редактирование: добавлено "Масштабирование поля зрения" с помощью колеса мыши, после чего код завершен.
using UnityEngine;
using System.Collections;
public class PlayerViewController : MonoBehaviour {
// General Vars
public Transform targetFollow;
private bool lookAround = false;
// For SmoothDampFollow
public Vector3 followDefaultDistance = new Vector3 (0f, 12.0f, -20f);
public float followDistanceDamp = 0.2f;
public Vector3 followVelocity = Vector3.one;
// For Camera Orbit
public float orbitDistance = 20.0f;
public float orbitDamp = 5.0f;
private const float angleMinY = 7.0f;
private const float angleMaxY = 50.0f;
private float currentX = 7.0f;
private float currentY = 50.0f;
// For Zooming Field Of View
public float FOVmin = 50.0f;
public float FOVmax = 100.0f;
public float mouseWheelSpeed = 5.0f;
void Update () {
if (Input.GetMouseButtonDown (1)) {
currentX = transform.eulerAngles.y;
currentY = transform.eulerAngles.x;
}
if (Input.GetMouseButton (1)) {
lookAround = true;
} else {
lookAround = false;
}
ZoomFOV ();
}
void FixedUpdate () {
if (lookAround) {
CameraOrbit ();
} else {
SmoothDampFollow ();
}
}
void ZoomFOV () {
if (Input.GetAxis ("Mouse ScrollWheel") > 0) {
GetComponent<Camera> ().fieldOfView = GetComponent<Camera> ().fieldOfView - mouseWheelSpeed;
if (GetComponent<Camera> ().fieldOfView <= FOVmin) { GetComponent<Camera> ().fieldOfView = FOVmin; }
} else if (Input.GetAxis ("Mouse ScrollWheel") < 0) {
GetComponent<Camera> ().fieldOfView = GetComponent<Camera> ().fieldOfView + mouseWheelSpeed;
if (GetComponent<Camera> ().fieldOfView >= FOVmax) { GetComponent<Camera> ().fieldOfView = FOVmax; }
}
}
void SmoothDampFollow () {
if (!targetFollow) {
return;
} else {
Vector3 wantedPosition = targetFollow.position + (targetFollow.rotation * followDefaultDistance);
transform.position = Vector3.SmoothDamp (transform.position, wantedPosition, ref followVelocity, followDistanceDamp);
transform.LookAt (targetFollow, targetFollow.up);
}
}
void CameraOrbit () {
if (!targetFollow) {
return;
} else {
currentX += Input.GetAxis ("Mouse X");
currentY += Input.GetAxis ("Mouse Y");
currentY = Mathf.Clamp (currentY, angleMinY, angleMaxY);
Vector3 dir = new Vector3 (0, 0, -orbitDistance);
Quaternion rotation = Quaternion.Euler (currentY, currentX, 0);
Vector3 wantedPosition = targetFollow.position + rotation * dir;
transform.position = Vector3.Lerp (transform.position, wantedPosition, Time.deltaTime * orbitDamp);
transform.LookAt (targetFollow.position);
}
}
}
1 ответ
Обновлено: попробуйте это
void LateUpdate()
{
if (lookAround)
{
currentX += Input.GetAxisRaw("Mouse X");
currentY += Input.GetAxisRaw("Mouse Y");
currentY = Mathf.Clamp(currentY, angleMinY, angleMaxY);
Vector3 dir = new Vector3(0, 0, -distance);
Quaternion rotation = Quaternion.Euler(currentY, currentX, 0);
Vector3 wantedPosition = target.position + rotation * dir;
transform.position = Vector3.Lerp(transform.position, wantedPosition, Time.deltaTime * damping);
camTransform.LookAt(target.position);
}
...
А также
void Update()
{
// Here
if (Input.GetMouseButtonDown(1))
{
currentX = transform.eulerAngles.y;
currentY = transform.eulerAngles.x;
}
if (Input.GetMouseButton(1))
{
...
То, что я сделал, я сбросил currentX и currentY к их текущим значениям eulerangle при нажатии мыши в Update(). И я добавил позицию Lerp в нужную позицию lookAround в LateUpdate()
РЕДАКТИРОВАТЬ:
Хотя я все еще не исправил плавное масштабирование вида мыши, когда правая кнопка мыши изначально нажата
Попробуйте это изменение
void CameraOrbit()
{
currentX += Input.GetAxisRaw("Mouse X");
currentY += Input.GetAxisRaw("Mouse Y");
currentY = Mathf.Clamp(currentY, angleMinY, angleMaxY);
Vector3 dir = new Vector3(0, 0, -distance);
Quaternion rotation = Quaternion.Euler(currentY, currentX, 0);
// -->
Vector3 wantedPosition = target.position + rotation * dir;
transform.position = Vector3.Lerp(transform.position, wantedPosition, Time.deltaTime * damping);
// <--
camTransform.LookAt(target.position);
}