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 關注
- 208 瀏覽
添加回答
舉報