英文:
Rotate a vector in unity
问题
在纸上看,这似乎是一个简单的问题,但我整天都卡在这里。问题是有许多方法,我不能旋转它,因为我稍后要添加其他东西,这对其中许多解决方案都不适用。我正在制作一个第三人称玩家控制器(从上方俯视,类似于"foxhole"或"wasteland 3")。
我的问题是玩家需要相对于摄像机移动,但需要独立于摄像机旋转。按下A和D将使角色相对于摄像机向左和向右移动,按下W和S将使角色相对于摄像机向前和向后移动。然而,我需要能够使角色独立于摄像机旋转,所以我需要能够在仍然按照上述规则移动角色的同时面向任何方向。
Vector2 targetHorizontalMoveDirection = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
Vector2 horizontalMoveDirection = Vector2.MoveTowards(horizontalMoveDirection, targetHorizontalMoveDirection.normalized * maxSpeed, movementAcceleration * Time.deltaTime);
Vector3 finalMoveDirection = new Vector3(horizontalMoveDirection.x, 0, horizontalMoveDirection.y);
if(finalMoveDirection != Vector3.zero)
{
playerCharacterController.Move(finalMoveDirection * Time.deltaTime);
}
我希望保留前三行基本不变,因为它们提供了我想要保留的移动权重和加速度。我觉得理想的解决方案应该介于finalMoveDirection
和Controller.move
之间,允许我旋转finalMoveDirection
向量以获得一个新向量,其前进方向与摄像机面对的方向相匹配。
我尝试过的一个解决方案,但无法完全解决的是像这样的东西,我真正更改的只是角色控制器行。
playerCharacterController.Move(
(finalMoveDirection.x * cam.transform.right) +
(finalMoveDirection.z * cam.transform.forward) +
(0f * Vector3.up)
)
这在某种程度上有效,但问题是摄像机倾斜下来,指向地面,这意味着试图向前和向后行走会导致您朝着摄像机前进,进入空中,或者向前,进入地面。如果有一种方法可以获取摄像机的前进方向,而不是指向地面(就像它是直视前方一样),那也可以工作,但我无法弄清楚。我觉得这可能是一个可行的解决方案,但如果我可以旋转向量使其与地面水平,那么为什么我不首先旋转移动向量以远离摄像机呢?
还有其他一些解决方案,比如使用Mathf.Atan2
来获取角度,然后使用Quaternion.AngleAxis
来旋转向量,但没有成功。我尝试了很多我现在记不起来的东西,但迄今为止没有运气。
英文:
On paper, it seems like a simple issue, but ive been stuck on it all day. The issue is that there are many ways that I cant rotate this because i have additional things that i am going to add later that wouldnt work for many of these solutions. I am making a 3rd person player controller (top down perspective like foxhole or wasteland 3).
The issue i have is that the player needs to move relative to the camera, but rotate independently of it. Pressing A and D will move the character left and right relative to the camera, W and S forward and back relative to camera. However, I need to be able to have the character rotate independently of the camera, so i need to be able to face any direction while still moving the character relative to the camera as the rules above tell it to.
Vector2 targetHorizontalMoveDirection = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
Vector2 horizontalMoveDirection = Vector2.MoveTowards(horizontalMoveDirection, targetHorizontalMoveDirection.normalized * maxSpeed, movementAcceleration*Time.deltaTime);
Vector3 finalMoveDirection = new Vector3(horizontalMoveDirection.x, 0, horizontalMoveDirection.y);
if(finalMoveDirection != Vector3.zero)
{
playerCharacterController.Move(finalMoveDirection * Time.deltaTime);
}
I would like to keep the first 3 lines mostly as they are, as that gives the movement weight and acceleration which id like to keep. I feel an ideal solution would be something between finalMoveDirection and Controller.move that lets me rotate the finalMoveDirection Vector to get a new vector that has a forward direction that matches the direction the camera is facing.
One solution that i tried but couldnt quite figure out was something like this, the only thing i really changed was the character controller line.
playerCharacterController.Move(
(finalMoveDirection.x*cam.transform.right)+
(finalMoveDirection.z*cam.transform.forward)+
(0f*Vector3.up)
)
This sort of worked but the issue was that the camera is angled down and points into the floor, meaning trying to walk forwards and back would cause you to walk towards the camera, into the air, or forward, into the ground. If theres a way to get the forward direction of the camera without having it point into the ground (like if it was looking completely straight) then that could work also, but i couldnt figure that out. I feel like this could be a likely solution but if i could rotate the vector to be level to the ground, what would be stopping me from just rotating the move vector to just face away from the camera in the first place?
Theres a number of other solutions i tried, like using Mathf.Atan2 to get an angle and then using Quaternion.AngleAxis to rotate the vector, which didnt work. I tried a bunch of stuff that i cant remember now but so far no luck.
答案1
得分: 0
根据通常情况,我一提出问题就能理解。尽管如此,我仍然觉得应该回答它,以防其他人需要。
Vector2 targetHorizontalMoveDirection = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
Vector2 horizontalMoveDirection = Vector2.MoveTowards(horizontalMoveDirection, targetHorizontalMoveDirection.normalized * maxSpeed, movementAcceleration * Time.deltaTime);
Vector3 finalMoveDirection = new Vector3(horizontalMoveDirection.x, 0, horizontalMoveDirection.y);
if (finalMoveDirection != Vector3.zero)
{
Vector3 CameraVectorParallelToGround = Vector3.ProjectOnPlane(cam.forward, Vector3.up);
playerCharacterController.Move(
(
(finalMoveDirection.x * CameraVectorParallelToGround.normalized) +
(Vector3.up * 0f) +
(finalMoveDirection.z * CameraVectorParallelToGround.normalized)
)
* Time.deltaTime);
}
'cam' 是相机的 transform。'playerCharacterController' 是玩家上的角色控制器组件。
英文:
As per usual, i figure it out the moment i ask the question. I still feel like it should be answered though in case anyone else needs it.
Vector2 targetHorizontalMoveDirection = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
Vector2 horizontalMoveDirection = Vector2.MoveTowards(horizontalMoveDirection, targetHorizontalMoveDirection.normalized * maxSpeed, movementAcceleration*Time.deltaTime);
Vector3 finalMoveDirection = new Vector3(horizontalMoveDirection.x, 0, horizontalMoveDirection.y);
if(finalMoveDirection != Vector3.zero)
{
Vector3 CameraVectorParallelToGround = Vector3.ProjectOnPlane(cam.forward, Vector3.up);
playerCharacterController.Move(
(
(finalMoveDirection.x * CameraVectorParallelToGround.normalized) +
(Vector3.up*0f)+
(finalMoveDirection.z * CameraVectorParallelToGround.normalized)
)
* Time.deltaTime);
}
'cam' is the transform of the camera. And 'playerCharacterController' is the character controller component on the player.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论