
在 Ursina 中,敌人不移动的根本原因是缺少每帧更新位置的逻辑;必须将移动代码放入 update() 方法中,结合时间步长(time.dt)或目标追踪算法,才能实现平滑、可控的动态行为。
在 ursina 中,敌人不移动的根本原因是缺少每帧更新位置的逻辑;必须将移动代码放入 update() 方法中,结合时间步长(time.dt)或目标追踪算法,才能实现平滑、可控的动态行为。
Ursina 是一个基于 Python 的轻量级 3D 游戏框架,其核心设计遵循“实体-组件”思想:实体(Entity)本身不具备自动行为,所有动态逻辑(如移动、旋转、碰撞响应)都必须显式编写在 update() 函数中。你提供的代码成功创建了敌人实体,但未定义任何运行时行为——这正是敌人“静止不动”的根本原因。
✅ 正确做法:在 update() 中驱动移动
首先,确保每个敌人实体都具备可访问的引用(如存入列表),并在主循环中统一更新。以下是修复后的完整结构示例:
from ursina import *
from ursina.prefabs.first_person_controller import FirstPersonController
app = Ursina()
# 创建玩家(用于后续追踪)
player = FirstPersonController()
# 创建敌人列表并初始化
enemies = []
for i in range(4):
enemy = Entity(
model='ArtStation - Stylized Anatomy BASEMESHESo/3D Model character Ghoul.obj',
texture='Jowhareh_galleries_7_poster_0c03a8fa-b5b4-4815-9a32-bc830b07ff58.png',
scale=(0.02, 0.02, 0.02),
position=(random.uniform(-10, 10), 0, random.uniform(-10, 10)), # 避免重叠
collider='box' # 建议添加简单碰撞体
)
enemies.append(enemy)
# ? 关键:定义 update() 函数,Ursina 每帧自动调用
def update():
for enemy in enemies:
# 方式1:匀速向玩家水平移动(XZ平面)
direction = (player.position - enemy.position).xz # 忽略Y轴,仅水平追击
if direction.length() > 0.5: # 防止过近抖动
direction = direction.normalized()
enemy.position += direction * 2 * time.dt # 2单位/秒,平滑插值
# 方式2(可选):沿固定路径往返移动(如左右巡逻)
# enemy.x += math.sin(time.time * 2) * 0.5 * time.dt
# 可选:添加基础光照与地面
ground = Entity(model='plane', scale=(50,1,50), texture='grass', collider='box')
EditorCamera()
app.run()
⚠️ 注意事项与常见陷阱
-
不要遗漏
time.dt:直接写enemy.x += 0.1会导致移动速度严重依赖帧率(FPS)。务必乘以time.dt实现帧率无关的恒定速度。 -
避免重复嵌套模型:你原代码中同时使用
FrameAnimation3d和子Entity,不仅冗余,还易引发渲染冲突。推荐统一使用Entity+model+texture,动画需求再引入Animator或自定义update()控制顶点/骨骼(需 OBJ 支持动画)。 -
位置初始化要合理:
position=(0, -4)若场景无足够高度空间,敌人可能被地面遮挡或掉出视图。建议先用EditorCamera()手动探查坐标范围。 -
性能提示:当敌人数量较多时,考虑使用
invoke()实现异步行为,或启用enemy.eternal = True配合对象池复用,避免频繁创建销毁。
✅ 总结
让敌人动起来 ≠ “创建时设置位置”,而在于持续、有逻辑地修改其变换属性(position/rotation/scale)。掌握 update() 的作用机制,结合向量运算(如 normalized()、distance())、时间缩放(time.dt)和基础物理思想(如线性插值、朝向计算),即可构建出巡逻、追击、躲避等丰富 AI 行为。下一步可拓展添加 raycast 碰撞检测、状态机(idle/chase/attack)或 AudioSource 配音反馈,使敌人真正“活”起来。










