Unity C#:使用自动定位和鼠标查看的相机控制
Unity C#: Camera Control Using Automatic Positioning & Mouse Look
我通常 post 不在这里,但现在我花了好几个小时才弄明白这个问题,而且我已经在网上搜索过但找不到答案。我希望有人可以在这里帮助我。我是新手,这是我第一次尝试在 Unity C#[=33] 中结合两种跟随玩家移动的 第三人称视角控制 =]:
- 当玩家移动时,相机会捕捉到预定义的位置和旋转(无鼠标注视)
- 按住鼠标按钮时会激活鼠标外观,因此无论玩家的位置是否发生变化,相机都会根据鼠标移动进行旋转
它几乎可以正常工作,只是我似乎无法将鼠标外观重置为它的第一个预定义设置。在玩家释放鼠标按钮后,#1 的代码开始运行,因此相机似乎回到了默认视图。但是做进一步的鼠标外观,我注意到相机总是 returns 到它被停用的最后位置和旋转。我需要它回到原来的预定义位置和旋转,甚至在玩家激活他的第一个鼠标外观之前,这样它就不会让玩家迷失方向。
我尝试了几个代码,但无法让它工作,所以我删除了非工作行,只 post编辑了我认为适用的行。请参考我下面的代码。如果有人能帮助我,我将不胜感激。提前致谢!
编辑:更新了代码以提供两种控制相机的方法,并添加了建议的代码以重置当前的 X 和 Y 值。 Comment/uncomment 对每个方法调用进行测试。但是我还是遇到鼠标look的缩放不能平滑的问题
最终编辑: 我再次更新了下面的代码,对其进行了清理,并包含了建议的更改。代码现在应该可以正常工作并且没有任何抖动。感谢您的协助! :-)
上次最终编辑: 通过鼠标滚轮添加 "Field of View Zooming" 并因此完成了代码。
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);
}
}
}
更新:
试试这个
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))
{
...
我所做的是在 Update() 中按下鼠标时将 currentX 和 currentY 重置为其当前的欧拉角值。我在 LateUpdate()
中添加了一个位置 Lerp 到想要的 lookAround 位置
编辑:
Though I still haven't fixed the smooth zooming of the mouse look when right mouse button is initially held down
试试这个改变
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);
}
我通常 post 不在这里,但现在我花了好几个小时才弄明白这个问题,而且我已经在网上搜索过但找不到答案。我希望有人可以在这里帮助我。我是新手,这是我第一次尝试在 Unity C#[=33] 中结合两种跟随玩家移动的 第三人称视角控制 =]:
- 当玩家移动时,相机会捕捉到预定义的位置和旋转(无鼠标注视)
- 按住鼠标按钮时会激活鼠标外观,因此无论玩家的位置是否发生变化,相机都会根据鼠标移动进行旋转
它几乎可以正常工作,只是我似乎无法将鼠标外观重置为它的第一个预定义设置。在玩家释放鼠标按钮后,#1 的代码开始运行,因此相机似乎回到了默认视图。但是做进一步的鼠标外观,我注意到相机总是 returns 到它被停用的最后位置和旋转。我需要它回到原来的预定义位置和旋转,甚至在玩家激活他的第一个鼠标外观之前,这样它就不会让玩家迷失方向。
我尝试了几个代码,但无法让它工作,所以我删除了非工作行,只 post编辑了我认为适用的行。请参考我下面的代码。如果有人能帮助我,我将不胜感激。提前致谢!
编辑:更新了代码以提供两种控制相机的方法,并添加了建议的代码以重置当前的 X 和 Y 值。 Comment/uncomment 对每个方法调用进行测试。但是我还是遇到鼠标look的缩放不能平滑的问题
最终编辑: 我再次更新了下面的代码,对其进行了清理,并包含了建议的更改。代码现在应该可以正常工作并且没有任何抖动。感谢您的协助! :-)
上次最终编辑: 通过鼠标滚轮添加 "Field of View Zooming" 并因此完成了代码。
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);
}
}
}
更新: 试试这个
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))
{
...
我所做的是在 Update() 中按下鼠标时将 currentX 和 currentY 重置为其当前的欧拉角值。我在 LateUpdate()
中添加了一个位置 Lerp 到想要的 lookAround 位置编辑:
Though I still haven't fixed the smooth zooming of the mouse look when right mouse button is initially held down
试试这个改变
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);
}