如何实现可受撞击变形的可控2D类软体角色
我想制作一个可控角色,要求它受到撞击时能产生轻微变形。我原本考虑用软体实现,但软体效果过于不可预测。试过godot-softbody2d插件,插件本身功能没问题,但不符合我的需求——花费大量时间调整参数仍没得到满意结果,这套方案对我来说太复杂。
不能使用AnimatedSprite2D(如参考图所示),因为角色需要根据不同撞击点,对应部位产生变形。
我的核心问题:有哪些可行方案?
理想状态下,角色平时尽量保持类圆形,在重力作用下会呈现类似GIF中的形态,重力反转也能正常表现。它不需要实现翻越障碍物这类功能,只需能应对不同位置的撞击、维持类椭圆形形态即可。
我从未做过这类开发,完全不知从何入手。了解到可以通过复杂的顶点着色器实现变形,但需要一个明确的入门方向。
如果想要类软体效果,哪怕没有相关开发经验,也可以通过关节组件实现,难度并不高——只需调整参数并添加纹理就能做出不错的效果,无需自行编写物理系统(当然自行编写效果可能更理想,但游戏核心在于趣味性而非完美模拟软体)。
查看godot-softbody2d插件的源码会发现,它本质也是采用类似思路:通过自定义刚体、Polygon2D和骨骼实现多边形与纹理的变形,但这套逻辑过于冗余。用自己能理解的方案,后续更便于按需调整。
我最初用4个Rigidbody2D和DampedSpringJoint2D,让每个刚体与另外3个相连,效果符合预期。之后增加刚体数量,角色形态就更接近圆形了,你也可以尝试这种方式,找到适合自己的最优配置。
另外,Godot没有内置功能能让DampedSpringJoint2D完美连接两个物体的中心,你可以用下面这个工具脚本自动化操作:
spring_connector.gd
@tool extends DampedSpringJoint2D # 编辑器按钮触发 @export var connect_centers: bool = false: set(value): connect_centers = value if value: _connect_centers() connect_centers = false func _connect_centers(): var body_a: Node2D = get_node_or_null(node_a) var body_b: Node2D = get_node_or_null(node_b) if not is_instance_valid(body_a) or not is_instance_valid(body_b): return var direction: Vector2 = body_b.global_position - body_a.global_position global_position = body_a.global_position # 减去PI/2是因为DampedSpringJoint2D初始旋转的问题,不用纠结细节 global_rotation = direction.angle() - PI/2 length = direction.length()
内容的提问来源于stack exchange,提问作者Sebastian Lore

