2D 中的大量旋转

Ulr*_*rar 5 rust bevy

我正在尝试使用 Bevy 0.3,并且我能够轻松地将内置转换与Camera2dComponents::default(). 这是自上而下的二维。

问题在于尝试将玩家的旋转与鼠标同步:

for event in evreader.iter(&cursor_moved_events) {
    println!("{:?}", transform);
    transform.look_at(Vec3::new(event.position.x(), event.position.y(), 0.0), Vec3::new(0.0, 0.0, 1.0));
    println!("{:?}", transform);
}
Run Code Online (Sandbox Code Playgroud)

当然,这个变换是我的玩家的变换。这是输出的内容:

Transform { translation: Vec3(0.0, 0.0, 0.0), rotation: Quat(0.0, 0.0, 0.0, 1.0), scale: Vec3(1.0, 1.0, 1.0) }
Transform { translation: Vec3(0.0, 0.0, 0.0), rotation: Quat(0.5012898, -0.49870682, -0.49870682, 0.5012898), scale: Vec3(1.0, 1.0, 1.0) }
Run Code Online (Sandbox Code Playgroud)

我对 2D 中的look_atup中的内容有点困惑,但我尝试了一些不同的值,结果总是相同的:一旦look_at 运行,玩家就会从视图中消失。

为什么此后相机再也看不到玩家了?我的这个look_at做错了什么?

小智 10

对于未来的用户,我在 Bevy v0.5 中遇到了类似的问题(让 2d 精灵面对鼠标点击位置),但无论出于何种原因,我都无法获得可接受的答案。

我通过 Unity 线程中的实现解决了这个问题:https ://answers.unity.com/questions/650460/rotating-a-2d-sprite-to-face-a-target-on-a-single.html

代码示例:

let diff = targ.translation - pos.translation;
let angle = diff.y.atan2(diff.x); // Add/sub FRAC_PI here optionally
pos.rotation = Quat::from_axis_angle(Vec3::new(0., 0., 1.), angle);
Run Code Online (Sandbox Code Playgroud)

  • 想用atan重写最佳答案,因为它不起作用,看到你的,它确实起作用了。谢谢 (2认同)

Val*_*tin 6

当您使用的Camera2dComponents是用于 2D 的程序时,Transform它不是。Transform通用,还包括 3D 所需的内容。

就您而言,听起来look_at()可能不会像您想象的那样。它创建一个3D 观察矩阵,该矩阵计算一个观察矩阵,该观察矩阵是“ at”位置 ( self.translation) 并朝向 a target(第一个参数)。这up是“上方世界”的 3D 向量。这样就可以计算出旋转修正量。


更新的解决方案:

如果您想旋转自上而下的 2D 播放器,即让播放器的一侧朝向光标。然后您需要计算玩家位置与目标之间的角度。您可以使用 轻松做到这一点Vec2::angle_between()

let pos: Vec2 = ...;
let target: Vec2 = ...;

let angle = (target - pos).angle_between(pos);
transform.rotation = Quat::from_rotation_z(angle);
Run Code Online (Sandbox Code Playgroud)

根据玩家本身的方向,即如果您使用的是精灵,默认方向可能是“看”向左或向上。那么您可能需要抵消angle. 您可以通过添加+ FRAC_PI_2(或无论需要多少)来做到这一点。

假设transform.translation是玩家的中心位置,那么它看起来像这样:

use bevy::math::{Quat, Vec2};

let pos = transform.translation.truncate();
let target = event.position;

let angle = (target - pos).angle_between(pos);
transform.rotation = Quat::from_rotation_z(angle);
Run Code Online (Sandbox Code Playgroud)

旧答案:

因为您希望将相机定位在自上而下的 2D 视图中的光标上方。然后你必须使用from_translation()或简单地移动self.translation,这是你的相机的位置。

transform.translation = Vec3::new(event.position.x(), event.position.y(), 0.0);
Run Code Online (Sandbox Code Playgroud)

如果您希望光标位置位于屏幕中心,那么您可能需要减去屏幕尺寸的一半。