Unity中Transform逻辑实现及线程模拟父节点设置的坐标转换疑问
线程模拟Transform父节点设置与空间转换问题
设置父节点时更新local属性的逻辑
给虚拟Transform换父节点的核心是让它在世界空间里的位置、旋转、缩放保持不变,然后反推相对于新父节点的local属性,步骤如下:
- 先算出当前虚拟Transform的世界空间属性:如果之前没父节点,世界属性就是local属性;如果有旧父节点,用旧父的世界变换矩阵把当前local属性转成世界属性。
- 算出新父节点的逆变换矩阵:这个矩阵的作用是把世界空间的坐标转成新父节点的局部空间坐标。
- 用逆矩阵转换世界属性得到新的local值:
- 新localPosition = 逆矩阵作用于世界position(向量乘法,要算上平移分量)
- 新localRotation = 新父节点世界旋转的逆四元数 乘以 世界rotation
- 新localScale = 世界scale逐分量除以新父节点的世界scale(注意如果父节点缩放为0要做异常处理,非均匀缩放+旋转的情况建议用矩阵提取缩放,避免误差)
local与世界空间属性的转换关系
从local转世界空间
- position:
世界位置 = 父节点世界位置 + 父节点世界旋转 * (父节点世界缩放 * localPosition)
(父节点无缩放时,简化成父节点世界位置 + 父节点世界旋转 * localPosition) - rotation:
世界旋转 = 父节点世界旋转 * localRotation
(四元数乘法顺序要注意,多数引擎是父旋转在前乘子local旋转) - scale:
世界缩放 = 父节点世界缩放 逐分量 * localScale
(如果父节点有非均匀缩放且子节点带旋转,实际世界缩放会扭曲,这时候用矩阵计算更准确,因为旋转和缩放的顺序会影响结果)
从世界转local空间
- localPosition:
localPosition = 父节点世界旋转的逆 * (世界位置 - 父节点世界位置) 逐分量 / 父节点世界缩放
(父节点无缩放时去掉除以缩放的步骤) - localRotation:
localRotation = 父节点世界旋转的逆 * 世界旋转 - localScale:
localScale = 世界缩放 逐分量 / 父节点世界缩放
(非均匀缩放+旋转场景,建议用逆矩阵提取缩放,避免扭曲带来的计算误差)
线程模拟的小提示
- 所有计算都在线程内完成,别和主线程的真实Transform数据混着用
- 四元数、矩阵计算要保证线程安全,别用全局共享的临时变量
- 如果是复杂层级嵌套,建议每个虚拟Transform都维护自己的世界变换矩阵,这样转换时不用递归找父节点,效率更高
内容的提问来源于stack exchange,提问作者fangqi wu
相关产品推荐
相关产品推荐

