gpt4 book ai didi

math - 围绕枢轴移动和旋转对象并从它停止的位置恢复

转载 作者:行者123 更新时间:2023-12-04 10:40:50 24 4
gpt4 key购买 nike

我想在另一个物体周围移动一个物体 - 就像一个物体是另一个物体的 child 一样。这是GDscript - Godot Engine 3.2,但逻辑应该与其他游戏引擎非常相似。

每当我按住空格键时,绿色立方体都会跟随蓝色立方体旋转。

第一个 GIF 演示了从位置 Vector3(0, 4, 0) 开始的绿色立方体,没有应用任何旋转。这工作得很好。

在第二个 GIF 中,我反复按住和释放空格键。 我希望绿色立方体从它离开的地方继续,但它“跳”到一个新位置并从那里继续。

enter image description here

enter image description here

下面的代码不包括蓝色立方体(枢轴点)的实际旋转,而仅包括移动/旋转绿色立方体所需的计算。蓝色立方体的旋转不是问题。此外,旋转只是为了演示 - 在实际场景中,蓝色立方体也会四处移动。

旋转是使用四元数计算的,但这不是必需的。

extends Node

var _parent
var _child
var _subject
var _positionOffset: Vector3
var _rotationOffset: Quat

func _ready():
_parent = get_parent()
_child = $"/root/Main/Child"

func _input(event):
if event is InputEventKey:
if event.scancode == KEY_SPACE:
if event.is_action_pressed("ui_accept") and _child != null:
_subject = _child
_set_subject_offset(_parent.transform, _child.transform)
elif event.is_action_released("ui_accept"):
_subject = null

func _set_subject_offset(pivot: Transform, subject: Transform):
_positionOffset = (pivot.origin - subject.origin)
_rotationOffset = pivot.basis.get_rotation_quat().inverse() * subject.basis.get_rotation_quat()

func _rotate_around_pivot(subject_position: Vector3, pivot: Vector3, subject_rotation: Quat):
return pivot + (subject_rotation * (subject_position - pivot))

func _physics_process(_delta):
if _subject == null: return

var target_position = _parent.transform.origin - _positionOffset
var target_rotation = _parent.transform.basis.get_rotation_quat() * _rotationOffset
_subject.transform.origin = _rotate_around_pivot(target_position, _parent.transform.origin, target_rotation)
_subject.set_rotation(target_rotation.get_euler())

我觉得我错过了一些明显的东西。

最佳答案

您可以通过暂时将主体置于枢轴点的父级,同时保留全局变换来轻松实现此目的:

extends Spatial

onready var obj1: Spatial = $Object1
onready var obj2: Spatial = $Object2

func reparent(obj: Spatial, new_parent: Spatial):
# Preserve the global transform while reparenting
var old_trans := obj.global_transform
obj.get_parent().remove_child(obj)
new_parent.add_child(obj)
obj.global_transform = old_trans

func _physics_process(delta: float):
obj1.rotate_z(delta)

func _input(event: InputEvent):
if event.is_action_pressed("ui_accept"):
reparent(obj2, obj1)
elif event.is_action_released("ui_accept"):
reparent(obj2, self)

enter image description here

如果重新养育不可行,您可以改为养育 RemoteTransform到枢轴,并将其转换为您要旋转的对象:
extends Spatial

onready var remote_trans: RemoteTransform = $RemoteTransform

func _process(delta):
rotate_z(delta)

func attach(n: Node):
# move the remote so the target maintains its transform
remote_trans.global_transform = n.global_transform
remote_trans.remote_path = n.get_path()

func detach():
remote_trans.remote_path = ""

关于math - 围绕枢轴移动和旋转对象并从它停止的位置恢复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59938057/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com