Example #1
0
        /// <summary>
        /// Run this safe method if you want to edit anything on the specific tree instance.
        /// This will cause the changes to be saved over the chunks and it will be "safe".
        /// </summary>
        /// <param name="treeInstance">the tree instance</param>
        /// <param name="treeInstanceID">The id of the tree instance</param>
        /// <param name="action">the action</param>
        public static void RunActionOnTreeInstance(this Terrain terrain, TreeInstance treeInstance, int treeInstanceID, System.Func <TreeInstance, TreeInstance> action, System.Action <Sectors.ChunkObject> runOnChunk)
        {
            UNTerrain baseTerrain = terrain.GetComponent <UNTerrain>();

            if (baseTerrain != null)
            {
                TIChunk chunk = baseTerrain.sector.getChunk(treeInstance.position.LocalToWorld(terrain.terrainData.size, Vector3.zero), 0) as TIChunk;

                if (chunk != null)
                {
                    if (action != null)
                    {
                        TreeInstance result = action(treeInstance);

                        if (chunk != null)
                        {
                            for (int i = 0; i < chunk.objects.Count; i++)
                            {
                                if (chunk.objects[i].instanceID == treeInstanceID)
                                {
                                    chunk.objects[i].treeInstance = result; // update tree instance

                                    if (runOnChunk != null)
                                    {
                                        runOnChunk(chunk.objects[i]);
                                    }

                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// Called when the size is changed
        /// </summary>
        protected override void OnSizeChanged()
        {
            base.OnSizeChanged();

            UNTerrain baseTerrain = GetComponentInParent <UNTerrain>();

            terrainRelativeSize = size.GetRelativeScale(baseTerrain);
        }
Example #3
0
        /// <summary>
        /// Pack the data and create a data instance
        /// </summary>
        public static T2 Pack <T1, T2>(Terrain terrain, int treeInstanceID, int health, PacketType type) where T2 : UNNetworkData <T1>
        {
            T2 instance = System.Activator.CreateInstance <T2>();

            instance.terrainID      = terrain.name;
            instance.treeInstanceID = treeInstanceID;
            instance.eventType      = type;

            UNTerrain UNTerrain = terrain.GetComponent <UNTerrain>();

            if (instance.minHealth == -1 && instance.maxHealth == -1 && UNTerrain != null)
            {
                TreeInstance          treeInstance         = UNTerrain.terrain.terrainData.GetTreeInstance(treeInstanceID);
                HarvestableTIPoolItem harvestableComponent = UNTerrain.terrain.terrainData.treePrototypes[treeInstance.prototypeIndex].prefab.GetComponent <HarvestableTIPoolItem>();

                if (harvestableComponent != null)
                {
                    instance.minHealth = harvestableComponent.minHealth;
                    instance.maxHealth = harvestableComponent.maxHealth;
                }
                else
                {
                    harvestableComponent = UNTerrain.Pool.TryGetType <HarvestableTIPoolItem>();

                    if (harvestableComponent != null)
                    {
                        instance.minHealth = harvestableComponent.minHealth;
                        instance.maxHealth = harvestableComponent.maxHealth;
                    }
                }
            }

            instance.health = health;

            return(instance);
        }
Example #4
0
        /// <summary>
        /// Get relative to terrain scale. (in order to use terrain's properties)
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="terrain"></param>
        /// <returns></returns>
        public static Vector2 GetRelativeScale(this Vector2 scale, UNTerrain terrain)
        {
            Vector2 relatedScale = new Vector2(scale.x / (terrain.terrainData.multiThreaded_terrainDataSize.x / terrain.terrainData.multiThreaded_detailWidth), scale.y / (terrain.terrainData.multiThreaded_terrainDataSize.z / terrain.terrainData.multiThreaded_detailHeight));

            return(relatedScale);
        }
Example #5
0
        /// <summary>
        /// Convert a tree and assign a Pool item to it.
        /// </summary>
        /// <param name="terrain">the terrain.</param>
        /// <param name="treeInstanceID">the tree instance id</param>
        /// <param name="UNTerrain">the UN terrain instance</param>
        public static void ConvertTreeInstance(this Terrain terrain, int treeInstanceID, UNTerrain UNTerrain)
        {
            TreeInstance tree = terrain.terrainData.GetTreeInstance(treeInstanceID);

            Vector3    treeScale    = tree.GetWorldScale();
            Quaternion treeRotation = tree.GetWorldRotation();

            terrain.terrainData.RemoveTreeInstance(treeInstanceID, UNTerrain);

            Vector3 pos = tree.position.LocalToWorld(terrain.terrainData.size, terrain.transform.position);

            UNTerrain.Pool.TryResetOnUID(treeInstanceID, true);
            var item = UNTerrain.Pool.TryPool <HarvestableTIPoolItem>(tree.prototypeIndex, 0, treeInstanceID, true);

            if (item != null)
            {
                item.transform.rotation   = treeRotation;
                item.transform.localScale = treeScale;

                item.MoveItem(pos);
            }
        }
Example #6
0
        /// <summary>
        /// Restore a certain tree instance from the terrain.
        /// </summary>
        /// <param name="treeInstanceID">the tree instance id of the tree you wish to restore.</param>
        /// <param name="originalHeight">the original height of the targeted tree.</param>
        public static void RestoreTreeInstance(this TerrainData terrainData, int treeInstanceID, UNTerrain UNTerrain)
        {
            TreeInstance treeInstance = terrainData.GetTreeInstance(treeInstanceID);

            Sectors.ChunkObject chunkObject;

            // Update the sector chunk...
            TIChunk chunk = UNTerrain.sector.getChunk(treeInstance.position.LocalToWorld(UNTerrain.terrainData.multiThreaded_terrainDataSize, Vector3.zero), 0) as TIChunk;

            if (chunk != null)
            {
                for (int i = 0; i < chunk.objects.Count; i++)
                {
                    chunkObject = chunk.objects[i];

                    if (chunkObject.instanceID == treeInstanceID)
                    {
                        UNTerrain.Pool.TryResetOnUID(treeInstanceID, true);

                        treeInstance.heightScale = chunkObject.originalHeight;

                        terrainData.SetTreeInstance(treeInstanceID, treeInstance);

                        chunkObject.treeInstance = treeInstance;

                        UNSeeker seeker;
                        for (int c = 0; c < UNSeeker.FReceivers.Count; c++)
                        {
                            seeker = UNSeeker.FReceivers[c] as UNSeeker;

                            Targets.UNTarget.CheckTargets(seeker, seeker.seekingDistance); // check targets to verify colliders assigning
                        }

                        break;
                    }
                }
            }
        }
Example #7
0
        /// <summary>
        /// Remove a certain tree instance from the terrain.
        /// </summary>
        /// <param name="treeInstanceID">the tree instance id of the tree you wish to remove.</param>
        public static void RemoveTreeInstance(this TerrainData terrainData, int treeInstanceID, UNTerrain UNTerrain)
        {
            TreeInstance _treeInstance = terrainData.GetTreeInstance(treeInstanceID);

            UNTerrain.terrain.RunActionOnTreeInstance(_treeInstance, treeInstanceID, (TreeInstance treeInstance) =>
            {
                treeInstance.heightScale = UNTerrain.removedTreeInstanceHeight;

                terrainData.SetTreeInstance(treeInstanceID, treeInstance);

                return(treeInstance);
            },
                                                      (Sectors.ChunkObject chunkObject) =>
            {
                chunkObject.Remove();
            });
        }
Example #8
0
        /// <summary>
        /// Check and assign nearby tree instances.
        /// </summary>
        public void CheckForNearbyTreeInstances(UNSeeker seeker, UNTerrain terrain)
        {
            if (objects.Count == 0)
            {
                return;                     // no objects found on this specific chunk.
            }
            objects.Sort((ChunkObject objA, ChunkObject objB) =>
            {
                return(Vector2.Distance(objA.depthPosition, seeker.threadPositionDepth).CompareTo(Vector2.Distance(objB.depthPosition, seeker.threadPositionDepth)));
            });

            ChunkObject item;
            PoolItem    PoolItem;
            ThreadTask <PoolItem, Vector3, TreeInstance> threadTask;

            for (int b = 0; b < objects.Count; b++)
            {
                item = objects[b];

                if (Vector2.Distance(item.depthPosition, seeker.threadPositionDepth) > seeker.seekingDistance || item.isRemoved)
                {
                    continue;                                                                                                                             // continue if out of distance or if the tree is "removed"
                }
                PoolItem = terrain.Pool.TryPool <TerrainPoolItem>(item.prototypeID, UNTerrain.collidersPoolItemInstanceIncrease, item.instanceID, false); // add 1000 at the start to provide a unique symbol.

                if (PoolItem != null)
                {
                    threadTask = new ThreadTask <PoolItem, Vector3, TreeInstance>((PoolItem _PoolItem, Vector3 _pos, TreeInstance _item) =>
                    {
                        Vector3 scale       = _item.GetWorldScale();
                        Quaternion rotation = _item.GetWorldRotation();

                        _PoolItem.transform.rotation   = rotation;
                        _PoolItem.transform.localScale = scale;

                        _PoolItem.MoveItem(_pos);
                    }, PoolItem, item.worldPosition, item.treeInstance);

                    ThreadManager.instance.RunOnUnityThread(threadTask);
                }
                else
                {
                    if (!terrain.Pool.IsAlreadyPooled(item.instanceID))
                    {
                        List <PoolItem> PoolItems = terrain.Pool.GetPoolOfItem(item.prototypeID, UNTerrain.collidersPoolItemInstanceIncrease);

                        if (PoolItems.Count > 0)
                        {
                            PoolItems.Sort((PoolItem PoolItemA, PoolItem PoolItemB) =>
                            {
                                return(Vector2.Distance(PoolItemA.threadPositionDepth, seeker.threadPositionDepth).CompareTo(Vector2.Distance(PoolItemB.threadPositionDepth, seeker.threadPositionDepth)));
                            });

                            PoolItem = PoolItems[PoolItems.Count - 1];
                            terrain.Pool.PoolItem(PoolItem, false, item.instanceID);

                            threadTask = new ThreadTask <PoolItem, Vector3, TreeInstance>((PoolItem _PoolItem, Vector3 _pos, TreeInstance _item) =>
                            {
                                Vector3 scale       = _item.GetWorldScale();
                                Quaternion rotation = _item.GetWorldRotation();

                                _PoolItem.transform.rotation   = rotation;
                                _PoolItem.transform.localScale = scale;

                                _PoolItem.MoveItem(_pos);
                            }, PoolItem, item.worldPosition, item.treeInstance);
                            ThreadManager.instance.RunOnUnityThread(threadTask);
                        }
                    }
                }
            }
        }