2 回答
TA贡献1836条经验 获得超4个赞
好 的 , 我 现在 要 做 三 件 事 。First and foremost, I'm going to recommend that if you're working with advanced camera behavior, you probably want to at least consider using Cinemachine.我 想 亲自 给 你 讲解 一下 , 但 鉴于 我 缺乏 亲身 经历 , 我 可能 会 给 你 带来 伤害 。有 很多 很 好 的 教程 在 那里 。youtube 和 谷歌 应该 提供 。
我要做的第二件事是用我能管理的最直接的方式解决你的问题,然后,我们再看看是否能想出一个更好的方法来解决你的问题。
所以,这里的关键是Unity的滚轮输入是非常二进制的。当你检查一个滚轮轴时,结果直接基于自上次帧更新以来你的滚轮经历了多少次“点击”,但你真正想要的是一些有一点给予的东西。默认情况下,Unity实际上可以对大多数轴输入执行此操作:您可能会注意到,如果您在默认Unity项目中使用WASD,则会有一种“滞后”现象,您的手指会离开按键,但仍会从输入.获取轴()对于几个帧。这与重力输入设置中的值,以及输入.GetAxisRaw()函数实际上是用来完全规避这一点的。不管出于什么原因,滚轮轴似乎不受轴重力的影响,所以我们本质上必须自己实现类似的东西。
// Add this property to your class definition (so it persists between updates):
private float wheelAxis = 0;
// Delete this line:
var zoomDelta = Input.GetAxis("Mouse ScrollWheel") * zoomSpeed * Time.deltaTime;
// And put these three new lines in its place:
wheelAxis += Input.GetAxis("Mouse ScrollWheel");
wheelAxis = Mathf.MoveTowards(wheelTotal, 0f, Time.deltaTime);
var zoomDelta = Mathf.Clamp(wheelAxis, -0.05f, 0.05f) * zoomSpeed * Time.deltaTime;
好的,我们在这里做一些事情。每次更新时,我们都会将当前滚轮值添加到轮轴。接下来,我们将电流Time.deltatime“重力”通过数学函数移动到()得双曲余切值.最后,我们称之为“老”缩放增量经过简单修改代码:我们约束轮轴与Mathf.Clamp以尝试和调节变焦可以发生得多快。
您 可以 通过 几 种 方式 修改 此 代码 。If you multiply the Time.deltaTime parameter you can affect how long your input will "persist" for. If you mess with the Mathf.Clamp() values, you'll get faster or slower zooming.总 而言 之 , 如果 您 只 想 在 对 代码 进行 最 小 更改 的 情况 下 实现 平滑 缩放 , 这 可能 是 最 好 的 选择 。
这样 啊 !
现在 我们 已经 完成 了 这些 , 让 我们 来 讨论 一下 您 的 代码 , 以及 您 是 如何 处理 问题 的 , 看看 我们 是否 能 找到 一 个 稍微 干净 一些 的 解决 方案 。
让一台好的相机工作起来是非常重要的。你的代码看起来像我看到的很多试图解决复杂问题的代码:看起来您添加了一些功能,然后对其进行了测试,发现了一些崩溃的边缘情况,然后修补了这些情况,然后尝试在旧代码上实现新功能,但它以各种其他方式中断,等等,我们在这一点上得到的有点混乱。
你的代码最大的问题是摄像头位置摄像头自转紧密地联系在一起。当与字符工作时,这通常是好的,但当与相机工作时,你想要打破这一点。想想摄像头是以及相机是什么查看作为非常独立的事情来记录。
因此 , 这里 有 一 个 工作 的 相机 脚本 , 你 应该 能够 插入 和 运行 :
using UnityEngine;
public class RTSCamera : MonoBehaviour
{
public float zoomSpeed = 100f;
public float zoomTime = 0.1f;
public float maxHeight = 100f;
public float minHeight = 20f;
public float focusHeight = 10f;
public float focusDistance = 20f;
public int panBorder = 25;
public float dragPanSpeed = 25f;
public float edgePanSpeed = 25f;
public float keyPanSpeed = 25f;
private float zoomVelocity = 0f;
private float targetHeight;
void Start()
{
// Start zoomed out
targetHeight = maxHeight;
}
void Update()
{
var newPosition = transform.position;
// First, calculate the height we want the camera to be at
targetHeight += Input.GetAxis("Mouse ScrollWheel") * zoomSpeed * -1f;
targetHeight = Mathf.Clamp(targetHeight, minHeight, maxHeight);
// Then, interpolate smoothly towards that height
newPosition.y = Mathf.SmoothDamp(transform.position.y, targetHeight, ref zoomVelocity, zoomTime);
// Always pan the camera using the keys
var pan = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")) * keyPanSpeed * Time.deltaTime;
// Optionally pan the camera by either dragging with middle mouse or when the cursor touches the screen border
if (Input.GetMouseButton(2)) {
pan -= new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y")) * dragPanSpeed * Time.deltaTime;
} else {
var border = Vector2.zero;
if (Input.mousePosition.x < panBorder) border.x -= 1f;
if (Input.mousePosition.x >= Screen.width - panBorder) border.x += 1f;
if (Input.mousePosition.y < panBorder) border.y -= 1f;
if (Input.mousePosition.y > Screen.height - panBorder) border.y += 1f;
pan += border * edgePanSpeed * Time.deltaTime;
}
newPosition.x += pan.x;
newPosition.z += pan.y;
var focusPosition = new Vector3(newPosition.x, focusHeight, newPosition.z + focusDistance);
transform.position = newPosition;
transform.LookAt(focusPosition);
}
}
虽然我鼓励你在自己的时间里去经历它,但我不打算拖你走过它的每一寸,相反,我只会把主要的症结过一遍。
The key idea here is that rather than controlling the camera's height and orientation directly, we just let the scrollwheel dictate where want the camera's height to be, and then we use Mathf.SmoothDamp() to move the camera smoothly into that position over several frames.( Unity 有 很多 像 这样 有用 的 功能 。Consider Mathf.MoveTowards() for an alternative interpolation method.)在 最 后 , 我们 并 没有 直接 调整 摄像 机 的 旋转 值 , 而是 在 我们 面前 靠近 地面 的 地方 选择 一 个 点 , 然后 直接 将 摄像 机 对准 那个 点 。
通过保持摄像机的位置和方向完全独立,以及分离出摄像机高度的“动画”,我们避免了很多麻烦,并消除了许多混乱交织的错误的可能性。
希望 能 帮 上 忙 。
- 2 回答
- 0 关注
- 266 浏览
添加回答
举报
