/// <summary> /// Generates tileset assets by looking at previously defined atlas brushes. /// </summary> private void GenerateTilesetsForUpgradedBrushes() { RtsUpgradedBrushMap map = RtsUpgradedBrushMap.BrushMappings; foreach (RtsBrushAssetRecordWrapper record in RtsBrushDatabaseWrapper.Instance.records) { ++_tasksCompleted; // Skip if invalid or brush has already been upgraded. if (record.brush == null || map.Lookup(record.brush) != null) { continue; } DisplayProgress("Generating tilesets from atlas brushes."); if (record.brush.GetType() == _tyAtlasTileBrush) { GenerateTilesetFromAtlasBrush(record.brush); } } // Need to rescan brush database so that tilesets can be accessed when // upgrading atlas brushes to tileset brushes. BrushDatabase.Instance.Rescan(); }
/// <summary> /// Copy tile data from v1.x tile system to v2.x tile system. /// </summary> /// <param name="v1">Old tile system.</param> /// <param name="v2">New tile system.</param> private static void CopyTileData(MonoBehaviour v1, TileSystem v2) { RtsUpgradedBrushMap map = RtsBrushUpgradeUtility.BrushMappings; FieldInfo fiFlagsV1 = (_tyTileData != null) ? _tyTileData.GetField("_flags", BindingFlags.NonPublic | BindingFlags.Instance) : null; FieldInfo fiFlagsV2 = typeof(TileData).GetField("_flags", BindingFlags.NonPublic | BindingFlags.Instance); TileData newTile = new TileData(); int rows = (int)_fiTileSystem_rows.GetValue(v1); int columns = (int)_fiTileSystem_columns.GetValue(v1); for (int row = 0; row < rows; ++row) { for (int column = 0; column < columns; ++column) { object oldTile = _miTileSystem_GetTile.Invoke(v1, new object[] { row, column }); if (oldTile == null) { continue; } if (fiFlagsV1 != null) { fiFlagsV2.SetValue(newTile, fiFlagsV1.GetValue(oldTile)); } // Prepare new tile from old tile. newTile.brush = map.Lookup((Object)_fiTileData_brush.GetValue(oldTile)); newTile.gameObject = (GameObject)_fiTileData_gameObject.GetValue(oldTile); newTile.orientationMask = (byte)_fiTileData_orientationMask.GetValue(oldTile); newTile.variationIndex = (byte)(int)_fiTileData_variationIndex.GetValue(oldTile); newTile.Empty = false; v2.SetTileFrom(row, column, newTile); Chunk chunk = v2.GetChunkFromTileIndex(row, column); ForceRepaintForAtlasTiles(newTile, chunk); if (newTile.gameObject != null) { // Transfer ownership of attached game object. newTile.gameObject.transform.parent = chunk.transform; } } } // Some tiles might need to be refreshed! v2.RefreshAllTiles( RefreshFlags.PreservePaintedFlags | RefreshFlags.PreserveTransform | RefreshFlags.UpdateProcedural ); }
/// <summary> /// Upgrades oriented brush (v1.x) into an oriented brush (v2.x). /// </summary> /// <param name="record">Record for existing v1.x brush.</param> private void UpgradeOrientedBrush(RtsBrushAssetRecordWrapper record) { if (useNewAssets) { // Is this the original "Smooth Platform" master brushes? if (record.assetPath == "Assets/Rotorz Tile System/Brushes/Smooth Platform.prefab" || record.assetPath == "Assets/Rotorz Tile System/Brushes/Smooth Platform (Join).prefab" || record.assetPath == "Assets/Rotorz Tile System/Brushes/Smooth Platform (Small).prefab") { // This is a special case that can be switched to new version // if it was imported. OrientedBrush newMasterBrush = AssetDatabase.LoadAssetAtPath("Assets/Rotorz/Tile System/TileBrushes/Master/" + record.displayName + ".brush.asset", typeof(OrientedBrush)) as OrientedBrush; if (newMasterBrush != null) { RtsUpgradedBrushMap.BrushMappings.SetMapping(record.brush, newMasterBrush); return; } // If new version was not found then just proceed to upgrade // existing version. } // Is this one of the original demo brushes? else if (record.assetPath == "Assets/Rotorz Tile System/_Demos/TilePrefabs/Diamond.prefab" || record.assetPath == "Assets/Rotorz Tile System/_Demos/TilePrefabs/Hat Guy.prefab" || record.assetPath == "Assets/Rotorz Tile System/_Demos/TilePrefabs/Steel Brick.prefab") { // This is a special case that can be switched to new version // if it was imported. OrientedBrush newDemoBrush = AssetDatabase.LoadAssetAtPath("Assets/Rotorz/Tile System/Demo/Hat Guy/TileBrushes/" + record.displayName + ".brush.asset", typeof(OrientedBrush)) as OrientedBrush; if (newDemoBrush != null) { RtsUpgradedBrushMap.BrushMappings.SetMapping(record.brush, newDemoBrush); return; } // If new version was not found then just proceed to upgrade // existing version. } } Transform oldBrushTransform = record.brush.transform; OrientedBrush newBrush = BrushUtility.CreateOrientedBrush(record.displayName); newBrush.RemoveOrientation(newBrush.DefaultOrientationMask); List <Object> variations = new List <Object>(); RtsUpgradedBrushMap map = RtsUpgradedBrushMap.BrushMappings; // Copy orientations from old brush. for (int ti = 0; ti < oldBrushTransform.childCount; ++ti) { MonoBehaviour oldOrientation = oldBrushTransform.GetChild(ti).GetComponent(_tyTileBrushOrientation) as MonoBehaviour; if (oldOrientation == null) { continue; } Object[] oldVariations = (Object[])_fiTileBrushOrientation_variations.GetValue(oldOrientation); BrushOrientation newOrientation = newBrush.AddOrientation(OrientationUtility.MaskFromName(oldOrientation.name)); variations.Clear(); for (int i = 0; i < oldVariations.Length; ++i) { if (oldVariations[i] == null) { continue; } Type variationType = oldVariations[i].GetType(); GameObject variationGO = oldVariations[i] as GameObject; Object variationBrush = null; // If game object is nested, check if it is a tile brush prefab! if (variationGO != null) { variationBrush = variationGO.GetComponent(_tyTileBrush); } // If variation is a tile brush then... else if (_tyTileBrush.IsAssignableFrom(variationType)) { variationBrush = oldVariations[i]; } // Need to isolate nested brushes! if (variationBrush != null) { // Note: This only works because oriented brushes are processed last, // and it is not possible to nest oriented brushes. // Use new version of brush! Brush replacementBrush = map.Lookup(variationBrush); if (replacementBrush != null) { variations.Add(replacementBrush); } } else if (variationGO != null) { variations.Add(variationGO); } } newOrientation.variations = variations.ToArray(); } newBrush.DefaultOrientationMask = OrientationUtility.MaskFromName((string)_fiOrientedTileBrush_defaultOrientation.GetValue(record.brush)); newBrush.FallbackMode = (FallbackMode)_fiOrientedTileBrush_fallbackMode.GetValue(record.brush); if (_fiTileBrush_coalesce != null) { newBrush.Coalesce = (Coalesce)_fiTileBrush_coalesce.GetValue(record.brush); } if (_fiTileBrush_coalesceTileGroup != null) { newBrush.CoalesceBrushGroup = (int)_fiTileBrush_coalesceTileGroup.GetValue(record.brush); } if (_fiOrientedTileBrush_forceOverrideFlags != null) { newBrush.forceOverrideFlags = (bool)_fiOrientedTileBrush_forceOverrideFlags.GetValue(record.brush); } FinalizeStandaloneBrush(record, newBrush); }
/// <summary> /// Generate tileset using an atlas brush. /// </summary> /// <remarks> /// <para>One tileset asset is generated for each unique atlas material that /// exists amongst all defined atlas brushes.</para> /// </remarks> /// <param name="brush">Existing atlas brush.</param> /// <returns> /// The tileset. /// </returns> private Tileset GenerateTilesetFromAtlasBrush(MonoBehaviour brush) { MeshRenderer renderer = brush.GetComponent <MeshRenderer>(); if (renderer == null) { return(null); } Material mat = renderer.sharedMaterial; if (mat == null) { return(null); } Texture2D atlasTexture = _fiAtlasTileBrush_atlasTexture.GetValue(brush) as Texture2D; if (atlasTexture == null) { return(null); } RtsUpgradedBrushMap map = RtsUpgradedBrushMap.BrushMappings; Tileset tileset = map.Lookup(mat); if (tileset != null) { return(tileset); } // Create folder for atlas assets string atlasFolder = AssetDatabase.GenerateUniqueAssetPath(BrushUtility.GetBrushAssetPath() + atlasTexture.name); Directory.CreateDirectory(Directory.GetCurrentDirectory() + "/" + atlasFolder); // Create material for tileset Material material = Object.Instantiate(mat) as Material; material.mainTexture = atlasTexture; AssetDatabase.CreateAsset(material, atlasFolder + "/atlas.mat"); AssetDatabase.ImportAsset(atlasFolder + "/atlas.mat"); int atlasTileWidth = (int)_fiAtlasTileBrush_atlasTileWidth.GetValue(brush); int atlasTileHeight = (int)_fiAtlasTileBrush_atlasTileHeight.GetValue(brush); // Calculate metrics for tileset TilesetMetrics metrics = new TilesetMetrics(atlasTexture, atlasTileWidth, atlasTileHeight, 0, 0.5f); // Create new tileset asset. tileset = ScriptableObject.CreateInstance <Tileset>(); tileset.Initialize(material, atlasTexture, metrics); tileset.procedural = useProceduralTilesets; // Save tileset asset. string assetPath = atlasFolder + "/" + atlasTexture.name + ".set.asset"; AssetDatabase.CreateAsset(tileset, assetPath); AssetDatabase.ImportAsset(assetPath); map.SetMapping(mat, tileset); return(tileset); }
/// <summary> /// Upgrade brushes created using v1.x brush components to v2.x brush assets. /// </summary> public void UpgradeBrushes() { PrepareReflection(); // Rescan old brush database just in case user is experimenting with // deleting upgraded brushes, creating new ones, and then performing // upgrade again. RtsBrushDatabaseWrapper.Instance.Rescan(); BeginBulkEdit(); try { CopyBrushCategoryData(); CopyPresetFile(); // Ensure that brush mappings asset is available. RtsUpgradedBrushMap map = BrushMappings; // Count of tasks that will be indicated to user using progress bar. _taskCount = RtsBrushDatabaseWrapper.Instance.records.Count * 5; _tasksCompleted = 0; _taskRatio = 1.0f / (float)_taskCount; GenerateTilesetsForUpgradedBrushes(); // Do not upgrade oriented or alias brushes yet because those types // of brush may require that other brushes are upgraded beforehand. foreach (RtsBrushAssetRecordWrapper record in RtsBrushDatabaseWrapper.Instance.records) { ++_tasksCompleted; // Skip if invalid or brush has already been upgraded. if (record.brush == null || map.Lookup(record.brush) != null) { continue; } Type brushType = record.brush.GetType(); if (brushType == _tyOrientedTileBrush) { continue; // Save oriented brushes until last! } else if (brushType == _tyAliasTileBrush) { continue; // Do these afterwards! } else if (brushType == _tyAtlasTileBrush) { UpgradeAtlasBrush(record); } else if (brushType == _tyBasicTileBrush) { UpgradeBasicBrush(record); } else if (brushType == _tyEmptyTileBrush) { UpgradeEmptyBrush(record); } else { Debug.LogError(string.Format("Cannot upgrade unknown brush type '{0}'.", record.brush.GetType().FullName)); } DisplayProgress("Upgrading primative brushes."); } // Upgrade alias brushes that do not target oriented brushes. // Reason: Alias brushes can be nested inside oriented brushes. foreach (RtsBrushAssetRecordWrapper record in RtsBrushDatabaseWrapper.Instance.records) { ++_tasksCompleted; // Skip if invalid or brush has already been upgraded. if (record.brush == null || map.Lookup(record.brush) != null) { continue; } if (record.brush.GetType() == _tyAliasTileBrush) { object aliasOf = _fiAliasTileBrush_aliasOf.GetValue(record.brush); if (aliasOf != null && aliasOf.GetType() != _tyOrientedTileBrush) { UpgradeAliasBrush(record); } } DisplayProgress("Upgrading alias brushes."); } // Upgrade oriented brushes! foreach (RtsBrushAssetRecordWrapper record in RtsBrushDatabaseWrapper.Instance.records) { ++_tasksCompleted; // Skip if invalid or brush has already been upgraded. if (record.brush == null || map.Lookup(record.brush) != null) { continue; } if (record.brush.GetType() == _tyOrientedTileBrush) { UpgradeOrientedBrush(record); } DisplayProgress("Upgrading oriented brushes."); } // Finally upgrade alias brushes that target oriented brushes. foreach (RtsBrushAssetRecordWrapper record in RtsBrushDatabaseWrapper.Instance.records) { ++_tasksCompleted; // Skip if invalid or brush has already been upgraded. if (record.brush == null || map.Lookup(record.brush) != null) { continue; } if (record.brush.GetType() == _tyAliasTileBrush) { object aliasOf = _fiAliasTileBrush_aliasOf.GetValue(record.brush); if (aliasOf != null && aliasOf.GetType() == _tyOrientedTileBrush) { UpgradeAliasBrush(record); } } DisplayProgress("Upgrading oriented brushes."); } // The brush map likely needs to be saved now. EditorUtility.SetDirty(map); } finally { // Make sure that the progress bar is hidden before leaving method! EditorUtility.ClearProgressBar(); // Finish bulk editing regardless of whether an exception has occurred. EndBulkEdit(); } }
/// <summary> /// Upgrade tile system from v1.0.0-v1.0.8 to v2.0.0. /// </summary> /// <remarks> /// <para>Replicates upgrade process that was included in v1.0.9+ but converts straight /// to v2.0.0 instead of v1.0.9.</para> /// </remarks> /// <param name="v1">Old tile system.</param> public static void UpgradeTileSystemA(MonoBehaviour v1) { RtsUpgradedBrushMap map = RtsBrushUpgradeUtility.BrushMappings; EditorUtility.DisplayProgressBar("Upgrade Tile System", "Initializing new data structure...", 0.0f); try { PropertyInfo piTileData_hasGameObject = typeof(TileData).GetProperty("HasGameObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Vector3 tileSize = (Vector3)_fiTileSystem_tileSize.GetValue(v1); int rows = (int)_fiTileSystem_rows.GetValue(v1); int columns = (int)_fiTileSystem_columns.GetValue(v1); // Create v2.x tile system. TileSystem v2 = v1.gameObject.AddComponent <TileSystem>(); v2.CreateSystem(tileSize.x, tileSize.y, tileSize.z, rows, columns, 30, 30); CopyProperties(v1, v2); // Assume value that was consistent with original default settings v2.applyRuntimeStripping = true; v2.StrippingPreset = StrippingPreset.NoStripping; v2.BeginBulkEdit(); Component[] instanceComponents = v1.GetComponentsInChildren(_tyTileInstance, true); float task = 0.0f; float taskCount = instanceComponents.Length; float taskRatio = 1.0f / taskCount; TileData tile = new TileData(); // Retrieve all tile instance components foreach (MonoBehaviour instance in instanceComponents) { EditorUtility.DisplayProgressBar("Upgrade Tile System", "Processing tile data...", (task++) * taskRatio); int row = (int)_fiTileInstance_row.GetValue(instance); int column = (int)_fiTileInstance_column.GetValue(instance); tile.Clear(); // Create and assign tile data tile.brush = map.Lookup((Object)_piTileInstance_brush.GetValue(instance, null)); tile.orientationMask = (byte)OrientationUtility.MaskFromName((string)_fiTileInstance_orientationName.GetValue(instance)); tile.variationIndex = (byte)(int)_fiTileInstance_variationIndex.GetValue(instance); tile.Empty = false; tile.gameObject = instance.gameObject; piTileData_hasGameObject.SetValue(tile, true, null); v2.SetTileFrom(row, column, tile); Chunk chunk = v2.GetChunkFromTileIndex(row, column); ForceRepaintForAtlasTiles(v2.GetTile(row, column), chunk); if (instance == null) { continue; } // Cleanup original tile instance? if (!StrippingUtility.StripEmptyGameObject(instance.transform)) { // Reparent game object to its shiny new chunk! instance.gameObject.transform.parent = chunk.transform; } // Destroy unwanted tile instance component Object.DestroyImmediate(instance); } int count = v2.EndBulkEdit(); RemoveTileSystem(v1); if (count > 0) { Debug.Log(string.Format("Upgrade of tile system '{0}' completed and {1} tile(s) were force refreshed.", v2.name, count)); } else { Debug.Log(string.Format("Upgrade of tile system '{0}' completed.", v2.name)); } } finally { EditorUtility.ClearProgressBar(); } }