protected override void ReadFromImpl(object obj)
 {
     base.ReadFromImpl(obj);
     ParticleSystem.MainModule uo = (ParticleSystem.MainModule)obj;
     duration                  = uo.duration;
     loop                      = uo.loop;
     prewarm                   = uo.prewarm;
     startDelay                = uo.startDelay;
     startDelayMultiplier      = uo.startDelayMultiplier;
     startLifetime             = uo.startLifetime;
     startLifetimeMultiplier   = uo.startLifetimeMultiplier;
     startSpeed                = uo.startSpeed;
     startSpeedMultiplier      = uo.startSpeedMultiplier;
     startSize3D               = uo.startSize3D;
     startSize                 = uo.startSize;
     startSizeMultiplier       = uo.startSizeMultiplier;
     startSizeX                = uo.startSizeX;
     startSizeXMultiplier      = uo.startSizeXMultiplier;
     startSizeY                = uo.startSizeY;
     startSizeYMultiplier      = uo.startSizeYMultiplier;
     startSizeZ                = uo.startSizeZ;
     startSizeZMultiplier      = uo.startSizeZMultiplier;
     startRotation3D           = uo.startRotation3D;
     startRotation             = uo.startRotation;
     startRotationMultiplier   = uo.startRotationMultiplier;
     startRotationX            = uo.startRotationX;
     startRotationXMultiplier  = uo.startRotationXMultiplier;
     startRotationY            = uo.startRotationY;
     startRotationYMultiplier  = uo.startRotationYMultiplier;
     startRotationZ            = uo.startRotationZ;
     startRotationZMultiplier  = uo.startRotationZMultiplier;
     flipRotation              = uo.flipRotation;
     startColor                = uo.startColor;
     gravityModifier           = uo.gravityModifier;
     gravityModifierMultiplier = uo.gravityModifierMultiplier;
     simulationSpace           = uo.simulationSpace;
     customSimulationSpace     = ToID(uo.customSimulationSpace);
     simulationSpeed           = uo.simulationSpeed;
     useUnscaledTime           = uo.useUnscaledTime;
     scalingMode               = uo.scalingMode;
     playOnAwake               = uo.playOnAwake;
     maxParticles              = uo.maxParticles;
     emitterVelocityMode       = uo.emitterVelocityMode;
     stopAction                = uo.stopAction;
     cullingMode               = uo.cullingMode;
     ringBufferMode            = uo.ringBufferMode;
     ringBufferLoopRange       = uo.ringBufferLoopRange;
 }
        /// <summary>
        /// Update meshe.
        /// </summary>
        void UpdateMesh()
        {
            if (m_ParticleSystem && lastCount != m_ParticleSystem.particleCount)
            {
                lastCount = m_ParticleSystem.particleCount;
            }
            else
            {
                if (dontManage && gameObject.layer != 16)
                {
                    return;
                }
            }

            try
            {
                Profiler.BeginSample("CheckTrail");
                CheckTrail();
                Profiler.EndSample();

                if (m_ParticleSystem && canvas)
                {
                    // I do not know why, but it worked fine when setting `transform.localPosition.z` to `0.01`. (#34, #39)
                    //{
                    //	Vector3 pos = rectTransform.localPosition;
                    //	if (Mathf.Abs (pos.z) < 0.01f)
                    //	{
                    //		pos.z = 0.01f;
                    //		rectTransform.localPosition = pos;
                    //	}
                    //}

                    var rootCanvas = canvas.rootCanvas;
                    Profiler.BeginSample("Disable ParticleSystemRenderer");
                    if (_renderer && Application.isPlaying)
                    {
                        _renderer.enabled = false;
                    }
                    Profiler.EndSample();

                    Profiler.BeginSample("Make Matrix");
                    ParticleSystem.MainModule main = m_ParticleSystem.main;
                    if (!initCulling)
                    {
                        initCulling       = true;
                        originCullingMode = m_ParticleSystem.main.cullingMode;
                    }
                    if (m_ParticleSystem.main.cullingMode != ParticleSystemCullingMode.AlwaysSimulate)
                    {
                        var mainParticle = m_ParticleSystem.main;
                        mainParticle.cullingMode = ParticleSystemCullingMode.AlwaysSimulate;
                    }
                    //scaleaMatrix = main.scalingMode == ParticleSystemScalingMode.Hierarchy
                    //							   ? Matrix4x4.Scale (scale * Vector3.one)
                    //							   : Matrix4x4.Scale (scale * rootCanvas.transform.localScale);

                    /*
                     * fxc
                     *  不做跟随rootCanvas的缩放
                     */
                    scaleaMatrix = Matrix4x4.Scale(scale * Vector3.one);
                    Matrix4x4 matrix = default(Matrix4x4);
                    switch (main.simulationSpace)
                    {
                    case ParticleSystemSimulationSpace.Local:
                        matrix =
                            //scaleaMatrix
                            //* Matrix4x4.Rotate (rectTransform.rotation).inverse
                            //* Matrix4x4.Scale (rectTransform.lossyScale).inverse;

                            /*
                             * fxc
                             * 1.添加zScale解决z为0的情况
                             * 2.逆矩阵应该先旋转再缩放
                             */
                            scaleaMatrix
                            * Matrix4x4.Scale(rectTransform.lossyScale + zScale).inverse
                            *Matrix4x4.Rotate(rectTransform.rotation).inverse;
                        break;

                    case ParticleSystemSimulationSpace.World:
                        matrix =
                            scaleaMatrix
                            * rectTransform.worldToLocalMatrix;

                        bool    isLocalScaling = main.scalingMode == ParticleSystemScalingMode.Local;
                        Vector3 newPos         = rectTransform.position;
                        Vector3 delta          = (newPos - _oldPos);
                        _oldPos = newPos;

                        if (!Mathf.Approximately(scale, 0) && 0 < delta.sqrMagnitude)
                        {
                            if (isLocalScaling)
                            {
                                var s = rootCanvas.transform.localScale * scale;
                                delta.x *= 1f - 1f / s.x;
                                delta.y *= 1f - 1f / s.y;
                                delta.z *= 1f - 1f / s.z;
                            }
                            else
                            {
                                delta = delta * (1 - 1 / scale);
                            }

                            int count = m_ParticleSystem.particleCount;
                            if (s_Particles.Length < count)
                            {
                                s_Particles = new ParticleSystem.Particle [s_Particles.Length * 2];
                            }

                            m_ParticleSystem.GetParticles(s_Particles);
                            for (int i = 0; i < count; i++)
                            {
                                var p = s_Particles [i];
                                p.position      = p.position + delta;
                                s_Particles [i] = p;
                            }
                            m_ParticleSystem.SetParticles(s_Particles, count);
                        }
                        break;

                    case ParticleSystemSimulationSpace.Custom:
                        break;
                    }
                    Profiler.EndSample();

                    _mesh.Clear();
                    if (0 < m_ParticleSystem.particleCount)
                    {
                        Profiler.BeginSample("Bake Mesh");
                        var cam = rootCanvas.renderMode == RenderMode.ScreenSpaceOverlay
                                                        ? UIParticleOverlayCamera.GetCameraForOvrelay(rootCanvas)
                                                        : canvas.worldCamera ?? Camera.main;

                        if (!cam)
                        {
                            return;
                        }
                        if (m_IsTrail)
                        {
                            _renderer.BakeTrailsMesh(_mesh, cam, true);
                        }
                        else
                        {
                            _renderer.BakeMesh(_mesh, cam, true);
                        }
                        Profiler.EndSample();

                        // Apply matrix.
                        Profiler.BeginSample("Apply matrix to position");
                        _mesh.GetVertices(s_Vertices);
                        var count = s_Vertices.Count;
                        for (int i = 0; i < count; i++)
                        {
                            s_Vertices [i] = matrix.MultiplyPoint3x4(s_Vertices [i]);
                        }
                        _mesh.SetVertices(s_Vertices);
                        s_Vertices.Clear();
                        Profiler.EndSample();
                    }


                    // Set mesh to CanvasRenderer.
                    Profiler.BeginSample("Set mesh and texture to CanvasRenderer");
                    canvasRenderer.SetMesh(_mesh);
                    canvasRenderer.SetTexture(mainTexture);
                    if (originRenderQueue == 0 && _renderer != null && _renderer.sharedMaterial != null)
                    {
                        originRenderQueue = _renderer.sharedMaterial.renderQueue;
//#if UNITY_EDITOR
//                        if (Application.isPlaying && _renderer.material != null)
//                            _renderer.material.renderQueue = 3000;
//#else
                        _renderer.sharedMaterial.renderQueue = 3000;
//#endif
                    }
                    // Copy the value from MaterialPropertyBlock to CanvasRenderer (#41)
                    UpdateAnimatableMaterialProperties();

                    Profiler.EndSample();
                }
            }
            catch (System.Exception e)
            {
                Debug.LogException(e);
            }
        }