You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Ursina Engine开发Python FPS游戏遇错误,求解决方法

错误修复方案

1. 核心错误:未正确实例化Ursina应用

代码中app = Ursina写法错误,Ursina是类,必须通过()实例化,否则游戏核心渲染上下文(包括render节点)不会创建,直接导致NameError: name 'render' is not defined。

修复代码:

app = Ursina()  # 添加括号,实例化应用

2. Texture参数大小写错误

代码里Texture='M1911-RIGHT'和Texture='knife'用了大写开头的Texture,但Ursina的Entity参数是小写的texture,大写写法会被识别为自定义属性,导致Texture对象初始化异常,出现AttributeError: _cached_image警告。

修复代码:

self.hand_gun = Entity(parent=self.controller.camera_pivot, scale=0.1, position=Vec3(0.7, -1, 1.5), rotation=Vec3(0, 170, 0), model='gun', texture='M1911-RIGHT', visible=False)
self.knife = Entity(parent=self.controller.camera_pivot, scale=0.4, position=Vec3(0.7, -1, 1.5), rotation=Vec3(0, 170, 0), model='knife', texture='knife', visible=False)

3. 子弹移动逻辑错误

Bullet类的update方法中,使用time.daylight计算移动距离是错误的——time.daylight是表示夏令时的布尔值(0或1),应使用time.dt(帧间隔时间)实现平滑的帧无关移动。

修复代码:

self.world_position += self.forward * self.speed * time.dt

4. 方法调用名称错误

Player类的__init__里调用了self.switch_weapons(),但方法定义是switch_weapon(单数),名称不匹配会导致初始化时抛出AttributeError,需修正调用名称:

修复代码:

self.switch_weapon()  # 去掉末尾的s

5. 初始化顺序优化(可选,更规范)

Player类的初始化建议先调用父类__init__,再创建FirstPersonController,避免潜在上下文问题:

调整后的Player类__init__:

def __init__(self, **kwargs):
    super().__init__(**kwargs)  # 先初始化父类Entity
    self.controller = FirstPersonController(**kwargs)
    self.parent = self.controller  # 设置父节点
    # 后续武器初始化代码...

完整修复后的代码

from ursina import *
from ursina.prefabs.first_person_controller import *

class Player(Entity):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.controller = FirstPersonController(**kwargs)
        self.parent = self.controller

        self.hand_gun = Entity(parent=self.controller.camera_pivot, scale=0.1, position=Vec3(0.7, -1, 1.5), rotation=Vec3(0, 170, 0), model='gun', texture='M1911-RIGHT', visible=False)
        self.knife = Entity(parent=self.controller.camera_pivot, scale=0.4, position=Vec3(0.7, -1, 1.5), rotation=Vec3(0, 170, 0), model='knife', texture='knife', visible=False)

        self.weapons = [self.hand_gun, self.knife]
        self.current_weapon = 0
        self.switch_weapon()

    def switch_weapon(self):
        for i, v in enumerate(self.weapons):
            v.visible = (i == self.current_weapon)
  
    def input(self, key):
        try:
            self.current_weapon = int(key) - 1
            self.switch_weapon()
        except ValueError:
            pass

        if key == 'scroll up':
            self.current_weapon = (self.current_weapon + 1) % len(self.weapons)
            self.switch_weapon()

        if key == 'scroll down':
            self.current_weapon = (self.current_weapon - 1) % len(self.weapons)
            self.switch_weapon()

        if key == 'left_mouse_down' and self.current_weapon == 0:
            Bullet(model='sphere', color=color.black, scale=0.2, position=self.controller.camera_pivot.world_position, rotation=self.controller.camera_pivot.world_rotation)

    def update(self):
        self.controller.camera_pivot.y = 2 - held_keys['left control']

class Bullet(Entity):
    def __init__(self, speed=50, lifetime = 10, **kwargs):
        super().__init__(**kwargs)
        self.speed = speed
        self.lifetime = lifetime
        self.start = time.time()

    def update(self):
        ray = raycast(self.world_position, self.forward, distance=self.speed*time.dt)
        if not ray.hit and time.time() - self.start < self.lifetime:
            self.world_position += self.forward * self.speed * time.dt
        else:
            destroy(self)

app = Ursina()

ground = Entity(model='plane', scale=20, texture='white_cube', texture_scale='mesh')
player = Player(position=(0,10,0))

app.run()

内容的提问来源于stack exchange,提问作者Yunwoo Chang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 02:41:56