Godot建筑系统脚本精度问题求助:方块放置位置不准确
Godot建筑放置脚本精度优化方案
核心问题分析
脚本出现方块放置偏移,主要源于三个关键问题:
- 浮点数精度误差导致法线精确相等判断失效(物理计算出的法线可能是
0.9999999而非严格1.0,触发不了分支逻辑) - 直接用
ceil()做坐标对齐不符合网格逻辑,容易出现错位 - 位置调整的条件分支覆盖不全,仅处理了部分法线方向
优化后的完整代码
func _input(ev): if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT): var space_state = get_world_3d().direct_space_state var mousepos = get_viewport().get_mouse_position() var origin = camera.project_ray_origin(mousepos) var end = origin + camera.project_ray_normal(mousepos) * raycast_distance var query = PhysicsRayQueryParameters3D.create(origin, end) query.collide_with_areas = true var result = space_state.intersect_ray(query) if result and timer > 0.5: timer = 0 var hit_pos = result.position var hit_normal = result.normal.normalized() # 确保法线为单位向量,消除精度偏差 # 计算初始放置位置,再对齐到网格 var grid_pos = hit_pos + hit_normal * snapValue grid_pos = snap_to_grid(grid_pos, snapValue) # 用法线范围判断替代精确相等,覆盖所有轴正负方向 if hit_normal.x > 0.9: grid_pos.x -= snapValue elif hit_normal.x < -0.9: grid_pos.x += snapValue elif hit_normal.z > 0.9: grid_pos.z -= snapValue elif hit_normal.z < -0.9: grid_pos.z += snapValue elif hit_normal.y > 0.9: grid_pos.y -= snapValue elif hit_normal.y < -0.9: grid_pos.y += snapValue result.collider.add_to_group("Grass", true) var grass = preload("res://Dirt.tscn") var clone = grass.instantiate() clone.name = "grass" add_sibling(clone) clone.position = grid_pos # 新增网格对齐函数,确保坐标严格匹配网格步长 func snap_to_grid(position: Vector3, snap: float) -> Vector3: return Vector3( round(position.x / snap) * snap, round(position.y / snap) * snap, round(position.z / snap) * snap )
关键修改说明
- 法线精度修正:对
hit_normal执行normalized(),并用范围判断(如>0.9)替代精确==1,避免浮点数误差导致分支失效 - 网格对齐逻辑:新增
snap_to_grid函数,通过取整后乘以网格步长,确保坐标严格对齐到snapValue设定的网格,替代不可靠的ceil() - 完整方向覆盖:补充了X/Z/Y轴负方向的判断,确保所有面的放置位置都能正确调整
- 位置调整适配:基于
snapValue调整坐标,避免固定减1导致的网格错位
内容的提问来源于stack exchange,提问作者Keaton Rozema
相关产品推荐
相关产品推荐

