如何将局部缩放转换为世界缩放?粒子模块匹配父物体尺寸
Unity局部缩放转世界缩放:匹配粒子发射器与父物体尺寸
如果父物体和粒子系统的localScale均为(1,1,1)但实际尺寸不符,问题大概率出在父物体的缩放来源不是自身transform(比如父级有层级缩放、模型导入时自带缩放),或者你没正确将世界空间尺寸转换到粒子系统的局部空间。以下是针对性解决方案:
情况1:父物体尺寸来自transform层级缩放(父级有缩放)
直接从父物体的世界变换矩阵中提取准确的世界缩放(避免lossyScale在旋转场景下的误差),再转换到粒子系统的局部空间:
// 获取目标父物体的世界变换矩阵 Matrix4x4 parentWorldMatrix = x.transform.localToWorldMatrix; // 从矩阵中提取三个轴的真实世界缩放 Vector3 parentWorldScale = new Vector3( parentWorldMatrix.GetColumn(0).magnitude, parentWorldMatrix.GetColumn(1).magnitude, parentWorldMatrix.GetColumn(2).magnitude ); // 获取粒子系统组件及Shape模块 ParticleSystem ps = GetComponent<ParticleSystem>(); var shape = ps.shape; // 将父物体的世界缩放转换到粒子系统的局部空间 Vector3 localScaleForShape = ps.transform.InverseTransformVector(parentWorldScale); // 设置Shape缩放 shape.scale = localScaleForShape;
情况2:父物体尺寸来自模型导入缩放(transform为1但模型本身有缩放)
这种情况下transform的缩放值无法反映实际尺寸,需通过Renderer的包围盒获取真实世界尺寸:
Renderer parentRenderer = x.GetComponent<Renderer>(); if (parentRenderer == null) return; // 获取父物体的世界空间包围盒尺寸 Vector3 parentWorldSize = parentRenderer.bounds.size; // 获取粒子系统组件及Shape模块 ParticleSystem ps = GetComponent<ParticleSystem>(); var shape = ps.shape; // 将世界尺寸转换到粒子系统局部空间 Vector3 localSizeForShape = ps.transform.InverseTransformVector(parentWorldSize); // 设置Shape缩放 shape.scale = localSizeForShape;
为什么之前的方法没用?
localScale仅反映自身transform的缩放,不包含父级累积或模型导入缩放;lossyScale是只读的累积缩放值,但如果父物体有旋转,会因旋转与缩放的耦合产生误差,无法准确表示各轴的真实缩放。
内容的提问来源于stack exchange,提问作者Olizen
相关产品推荐
相关产品推荐

