发布
社区首页 >问答首页 >相对于屏幕移动

相对于屏幕移动
EN

Game Development用户
提问于 2016-11-27 18:02:02
回答 2查看 487关注 0票数 0

我使用自上而下的60度倾斜相机,并希望在视觉上总是相对于屏幕(上、下、左、右)直线移动。当物体靠近屏幕边缘时,它开始对角(视觉)移动,这可能是因为摄像机倾斜。

我尝试过使用WorldToViewportPoint / ViewportPointToRay,但是它不能完全工作,因为即使没有输入,转换到viewport和返回世界的值有时也会轻微地抵消起始位置的影响。

代码语言:javascript
代码运行次数:0
复制
float delta = Time.deltaTime;

float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");

Vector3 view = MainCamera.WorldToViewportPoint(transform.position);

view.x = (h > 0) ? 1 : (h < 0) ? 0 : view.x;
view.y = (v > 0) ? 1 : (v < 0) ? 0 : view.y;

Ray ray = MainCamera.ViewportPointToRay(view);

RaycastHit hit;

Physics.Raycast(ray, out hit, Mathf.Infinity, 1 << 15); // 15 - ground plane layer

Vector3 world = new Vector3(hit.point.x, transform.position.y, hit.point.z);

Vector3 dir = (world - transform.position).normalized;

transform.position += dir * Speed * delta;
EN

回答 2

Game Development用户

发布于 2016-11-27 22:04:36

您目前正在尝试将相机空间矢量转换为世界空间矢量,这是矩阵的最佳用例之一!(关于数学相关的问题,我可能被夸大了一点)

老实说,如果我说我知道Unity我会撒谎,但我知道它有一个Matrix4x4类,并且您可以用TRS(Vector3 position, Quaternion rotation, Vector3 scale)函数创建一个转换矩阵。因为我们不想移动或缩放向量,所以我们可以将一个(0; 0; 0)和一个(1; 1; 1)向量分别传递到位置和比例。

rotation是我们最关心的。为此,您将需要您的相机的角度和Quaternion,如果您还没有,您可以得到如下所示:

代码语言:javascript
代码运行次数:0
复制
Quaternion rotation = Quaternion.Euler(cameraRotation.x, cameraRotation.y, cameraRotation.z);

你就快完蛋了!现在您只需要将这些作为参数传递给TRS函数,然后使用得到的矩阵得到世界空间向量。

代码语言:javascript
代码运行次数:0
复制
Matrix4x4 rotation = Matrix4x4.TRS(new Vector3(0, 0, 0), rotation, new Vector3(1, 1, 1));
// Here I assume your camera-space vector is a 2d vector named "move"
Vector4 worldSpaceMove = rotation * new Vector4(move.x, move.y, 0, 0);

worldPosMove是你的世界空间矢量。它是一个4d向量,因为你不能把一个4x4矩阵和一个3d向量相乘。

编辑:

第二种方法:

当前解决方案将对象移动到平面上。正因为如此,物体在某些点上实际上会离摄像机更远。要解决这个问题,你需要把它移到摄像机周围。

这也很简单:你需要得到相机和物体之间的矢量,旋转它,然后你可以通过把矢量添加到摄像机的位置来得到物体的新位置:

代码语言:javascript
代码运行次数:0
复制
Vector3 toObject = objectPosition - camera.transform.position;
Vector4 tempVector = new Vector4(toObject.x, toObject.y, toObject.z, 0);
// Note the order of the coordinates when creating the quaternion
Matrix4x4 rotation = Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.Euler(move.y, move.x, 0), new Vector3(1, 1, 1));
tempVector *= rotation;
Vector3 newPosition = camera.transform.position + new Vector3(tempVector.x, tempVector.y, tempVector.z);

现在将对象的位置设置为newPosition。

票数 1
EN

Game Development用户

发布于 2016-11-28 10:54:43

谢谢你帮忙。我想了个办法让它看起来很直。如果任何人有更可靠和正确的解决方案,我将接受答案。8层平面/盒对撞机。

代码语言:javascript
代码运行次数:0
复制
float delta = Time.deltaTime;

float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");

Vector3 screen = MainCamera.WorldToScreenPoint(transform.position);

Vector3 move = screen + new Vector3(h, v, 0);

Ray ray = MainCamera.ScreenPointToRay(screen);

RaycastHit hit;

Physics.Raycast(ray, out hit, Mathf.Infinity, 1 << 8);

Vector3 world = hit.point;

ray = MainCamera.ScreenPointToRay(move);

Physics.Raycast(ray, out hit, Mathf.Infinity, 1 << 8);

Vector3 dir = (hit.point - world).normalized;

transform.position += dir * Speed * delta;
票数 0
EN
页面原文内容由Game Development提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://gamedev.stackexchange.com/questions/133611

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档