我正在制作一款 fps 游戏,考虑到这一点,扫射很重要。我试图让玩家相对于他们在游戏中看到的位置移动。 我有 3 个 Vector3,
moveDir
、lookDir
和 forceDir
。 moveDir
是运动矢量(即按 D(向右)使 moveDir
的 Z 设置为 1,W(向前)将 X 值设置为 1,等等)。 `lookDir` 是玩家正在看的方向,扁平化后只关心 y 旋转。 forceDir
是要施加的矢量力。
我尝试了各种组合 move & Look Dir 来设置
forceDir
的方法(主要是乘以 move & Look Dirs),但这产生了奇怪的结果。
粗略绘制的我想要的与实际玩家动作的图像。
如果我按住 W(向前),我会期望向玩家所面对的方向移动,如果按住 A(向左),我会期望垂直向左移动到玩家所面对的方向。相反,它仅应用相对于世界空间的这些力,或者更奇怪的是,当我俯视 X 或 Z 平面时。
上下文的代码块:(每帧运行)
private void MovePlayer()
{
//above I have it so inputs are handled (fore & backwards motion is handled in walkY, strafing in walkX)
walkX = Mathf.Clamp(walkX, -1.42f, 1.42f); walkY = Mathf.Clamp(walkY, -1.42f, 1.42f);
walkDir = new Vector3(walkY, 0, walkX);
walkX *= 0.7f; walkY *= 0.7f;
walkX = (walkX >= 0.001f || walkX <= 0.001f ? 0 : walkX);
walkY = (walkY >= 0.001f || walkY <= 0.001f ? 0 : walkY);
//"flattening" the look direction, so it only cares about Y rotation
Vector3 lookDir = Vector3.Scale(mainCamera.transform.forward, new Vector3(0, 1, 0));
//Vector3.zero until I can find out how to properly do what I want
Vector3 forceDir = Vector3.zero;
//apply the force
playerRB.AddForce(forceDir * walkSpeed, ForceMode.Acceleration);
}
首先,不要奇怪地夹紧
+- 1.42
(我假设你的意思是√2
),你应该使用Vector3.ClampMagnitude
来夹紧整个输入向量
var input = new Vector3(walkY, 0, walkX);
// This ensures that even when moving diagonal the input is never bigger than 1 in total
input = Vector3.ClampMagnitude(input, 1f);
walkDir = input;
// not sure why this magic factor
input *= 0.7f;
然后是你的条件
walkX >= 0.001f || walkX <= 0.001f
将永远是真的 - 我想你忘记添加一些
-
符号并使用&&
而不是||
,如
input.x = input.x >= -0.001f && input.x <= 0.001f ? 0 : input.x;
或者简单地使用
Mathf.Abs
使其更易于阅读
input.x = Mathf.Abs(input.x) <= 0.001f ? 0f : input.x;
然后回到您的实际问题:您可以简单地使用
camera.transform.forward
来旋转整个输入向量并随后将其展平,而不是使用 camera.transform.rotation
这是一个向量:
// input is now aligned with the camera rotation so
// input.x points in camera.transform.right direction
// input.z points in camera.transform.forward direction
input = camera.transform.rotation * input;
// erases the Y and normalizes so now you have a vector in the global XZ plane
input.y = 0;
// optional - it could e.g. be desired that if looking straight down the forward is shrinking
input = input.normalized;
所以现在应该将你的力量添加到正确的方向
playerRB.AddForce(input * walkSpeed, ForceMode.Acceleration);