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

Ursina Engine中能否删除非列表内Entity?点击删除游戏崩溃求助

Ursina Engine点击销毁Entity导致游戏崩溃问题解决

问题描述

使用Ursina Engine开发游戏时,尝试通过点击操作删除敌人Entity,但点击后目标Entity未被销毁,反而导致游戏直接崩溃。以下是出现问题的代码:

from ursina.prefabs.health_bar import HealthBar
from ursina import *
app = Ursina()
import time

def file_path(relative_path):
    try:
        base_path = sys._MEIPASS
    except Exception as e:
        base_path = os.path.abspath('.')
    return os.path.join(base_path, relative_path)

from ursina.prefabs.first_person_controller import FirstPersonController

HB1 = HealthBar(bar_color=color.lime.tint(-.25),
                roundness=.5,
                scale=(1.5, .06))

def input(key):
    if key == '-' or key == '- hold':
        damage(5)
    if key == '+' or key == '+ hold':
        heal(5)

def damage(power):
    HB1.value -= power

def heal(value):
    HB1.value += value

player = FirstPersonController(
  collider='box'
)

enemy = Entity(model='cube', position=(2,2,6), color=color.dark_gray, scale=2, collider='box', texture='white_cube')

enemy.add_script(SmoothFollow(target = player, offset = [0,0,0], speed = 0.2))

floor = Entity(model='cube', position=(0,0,0), scale=(100,1,100), texture='grass', double_sided=True, collider='box')

def kill():
    if distance_xz(enemy, player) < 3:
        if enemy.hovered:
            if held_keys['left mouse']:
                destroy(enemy)  
def update():
    kill()
    if distance_xz(enemy, player) < 2:
        damage(2)
    if HB1.value == 0:
        quit()

sky = Sky()

app.run()

崩溃原因

销毁enemy对象后,update()函数仍然持续尝试访问已被销毁的enemy(比如调用distance_xz(enemy, player)),引发空引用错误,导致游戏崩溃。

修复方案

方案1:添加存活标记并在逻辑中判断

给enemy添加alive属性,销毁时标记为False,后续所有涉及enemy的逻辑先检查存活状态:

# 创建enemy时添加alive属性
enemy = Entity(model='cube', position=(2,2,6), color=color.dark_gray, scale=2, collider='box', texture='white_cube', alive=True)

def kill():
    if enemy.alive and distance_xz(enemy, player) < 3:
        if enemy.hovered:
            if held_keys['left mouse']:
                enemy.alive = False
                destroy(enemy)  

def update():
    if enemy.alive:
        kill()
        if distance_xz(enemy, player) < 2:
            damage(2)
    if HB1.value == 0:
        quit()

方案2:将enemy设为None并检查存在性

销毁enemy后将其赋值为None,后续逻辑先判断enemy是否存在:

def kill():
    global enemy  # 声明使用全局变量
    if enemy and distance_xz(enemy, player) < 3:
        if enemy.hovered:
            if held_keys['left mouse']:
                destroy(enemy)
                enemy = None  

def update():
    global enemy
    if enemy:
        kill()
        if distance_xz(enemy, player) < 2:
            damage(2)
    if HB1.value == 0:
        quit()

方案3:改用鼠标点击事件检测(更高效)

避免在update中反复检测,直接通过input事件处理点击逻辑:

def input(key):
    if key == '-' or key == '- hold':
        damage(5)
    if key == '+' or key == '+ hold':
        heal(5)
    # 处理鼠标点击
    if key == 'left mouse down':
        global enemy
        if enemy and distance_xz(enemy, player) < 3 and enemy.hovered:
            destroy(enemy)
            enemy = None

# 移除原有的kill函数,修改update如下
def update():
    global enemy
    if enemy and distance_xz(enemy, player) < 2:
        damage(2)
    if HB1.value == 0:
        quit()

以上三种方案都能解决崩溃问题,推荐方案3,因为Ursina的input事件更适合处理一次性的用户交互,比在update循环中轮询更高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:45:33