
在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)则定义了碰撞箱的局部尺寸。这些值是根据假设的模型原始尺寸和期望的碰撞效果进行估算的,实际使用时需要根据你的具体模型进行调整。
Teleporthq
一体化AI网站生成器,能够快速设计和部署静态网站
182
查看详情
调试与可视化碰撞器
Ursina提供了一个极其有用的调试功能:在游戏运行时按下F10键两次。第一次按下F10会显示调试信息,第二次按下F10则会显示所有碰撞器的可视化边界。这是一个蓝色的线框,精确地表示了碰撞箱的实际大小和位置。
调试步骤:
- 运行你的Ursina应用。
- 在游戏窗口中,按下F10键。
- 再次按下F10键。
- 此时,所有具有碰撞器的Entity都会显示其碰撞器的蓝色线框。你可以通过移动相机(使用EditorCamera或自定义相机控制)来观察这些碰撞器。
- 根据可视化结果,回到代码中微调BoxCollider的center和size参数,直到碰撞器完美符合你的需求。
通过这种可视化方法,你可以精确地调整碰撞箱,确保它们既能提供正确的碰撞检测,又能避免不必要的阻碍。
总结为Ursina中的Entity对象设置自定义碰撞器是一个常见的需求,尤其是在需要精细控制碰撞行为时。理解BoxCollider的center和size参数是相对于Entity局部坐标系的关键概念,是正确实现自定义碰撞器的基础。结合Ursina内置的F10调试功能,开发者可以高效地可视化和调整碰撞器,确保游戏体验的流畅和准确。记住,实践和迭代是掌握这一技能的最佳途径。
以上就是Ursina进阶:自定义Entity碰撞器尺寸与位置的详细内容,更多请关注知识资源分享宝库其它相关文章!
相关标签: app 对象 position 大家都在看: python抢票神器app 第一个完全多 GPU 支持和非常先进的带有 Gradio 接口的批量图像字幕生成器 APP 发布 怎么利用Python开发App 利用Python开发App实战 可以搜Python题答案的APP有哪些?






发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。