防止玩家乘坐敌对单位或被其乘坐

您好!
关于上述问题,是否可以实现以下功能:

  • 与敌人物体横向接触:允许
  • 与敌人物体上下接触:无法攀爬(使其滑下)

似乎通过将 CollisionShape2D 的形状设置为胶囊形或圆形,并将 CharacterBody2D 的 floor_max_angle 设置为很小的值即可实现,但目前地图最大坡度为 45 度,因此我们希望保持 floor_max_angle 为默认值 45 度,同时实现上述功能。

我们也考虑过使用 CollisionPolygon2D 使上下端变尖、在上下接触时切换图层或掩码、利用单向碰撞等方法,但都不够现实且未能成功……

如果有其他替代方案,请不吝赐教。

据我理解,你希望敌人从侧面看像一堵实墙,但从上方或下方无法站立或骑乘。我理解你的目标,但我想提出一个设计方面的考量,因为在平台跳跃游戏的物理系统中,要实现这种效果会非常具有挑战性,而且大多数动作平台游戏实际上并不会以这种方式处理与敌人的接触。

我的建议是将这视为一个设计决策。让敌人的攻击区域(AttackArea)和玩家受击区域(HitArea)来处理接触会更简单、更可预测,这也是该类型的标准做法。以下是我考虑的几个方案:

  1. 穿透并伴随攻击。玩家可以自由穿过敌人。真正威胁玩家的是敌人的攻击(如挥击、投射物等),因此时机和位置至关重要,而非身体接触。这在动作平台游戏中非常常见。
  2. 穿透并伴随接触伤害。玩家可以穿过,但敌人拥有一个在接触时造成伤害的攻击区域,击退效果会将玩家推开。类似《恶魔城》或《银河战士》的风格。
  3. 接触伤害并带有顶部反弹区。与上述方案相同,但在顶部(可选地也在底部用于向上攻击)添加一个独立的攻击区域,触发反弹而非造成伤害。类似《超级马里奥》的踩踏风格。
  4. 上述方案的组合。根据敌人类型混合使用。有些可以穿透,有些接触即造成伤害,有些则可以被踩踏。

选项 1 或 2 通常是最干净的起点,之后你可以在此基础上叠加反弹区域或根据敌人类型混合不同的行为。

1 个赞

谢谢。

我的理解是正确的。同时,也感谢您的建议。

我了解到在现有功能中很难实现这一点。

在提问之后,我自己也进行了考虑,打算先按照以下实现方案推进:

  1. 向对象添加 Area2D

  2. 向 Area2D 添加 CollisionShape2D 并放置在对象底部

  3. 在 Area2D 的脚本中编写以下内容:

extends Area2D

# 弹开的力度(像素)
@export var push_dist: float = 5.0

func _physics_process(_delta):
	var bodies = get_overlapping_bodies()

	for body in bodies:
		# 排除自身(父节点)
		if body == get_parent():
			continue

		# 检查对方是否属于特定组
		if body.is_in_group("Enemy"):
			var parent = get_parent() as CharacterBody2D
			if parent:
				# 根据与对方的位置关系强制左右移动
				var direction = 1 if parent.global_position.x > body.global_position.x else -1
				# 通过直接重写坐标,忽略物理运算将其推开
				parent.global_position.x += direction * push_dist

这种方法可能略显粗糙,而且不清楚上述实现会导致多大的性能开销,但我打算在后续验证中继续推进。

testmovie (1)

如有需要,我也会参考您提出的其他方法。

非常感谢。