Python Ursina中平滑旋转功能失效问题求助
Python Ursina中平滑旋转功能失效问题求助
兄弟,我看完你的代码,发现几个关键问题导致角色完全不转,咱们一步步拆解解决:
核心问题1:混淆了方向向量和旋转角度
你现在用target_rot = (target_position - self.position)得到的是方向向量,但self.rotation.y需要的是欧拉角(角度值),这俩完全不是一个概念!你直接拿向量的y分量来算旋转增量,逻辑根本不对,自然转不起来。
正确的做法是把方向向量转换成y轴的旋转角度——Ursina里y轴是向上的,水平旋转由x和z轴的向量决定,咱们用math.atan2来计算对应的角度:
import math target_dir = target_position - self.position # 把向量转换成y轴旋转角度(转成度数,因为Ursina的rotation用度数) target_rot_y = math.degrees(math.atan2(target_dir.x, target_dir.z))
核心问题2:浮点数精度导致判断永远不触发
你用if self.rotation == target_rot:来判断是否到达目标,这里有两个致命问题:
- 类型不匹配:
self.rotation是欧拉角对象,target_rot是方向向量,永远不可能相等 - 就算都是角度,浮点数累加的精度问题也会让这个条件几乎永远不成立,导致
self.pass_一直是True,函数再也不会重新计算目标值,相当于只执行了一次初始化就停了
解决办法是用角度差值的阈值来判断,比如当当前角度和目标角度的差小于1度时,就认为到达目标:
angle_diff = target_rot_y - self.rotation.y # 处理角度绕圈的问题(比如从350°转到10°,应该转20°而不是-340°) angle_diff = (angle_diff + 180) % 360 - 180 # 当差值小于1度时,认为到达目标 if abs(angle_diff) < 1: self.rotation.y = target_rot_y # 直接修正到目标角度,避免抖动 self.pass_ = False return True
额外问题:全局变量容易冲突
你用了global target_rot,如果有多个实体调用这个函数,它们会共用同一个目标值,互相干扰。应该改成实例变量,比如self.target_rot_y,每个对象自己存自己的目标角度。
修正后的完整代码
先在你的Entity子类的__init__里初始化必要的实例变量:
from ursina import Entity, time import math class YourEntity(Entity): def __init__(self, **kwargs): super().__init__(**kwargs) self.pass_ = False # 标记是否已经设置了目标角度 self.target_rot_y = 0 # 存储目标y轴旋转角度
然后是修正后的smooth_look_at函数:
def smooth_look_at(self, target_position, speed=10): if not self.pass_: # 计算方向向量并转换成目标角度 target_dir = target_position - self.position self.target_rot_y = math.degrees(math.atan2(target_dir.x, target_dir.z)) self.pass_ = True # 计算角度差值并处理绕圈问题 angle_diff = self.target_rot_y - self.rotation.y angle_diff = (angle_diff + 180) % 360 - 180 # 平滑旋转:用差值乘以速度和dt,保证帧率无关 self.rotation.y += angle_diff * speed * time.dt # 判断是否到达目标 if abs(angle_diff) < 1: self.rotation.y = self.target_rot_y self.pass_ = False return True return False
为什么这样改?
- 用
atan2正确计算了水平旋转角度,匹配Ursina的坐标系规则 - 处理了角度绕圈的问题,角色会选择最短路径旋转
- 用阈值判断代替直接相等,避免浮点数精度坑
- 用
angle_diff * speed * time.dt来旋转,速度不受帧率影响,旋转更平滑 - 最后直接设置到目标角度,防止角色在目标附近微小抖动
这样你的角色应该就能正常平滑旋转了,试试吧!
备注:内容来源于stack exchange,提问作者user30081523
相关产品推荐
相关产品推荐

