Ursina进阶:自定义Entity碰撞器尺寸与位置

Ursina进阶:自定义Entity碰撞器尺寸与位置

本教程详细阐述了在Ursina引擎中为Entity对象设置自定义碰撞器的方法,重点解决BoxCollider的center和size参数理解误区。文章强调了这些参数是相对于Entity的局部坐标系而非世界坐标系,并提供了正确的代码示例。同时,教程还推荐使用Ursina内置的F10调试功能来可视化碰撞器,以实现精确调整。

理解Ursina中的碰撞器

在ursina引擎中,为entity对象添加碰撞检测是构建交互式世界的基础。通常,我们可以通过设置collider=’box’、’sphere’或’mesh’来快速为entity指定一个基于其模型边界的默认碰撞器。然而,这些默认碰撞器可能无法满足所有需求。例如,当模型尺寸较大或形状复杂时,默认碰撞器可能过于粗糙,导致不必要的碰撞或阻碍玩家移动。此时,就需要自定义碰撞器的尺寸和位置。

默认的collider=’box’会根据模型的轴对齐包围盒(AABB)自动生成一个碰撞箱。但当我们需要一个比模型本身更小、更大或位置有所偏移的碰撞箱时,直接修改默认碰撞器的属性往往无效,或者需要更精细的控制。Ursina提供了BoxCollider、SphereCollider等类,允许我们手动创建和配置碰撞器。

正确使用BoxCollider自定义碰撞箱

在使用BoxCollider时,最常见的误区是对其center和size参数的理解。关键在于,这两个参数都是相对于Entity的局部坐标系而言的,而非世界坐标系。

  • center参数:表示碰撞箱相对于其关联Entity局部原点(即Entity的position)的偏移量。如果Entity的枢轴点(pivot)在模型底部中心,那么center=Vec3(0,0,0)会将碰撞箱的中心放置在Entity的枢轴点。若要将碰撞箱中心上移,例如放置在模型高度的一半,则需要调整center.y的值。
  • size参数:表示碰撞箱在Entity局部坐标系下的尺寸(长、宽、高)。这些尺寸会受到Entity自身scale属性的影响。例如,如果Entity.scale为0.007,而你设置BoxCollider(size=Vec3(10, 20, 10)),那么最终在世界空间中碰撞箱的尺寸将是Vec3(10*0.007, 20*0.007, 10*0.007)。

为了实现“缩小碰撞箱以允许穿过”的需求,我们需要在Entity的类定义中,移除默认的collider=’box’,并手动创建一个BoxCollider实例,为其指定合适的center和size。

以下是修正后的代码示例,演示如何为树木Entity设置一个自定义的、更小的碰撞箱:

from ursina import * from random import randint, random  # 初始化Ursina应用 app = Ursina()  # 玩家实体(用于测试碰撞) player = Entity(model='cube', collider='box', position=(0,1,0), color=color.blue) # 添加编辑器相机,方便观察和调试 EditorCamera()   # 自定义树木类 class Tree(Entity):     def __init__(self, position):         super().__init__(             model="Assets/SimpleTree.fbx", # 假设模型文件路径正确             texture="Assets/Treesnow.png", # 假设纹理文件路径正确             scale=0.007, # 实体缩放比例             position=position,             double_sided=True,             # 移除默认的 'box' 碰撞器,我们将手动创建             # collider='box'          )          # --- 设置自定义BoxCollider ---         # 假设 'Assets/SimpleTree.fbx' 模型在未缩放时,其原始尺寸大致为:         # 宽度(X/Z)约50单位,高度(Y)约100单位,且枢轴点在底部中心。          # 目标:创建一个比视觉模型稍小的碰撞箱。         # 如果原始模型高100单位,宽50单位:         # 我们可以将碰撞箱的高度设置为原始模型高度的约75% (75单位),         # 宽度和深度设置为原始模型宽度的约50% (25单位)。         # 碰撞箱中心Y轴偏移:如果枢轴在底部,中心应在碰撞箱高度的一半,即 75/2 = 37.5 单位。          # 这些 'center' 和 'size' 值是相对于 Entity 局部坐标系的,         # 它们会受到 Entity 的 'scale' (0.007) 影响,最终在世界空间中呈现。         self.collider = BoxCollider(self,                                      center=Vec3(0, 37.5, 0), # 碰撞箱中心相对于Entity局部原点的偏移                                     size=Vec3(25, 75, 25))   # 碰撞箱在Entity局部坐标系下的尺寸         # 最终在世界空间中,碰撞箱的尺寸将是:         # Vec3(25*0.007, 75*0.007, 25*0.007) = Vec3(0.175, 0.525, 0.175)         # 碰撞箱中心的世界坐标将是:         # Entity.position + Vec3(0, 37.5*0.007, 0) = Entity.position + Vec3(0, 0.2625, 0)   # --- 随机生成树木 --- # 缩小范围以方便测试和观察 for i in range(-10, 10, 2):      for j in range(-10, 10, 2):         chance = random()         # 避免在玩家初始位置生成树木         if abs(i - player.position[0]) < 2 and abs(j - player.position[2]) < 2:             chance = 0          if chance > 0.5:             # 添加小幅随机偏移,使树木分布更自然             spawnTree = Tree(position=(i + randint(-1, 1), 0, j + randint(-1, 1)))   # 运行应用 app.run()

在上述代码中,我们移除了Tree类中的collider=’box’,并在__init__方法中手动创建了一个BoxCollider。center=Vec3(0, 37.5, 0)将碰撞箱的中心向上偏移了37.5个单位(在Entity的局部Y轴上),而size=Vec3(25, 75, 25)则定义了碰撞箱的局部尺寸。这些值是根据假设的模型原始尺寸和期望的碰撞效果进行估算的,实际使用时需要根据你的具体模型进行调整。

Ursina进阶:自定义Entity碰撞器尺寸与位置

DALL·E 2

OpenAI基于GPT-3模型开发的AI绘图生成工具,可以根据自然语言的描述创建逼真的图像和艺术。

Ursina进阶:自定义Entity碰撞器尺寸与位置53

查看详情 Ursina进阶:自定义Entity碰撞器尺寸与位置

调试与可视化碰撞器

Ursina提供了一个极其有用的调试功能:在游戏运行时按下F10键两次。第一次按下F10会显示调试信息,第二次按下F10则会显示所有碰撞器的可视化边界。这是一个蓝色的线框,精确地表示了碰撞箱的实际大小和位置。

调试步骤:

  1. 运行你的Ursina应用。
  2. 在游戏窗口中,按下F10键。
  3. 再次按下F10键。
  4. 此时,所有具有碰撞器的Entity都会显示其碰撞器的蓝色线框。你可以通过移动相机(使用EditorCamera或自定义相机控制)来观察这些碰撞器。
  5. 根据可视化结果,回到代码中微调BoxCollider的center和size参数,直到碰撞器完美符合你的需求。

通过这种可视化方法,你可以精确地调整碰撞箱,确保它们既能提供正确的碰撞检测,又能避免不必要的阻碍。

总结

为Ursina中的Entity对象设置自定义碰撞器是一个常见的需求,尤其是在需要精细控制碰撞行为时。理解BoxCollider的center和size参数是相对于Entity局部坐标系的关键概念,是正确实现自定义碰撞器的基础。结合Ursina内置的F10调试功能,开发者可以高效地可视化和调整碰撞器,确保游戏体验的流畅和准确。记住,实践和迭代是掌握这一技能的最佳途径。

相关标签:

app 对象 position

上一篇
下一篇
text=ZqhQzanResources