Ursina添加相机后玩家坠落并Y轴旋转问题排查
问题修复方案
核心错误分析与解决
1. 玩家坠落+绕Y轴旋转的问题
- 同时启用
EditorCamera()和FirstPersonController,两者相机控制逻辑冲突,引发视角混乱。 - 将
Player设为FirstPersonController的子物体,同时手动编写WASD移动逻辑,和FirstPersonController自带的移动控制冲突,导致旋转异常。 Player的origin=(0,0,-2)设置导致实体位置偏移,进一步加剧移动混乱。
修复步骤:
- 删除
EditorCamera(),FirstPersonController已集成相机和玩家控制功能。 - 调整
Player的实现逻辑,基于FirstPersonController扩展自定义玩家,而非将其作为子物体。 - 移除手动编写的
p.z/p.x移动代码,使用FirstPersonController自带的WASD移动。
2. Ground未成功创建的问题
- 在
update()函数中每帧调用Ground(),会持续生成大量重复的Ground实体,既无法正常显示,还会导致性能问题。 - Ground的
scale=2过小,position=Vec3(1,0,2)不在玩家初始位置下方,导致玩家看不到地面且持续坠落。
修复步骤:
- 在初始化阶段(而非update中)创建一次Ground实体。
- 增大Ground的scale(比如
scale=10),调整position到玩家初始位置下方(比如position=(0,-0.5,0)),确保玩家能站在地面上。
修正后的完整代码
from ursina import * from ursina.prefabs.first_person_controller import FirstPersonController app = Ursina() # 基于FirstPersonController扩展自定义玩家 class Player(FirstPersonController): def __init__(self, **kwargs): super().__init__(**kwargs) self.model = 'cube' self.color = color.orange self.collider = 'box' self.health_bar = Entity(parent=self, model='quad', color=color.red, scale_y=.1, y=1.2) self.max_health = 100 self.health = self.max_health class Beings(Entity): def __init__(self, **kwargs): super().__init__(model='cube', color=color.gray, scale=2, collider='box', position=Vec3(1,0,2), origin_y=-.5) self.health_bar = Entity(parent=self, model='quad', color=color.red, scale_y=.1, y=1.2) self.max_health = 100 self.health = self.max_health class Ground(Entity): def __init__(self, **kwargs): super().__init__(model='plane', color=color.gray, scale=10, collider='mesh', position=(0,-0.5,0)) class Buildings(Entity): def __init__(self, **kwargs): super().__init__(model='cube', color=color.gray, scale=2, collider='box', position=Vec3(1,0,2), origin_y=-.5) self.health_bar = Entity(parent=self, model='quad', color=color.red, scale_y=.1, y=1.2) self.max_health = 100 self.health = self.max_health class plants(Entity): def __init__(self, **kwargs): super().__init__(model='cube', color=color.gray, scale=2, collider='box', position=Vec3(1,0,2), origin_y=-.5) self.health_bar = Entity(parent=self, model='quad', color=color.red, scale_y=.1, y=1.2) self.max_health = 100 self.health = self.max_health class Earth(Entity): def __init__(self, **kwargs): super().__init__(model='cube', color=color.gray, scale=2, collider='box', position=Vec3(1,0,2), origin_y=-.5) self.health_bar = Entity(parent=self, model='quad', color=color.red, scale_y=.1, y=1.2) self.max_health = 100 self.health = self.max_health # 初始化实体:仅创建一次Ground ground = Ground() b = Beings() p = Player() def update(): # 保留碰撞检测逻辑 if p.intersects(b).hit: b.color = color.lime print('player is inside trigger box') else: b.color = color.gray app.run()
额外说明
FirstPersonController自带重力、WASD移动、鼠标视角控制,无需手动实现这些功能,避免冲突。- 实体的
collider设置要确保正确,地面用collider='mesh'或'box'都可,只要能和玩家产生碰撞检测,防止坠落。 - 避免在
update()中创建实体,每帧创建会导致内存占用飙升,所有静态实体都应在初始化阶段创建。
内容的提问来源于stack exchange,提问作者loudmounth artist
相关产品推荐
相关产品推荐

