相对于另一个物体的方向向一个物体施加力

问题描述 投票:0回答:1

我正在制作一款 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);
}
c# unity-game-engine
1个回答
0
投票

首先,不要奇怪地夹紧

+- 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);
© www.soinside.com 2019 - 2024. All rights reserved.