예제 #1
0
 /// <summary>
 /// Spawn the specified prefab, syncing it to all clients
 /// </summary>
 /// <param name="prefab">Prefab to spawn an instance of. This is intended to be made to work for pretty much any prefab, but don't
 /// be surprised if it doesn't as there are LOTS of prefabs in the game which all have unique behavior for how they should spawn. If you are trying
 /// to instantiate something and it isn't properly setting itself up, check to make sure each component that needs to set something up has
 /// properly implemented necessary lifecycle methods.</param>
 /// <param name="destination">destination to spawn at</param>
 /// <param name="count">number of instances to spawn, defaults to 1</param>
 /// <param name="scatterRadius">radius to scatter the spawned instances by from their spawn position. Defaults to
 /// null (no scatter).</param>
 /// <returns>the newly created GameObject</returns>
 public static SpawnResult ServerPrefab(GameObject prefab, SpawnDestination destination, int count = 1, float?scatterRadius = null)
 {
     return(Server(
                SpawnInfo.Spawnable(
                    SpawnablePrefab.For(prefab),
                    destination,
                    count, scatterRadius)));
 }
예제 #2
0
 /// <summary>
 /// Spawn the specified prefab locally, for this client only.
 /// </summary>
 /// <param name="prefabName">name of prefab to spawn an instance of. This is intended to be made to work for pretty much any prefab, but don't
 /// be surprised if it doesn't as there are LOTS of prefabs in the game which all have unique behavior for how they should spawn. If you are trying
 /// to instantiate something and it isn't properly setting itself up, check to make sure each component that needs to set something up has
 /// properly implemented necessary lifecycle methods.</param>
 /// <param name="worldPosition">world position to appear at. Defaults to HiddenPos (hidden / invisible)</param>
 /// <param name="localRotation">local rotation to spawn with, defaults to Quaternion.identity</param>
 /// <param name="parent">Parent to spawn under, defaults to no parent. Most things
 /// should always be spawned under the Objects transform in their matrix. Many objects (due to RegisterTile)
 /// usually take care of properly parenting themselves when spawned so in many cases you can leave it null.</param>
 /// <param name="count">number of instances to spawn, defaults to 1</param>
 /// <param name="scatterRadius">radius to scatter the spawned instances by from their spawn position. Defaults to
 /// null (no scatter).</param>
 /// <returns>the newly created GameObject</returns>
 public static SpawnResult ClientPrefab(string prefabName, Vector3?worldPosition = null, Transform parent = null, Quaternion?localRotation = null, int count = 1, float?scatterRadius = null)
 {
     return(Client(
                SpawnInfo.Spawnable(
                    SpawnablePrefab.For(prefabName),
                    SpawnDestination.At(worldPosition, parent, localRotation),
                    count, scatterRadius)));
 }
예제 #3
0
 /// <summary>
 /// Spawn the specified prefab, syncing it to all clients
 /// </summary>
 /// <param name="prefabName">name of prefab to spawn an instance of. This is intended to be made to work for pretty much any prefab, but don't
 /// be surprised if it doesn't as there are LOTS of prefabs in the game which all have unique behavior for how they should spawn. If you are trying
 /// to instantiate something and it isn't properly setting itself up, check to make sure each component that needs to set something up has
 /// properly implemented necessary lifecycle methods.</param>
 /// <param name="worldPosition">world position to appear at. Defaults to HiddenPos (hidden / invisible)</param>
 /// <param name="localRotation">local rotation to spawn with, defaults to Quaternion.identity</param>
 /// <param name="parent">Parent to spawn under, defaults to no parent. Most things
 /// should always be spawned under the Objects transform in their matrix. Many objects (due to RegisterTile)
 /// usually take care of properly parenting themselves when spawned so in many cases you can leave it null.</param>
 /// <param name="count">number of instances to spawn, defaults to 1</param>
 /// <param name="scatterRadius">radius to scatter the spawned instances by from their spawn position. Defaults to
 /// null (no scatter).</param>
 /// <param name="cancelIfImpassable">If true, the spawn will be cancelled if the location being spawned into is totally impassable.</param>
 /// <returns>the newly created GameObject</returns>
 public static SpawnResult ServerPrefab(string prefabName, Vector3?worldPosition = null, Transform parent = null,
                                        Quaternion?localRotation = null, int count = 1, float?scatterRadius = null, bool cancelIfImpassable = false)
 {
     return(Server(
                SpawnInfo.Spawnable(
                    SpawnablePrefab.For(prefabName),
                    SpawnDestination.At(worldPosition, parent, localRotation, cancelIfImpassable),
                    count, scatterRadius)));
 }
예제 #4
0
파일: Spawn.cs 프로젝트: ewy0/unitystation
 /// <summary>
 /// Spawn the specified prefab, syncing it to all clients
 /// </summary>
 /// <param name="prefab">Prefab to spawn an instance of. This is intended to be made to work for pretty much any prefab, but don't
 /// be surprised if it doesn't as there are LOTS of prefabs in the game which all have unique behavior for how they should spawn. If you are trying
 /// to instantiate something and it isn't properly setting itself up, check to make sure each component that needs to set something up has
 /// properly implemented necessary lifecycle methods.</param>
 /// <param name="worldPosition">world position to appear at. Defaults to HiddenPos (hidden / invisible)</param>
 /// <param name="localRotation">local rotation to spawn with, defaults to Quaternion.identity</param>
 /// <param name="parent">Parent to spawn under, defaults to no parent. Most things
 /// should always be spawned under the Objects transform in their matrix. Many objects (due to RegisterTile)
 /// usually take care of properly parenting themselves when spawned so in many cases you can leave it null.</param>
 /// <param name="count">number of instances to spawn, defaults to 1</param>
 /// <param name="scatterRadius">radius to scatter the spawned instances by from their spawn position. Defaults to
 /// null (no scatter).</param>
 /// <param name="cancelIfImpassable">If true, the spawn will be cancelled if the location being spawned into is totally impassable.</param>
 /// <returns>the newly created GameObject</returns>
 public static SpawnResult ServerPrefab(GameObject prefab, Vector3?worldPosition = null, Transform parent = null,
                                        Quaternion?localRotation = null, int count = 1, float?scatterRadius = null, bool cancelIfImpassable = false, bool spawnItems = true, bool AutoOnSpawnServerHook = true)
 {
     return(Server(
                SpawnInfo.Spawnable(
                    SpawnablePrefab.For(prefab),
                    SpawnDestination.At(worldPosition, parent, localRotation, cancelIfImpassable),
                    count, scatterRadius, spawnItems: spawnItems), AutoOnSpawnServerHook));
 }
예제 #5
0
    /// <summary>
    /// Special type of spawn, performed on each object mapped in the scene once the scene is done loading.
    /// </summary>
    /// <param name="mappedObject">object which was mapped into the scene.</param>
    /// <returns></returns>
    public static SpawnInfo Mapped(GameObject mappedObject)
    {
        var destination = SpawnDestination.At(mappedObject);
        //assume prefab
        var prefab    = Spawn.DeterminePrefab(mappedObject);
        var spawnable = SpawnablePrefab.For(prefab);

        return(new SpawnInfo(SpawnType.Mapped, spawnable, destination, null, 1, null));
    }
예제 #6
0
 /// <summary>
 /// Spawn the specified prefab, syncing it to all clients
 /// </summary>
 /// <param name="prefab">Prefab to spawn an instance of. This is intended to be made to work for pretty much any prefab, but don't
 /// be surprised if it doesn't as there are LOTS of prefabs in the game which all have unique behavior for how they should spawn. If you are trying
 /// to instantiate something and it isn't properly setting itself up, check to make sure each component that needs to set something up has
 /// properly implemented necessary lifecycle methods.</param>
 /// <param name="destination">destination to spawn at</param>
 /// <param name="count">number of instances to spawn, defaults to 1</param>
 /// <param name="scatterRadius">radius to scatter the spawned instances by from their spawn position. Defaults to
 /// null (no scatter).</param>
 /// <returns>the newly created GameObject</returns>
 public static SpawnResult ServerPrefab(GameObject prefab, SpawnDestination destination, int count = 1,
                                        float?scatterRadius = null, bool mapspawn = false, bool PrePickRandom = false)
 {
     return(Server(
                SpawnInfo.Spawnable(
                    SpawnablePrefab.For(prefab, PrePickRandom),
                    destination,
                    count, scatterRadius, mapspawn: mapspawn)));
 }
예제 #7
0
 /// <summary>
 /// Spawn the specified prefab locally, for this client only.
 /// </summary>
 /// <param name="prefab">Prefab to spawn an instance of. This is intended to be made to work for pretty much any prefab, but don't
 /// be surprised if it doesn't as there are LOTS of prefabs in the game which all have unique behavior for how they should spawn. If you are trying
 /// to instantiate something and it isn't properly setting itself up, check to make sure each component that needs to set something up has
 /// properly implemented necessary lifecycle methods.</param>
 /// <param name="worldPosition">world position to appear at. Defaults to HiddenPos (hidden / invisible)</param>
 /// <param name="localRotation">local rotation to spawn with, defaults to Quaternion.identity</param>
 /// <param name="parent">Parent to spawn under, defaults to no parent. Most things
 /// should always be spawned under the Objects transform in their matrix. Many objects (due to RegisterTile)
 /// usually take care of properly parenting themselves when spawned so in many cases you can leave it null.</param>
 /// <param name="count">number of instances to spawn, defaults to 1</param>
 /// <param name="scatterRadius">radius to scatter the spawned instances by from their spawn position. Defaults to
 /// null (no scatter).</param>
 /// <returns>the newly created GameObject</returns>
 public static SpawnResult ClientPrefab(GameObject prefab, Vector3?worldPosition = null, Transform parent = null,
                                        Quaternion?localRotation = null, int count = 1, float?scatterRadius = null, bool mapspawn = false)
 {
     return(Client(
                SpawnInfo.Spawnable(
                    SpawnablePrefab.For(prefab),
                    SpawnDestination.At(worldPosition, parent, localRotation),
                    count, scatterRadius, mapspawn: mapspawn)));
 }
예제 #8
0
 public SpawnablePrefab(SpawnablePrefab copyPrefabs)
 {
     this._prefab      = copyPrefabs._prefab;
     this._probability = copyPrefabs._probability;
     this._height      = copyPrefabs._height;
     this._fixedHeight = copyPrefabs._fixedHeight;
     this._scale       = copyPrefabs._scale;
     this._scaleRandom = copyPrefabs._scaleRandom;
 }
예제 #9
0
    static SpawnablePrefab[] CopyPrefabs(SpawnablePrefab[] prefabs)
    {
        SpawnablePrefab[] newPrefabs = new SpawnablePrefab[prefabs.Length];

        for (int i = 0; i < newPrefabs.Length; i++)
        {
            newPrefabs[i] = new SpawnablePrefab(prefabs[i]);
        }

        return(newPrefabs);
    }
예제 #10
0
    private void SpawnPrefab(SpawnablePrefab spawnable)
    {
        if (spawnable.SpawnPoint == null)
        {
            spawnable.SpawnPoint = _currentWave.GetSpawnPoint();
        }
        var go = Instantiate(spawnable.Prefab, spawnable.SpawnPoint.transform.position, spawnable.SpawnPoint.transform.rotation);

        spawnable.OnSpawn(go);
        _activeGameObjects.Add(go);
    }
예제 #11
0
    // Used to calculate all the different noises for every spawable
    public void Setup(float[,] parentNoise, int chunkSize, NoiseSettingsData offsetNoiseSettings, Vector2 center, Vector2 offsetNoiseOffset)
    {
        if (parentNoise != null)
        {
            _noise = Noise.MergeNoise(chunkSize, chunkSize, 1, _noiseSettingsData.NoiseSettingsDataMerge, parentNoise, _noiseMergeType, new Vector2(center.x, -center.y));
        }
        else
        {
            _noise = Noise.GenerateNoiseMap(chunkSize, chunkSize, 1, _noiseSettingsData.NoiseSettingsDataMerge, new Vector2(center.x, -center.y));
        }

        _noise = Noise.Clamp(_noise, _noiseSettingsData);

        _offsetNoise = Noise.GenerateNoiseMap(chunkSize, chunkSize, 1, offsetNoiseSettings.NoiseSettingsDataMerge, new Vector2(center.x, -center.y) + offsetNoiseOffset);
        _spreadNoise = Noise.GenerateNoiseMap(chunkSize, chunkSize, 1, offsetNoiseSettings.NoiseSettingsDataMerge, new Vector2(center.x, -center.y) + offsetNoiseOffset * 2);

        _prefabMaxProbability = SpawnablePrefab.GetMaxSize(_prefabs);

        for (int i = 0; i < _subSpawners.Length; i++)
        {
            _subSpawners[i].Setup(_noise, chunkSize, offsetNoiseSettings, new Vector2(center.x, -center.y), offsetNoiseOffset * 2);
        }
    }
예제 #12
0
 /// <summary>
 /// Spawn a player with the specified occupation
 /// </summary>
 /// <param name="occupation">Occupation details to use to spawn this player</param>
 /// <param name="characterSettings">settings to use for this player</param>
 /// <param name="playerPrefab">Prefab to use to spawn this player</param>
 /// <param name="spawnDestination">destinaton to spawn at</param>
 /// <param name="spawnItems">whether player should spawn naked or with their default loadout</param>
 /// <returns>the newly created GameObject</returns>
 /// <returns></returns>
 public static SpawnInfo Player(Occupation occupation, CharacterSettings characterSettings, GameObject playerPrefab, SpawnDestination spawnDestination,
                                bool spawnItems = false)
 {
     return(new SpawnInfo(SpawnType.Player, SpawnablePrefab.For(playerPrefab), spawnDestination, null, 1, occupation, characterSettings: characterSettings, spawnItems: spawnItems));
 }
예제 #13
0
 /// <summary>
 /// Spawn a ghost with the specified occupation
 /// </summary>
 /// <param name="occupation">Occupation details to use to spawn this ghost</param>
 /// <param name="characterSettings">settings to use for this ghost</param>
 /// <param name="ghostPrefab">Prefab to use to spawn this ghost</param>
 /// <param name="spawnDestination">destinaton to spawn at</param>
 /// <returns>the newly created GameObject</returns>
 /// <returns></returns>
 public static SpawnInfo Ghost(Occupation occupation, CharacterSettings characterSettings, GameObject ghostPrefab,
                               SpawnDestination spawnDestination)
 {
     return(new SpawnInfo(SpawnType.Ghost, SpawnablePrefab.For(ghostPrefab), spawnDestination,
                          null, 1, occupation, characterSettings: characterSettings));
 }
예제 #14
0
    private List <SpawnInfo> SpawnFromSpawnables(int detailType, int levelOfDetail, Biome biome, Spawnable[] spawnables, HeightMap heightMap, MeshData meshData, MeshSettings meshSettings, Vector2 chunkPosition, Vector2 chunkCoord, bool firstCall = false)
    {
        List <SpawnInfo> spawnInfo = new List <SpawnInfo>();

        //Spawn Water - water has detail type of highest level even if it spawns in low LOD because it has no need to check normals
        if (firstCall)
        {
            spawnInfo.Add(new SpawnInfo(biome.WaterChunk, 0, new Vector3(chunkPosition.x, biome.WaterHeight, -chunkPosition.y), Vector3.up, 0, 0, chunkCoord, Vector2.zero, false, new Vector3((meshSettings.ChunkSize - 1) * meshSettings.MeshScale, 1, (meshSettings.ChunkSize - 1) * meshSettings.MeshScale), false));
        }

        for (int i = 0; i < spawnables.Length; i++)
        {
            //First spawn the subspawners prefabs as they are harder to make room for
            if (spawnables[i].SubSpawners.Length > 0)
            {
                List <SpawnInfo> childSpawnInfo = SpawnFromSpawnables(detailType, levelOfDetail, biome, spawnables[i].SubSpawners, heightMap, meshData, meshSettings, chunkPosition, chunkCoord);
                spawnInfo.AddRange(childSpawnInfo);
            }

            //This spawnable has nothing to spawn, act only as parent
            if (!spawnables[i].ParentOnly)
            {
                //Get noise specific to this prefab
                float[,] spawnNoise = spawnables[i].GetNoise;
                //Local size occupation
                bool[,] localOccupiedGrid = new bool[_occupiedGrid.GetLength(0), _occupiedGrid.GetLength(1)];

                //+ 1 offset in loops are due to border around mesh
                for (int x = 0; x < meshSettings.ChunkSize - spawnables[i].Size; x++)
                {
                    for (int y = 0; y < meshSettings.ChunkSize - spawnables[i].Size; y++)
                    {
                        Vector2         itemIndex       = new Vector2(x, y);
                        ChunkCoordIndex chunkCoordIndex = new ChunkCoordIndex(chunkCoord, itemIndex);
                        bool            shouldSpawn     = true;
                        bool            partialSpawn    = false;

                        if (PrefabSpawnerSaveData.InsideSpawnArea(chunkCoordIndex) && !spawnables[i].OthersCanSpawnInside)
                        {
                            shouldSpawn = false;
                        }
                        //This thing is already picked up! (Size > 0 is just to check if the thing is pickable)
                        if (!spawnables[i].OthersCanSpawnInside && PrefabSpawnerSaveData.ContainsChunkCoordIndex(chunkCoordIndex))
                        {
                            StoredSaveData data = PrefabSpawnerSaveData.GetStoredSaveData(chunkCoordIndex);

                            if (data.PartialSpawn)
                            {
                                partialSpawn = true;
                            }
                            else
                            {
                                shouldSpawn = false;
                            }
                        }
                        if (shouldSpawn)
                        {
                            bool canObjectSpawnSize = CanObjectSpawnSize(x, y, spawnables[i].Size, meshSettings.ChunkSize, ref localOccupiedGrid) && (CanObjectSpawnSize(x, y, spawnables[i].Spacing, meshSettings.ChunkSize, ref _occupiedGrid) || spawnables[i].OthersCanSpawnInside);
                            bool canObjectSpawnDiff = CanObjectSpawnDiff(x, y, spawnables[i].Size, spawnables[i].OthersCanSpawnInside, heightMap.heightMap, spawnables[i].SpawnDifferencial, meshSettings.ChunkSize);

                            //No use in checking if it can spawn if that square is occopied
                            if (canObjectSpawnSize && canObjectSpawnDiff)
                            {
                                bool insideNoise   = spawnNoise[x, y] > spawnables[i].NoiseStartPoint;                                         //is it inside the noise?
                                bool gradientSpawn = spawnNoise[x, y] + spawnables[i].OffsetNoise[x, y] > spawnables[i].Thickness;             //If it is, transition?
                                bool uniformSpread = x % spawnables[i].UniformSpreadAmount == 0 && y % spawnables[i].UniformSpreadAmount == 0; //uniform spread?
                                bool noiseSpread   = spawnables[i].SpreadNoise[y, x] > spawnables[i].RandomSpread;

                                //Slope
                                Vector3 normal = Vector3.up;
                                //Only on the highest detail level, care about normal
                                if (levelOfDetail == 0)
                                {
                                    normal = meshData.GetNormal(y * (meshSettings.ChunkSize) + x);
                                }

                                float slopeAngle = Vector3.Angle(Vector3.up, normal);

                                bool minSlope = (slopeAngle <= spawnables[i].SoftMinSlope * spawnables[i].OffsetNoise[x, y]);
                                minSlope = minSlope && slopeAngle <= spawnables[i].HardMinSlope;
                                bool maxSlope = (slopeAngle >= spawnables[i].SoftMaxSlope * spawnables[i].OffsetNoise[x, y]);
                                maxSlope = maxSlope && slopeAngle >= spawnables[i].HardMaxSlope;

                                //height bools
                                bool minHeight = (heightMap.heightMap[x, y] > spawnables[i].HardMinHeight + spawnables[i].SoftMinAmount * spawnables[i].OffsetNoise[x, y]);
                                bool maxHeight = (heightMap.heightMap[x, y] <= spawnables[i].HardMaxHeight - spawnables[i].SoftMaxAmount * spawnables[i].OffsetNoise[x, y]);

                                SpawnablePrefab spawnPrefab = spawnables[i].GetPrefab(x, y);

                                bool shouldSpawnIfFixedHeight = true;
                                if (spawnables[i].SpawnFixedHeight)
                                {
                                    shouldSpawnIfFixedHeight = heightMap.heightMap[x + (int)(STANDARD_GRID_OFFSET * spawnables[i].Size) + 1, y + (int)(STANDARD_GRID_OFFSET * spawnables[i].Size) + 1] + spawnPrefab.Height <= spawnPrefab.FixedHeight + spawnPrefab.Height;
                                }

                                //Things inside the if statement only need to be determined if it should spawn
                                if (insideNoise && gradientSpawn && uniformSpread && noiseSpread && minHeight && maxHeight && minSlope && maxSlope && shouldSpawnIfFixedHeight)
                                {
                                    //Since the object can spawn, mark it's space as occopied
                                    if (!spawnables[i].OthersCanSpawnInside)
                                    {
                                        OccupyWithObject(x, y, spawnables[i].Size, meshSettings.ChunkSize, ref _occupiedGrid);
                                    }

                                    OccupyWithObject(x, y, spawnables[i].Spacing, meshSettings.ChunkSize, ref localOccupiedGrid);

                                    float   scale    = spawnPrefab.ScaleRandom * spawnables[i].OffsetNoise[x, y] + spawnPrefab.Scale;
                                    Vector3 newScale = new Vector3(scale, scale, scale);

                                    //Current local positions in x and y in chunk, used only to spawn from
                                    float xPos = x + STANDARD_GRID_OFFSET + (STANDARD_GRID_OFFSET * spawnables[i].Size) - meshSettings.ChunkSize / 2 - 1; //Due to the border around the mesh + STANDARD_GRID_OFFSET corrects it to the right grid position
                                    float zPos = y + STANDARD_GRID_OFFSET + (STANDARD_GRID_OFFSET * spawnables[i].Size) - meshSettings.ChunkSize / 2 - 1; //Due to the border around the mesh + STANDARD_GRID_OFFSET corrects it to the right grid position
                                    float yPos = heightMap.heightMap[x + (int)(STANDARD_GRID_OFFSET * spawnables[i].Size) + 1, y + (int)(STANDARD_GRID_OFFSET * spawnables[i].Size) + 1] + spawnPrefab.Height;

                                    //Used if the object should not follow the world geometry and spawn at fixed height -> spawn in water
                                    // Only allow it if the object won't spawn under the terrain!
                                    if (spawnables[i].SpawnFixedHeight)
                                    {
                                        yPos = spawnPrefab.FixedHeight + spawnPrefab.Height;
                                    }

                                    //Position from grid in world
                                    Vector3 objectPosition = new Vector3((xPos + chunkPosition.x) * meshSettings.MeshScale, yPos, -(zPos + chunkPosition.y) * meshSettings.MeshScale);
                                    //Vector to offset from grid slightly to create less uniform distribution
                                    Vector3 offsetVector = new Vector3(spawnables[i].OffsetNoise[x, y] * 2 - 1, 0.0f, spawnables[i].SpreadNoise[x, y] * 2 - 1);

                                    objectPosition += offsetVector * spawnables[i].OffsetAmount;

                                    //How much along the normal should the object point?
                                    float tiltAmount = spawnables[i].SurfaceNormalAmount + (spawnables[i].SpreadNoise[x, y] * 2 - 1) * spawnables[i].PointAlongNormalRandomness;

                                    float localRotationAmount = spawnables[i].OffsetNoise[x, y] * DEGREES_360 * spawnables[i].RotationAmount;


                                    spawnInfo.Add(new SpawnInfo(spawnPrefab.Prefab, detailType, objectPosition, normal, tiltAmount, localRotationAmount, chunkCoord, itemIndex, spawnables[i].Size != 0, newScale, partialSpawn));
                                }
                            }
                        }
                    }
                }
            }
        }

        return(spawnInfo);
    }
예제 #15
0
    /// <summary>
    /// FOR DEV / TESTING ONLY! Simulates destroying and recreating an item by putting it in the pool and taking it back
    /// out again. If item is not pooled, simply destroys and recreates it as if calling Despawn and then Spawn
    /// Can use this to validate that the object correctly re-initializes itself after spawning -
    /// no state should be left over from its previous incarnation.
    /// </summary>
    /// <returns>the re-created object</returns>
    public static GameObject ServerPoolTestRespawn(GameObject target)
    {
        var poolPrefabTracker = target.GetComponent <PoolPrefabTracker>();

        if (poolPrefabTracker == null)
        {
            //destroy / create using normal approach with no pooling
            Logger.LogWarningFormat("Object {0} has no pool prefab tracker, thus cannot be pooled. It will be destroyed / created" +
                                    " without going through the pool.", Category.ItemSpawn, target.name);

            //determine prefab
            var position = target.TileWorldPosition();
            var prefab   = DeterminePrefab(target);
            if (prefab == null)
            {
                Logger.LogErrorFormat("Object {0} at {1} cannot be respawned because it has no PoolPrefabTracker and its name" +
                                      " does not match a prefab name, so we cannot" +
                                      " determine the prefab to instantiate. Please fix this object so that it" +
                                      " has an attached PoolPrefabTracker or so its name matches the prefab it was created from.", Category.ItemSpawn, target.name, position);
                return(null);
            }

            Despawn.ServerSingle(target);
            return(ServerPrefab(prefab, position.To3Int()).GameObject);
        }
        else
        {
            //destroy / create with pooling
            //save previous position
            var destination = SpawnDestination.At(target);
            var worldPos    = target.TileWorldPosition();
            var transform   = target.GetComponent <IPushable>();
            var prevParent  = target.transform.parent;

            //this simulates going into the pool
            Despawn._ServerFireDespawnHooks(DespawnResult.Single(DespawnInfo.Single(target)));

            if (transform != null)
            {
                transform.VisibleState = false;
            }

            //this simulates coming back out of the pool
            target.SetActive(true);

            target.transform.parent   = prevParent;
            target.transform.position = worldPos.To3Int();

            var cnt = target.GetComponent <CustomNetTransform>();
            if (cnt)
            {
                cnt.ReInitServerState();
                cnt.NotifyPlayers();                 //Sending out clientState for already spawned items
            }
            var       prefab    = DeterminePrefab(target);
            SpawnInfo spawnInfo = SpawnInfo.Spawnable(
                SpawnablePrefab.For(prefab),
                destination);


            _ServerFireClientServerSpawnHooks(SpawnResult.Single(spawnInfo, target));
            return(target);
        }
    }