internal ManagedAsset(BuildingInfo asset)
        {
            TypeOfAsset = AssetType.Building;
            Building    = asset;

            Info = new ShaderInfo(asset.m_mesh.name, nameof(BuildingInfo), asset.name);

            backup_lodHasDifferentShader = asset.m_lodHasDifferentShader;
            backup_lodMissing            = asset.m_lodMissing;
            backup_InvFade    = asset.m_material.GetFloat("_InvFade");
            backup_meshColors = asset.m_mesh.colors;

            backup_maxLodDistance = asset.m_maxLodDistance;
            backup_minLodDistance = asset.m_minLodDistance;

            asset.m_lodHasDifferentShader = false;
            asset.m_lodMissing            = true;
            asset.m_material.SetFloat("_InvFade", Info.Fade);
            asset.m_mesh.colors = GetMeshColors(asset.m_mesh.vertexCount);

            CachedRenderDistance = GetRenderDistance(asset.m_generatedInfo.m_size);
            ApplyCachedRenderDistance();

            SetVisible(Info.IsAlwaysOn, FORCE_UPDATE);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ManagedAsset"/> class
        /// for a <see cref="BuildingInfo"/> asset which contains a shader-using
        /// <see cref="PropInfo"/> asset.
        /// </summary>
        /// <remarks>
        /// This is distinct from the other ShaderAsset types in that the building
        /// itself is not usually directly shader-using (if it is, a separate
        /// ShaderAsset will be created for it).
        /// </remarks>
        /// <param name="asset">The <see cref="BuildingInfo"/> which uses the shader.</param>
        /// <param name="isContainer">Ignored - just there to differentiate the overload.</param>
        /// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="isContainer"/> is not <c>true</c>.</exception>
        /// <exception cref="ArgumentNullException">Thrown if asset <c>m_mesh.name</c> is <c>null</c>.</exception>
        /// <exception cref="FormatException">Thrown if asset <c>m_mesh.name</c> format is invalid.</exception>
        internal ManagedAsset(BuildingInfo asset, bool isContainer)
        {
            if (!isContainer)
            {
                throw new ArgumentOutOfRangeException(nameof(isContainer), "This constructor can only be used for buildings that contain shader-using props.");
            }

            TypeOfAsset = AssetType.Container;
            Building    = asset;

            IsContainer = true;

            Info = new ShaderInfo(CONTAINER_BUILDING, nameof(BuildingInfo), asset.name);

            backup_maxPropDistance = asset.m_maxPropDistance;

            CachedRenderDistance = CONTAINER_MAX_PROP_DISTANCE;
            ApplyCachedRenderDistance();
        }
        private readonly float backup_maxPropDistance;         // Container (BuildingInfo)

        /// <summary>
        /// Initializes a new instance of the <see cref="ManagedAsset"/> class
        /// for a <see cref="PropInfo"/> asset.
        /// </summary>
        /// <param name="asset">The <see cref="PropInfo"/> which uses the shader.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="asset"/> is <c>null</c>.</exception>
        internal ManagedAsset(PropInfo asset)
        {
            TypeOfAsset = AssetType.Prop;
            Prop        = asset;

            Info = new ShaderInfo(asset.m_mesh.name, nameof(PropInfo), asset.name);

            backup_lodHasDifferentShader = asset.m_lodHasDifferentShader;
            backup_InvFade = asset.m_material.GetFloat("_InvFade");

            backup_lodRenderDistance = asset.m_lodRenderDistance;
            backup_maxRenderDistance = asset.m_maxRenderDistance;

            asset.m_lodHasDifferentShader = false;
            asset.m_material.SetFloat("_InvFade", Info.Fade);

            CachedRenderDistance = GetRenderDistance(asset.m_generatedInfo.m_size);
            ApplyCachedRenderDistance();

            SetVisible(Info.IsAlwaysOn, FORCE_UPDATE);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ManagedAsset"/> class
        /// for a <see cref="VehicleInfoSub"/> asset.
        /// </summary>
        /// <param name="asset">The <see cref="VehicleInfoSub"/> which uses the shader.</param>
        /// <exception cref="ArgumentNullException">Thrown if asset <c>m_mesh.name</c> is <c>null</c>.</exception>
        /// <exception cref="FormatException">Thrown if asset <c>m_mesh.name</c> format is invalid.</exception>
        internal ManagedAsset(VehicleInfoSub asset)
        {
            TypeOfAsset = AssetType.Vehicle;
            Vehicle     = asset;

            Info = new ShaderInfo(asset.m_mesh.name, nameof(VehicleInfoSub), asset.name);

            backup_InvFade    = asset.m_material.GetFloat("_InvFade");
            backup_meshColors = asset.m_mesh.colors;

            backup_lodRenderDistance = asset.m_lodRenderDistance;
            backup_maxRenderDistance = asset.m_maxRenderDistance;

            asset.m_material.SetFloat("_InvFade", Info.Fade);
            asset.m_mesh.colors = GetMeshColors(asset.m_mesh.vertexCount);

            CachedRenderDistance = GetRenderDistance(asset.m_generatedInfo.m_size);
            ApplyCachedRenderDistance();

            SetVisible(Info.IsAlwaysOn, FORCE_UPDATE);
        }