rust 2D中的Bevy旋转

zfycwa2u  于 2023-06-23  发布在  其他
关注(0)|答案(2)|浏览(163)

我正在尝试使用Bevy 0.3,并且我能够使用Camera2dComponents::default()轻松地使用内置转换。这是自上而下的2D。
问题是试图将玩家的旋转与鼠标同步:

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);
}

在这个变换是我的球员的转变,当然.下面是它的输出:

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) }

我对2D中的 look_at 中的up有点困惑,但我尝试了几个不同的值,结果总是相同的:当look_at运行时,播放器从视图中消失。
为什么在那之后摄像头再也看不到玩家了,我在这个 look_at 上做错了什么?

mhd8tkvw

mhd8tkvw1#

对于未来的用户,我在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);
h7appiyu

h7appiyu2#

当您使用的是用于2D的Camera2dComponents时,Transform不是。Transform更通用,也包括3D所需的内容。
在你的情况下,听起来look_at()可能不会做你认为它做的事情。它创建了一个3D look at matrix,它计算一个视图矩阵,它是“at”一个位置(self.translation),并看向target(第一个参数)。up是“世界向上”的3D向量。从而可以计算旋转校正。

更新解决方案:

如果您想旋转自上而下的2D播放器,即使玩家的一侧“看”向光标。然后你需要计算你的球员位置和目标之间的Angular 。您可以使用Vec2::angle_between()轻松完成。

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

let angle = (target - pos).angle_between(pos);
transform.rotation = Quat::from_rotation_z(angle);

取决于玩家本身的方向,即如果你使用的是一个精灵,默认的方向可以是“看”向左或向上。然后,您可能需要偏移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);

旧答案:

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

transform.translation = Vec3::new(event.position.x(), event.position.y(), 0.0);

如果您希望光标位置位于屏幕的中心,则可能需要减去屏幕大小的一半。

相关问题