diff --git a/Assets/Features/VoxelWorld/Data/VoxelWorldConfig.asset b/Assets/Features/VoxelWorld/Data/VoxelWorldConfig.asset index 1d1de8b2..08d31a21 100644 --- a/Assets/Features/VoxelWorld/Data/VoxelWorldConfig.asset +++ b/Assets/Features/VoxelWorld/Data/VoxelWorldConfig.asset @@ -36,6 +36,8 @@ MonoBehaviour: - {fileID: 11400000, guid: 6d0dbe510ed048440a3925ef40aeeb5b, type: 2} biomeNoiseScale: 0.02 biomeSize: 6 + placementCollections: + - {fileID: 11400000, guid: b91d23f483c774f4dbb1a77660881d87, type: 2} maxAsyncChunkJobs: 2 maxChunkBuildsPerFrame: 1 maxChunkMeshBuildsPerFrame: 1 diff --git a/Assets/Features/VoxelWorld/Data/WorldPrefabCollection.asset b/Assets/Features/VoxelWorld/Data/WorldPrefabCollection.asset index 918080dd..1c46d886 100644 --- a/Assets/Features/VoxelWorld/Data/WorldPrefabCollection.asset +++ b/Assets/Features/VoxelWorld/Data/WorldPrefabCollection.asset @@ -19,8 +19,9 @@ MonoBehaviour: - id: EntranceCrypt prefab: {fileID: 155468, guid: ea0c7071e67bf1c43940a8ab3ea121f8, type: 3} weight: 10 + spawnChancePercent: 100 placementMode: 1 - footprint: {x: 0, y: 0} + footprint: {x: 2, y: 2} clearance: 4 flattenPadding: 4 flattenSearchRadius: 4 @@ -28,8 +29,9 @@ MonoBehaviour: - id: GlowingOrb prefab: {fileID: 190932, guid: 20e0bf298681fcd4693097c822277593, type: 3} weight: 0 + spawnChancePercent: 100 placementMode: 0 - footprint: {x: 0, y: 0} + footprint: {x: 2, y: 2} clearance: 4 flattenPadding: 4 flattenSearchRadius: 4 diff --git a/Assets/Features/VoxelWorld/Runtime/VoxelWorldConfig.cs b/Assets/Features/VoxelWorld/Runtime/VoxelWorldConfig.cs index 4a886870..99bb439b 100644 --- a/Assets/Features/VoxelWorld/Runtime/VoxelWorldConfig.cs +++ b/Assets/Features/VoxelWorld/Runtime/VoxelWorldConfig.cs @@ -53,7 +53,7 @@ namespace InfiniteWorld.VoxelWorld internal readonly struct VoxelWorldResolvedSettings { private static readonly IReadOnlyList EmptyBiomes = System.Array.Empty(); - private static readonly IReadOnlyList EmptyPlacementCollections = System.Array.Empty(); + private static readonly IReadOnlyList EmptyPlacementCollections = System.Array.Empty(); public static readonly VoxelWorldResolvedSettings Default = Resolve(null); @@ -79,7 +79,7 @@ namespace InfiniteWorld.VoxelWorld IReadOnlyList biomeProfiles, float biomeNoiseScale, float biomeSize, - IReadOnlyList placementCollections, + IReadOnlyList placementCollections, int maxAsyncChunkJobs, int maxChunkBuildsPerFrame, int maxChunkMeshBuildsPerFrame, @@ -140,7 +140,7 @@ namespace InfiniteWorld.VoxelWorld public IReadOnlyList BiomeProfiles { get; } public float BiomeNoiseScale { get; } public float BiomeSize { get; } - public IReadOnlyList PlacementCollections { get; } + public IReadOnlyList PlacementCollections { get; } public int MaxAsyncChunkJobs { get; } public int MaxChunkBuildsPerFrame { get; } public int MaxChunkMeshBuildsPerFrame { get; } @@ -154,9 +154,7 @@ namespace InfiniteWorld.VoxelWorld IReadOnlyList biomes = config != null && config.biomeProfiles != null ? config.biomeProfiles : EmptyBiomes; - IReadOnlyList placements = config != null && config.placementCollections != null - ? config.placementCollections - : EmptyPlacementCollections; + IReadOnlyList placements = ResolvePlacementCollections(config); return new VoxelWorldResolvedSettings( Mathf.Max(8, config != null ? config.chunkSize : 16), @@ -189,5 +187,58 @@ namespace InfiniteWorld.VoxelWorld Mathf.Max(1, config != null ? config.renderRegionSizeInChunks : 4), Mathf.Max(1, config != null ? config.maxRegionBuildsPerFrame : 1)); } + + private static IReadOnlyList ResolvePlacementCollections(VoxelWorldConfig config) + { + if (config == null || config.placementCollections == null || config.placementCollections.Count == 0) + { + return EmptyPlacementCollections; + } + + List result = new List(config.placementCollections.Count); + for (int collectionIndex = 0; collectionIndex < config.placementCollections.Count; collectionIndex++) + { + WorldPrefabCollection collection = config.placementCollections[collectionIndex]; + if (collection == null) + { + continue; + } + + List entries = new List(); + if (collection.entries != null) + { + for (int entryIndex = 0; entryIndex < collection.entries.Count; entryIndex++) + { + WorldPrefabEntry entry = collection.entries[entryIndex]; + if (entry == null) + { + continue; + } + + entries.Add(new WorldPrefabEntryRuntime( + entryIndex, + entry.id, + entry.weight, + entry.spawnChancePercent, + entry.placementMode, + entry.footprint, + entry.clearance, + entry.flattenPadding, + entry.flattenSearchRadius, + entry.allowRotations, + entry.prefab != null)); + } + } + + result.Add(new WorldPrefabCollectionRuntime( + collectionIndex, + Mathf.Max(0, collection.maxPlacementsPerChunk), + Mathf.Max(1, collection.attemptsPerPlacement), + Mathf.Max(0, collection.chunkEdgePadding), + entries)); + } + + return result.Count > 0 ? result : EmptyPlacementCollections; + } } } diff --git a/Assets/Features/VoxelWorld/Runtime/VoxelWorldGenerator.Placements.cs b/Assets/Features/VoxelWorld/Runtime/VoxelWorldGenerator.Placements.cs index 1f515a82..89b02720 100644 --- a/Assets/Features/VoxelWorld/Runtime/VoxelWorldGenerator.Placements.cs +++ b/Assets/Features/VoxelWorld/Runtime/VoxelWorldGenerator.Placements.cs @@ -6,9 +6,8 @@ namespace InfiniteWorld.VoxelWorld public sealed partial class VoxelWorldGenerator { private readonly Dictionary chunkPlacementPlans = new Dictionary(); - private IReadOnlyList placementCollections => settings.PlacementCollections; - - public IReadOnlyList PlacementCollections => placementCollections; + private readonly object placementPlanLock = new object(); + private IReadOnlyList placementCollections => settings.PlacementCollections; public WorldChunkPlacementPlan GetChunkPlacementPlan(Vector2Int chunkCoord) { @@ -32,14 +31,26 @@ namespace InfiniteWorld.VoxelWorld private WorldChunkPlacementPlan GetOrCreateChunkPlacementPlan(Vector2Int chunkCoord) { - if (chunkPlacementPlans.TryGetValue(chunkCoord, out WorldChunkPlacementPlan plan)) + lock (placementPlanLock) { - return plan; + if (chunkPlacementPlans.TryGetValue(chunkCoord, out WorldChunkPlacementPlan cachedPlan)) + { + return cachedPlan; + } } - plan = WorldSpawnPlanner.PlanChunk(seed, chunkCoord, chunkSize, placementCollections, GetBaseHeightAtWorldCell); - chunkPlacementPlans[chunkCoord] = plan; - return plan; + WorldChunkPlacementPlan plan = WorldSpawnPlanner.PlanChunk(seed, chunkCoord, chunkSize, placementCollections, GetBaseHeightAtWorldCell); + + lock (placementPlanLock) + { + if (chunkPlacementPlans.TryGetValue(chunkCoord, out WorldChunkPlacementPlan cachedPlan)) + { + return cachedPlan; + } + + chunkPlacementPlans[chunkCoord] = plan; + return plan; + } } private int GetSampledFinalHeightAtWorldCell(Vector2Int worldCell) @@ -72,7 +83,10 @@ namespace InfiniteWorld.VoxelWorld private void CleanupPlacementPlans() { - chunkPlacementPlans.Clear(); + lock (placementPlanLock) + { + chunkPlacementPlans.Clear(); + } } } } diff --git a/Assets/Features/VoxelWorld/Runtime/VoxelWorldGenerator.cs b/Assets/Features/VoxelWorld/Runtime/VoxelWorldGenerator.cs index dc6ef37f..a3b269bf 100644 --- a/Assets/Features/VoxelWorld/Runtime/VoxelWorldGenerator.cs +++ b/Assets/Features/VoxelWorld/Runtime/VoxelWorldGenerator.cs @@ -286,7 +286,10 @@ namespace InfiniteWorld.VoxelWorld Vector2Int regionCoord = ChunkToRegion(coord); MarkRegionDirty(coord); chunks.Remove(coord); - chunkPlacementPlans.Remove(coord); + lock (placementPlanLock) + { + chunkPlacementPlans.Remove(coord); + } runtime.Dispose(); TryDisposeRegionIfEmpty(regionCoord); QueueNeighborRefresh(coord); diff --git a/Assets/Features/VoxelWorld/Runtime/WorldPrefabCollection.cs b/Assets/Features/VoxelWorld/Runtime/WorldPrefabCollection.cs index 5e96187d..c7ba553c 100644 --- a/Assets/Features/VoxelWorld/Runtime/WorldPrefabCollection.cs +++ b/Assets/Features/VoxelWorld/Runtime/WorldPrefabCollection.cs @@ -58,6 +58,54 @@ namespace InfiniteWorld.VoxelWorld public bool allowRotations = true; } + internal sealed class WorldPrefabCollectionRuntime + { + public WorldPrefabCollectionRuntime(int sourceIndex, int maxPlacementsPerChunk, int attemptsPerPlacement, int chunkEdgePadding, IReadOnlyList entries) + { + SourceIndex = sourceIndex; + MaxPlacementsPerChunk = maxPlacementsPerChunk; + AttemptsPerPlacement = attemptsPerPlacement; + ChunkEdgePadding = chunkEdgePadding; + Entries = entries ?? Array.Empty(); + } + + public int SourceIndex { get; } + public int MaxPlacementsPerChunk { get; } + public int AttemptsPerPlacement { get; } + public int ChunkEdgePadding { get; } + public IReadOnlyList Entries { get; } + } + + internal sealed class WorldPrefabEntryRuntime + { + public WorldPrefabEntryRuntime(int sourceIndex, string id, float weight, float spawnChancePercent, WorldPlacementMode placementMode, Vector2Int footprint, int clearance, int flattenPadding, int flattenSearchRadius, bool allowRotations, bool hasPrefab) + { + SourceIndex = sourceIndex; + Id = string.IsNullOrWhiteSpace(id) ? $"entry_{sourceIndex}" : id; + Weight = Mathf.Max(0f, weight); + SpawnChancePercent = Mathf.Clamp(spawnChancePercent, 0f, 100f); + PlacementMode = placementMode; + Footprint = new Vector2Int(Mathf.Max(1, footprint.x), Mathf.Max(1, footprint.y)); + Clearance = Mathf.Max(0, clearance); + FlattenPadding = Mathf.Max(0, flattenPadding); + FlattenSearchRadius = Mathf.Max(1, flattenSearchRadius); + AllowRotations = allowRotations; + HasPrefab = hasPrefab; + } + + public int SourceIndex { get; } + public string Id { get; } + public float Weight { get; } + public float SpawnChancePercent { get; } + public WorldPlacementMode PlacementMode { get; } + public Vector2Int Footprint { get; } + public int Clearance { get; } + public int FlattenPadding { get; } + public int FlattenSearchRadius { get; } + public bool AllowRotations { get; } + public bool HasPrefab { get; } + } + public sealed class WorldTerrainPatch { private readonly List flattenedCells; @@ -72,14 +120,14 @@ namespace InfiniteWorld.VoxelWorld public readonly struct WorldSpawnPoint { - public WorldSpawnPoint(long spawnId, Vector2Int chunkCoord, int spawnOrdinalInChunk, int collectionIndex, int entryIndex, WorldPrefabEntry entry, Vector3 position, Quaternion rotation) + public WorldSpawnPoint(long spawnId, Vector2Int chunkCoord, int spawnOrdinalInChunk, int collectionIndex, int entryIndex, string entryId, Vector3 position, Quaternion rotation) { SpawnId = spawnId; ChunkCoord = chunkCoord; SpawnOrdinalInChunk = spawnOrdinalInChunk; CollectionIndex = collectionIndex; EntryIndex = entryIndex; - Entry = entry; + EntryId = entryId; Position = position; Rotation = rotation; } @@ -89,7 +137,7 @@ namespace InfiniteWorld.VoxelWorld public int SpawnOrdinalInChunk { get; } public int CollectionIndex { get; } public int EntryIndex { get; } - public WorldPrefabEntry Entry { get; } + public string EntryId { get; } public Vector3 Position { get; } public Quaternion Rotation { get; } } diff --git a/Assets/Features/VoxelWorld/Runtime/WorldSpawnPlanner.cs b/Assets/Features/VoxelWorld/Runtime/WorldSpawnPlanner.cs index fe7b660e..36622a8b 100644 --- a/Assets/Features/VoxelWorld/Runtime/WorldSpawnPlanner.cs +++ b/Assets/Features/VoxelWorld/Runtime/WorldSpawnPlanner.cs @@ -9,7 +9,7 @@ namespace InfiniteWorld.VoxelWorld int worldSeed, Vector2Int chunkCoord, int chunkSize, - IReadOnlyList collections, + IReadOnlyList collections, System.Func getBaseHeight) { if (collections == null || collections.Count == 0) @@ -25,15 +25,15 @@ namespace InfiniteWorld.VoxelWorld for (int collectionIndex = 0; collectionIndex < collections.Count; collectionIndex++) { - WorldPrefabCollection collection = collections[collectionIndex]; - if (collection == null || collection.entries == null || collection.entries.Count == 0 || collection.maxPlacementsPerChunk <= 0) + WorldPrefabCollectionRuntime collection = collections[collectionIndex]; + if (collection == null || collection.Entries == null || collection.Entries.Count == 0 || collection.MaxPlacementsPerChunk <= 0) { continue; } - for (int placementIndex = 0; placementIndex < collection.maxPlacementsPerChunk; placementIndex++) + for (int placementIndex = 0; placementIndex < collection.MaxPlacementsPerChunk; placementIndex++) { - if (!TryPickEntry(collection, worldSeed, chunkCoord, collectionIndex, placementIndex, out int entryIndex, out WorldPrefabEntry entry)) + if (!TryPickEntry(collection, worldSeed, chunkCoord, collectionIndex, placementIndex, out int entryIndex, out WorldPrefabEntryRuntime entry)) { continue; } @@ -71,18 +71,18 @@ namespace InfiniteWorld.VoxelWorld return new WorldChunkPlacementPlan(spawnPoints, terrainPatches, flattenedCells.Count > 0 ? flattenedCells : null); } - private static bool TryPickEntry(WorldPrefabCollection collection, int worldSeed, Vector2Int chunkCoord, int collectionIndex, int placementIndex, out int entryIndex, out WorldPrefabEntry entry) + private static bool TryPickEntry(WorldPrefabCollectionRuntime collection, int worldSeed, Vector2Int chunkCoord, int collectionIndex, int placementIndex, out int entryIndex, out WorldPrefabEntryRuntime entry) { float totalWeight = 0f; - for (int i = 0; i < collection.entries.Count; i++) + for (int i = 0; i < collection.Entries.Count; i++) { - WorldPrefabEntry candidate = collection.entries[i]; - if (candidate == null || candidate.prefab == null || candidate.weight <= 0f) + WorldPrefabEntryRuntime candidate = collection.Entries[i]; + if (candidate == null || !candidate.HasPrefab || candidate.Weight <= 0f) { continue; } - totalWeight += candidate.weight; + totalWeight += candidate.Weight; } if (totalWeight <= 0f) @@ -94,15 +94,15 @@ namespace InfiniteWorld.VoxelWorld float pick = WorldSeedUtility.Value01(WorldSeedUtility.Hash(worldSeed, chunkCoord.x, chunkCoord.y, collectionIndex, placementIndex, 1)) * totalWeight; float accumulated = 0f; - for (int i = 0; i < collection.entries.Count; i++) + for (int i = 0; i < collection.Entries.Count; i++) { - WorldPrefabEntry candidate = collection.entries[i]; - if (candidate == null || candidate.prefab == null || candidate.weight <= 0f) + WorldPrefabEntryRuntime candidate = collection.Entries[i]; + if (candidate == null || !candidate.HasPrefab || candidate.Weight <= 0f) { continue; } - accumulated += candidate.weight; + accumulated += candidate.Weight; if (pick <= accumulated) { entryIndex = i; @@ -111,10 +111,10 @@ namespace InfiniteWorld.VoxelWorld } } - for (int i = collection.entries.Count - 1; i >= 0; i--) + for (int i = collection.Entries.Count - 1; i >= 0; i--) { - WorldPrefabEntry candidate = collection.entries[i]; - if (candidate == null || candidate.prefab == null || candidate.weight <= 0f) + WorldPrefabEntryRuntime candidate = collection.Entries[i]; + if (candidate == null || !candidate.HasPrefab || candidate.Weight <= 0f) { continue; } @@ -129,36 +129,36 @@ namespace InfiniteWorld.VoxelWorld return false; } - private static bool PassesSpawnChance(WorldPrefabEntry entry, int worldSeed, Vector2Int chunkCoord, int collectionIndex, int placementIndex) + private static bool PassesSpawnChance(WorldPrefabEntryRuntime entry, int worldSeed, Vector2Int chunkCoord, int collectionIndex, int placementIndex) { if (entry == null) { return false; } - if (entry.spawnChancePercent <= 0f) + if (entry.SpawnChancePercent <= 0f) { return false; } - if (entry.spawnChancePercent >= 100f) + if (entry.SpawnChancePercent >= 100f) { return true; } float roll = WorldSeedUtility.Value01(WorldSeedUtility.Hash(worldSeed, chunkCoord.x, chunkCoord.y, collectionIndex, placementIndex, 11)) * 100f; - return roll <= entry.spawnChancePercent; + return roll <= entry.SpawnChancePercent; } private static bool TryPlanPlacement( int worldSeed, Vector2Int chunkCoord, int chunkSize, - WorldPrefabCollection collection, + WorldPrefabCollectionRuntime collection, int collectionIndex, int placementIndex, int entryIndex, - WorldPrefabEntry entry, + WorldPrefabEntryRuntime entry, int spawnOrdinal, HashSet occupiedCells, HashSet flattenedCells, @@ -172,20 +172,20 @@ namespace InfiniteWorld.VoxelWorld patch = null; Vector2Int chunkOrigin = new Vector2Int(chunkCoord.x * chunkSize, chunkCoord.y * chunkSize); - int attempts = Mathf.Max(1, collection.attemptsPerPlacement); + int attempts = Mathf.Max(1, collection.AttemptsPerPlacement); for (int attempt = 0; attempt < attempts; attempt++) { - int rotationSteps = entry.allowRotations ? WorldSeedUtility.Range(WorldSeedUtility.Hash(worldSeed, chunkCoord.x, chunkCoord.y, collectionIndex, placementIndex, attempt, 2), 0, 4) : 0; - Vector2Int footprint = GetFootprint(entry.footprint, rotationSteps); + int rotationSteps = entry.AllowRotations ? WorldSeedUtility.Range(WorldSeedUtility.Hash(worldSeed, chunkCoord.x, chunkCoord.y, collectionIndex, placementIndex, attempt, 2), 0, 4) : 0; + Vector2Int footprint = GetFootprint(entry.Footprint, rotationSteps); if (footprint.x <= 0 || footprint.y <= 0) { continue; } - int localMinX = collection.chunkEdgePadding; - int localMinZ = collection.chunkEdgePadding; - int localMaxX = chunkSize - collection.chunkEdgePadding - footprint.x; - int localMaxZ = chunkSize - collection.chunkEdgePadding - footprint.y; + int localMinX = collection.ChunkEdgePadding; + int localMinZ = collection.ChunkEdgePadding; + int localMaxX = chunkSize - collection.ChunkEdgePadding - footprint.x; + int localMaxZ = chunkSize - collection.ChunkEdgePadding - footprint.y; if (localMaxX < localMinX || localMaxZ < localMinZ) { continue; @@ -194,14 +194,14 @@ namespace InfiniteWorld.VoxelWorld int localX = WorldSeedUtility.Range(WorldSeedUtility.Hash(worldSeed, chunkCoord.x, chunkCoord.y, collectionIndex, placementIndex, attempt, 3), localMinX, localMaxX + 1); int localZ = WorldSeedUtility.Range(WorldSeedUtility.Hash(worldSeed, chunkCoord.x, chunkCoord.y, collectionIndex, placementIndex, attempt, 4), localMinZ, localMaxZ + 1); RectInt footprintRect = new RectInt(localX, localZ, footprint.x, footprint.y); - RectInt reservedRect = ExpandRect(footprintRect, Mathf.Max(0, entry.clearance), chunkSize); + RectInt reservedRect = ExpandRect(footprintRect, Mathf.Max(0, entry.Clearance), chunkSize); if (IntersectsOccupied(chunkOrigin, reservedRect, occupiedCells)) { continue; } - if (entry.placementMode == WorldPlacementMode.GroundOnly) + if (entry.PlacementMode == WorldPlacementMode.GroundOnly) { if (!IsGroundArea(chunkOrigin, reservedRect, flattenedCells, getBaseHeight)) { @@ -227,7 +227,7 @@ namespace InfiniteWorld.VoxelWorld long spawnId = WorldSeedUtility.ToStableId( WorldSeedUtility.Hash(worldSeed, chunkCoord.x, chunkCoord.y, collectionIndex), WorldSeedUtility.Hash(entryIndex, placementIndex, spawnOrdinal, footprintRect.x, footprintRect.y)); - spawnPoint = new WorldSpawnPoint(spawnId, chunkCoord, spawnOrdinal, collectionIndex, entryIndex, entry, position, Quaternion.Euler(0f, rotationY, 0f)); + spawnPoint = new WorldSpawnPoint(spawnId, chunkCoord, spawnOrdinal, collectionIndex, entryIndex, entry.Id, position, Quaternion.Euler(0f, rotationY, 0f)); return true; } @@ -239,14 +239,14 @@ namespace InfiniteWorld.VoxelWorld int chunkSize, RectInt footprintRect, RectInt reservedRect, - WorldPrefabEntry entry, + WorldPrefabEntryRuntime entry, HashSet occupiedCells, HashSet flattenedCells, System.Func getBaseHeight, out WorldTerrainPatch patch, out List reservedCells) { - int flattenPadding = Mathf.Max(entry.clearance, entry.flattenPadding); + int flattenPadding = Mathf.Max(entry.Clearance, entry.FlattenPadding); RectInt flattenRect = ExpandRect(footprintRect, flattenPadding, chunkSize); List flattened = CollectCells(chunkOrigin, flattenRect); if (IntersectsOccupied(flattened, occupiedCells)) @@ -256,7 +256,7 @@ namespace InfiniteWorld.VoxelWorld return false; } - List corridor = TryBuildAccessCorridor(chunkOrigin, chunkSize, flattenRect, Mathf.Max(1, entry.flattenSearchRadius), occupiedCells, flattenedCells, getBaseHeight); + List corridor = TryBuildAccessCorridor(chunkOrigin, chunkSize, flattenRect, Mathf.Max(1, entry.FlattenSearchRadius), occupiedCells, flattenedCells, getBaseHeight); if (corridor == null) { patch = null; diff --git a/Assets/Features/VoxelWorld/Scenes/VoxelWorldTestScene.unity b/Assets/Features/VoxelWorld/Scenes/VoxelWorldTestScene.unity index 9aa2609d..e525a32b 100644 --- a/Assets/Features/VoxelWorld/Scenes/VoxelWorldTestScene.unity +++ b/Assets/Features/VoxelWorld/Scenes/VoxelWorldTestScene.unity @@ -277,63 +277,6 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1001 &1015513039 -PrefabInstance: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_Modification: - serializedVersion: 3 - m_TransformParent: {fileID: 0} - m_Modifications: - - target: {fileID: 155468, guid: ea0c7071e67bf1c43940a8ab3ea121f8, type: 3} - propertyPath: m_Name - value: SM_Env_Entrance_Crypt_01 - objectReference: {fileID: 0} - - target: {fileID: 492300, guid: ea0c7071e67bf1c43940a8ab3ea121f8, type: 3} - propertyPath: m_LocalPosition.x - value: 3.1642048 - objectReference: {fileID: 0} - - target: {fileID: 492300, guid: ea0c7071e67bf1c43940a8ab3ea121f8, type: 3} - propertyPath: m_LocalPosition.y - value: 0.00000032572393 - objectReference: {fileID: 0} - - target: {fileID: 492300, guid: ea0c7071e67bf1c43940a8ab3ea121f8, type: 3} - propertyPath: m_LocalPosition.z - value: 2.031263 - objectReference: {fileID: 0} - - target: {fileID: 492300, guid: ea0c7071e67bf1c43940a8ab3ea121f8, type: 3} - propertyPath: m_LocalRotation.w - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 492300, guid: ea0c7071e67bf1c43940a8ab3ea121f8, type: 3} - propertyPath: m_LocalRotation.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 492300, guid: ea0c7071e67bf1c43940a8ab3ea121f8, type: 3} - propertyPath: m_LocalRotation.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 492300, guid: ea0c7071e67bf1c43940a8ab3ea121f8, type: 3} - propertyPath: m_LocalRotation.z - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 492300, guid: ea0c7071e67bf1c43940a8ab3ea121f8, type: 3} - propertyPath: m_LocalEulerAnglesHint.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 492300, guid: ea0c7071e67bf1c43940a8ab3ea121f8, type: 3} - propertyPath: m_LocalEulerAnglesHint.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 492300, guid: ea0c7071e67bf1c43940a8ab3ea121f8, type: 3} - propertyPath: m_LocalEulerAnglesHint.z - value: 0 - objectReference: {fileID: 0} - m_RemovedComponents: [] - m_RemovedGameObjects: [] - m_AddedGameObjects: [] - m_AddedComponents: [] - m_SourcePrefab: {fileID: 100100000, guid: ea0c7071e67bf1c43940a8ab3ea121f8, type: 3} --- !u!1001 &1165873058 PrefabInstance: m_ObjectHideFlags: 0 @@ -395,79 +338,6 @@ PrefabInstance: m_AddedGameObjects: [] m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 0b650fca685f2eb41a86538aa883e4c1, type: 3} ---- !u!1001 &1382386155 -PrefabInstance: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_Modification: - serializedVersion: 3 - m_TransformParent: {fileID: 0} - m_Modifications: - - target: {fileID: 190932, guid: 20e0bf298681fcd4693097c822277593, type: 3} - propertyPath: m_Name - value: SM_Env_GlowingOrb_04 - objectReference: {fileID: 0} - - target: {fileID: 495720, guid: 20e0bf298681fcd4693097c822277593, type: 3} - propertyPath: m_LocalScale.x - value: 14.01 - objectReference: {fileID: 0} - - target: {fileID: 495720, guid: 20e0bf298681fcd4693097c822277593, type: 3} - propertyPath: m_LocalScale.y - value: 14.01 - objectReference: {fileID: 0} - - target: {fileID: 495720, guid: 20e0bf298681fcd4693097c822277593, type: 3} - propertyPath: m_LocalScale.z - value: 14.01 - objectReference: {fileID: 0} - - target: {fileID: 495720, guid: 20e0bf298681fcd4693097c822277593, type: 3} - propertyPath: m_LocalPosition.x - value: 11.45 - objectReference: {fileID: 0} - - target: {fileID: 495720, guid: 20e0bf298681fcd4693097c822277593, type: 3} - propertyPath: m_LocalPosition.y - value: 0.27 - objectReference: {fileID: 0} - - target: {fileID: 495720, guid: 20e0bf298681fcd4693097c822277593, type: 3} - propertyPath: m_LocalPosition.z - value: 4.4 - objectReference: {fileID: 0} - - target: {fileID: 495720, guid: 20e0bf298681fcd4693097c822277593, type: 3} - propertyPath: m_LocalRotation.w - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 495720, guid: 20e0bf298681fcd4693097c822277593, type: 3} - propertyPath: m_LocalRotation.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 495720, guid: 20e0bf298681fcd4693097c822277593, type: 3} - propertyPath: m_LocalRotation.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 495720, guid: 20e0bf298681fcd4693097c822277593, type: 3} - propertyPath: m_LocalRotation.z - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 495720, guid: 20e0bf298681fcd4693097c822277593, type: 3} - propertyPath: m_LocalEulerAnglesHint.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 495720, guid: 20e0bf298681fcd4693097c822277593, type: 3} - propertyPath: m_LocalEulerAnglesHint.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 495720, guid: 20e0bf298681fcd4693097c822277593, type: 3} - propertyPath: m_LocalEulerAnglesHint.z - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 495720, guid: 20e0bf298681fcd4693097c822277593, type: 3} - propertyPath: m_ConstrainProportionsScale - value: 1 - objectReference: {fileID: 0} - m_RemovedComponents: [] - m_RemovedGameObjects: [] - m_AddedGameObjects: [] - m_AddedComponents: [] - m_SourcePrefab: {fileID: 100100000, guid: 20e0bf298681fcd4693097c822277593, type: 3} --- !u!1001 &6493552143235564167 PrefabInstance: m_ObjectHideFlags: 0 @@ -528,6 +398,10 @@ PrefabInstance: propertyPath: placementCollections.Array.size value: 1 objectReference: {fileID: 0} + - target: {fileID: 2927522923773808063, guid: 91b5caa5457131b4f8c542529f4ad7c3, type: 3} + propertyPath: 'placementCollections.Array.data[0]' + value: + objectReference: {fileID: 11400000, guid: b91d23f483c774f4dbb1a77660881d87, type: 2} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] @@ -541,5 +415,3 @@ SceneRoots: - {fileID: 6493552143235564167} - {fileID: 1165873058} - {fileID: 171707223} - - {fileID: 1015513039} - - {fileID: 1382386155}