Godot4 RC1中StaticBody3D碰撞法线对齐异常问题求助
问题解决:Godot4中基于碰撞法线实现物体直立对齐
首先明确你的核心错误:Quaternion.from_euler()的参数是欧拉角(三个轴的旋转弧度值),而碰撞事件返回的normal是三维方向向量,两者数据类型语义完全不同,直接转换必然导致旋转错乱。
要实现类似站在星球表面直立的效果,核心是让物体的up轴与碰撞法线对齐,同时保持合理的水平朝向,以下是两种可行的实现方案:
方案1:保持物体原有水平旋转
如果希望物体移动后仍保持之前的朝向(比如一直面朝某个固定方向),可以用以下代码:
func _on_input_event(camera, event, position, normal, shape_idx): player.global_position = position # 保留物体当前绕up轴的旋转角度(yaw值) var current_yaw = player.global_basis.get_euler().y # 构造以法线为up轴的基础朝向,再应用原有水平旋转 var new_basis = Basis(normal, Vector3.FORWARD, Vector3.RIGHT).rotated(normal, current_yaw) player.global_basis = new_basis
方案2:让物体面朝相机方向
如果希望物体始终朝向相机的水平方向(更符合第三人称视角需求),可以用以下代码:
func _on_input_event(camera, event, position, normal, shape_idx): player.global_position = position # 计算相机到物体位置的方向,剥离法线方向分量得到水平方向 var camera_dir = (camera.global_position - position).normalized() var horizontal_dir = (camera_dir - normal * camera_dir.dot(normal)).normalized() # 构造以法线为up轴、水平方向为forward的朝向基 var new_basis = Basis.looking_at(horizontal_dir, normal) player.global_basis = new_basis
补充说明
- 碰撞法线
normal是从物体表面向外的方向向量,因此物体的up轴对齐法线后,会呈现“头朝星球外、脚朝球心”的直立姿态,符合站在星球表面的逻辑。 - 使用
global_basis而非basis可以确保旋转基于全局坐标系计算,避免父节点变换影响结果。
内容的提问来源于stack exchange,提问作者sooon
相关产品推荐
相关产品推荐

