public void Refresh()
        {
            if (Prefab == null)
            {
                SharedMesh        = null;
                SharedMaterials   = null;
                ShadowCastingMode = ShadowCastingMode.Off;
                ReceiveShadow     = false;
                Layer             = 0;
            }
            else
            {
                MeshFilter mf = Prefab.GetComponentInChildren <MeshFilter>();
                if (mf != null)
                {
                    SharedMesh = mf.sharedMesh;
                }

                MeshRenderer mr = Prefab.GetComponentInChildren <MeshRenderer>();
                if (mr != null)
                {
                    SharedMaterials   = mr.sharedMaterials;
                    ShadowCastingMode = mr.shadowCastingMode;
                    ReceiveShadow     = mr.receiveShadows;
                }

                CapsuleCollider col = Prefab.GetComponentInChildren <CapsuleCollider>();
                hasCollider = col != null;
                if (col != null)
                {
                    ColliderInfo = new GTreeColliderInfo(col);
                }

                if (KeepPrefabLayer)
                {
                    Layer = Prefab.layer;
                }
            }

            if (BaseScale == Vector3.zero)
            {
                BaseScale = Vector3.one;
            }
        }
        private void LateUpdate()
        {
            if (Terrain == null)
            {
                return;
            }
            if (Terrain.TerrainData == null)
            {
                return;
            }
            if (Terrain.TerrainData.Foliage.Trees == null)
            {
                return;
            }
            if (Terrain.TerrainData.Foliage.Trees.Prototypes.Count == 0)
            {
                return;
            }

            GameObject actualTarget = null;

            if (Target != null)
            {
                actualTarget = Target;
            }
            else if (Camera.main != null)
            {
                actualTarget = Camera.main.gameObject;
            }

            if (actualTarget == null)
            {
                return;
            }
            Vector3 terrainSize = new Vector3(
                Terrain.TerrainData.Geometry.Width,
                Terrain.TerrainData.Geometry.Height,
                Terrain.TerrainData.Geometry.Length);
            Vector3 targetLocalPos = Terrain.transform.InverseTransformPoint(actualTarget.transform.position);
            Vector3 treeLocalPos   = Vector3.zero;
            float   sqrDistance    = distance * distance;

            TreeInstances.Clear();
            List <GTreeInstance> instances = Terrain.TerrainData.Foliage.TreeInstances;

            for (int i = 0; i < instances.Count; ++i)
            {
                GTreeInstance tree = instances[i];
                treeLocalPos.Set(
                    tree.Position.x * terrainSize.x,
                    tree.Position.y * terrainSize.y,
                    tree.Position.z * terrainSize.z);
                if (Vector3.SqrMagnitude(targetLocalPos - treeLocalPos) <= sqrDistance)
                {
                    TreeInstances.Add(tree);
                }
            }

            Vector3 targetNormalizePos = Terrain.WorldPointToNormalized(actualTarget.transform.position);

            TreeInstances.Sort((t0, t1) =>
            {
                float d0 = Vector3.SqrMagnitude(targetNormalizePos - t0.Position);
                float d1 = Vector3.SqrMagnitude(targetNormalizePos - t1.Position);
                return(d0.CompareTo(d1));
            });

            List <GTreePrototype> prototypes = Terrain.TerrainData.Foliage.Trees.Prototypes;
            int colliderIndex = 0;

            for (int i = 0; i < TreeInstances.Count; ++i)
            {
                GTreeInstance  tree      = TreeInstances[i];
                GTreePrototype prototype = prototypes[tree.PrototypeIndex];
                if (!prototype.HasCollider)
                {
                    continue;
                }

                if (colliderIndex >= ColliderBudget)
                {
                    break;
                }
                CapsuleCollider col = GetCollider(colliderIndex);
                colliderIndex += 1;

                Vector3 localPos = new Vector3(
                    terrainSize.x * tree.Position.x,
                    terrainSize.y * tree.Position.y,
                    terrainSize.z * tree.Position.z);
                Vector3 worldPos = Terrain.transform.TransformPoint(localPos);
                col.transform.position   = worldPos;
                col.transform.rotation   = tree.Rotation;
                col.transform.localScale = tree.Scale;
                GTreeColliderInfo colliderInfo = prototype.ColliderInfo;
                col.center           = colliderInfo.Center;
                col.radius           = colliderInfo.Radius;
                col.height           = colliderInfo.Height;
                col.direction        = colliderInfo.Direction;
                col.gameObject.layer = prototype.Layer;
                col.gameObject.tag   = prototype.Prefab.tag;
                col.gameObject.SetActive(true);
            }

            for (int i = colliderIndex; i < ColliderBudget; ++i)
            {
                CapsuleCollider col = GetCollider(i);
                col.gameObject.SetActive(false);
            }
        }