-
[Particle System] 유니티 2017 -> 2018 업그레이드 시 변경 사항게임 엔진/Unity 2021. 7. 5. 21:22
유니티 업그레이드 시 파티클 시스템 변경사항
파티클 시스템 버그로 인해 2017에서 생성된 파티클 이펙트는 2018에서 정상적으로 보이지 않을 수 있다. 유니티에서 공개한 버그는 다음과 같다.
- 메시(Mesh)
- Offset 공식 변경(기존: size * size * pivot, 변경: size * pivot)
- 빌보드(Billboard)
- 비균등 스케일일 때 스케일의 y축과 z축이 반전됨
- 비균등 스케일일 때 회전 후 스케일링 적용됨
- 윈드존(Wind Zone)
- 윈드 존이 파티클에 영향 주는 방향 변경(기존: 나무와 반대 방향, 변경: 나무와 동일한 방향)
유니티 파티클 변경 사항 처리 참고 코드
유니티 업그레이드를 위해 사용한 코드이며 모든 버그를 수정하지는 못했으나 대부분의 버그는 수정하여 정상적으로 출력되도록 했다.
- 메시 처리 코드
ParticleSystemRenderer psr = psrArr[i]; ParticleSystem ps = psr.GetComponent<ParticleSystem>(); Transform psrTransform = psr.transform; if (psr.renderMode == ParticleSystemRenderMode.Mesh && psr.mesh != null) { Vector3 scale = psrTransform.localScale; ParticleSystem.MainModule main = ps.main; if (IsNonUniformScale(scale)) { ParticleSystem.MinMaxCurve startRotationX = main.startRotationX; ParticleSystem.MinMaxCurve startRotationY = main.startRotationY; ParticleSystem.MinMaxCurve startRotationZ = main.startRotationZ; float xMin = startRotationX.constant; float yMin = startRotationY.constant; float zMin = startRotationZ.constant; float xMax, yMax, zMax; xMax = yMax = zMax = 0; if (main.startRotation.mode == ParticleSystemCurveMode.TwoConstants) { xMin = Mathf.Min(startRotationX.constantMin, startRotationX.constantMax); yMin = Mathf.Min(startRotationY.constantMin, startRotationY.constantMax); zMin = Mathf.Min(startRotationZ.constantMin, startRotationZ.constantMax); xMax = Mathf.Max(startRotationX.constantMin, startRotationX.constantMax); yMax = Mathf.Max(startRotationY.constantMin, startRotationY.constantMax); zMax = Mathf.Max(startRotationZ.constantMin, startRotationZ.constantMax); } Quaternion scaleRotation = Quaternion.AngleAxis(Mathf.Rad2Deg * zMin, Vector3.forward); if (main.startRotation3D) { scaleRotation *= Quaternion.AngleAxis(Mathf.Rad2Deg * xMin, Vector3.right) * Quaternion.AngleAxis(Mathf.Rad2Deg * yMin, Vector3.up); } psrTransform.rotation *= scaleRotation; if (main.startRotation.mode == ParticleSystemCurveMode.TwoConstants) { startRotationX.constantMin = startRotationY.constantMin = startRotationZ.constantMin = 0; startRotationX.constantMax = xMax - xMin; startRotationY.constantMax = yMax - yMin; startRotationZ.constantMax = zMax - zMin; } else { startRotationX.constant = startRotationY.constant = startRotationZ.constant = 0; } main.startRotationX = startRotationX; main.startRotationY = startRotationY; main.startRotationZ = startRotationZ; changed = true; } if (!Mathf.Approximately(psr.pivot.x, 0) || !Mathf.Approximately(psr.pivot.y, 0) || !Mathf.Approximately(psr.pivot.z, 0)) { Vector3 meshSize = psr.mesh.bounds.size; Vector3 newPivot = new Vector3(psr.pivot.x, -psr.pivot.z, -psr.pivot.y); if (!Mathf.Approximately(meshSize.x, 0)) { newPivot.x /= meshSize.x; } if (!Mathf.Approximately(meshSize.y, 0)) { newPivot.y /= meshSize.y; } if (!Mathf.Approximately(meshSize.z, 0)) { newPivot.z /= meshSize.z; } ParticleSystem.MinMaxCurve startSizeX = main.startSizeX; ParticleSystem.MinMaxCurve startSizeY = main.startSizeY; ParticleSystem.MinMaxCurve startSizeZ = main.startSizeZ; float xMin = startSizeX.constant; float yMin = startSizeY.constant; float zMin = startSizeZ.constant; if (main.startRotation.mode == ParticleSystemCurveMode.TwoConstants) { xMin = Mathf.Min(startSizeX.constantMin, startSizeX.constantMax); yMin = Mathf.Min(startSizeY.constantMin, startSizeY.constantMax); zMin = Mathf.Min(startSizeZ.constantMin, startSizeZ.constantMax); } if (main.startSize3D) { if (!Mathf.Approximately(xMin, 0)) { newPivot.x *= xMin; } if (!Mathf.Approximately(yMin, 0)) { newPivot.y *= yMin; } if (!Mathf.Approximately(zMin, 0)) { newPivot.z *= zMin; } } else { if (!Mathf.Approximately(xMin, 0)) { newPivot.x *= xMin; newPivot.y *= xMin; newPivot.z *= xMin; } } psr.pivot = newPivot; changed = true; } }
- 빌보드 처리 코드
else if (psr.renderMode == ParticleSystemRenderMode.Billboard) { Vector3 scale = psrTransform.localScale; Transform parent = psrTransform.parent; ParticleSystem.MainModule main = ps.main; if (main.scalingMode != ParticleSystemScalingMode.Local) { if (parent != null) { while (psrTransform.childCount > 0) { psrTransform.GetChild(0).parent = parent; } } while (parent != null) { Vector3 parentScale = parent.localScale; if (!Mathf.Approximately(parentScale.x, 0)) scale.x *= parentScale.x; if (!Mathf.Approximately(parentScale.y, 0)) scale.y *= parentScale.y; if (!Mathf.Approximately(parentScale.z, 0)) scale.z *= parentScale.z; ParticleSystemRenderer ppsr = parent.GetComponent<ParticleSystemRenderer>(); if (ppsr != null && ppsr.enabled && ppsr.renderMode == ParticleSystemRenderMode.Billboard) { break; } parent = parent.parent; } } if (!Mathf.Approximately(scale.y, scale.z) || !Mathf.Approximately(psrTransform.localScale.y, psrTransform.localScale.z)) { psrTransform.localScale = new Vector3(scale.x, scale.z, scale.y); main.scalingMode = ParticleSystemScalingMode.Local; } changed = true; }
- 전체 코드
- 메시(Mesh)