Ursina中如何用A/D键实现FirstPersonController车辆转向(禁用鼠标)
Ursina 基于FirstPersonController的无鼠标控车转向实现方案
核心修改思路
默认FirstPersonController自带鼠标控视角、A/D左右平移的逻辑,和车辆操控的需求不匹配,需要做三类调整:
- 禁用默认鼠标视角控制、A/D键横向平移逻辑,完全移除鼠标对视角的影响
- 替换A/D键逻辑为转向输入,实现拟真转向规则:仅车辆移动时可转向、转向灵敏度随车速自适应、方向自动回正,贴合真实车辆过弯感受
- 转向旋转直接作用在玩家控制器根实体上,相机作为控制器子节点会自动同步旋转,无需单独编写视角跟随逻辑
关键参数说明
你可以根据手感调整以下数值适配游戏节奏:
max_steer_angle:车辆最大转向角度,现实家用车通常为30-40度steer_speed:打方向的响应速度steer_return_speed:松开方向键后方向盘回正速度max_speed:车辆最高前进速度acceleration:车辆前进/倒车加速度
可直接运行的实现代码
from ursina import * from ursina.prefabs.first_person_controller import FirstPersonController app = Ursina() # 基础地面 ground = Entity(model='plane', scale=(100,1,100), texture='grass', collider='box') class CarController(FirstPersonController): def __init__(self, **kwargs): super().__init__(**kwargs) # 关闭默认鼠标控制 self.mouse_sensitivity = Vec2(0,0) mouse.locked = False self.cursor.visible = True # 车辆操控参数 self.max_steer_angle = 35 self.steer_speed = 2.5 self.steer_return_speed = 3 self.current_steer = 0 self.current_speed = 0 self.max_speed = 22 self.acceleration = 14 self.brake_force = 20 self.friction = 6 # 屏蔽默认A/D横向移动逻辑 self.direction.x = 0 # 不需要跳跃可以把下面参数设为0 self.jump_height = 2 def update(self): # 1. 处理加减速 W前进 S后退/刹车 if held_keys['w']: self.current_speed = min(self.current_speed + self.acceleration * time.dt, self.max_speed) elif held_keys['s']: self.current_speed = max(self.current_speed - self.brake_force * time.dt, -self.max_speed/2) else: # 无输入时自然减速 if self.current_speed > 0: self.current_speed = max(self.current_speed - self.friction * time.dt, 0) elif self.current_speed < 0: self.current_speed = min(self.current_speed + self.friction * time.dt, 0) # 2. 处理转向输入 A左打方向 D右打方向 steer_input = 0 if held_keys['a']: steer_input = -1 if held_keys['d']: steer_input = 1 if steer_input != 0: self.current_steer = clamp( self.current_steer + steer_input * self.steer_speed * time.dt * 60, -self.max_steer_angle, self.max_steer_angle ) else: # 松开方向后自动回正 if self.current_steer > 0: self.current_steer = max(self.current_steer - self.steer_return_speed * time.dt * 60, 0) elif self.current_steer < 0: self.current_steer = min(self.current_steer + self.steer_return_speed * time.dt * 60, 0) # 3. 拟真转向逻辑:仅移动时生效,车速越快转向角速度越低,避免高速甩尾 speed_factor = abs(self.current_speed) / self.max_speed rotation_speed = self.current_steer * speed_factor * time.dt * 2 self.rotation_y += rotation_speed # 4. 沿车身朝向移动 self.position += self.forward * self.current_speed * time.dt # 生成车辆控制器 car = CarController(position=(0,2,0)) # 测试用障碍物 for i in range(20): Entity(model='cube', position=(random.randint(-30,30), 1, random.randint(-30,30)), color=color.random_color(), collider='box') app.run()
扩展优化提示
如果需要更接近真实驾驶的手感,可以额外加两个效果:一是转向时给车身加少量Z轴旋转模拟侧倾,二是高速大角度转向时给少量转向角度衰减模拟推头感,直接在update方法里对应位置加计算逻辑即可。
内容的提问来源于stack exchange,提问作者Tait Bunt
相关产品推荐
相关产品推荐

