Example #1
0
        public static void SnapshotObjects(this MMTerrainLayer layer, Terrain terrain)
        {
#if UNITY_EDITOR
            var terrainSize   = terrain.terrainData.size;
            var terrainPos    = terrain.GetPosition();
            var terrainBounds = new Bounds(terrainPos, Vector3.zero);
            terrainBounds.Encapsulate(terrainPos + terrainSize);
            terrainBounds.Expand(Vector3.up * 5000);

            var allTransforms = UnityEngine.Object.FindObjectsOfType <Transform>();
            var done          = new HashSet <Transform>();
            allTransforms = allTransforms.OrderBy(transform => TransformExtensions.GetHierarchyDepth(transform)).ToArray();
            HashSet <Transform> ignores = new HashSet <Transform>();

            layer.Objects.Clear();
            for (var i = 0; i < allTransforms.Length; i++)
            {
                var transform = allTransforms[i];

                if (done.Contains(transform) || ignores.Contains(transform))
                {
                    continue;
                }

                var ws = transform.GetComponentInAncestors <LayerComponentBase>();
                if (ws)
                {
                    //Debug.Log(string.Format("WorldStamp Object Capture : Ignored {0} as it contained a WorldStamp. Recursive WorldStamps are currently not supported.", transform), transform);
                    ignores.Add(transform);
                    var children = ws.transform.GetComponentsInChildren <Transform>(true);
                    foreach (var ignore in children)
                    {
                        ignores.Add(ignore);
                    }
                    continue;
                }
                var rn = transform.GetComponentInAncestors <RoadNetwork>();
                if (rn)
                {
                    ignores.Add(rn.transform);
                    var children = rn.transform.GetComponentsInChildren <Transform>(true);
                    foreach (var ignore in children)
                    {
                        ignores.Add(ignore);
                    }
                    continue;
                }
                var template = transform.GetComponentInAncestors <WorldStampTemplate>();
                if (template)
                {
                    ignores.Add(template.transform);
                    var children = template.transform.GetComponentsInChildren <Transform>(true);
                    foreach (var ignore in children)
                    {
                        ignores.Add(ignore);
                    }
                    continue;
                }

                var go         = transform.gameObject;
                var prefabRoot = PrefabUtility.GetPrefabObject(go);
                if (prefabRoot == null)
                {
                    //Debug.LogError("Unable to collect non-prefab object: " + go.name, go);
                    continue;
                }

#if UNITY_2018_2_OR_NEWER
                var prefabAsset = PrefabUtility.FindPrefabRoot(PrefabUtility.GetCorrespondingObjectFromSource(go) as GameObject);
#else
                var prefabAsset = PrefabUtility.FindPrefabRoot(PrefabUtility.GetPrefabParent(go) as GameObject);
#endif
                var rootInScene = PrefabUtility.FindPrefabRoot(go);

                var relativePos = rootInScene.transform.position - terrainPos;
                relativePos = new Vector3(relativePos.x / terrainSize.x,
                                          (rootInScene.transform.position.y - terrain.SampleHeight(rootInScene.transform.position)) -
                                          terrainPos.y,
                                          relativePos.z / terrainSize.z);
                layer.Objects.Add(new PrefabObjectData
                {
                    Guid              = Guid.NewGuid().ToString(),
                    Prefab            = prefabAsset,
                    Position          = relativePos,
                    Rotation          = rootInScene.transform.localRotation.eulerAngles,
                    Scale             = rootInScene.transform.localScale,
                    ContainerMetadata = layer.name,
                });

                done.Add(rootInScene.transform);
                var doneChildren = rootInScene.transform.GetComponentsInChildren <Transform>(true);
                foreach (var item in doneChildren)
                {
                    done.Add(item);
                }
            }
#endif
        }
Example #2
0
        protected override void CaptureInternal(Terrain terrain, Bounds bounds)
        {
#if UNITY_EDITOR
            BoundsMapping.Clear();
            Objects.Clear();

            var expandedBounds = bounds;
            expandedBounds.Expand(Vector3.up * 5000);

            var terrainPos = terrain.GetPosition();

            var allTransforms = Object.FindObjectsOfType <Transform>();
            var done          = new HashSet <Transform>();
            allTransforms = allTransforms.OrderBy(transform => TransformExtensions.GetHierarchyDepth(transform)).ToArray();
            HashSet <Transform> ignores = new HashSet <Transform>();
            for (int i = 0; i < allTransforms.Length; i++)
            {
                var transform = allTransforms[i];
                if (done.Contains(transform) || ignores.Contains(transform))
                {
                    continue;
                }
                if (transform.GetComponent <TerrainCollider>())
                {
                    continue;
                }
                if (!expandedBounds.Contains(transform.position))
                {
                    continue;
                }
                var ws = transform.GetComponentInAncestors <WorldStamp>();
                if (ws)
                {
                    //Debug.Log(string.Format("WorldStamp Object Capture : Ignored {0} as it contained a WorldStamp. Recursive WorldStamps are currently not supported.", transform), transform);
                    ignores.Add(transform);
                    var children = ws.transform.GetComponentsInChildren <Transform>(true);
                    foreach (var ignore in children)
                    {
                        ignores.Add(ignore);
                    }
                    continue;
                }
                var rn = transform.GetComponentInAncestors <RoadNetwork>();
                if (rn)
                {
                    ignores.Add(rn.transform);
                    var children = rn.transform.GetComponentsInChildren <Transform>(true);
                    foreach (var ignore in children)
                    {
                        ignores.Add(ignore);
                    }
                    continue;
                }
                var template = transform.GetComponentInAncestors <WorldStampTemplate>();
                if (template)
                {
                    ignores.Add(template.transform);
                    var children = template.transform.GetComponentsInChildren <Transform>(true);
                    foreach (var ignore in children)
                    {
                        ignores.Add(ignore);
                    }
                    continue;
                }

                var go = transform.gameObject;
                if (Mask != (Mask | (1 << go.layer)))
                {
                    continue;
                }

                var prefabRoot = PrefabUtility.GetPrefabObject(go);
                if (prefabRoot == null)
                {
                    //DebugHelper.DrawCube(collider.bounds.center, collider.bounds.extents, Quaternion.identity, Color.red, 30);
                    continue;
                }

                done.Add(transform);
                var subTransforms = transform.GetComponentsInChildren <Transform>();
                foreach (var childTransform in subTransforms)
                {
                    done.Add(childTransform);
                }

#if UNITY_2018_2_OR_NEWER
                var prefabAsset = PrefabUtility.FindPrefabRoot(PrefabUtility.GetCorrespondingObjectFromSource(go) as GameObject);
#else
                var prefabAsset = PrefabUtility.FindPrefabRoot(PrefabUtility.GetPrefabParent(go) as GameObject);
#endif
                var root = PrefabUtility.FindPrefabRoot(go);

                var relativePos = root.transform.position - bounds.min;
                relativePos = new Vector3(relativePos.x / bounds.size.x, 0, relativePos.z / bounds.size.z);

                if (RelativeMode == WorldStamp.EObjectRelativeMode.RelativeToTerrain)
                {
                    var terrainHeightAtPoint = terrain.SampleHeight(root.transform.position);
                    relativePos.y = (root.transform.position.y - terrainHeightAtPoint);
                }
                else
                {
                    relativePos.y = root.transform.position.y;
                }
                relativePos.y -= terrainPos.y;

                var newData = new PrefabObjectData()
                {
                    AbsoluteHeight = RelativeMode == WorldStamp.EObjectRelativeMode.RelativeToStamp,
                    Prefab         = prefabAsset,
                    Position       = relativePos,
                    Rotation       = root.transform.rotation.eulerAngles,
                    Scale          = root.transform.lossyScale,
                    Guid           = GUID.Generate().ToString(),
                };

                var c = transform.GetComponentInChildren <Collider>();
                if (c)
                {
                    BoundsMapping[newData] = c.bounds;
                }
                else
                {
                    var r = transform.GetComponentInChildren <Renderer>();
                    if (r)
                    {
                        BoundsMapping[newData] = r.bounds;
                    }
                }

                done.Add(root.transform);
                var doneChildren = root.transform.GetComponentsInChildren <Transform>(true);
                foreach (var item in doneChildren)
                {
                    done.Add(item);
                }
                Objects.Add(newData);
            }
#endif
        }