2

我正在尝试使用 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);
}

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

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

我对up2d 中的look_at 中的内容有些困惑,但我尝试了一些不同的值,结果始终相同:只要该look_at 运行,播放器就会从视图中消失。为什么在那之后相机不再看到玩家了,我在这个 look_at 上做错了什么?

谢谢

4

2 回答 2

4

虽然您使用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);

根据播放器本身的方向,即如果您使用精灵,默认方向可能是“看”向左或向上。然后你可能需要抵消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()或简单地 shift self.translation,这是你的相机的位置。

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

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

于 2020-12-19T14:54:47.887 回答
3

对于未来的用户,我在 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);
于 2021-08-25T19:55:51.723 回答