Godot 4.0-alpha15:基于3D鼠标坐标编辑SurfaceTool顶点实现地形升降
实现地形顶点升降的解决方案
一、MeshDataTool完全支持地形顶点修改
MeshDataTool就是专门用来编辑网格顶点、面等数据的工具,完全能满足你的地形升降需求,不用怀疑它的能力。
二、把3D鼠标位置转成对应顶点的步骤
你已经能移动贴花,说明已经有屏幕鼠标→3D世界碰撞点的逻辑了,直接复用这部分就行,接下来只需要把碰撞点转成地形的局部坐标,再计算对应顶点索引:
获取地形局部碰撞坐标
用射线检测得到碰撞点的全局坐标后,通过地形MeshInstance3D的to_local()方法转成局部坐标:var global_hit_pos = ray_cast.get_collision_point() var local_hit_pos = $MeshInstance3D.to_local(global_hit_pos)计算顶点索引(以平面地形为例)
假设你的地形是用SurfaceTool生成的平面网格,比如X方向有vertex_count_x个顶点,Z方向有vertex_count_z个顶点,每个顶点的间距是grid_step(比如1.0)。
先算出碰撞点在网格中的行列位置:# 假设地形中心在原点,所以要偏移半网格宽度 var grid_x = floor((local_hit_pos.x + (vertex_count_x - 1)*grid_step/2) / grid_step) var grid_z = floor((local_hit_pos.z + (vertex_count_z - 1)*grid_step/2) / grid_step) # 确保索引在合法范围内 grid_x = clamp(grid_x, 0, vertex_count_x - 1) grid_z = clamp(grid_z, 0, vertex_count_z - 1) # 计算顶点索引 var vertex_index = grid_z * vertex_count_x + grid_x如果你的地形生成逻辑不同(比如不是中心原点),调整偏移量就行,核心是把局部坐标映射到网格的行列。
三、用MeshDataTool修改顶点高度
拿到顶点索引后,就可以修改顶点的Y坐标了:
# 创建MeshDataTool并加载地形网格 var mdt = MeshDataTool.new() var mesh = $MeshInstance3D.mesh # 加载第一个表面(SurfaceTool生成的网格通常只有一个表面) mdt.create_from_surface(mesh, 0) # 调整顶点高度,比如按下按键时升高0.5 if Input.is_action_pressed("raise_terrain"): var vertex_pos = mdt.get_vertex(vertex_index) vertex_pos.y += 0.5 mdt.set_vertex(vertex_index, vertex_pos) elif Input.is_action_pressed("lower_terrain"): var vertex_pos = mdt.get_vertex(vertex_index) vertex_pos.y -= 0.5 mdt.set_vertex(vertex_index, vertex_pos) # 提交修改并更新网格 mdt.commit_to_surface(mesh) # 更新AABB,避免碰撞检测出错 mesh.regenerate_aabb()
四、注意事项
- 频繁修改MeshDataTool可能会有性能开销,如果是连续按住按键调整,建议加个时间间隔(比如用
Timer或者delta控制),不要每帧都修改。 - 如果你的地形是细分过的网格,或者用了高度图生成,计算顶点索引的逻辑要对应调整,核心是找到碰撞点对应的网格顶点位置。
- 记得在项目设置里绑定好
raise_terrain和lower_terrain的按键。
内容的提问来源于stack exchange,提问作者Andrew Gosselin
相关产品推荐
相关产品推荐

