Search code examples
c#unity-game-enginegame-engine

Instantiate Object at Certain Position?


Would just like to start by saying that I'm... VERY new to this. Hope this isn't a stupid question. I have just finished a script that allows me to cut down a tree and have 3 pieces of wood spawn after the tree disappears. The problem I'm having is that once the logs spawn, they spawn standing up and stacked on top of each other in the same position of the tree.

Is there any way to have them spawn slightly spread out and laying down where the tree has fallen?

This is my script for the tree.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class TreeAi : MonoBehaviour
{
GameObject thisTree;
public int treeHealth = 35;
private bool isFallen = false;
public GameObject treeLog;
public GameObject treeLogOne;
public GameObject treeLogTwo;
public AudioClip treeFall;
private void Start()
{
thisTree = transform.gameObject;
}
void DeductPoints(int damageAmount)
{
treeHealth -= damageAmount;
}
void Update()
{
if (treeHealth <= 0 && isFallen == false)
{
Rigidbody rb = thisTree.AddComponent<Rigidbody>();
rb.isKinematic = false;
rb.useGravity = true;
rb.AddForce(Vector3.forward, ForceMode.Impulse);
StartCoroutine(destroyTree());
isFallen = true;
AudioSource.PlayClipAtPoint(treeFall, this.gameObject.transform.position);
}
}
private IEnumerator destroyTree()
{
yield return new WaitForSeconds(2.2f);
Destroy(thisTree);
Instantiate(treeLog, transform.position, transform.rotation);
Instantiate(treeLogOne, transform.position, transform.rotation);
Instantiate(treeLogTwo, transform.position, transform.rotation);
}
}

Solution

  • The second parameter into Instantiate() is the location you wish to place the object. In this case you're using the same location as the tree.

    You'll want to modify the position vector slightly. Unity has a Random method which really helps in this case.

    You could update your code to use this offset like so

    // How far the random offset can stretch
    var randomSpawnRadius = 2.0f;
    // Take the current position and add a random offset times the radius
    var treeLogOffset = transform.position += Random.insideUnitSphere * randomSpawnRadius;
    Instantiate(treeLog, treeLogOffset , transform.rotation);
    // Get another random position inside the radius
    treeLogOffset = transform.position += Random.insideUnitSphere * randomSpawnRadius;
    Instantiate(treeLogOne, treeLogOffset , transform.rotation);
    treeLogOffset = transform.position += Random.insideUnitSphere * randomSpawnRadius;
    Instantiate(treeLogTwo, treeLogOffset , transform.rotation);
    }
    

    An alternative would be to make this a function since it is rather repetative

    private void InstantiateAtRandomOffset(GameObject objectToInstantiate, Transform transform, float randomSpawnRadius)
    {
      var itemOffset= transform.position += Random.insideUnitSphere * randomSpawnRadius;
      Instantiate(objectToInstantiate, itemOffset, transform.rotation);
    }
    

    Then you could replace the calls in your code with

    InstantiateAtRandomOffset(treeLog, transform, 2.0f);
    InstantiateAtRandomOffset(treeLogOne, transform, 2.0f);
    InstantiateAtRandomOffset(treeLogTwo, transform, 2.0f);