Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

3d Endless Runner! Destroy prefab!

Discussion in 'Scripting' started by ninjacupcake83, Jun 1, 2015.

  1. ninjacupcake83

    ninjacupcake83

    Joined:
    Mar 10, 2015
    Posts:
    55
    Hi guys,

    sorry to bother you all. I seem to have exhausted my google fu!

    I have been slowly creating a 3d Endless Runner and have all the needed parts in place. However, trying to make the endless part of the endless runner is making me want to bang my head on desk.

    I have created a script to call a ground spawn which works perfectly when I run through the placed box collider trigger. It spawns exactly at the end of the prefab world making the hero run through a clone of said prefab, except the fact it will only clone my world prefab once correctly with the following code, and then places all other clones at 388 which crashes unity and lays all prefabs on top of the other:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class GroundSpawn : MonoBehaviour
    5. {
    6.     public GameObject World;
    7.     private Vector3 groundSpawn = new Vector3 (0, 0, 388);
    8.  
    9.     void OnTriggerEnter (Collider other)
    10.     {
    11.         Instantiate (World, groundSpawn, Quaternion.identity);
    12.     }
    13.  
    14.     void OnTriggerExit (Collider other)
    15.     {
    16.  
    17.     }
    18. }
    If I change the new Vector 3 (0, 0, 388) part to the z axis of 0. Upon entering the box collider it clones the world on top of the existing world crashing unity again.

    I have run out of idea's and was wondering if any assistance could be offered.

    Sorry if you don't understand my post much. It's 1.30am here - and I have run out of coffee :(
     
    Last edited: Jun 1, 2015
  2. MattCarter24

    MattCarter24

    Joined:
    May 27, 2015
    Posts:
    120
  3. ninjacupcake83

    ninjacupcake83

    Joined:
    Mar 10, 2015
    Posts:
    55
    I have been following along with Mikes Tut to see how he generated his level but he does it by random. I have a pre-designed world prefab and want to instantiate a second, third, fourth and so on clone of this prefab to make the game endless.
     
  4. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    I suspect you want to do something along the lines of "this object's position + an offset" (the offset being the Vector3 with z of 388 or something). You also need to check within the OnTriggerEnter function what is causing the collision and act accordingly (check it's the player and only then spawn a new ground piece I would expect). Unity is most likely crashing because the platform triggers another ontop of itself, which triggers 2 more, then 4, then 8... .... splat.
     
    ninjacupcake83 likes this.
  5. ninjacupcake83

    ninjacupcake83

    Joined:
    Mar 10, 2015
    Posts:
    55
    I have it all setup with a destroy trigger placed also. When I enter the collider trigger it generates the new prefab clone at the point x - 0, y - 0, z - 388. PERFECT! When I then exit out of the collider trigger it destroys the previous terrain ran on, also PERFECT! However, when I reach the new collider trigger it is then that the world generates on top of itself indeed, then replicating itself out of control due to the trigger colliding with the trigger etc.

    Here is a video if it helps:

     
  6. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    so... you still need to instantiate the new section at a location relative to the current one. Not any absolute position.

    Code (csharp):
    1.  
    2. groundSpawn = transform.position + groundSpawn ;
    3.  
     
    ninjacupcake83 likes this.
  7. Defero

    Defero

    Joined:
    Jul 9, 2012
    Posts:
    200
    It looks as your first level section is 388 units long. That is why when you spawn the second level section at 388, it "stitches" perfectly with the first level section.

    For the this level section you should set the position relative to the second level section (and not the first like you are doing)

    The z axis on your ground spawn has to be the length sum of all previous level sections.

    The best way would probably be something like:

    spawnPoint = new Vector3(0,0, transform.position.z + offset)

    offset is some fixed number, as long as your ground spawn colliders are all the same length. Otherwise it will be length/2.
     
    ninjacupcake83 likes this.
  8. ninjacupcake83

    ninjacupcake83

    Joined:
    Mar 10, 2015
    Posts:
    55
    I can not thank you both enough for your assistance. I had been sat the majority of last night after work - and this morning - trying to work out how to put this in place. I like to think I was on the right track, but miles from solving the code HA!

    For anyone wanting to know in future, here is the script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class GroundSpawn : MonoBehaviour
    5. {
    6.     public GameObject World;
    7.     public Vector3 groundSpawn = new Vector3 (0, 0, 0);
    8.  
    9.     void OnTriggerEnter (Collider other)
    10.     {
    11.         groundSpawn = new Vector3 (0, 0, transform.position.z);
    12.         GameObject.Instantiate (World, groundSpawn, Quaternion.identity);
    13.     }
    14.  
    15.     void OnTriggerExit (Collider other)
    16.     {
    17.         Destroy (World);
    18.     }
    19. }
    This script allows the trigger to add a new prefab of the world on enter, and then removes the previous prefab on exit. It also adds the next prefab in the chain in the exact place it needs to be to "stitch" the level together endlessly. I also noticed that I had an alignment issue with my 'groundspawn' prefab. As it was making the new prefab appear 4 units above and 2 to the side of the existing prefab. Just fixed this by resetting its transform co-ords to 0 across the board.

    Thanks guys soooooooooooo much, all I can offer is a virtual handshake and pint =P

    A video to show this working:

     
    GreenBoxInteractive likes this.
  9. ninjacupcake83

    ninjacupcake83

    Joined:
    Mar 10, 2015
    Posts:
    55
    OK, so I have now got the world cloning and deleting correctly. Now my next issue is my coin spawn. I have it set up the same as my world spawn up above - with the exception of a few name changes. Here is my code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class CoinSpawn : MonoBehaviour
    5. {
    6.     // Call prefab to assign
    7.     public GameObject Coins;
    8.  
    9.     // Prefabs position (x, y, z)
    10.     public Vector3 coinSpawn = new Vector3 (0, 0, 0);
    11.  
    12.     // Box Collider set up with a enter trigger function
    13.     void OnTriggerEnter (Collider other)
    14.     {
    15.         // Spawn coins on the z axis where collider centers
    16.         coinSpawn = new Vector3 (0, transform.position.y, transform.position.z);
    17.         GameObject.Instantiate (Coins, coinSpawn, Quaternion.identity);
    18.     }
    19.  
    20.     // Update is called once per frame
    21.     void OnTriggerExit (Collider other)
    22.     {
    23.         Destroy (Coins);
    24.     }
    25. }
    upon calling the destroy function I receive a message:

    Destroying assets is not permitted to avoid data loss.
    If you really want to remove an asset use DestroyImmediate (theObject, true);

    when I change the line of code to:

    Code (CSharp):
    1. // Update is called once per frame
    2.  
    3.     void OnTriggerExit (Collider other)
    4.  
    5.     {
    6.  
    7.         DestroyImmediate (Coins, true);
    8.  
    9.     }
    I get a new message saying:

    Destroying GameObjects immediately is not permitted during physics trigger/contact, animation event callbacks or OnValidate. You must use Destroy instead.

    Can someone explain where I am going wrong.

    Thanks in advance...
     
  10. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    I suspect you don't want to destroy your prefab, you want to destroy the instances of the coins you have created within your level. The prefab is the "template" you are using to make something in your scene using instantiate.

    You're going to need to keep a reference to the instantiated coin.

    Code (csharp):
    1.  
    2. // class variable declaration
    3. GameObject coinClone;
    4.  
    5. // within TriggerEnter
    6. coinClone = Instantiate(Coins, coinSpawn, Quaternion.identity);
    7.  
    8. // within TriggerExit
    9. Destroy(coinClone);
    10.  
    on a side note, I always advise to keep to the "standard" practice of keeping variables to lowercase first letters and try to keep them "well named" i.e. "Coins" => "coinPrefab" etc. Classes and functions are uppercase first letter. Really helps when working with others and coming back to your own old code later :D
     
  11. manlaikin1994

    manlaikin1994

    Joined:
    May 15, 2015
    Posts:
    179
    Its is what i make.
    Since i am lazy, give this a simple but weird verison for you as ref
    Hope i can help you

    PS: There may a lot of stupid code. i am still a beginner.... but hoping someone can teach me a better way... really want to learn somethings

    Want to find some (teachers) teach me unity....
     

    Attached Files:

    Last edited: Jun 2, 2015
  12. ninjacupcake83

    ninjacupcake83

    Joined:
    Mar 10, 2015
    Posts:
    55
    You are off to a good start @manlaikin1994. I gave your game a quick run to have a look. Your walls don't have any collision detection on them so I just floated straight through. The code you have is not what I am looking for as both are games - although are runners - they are very different in how we instantiate our worlds etc.

    I really like the darkness effect with the torchlight. Very good idea :)

    Keep up your efforts. Any assistance I can offer let me know. Although some things I do still need to learn myself as this is my first real attempt at finishing a game project.

    @LeftyRighty I have placed the code all in to one script to make for better house keeping, so the following is what I have so far:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class GroundSpawn : MonoBehaviour
    5. {
    6.     // Call prefab to assign
    7.     public GameObject coinClone;
    8.     public GameObject worldClone;
    9.  
    10.     // Offset for spawning ground
    11.     private float groundOffset = 30;
    12.     private float coinOffset = 30;
    13.  
    14.     // Prefabs position (x, y, z)
    15.     public Vector3 groundSpawn = new Vector3 (0, 0, 0);
    16.     public Vector3 coinSpawn = new Vector3(0, 0, 0);
    17.  
    18.     // Box Collider set up with a enter trigger function
    19.     void OnTriggerEnter (Collider other)
    20.     {
    21.         // Spawn ground on the z axis where collider centers
    22.         groundSpawn = new Vector3 (0, 0, transform.position.z + groundOffset);
    23.         Instantiate (worldClone, groundSpawn, Quaternion.identity);
    24.  
    25.         // Spawn coins on the z axis where collider centers
    26.         coinSpawn = new Vector3(0, 0, transform.position.z + coinOffset);
    27.         Instantiate (coinClone, coinSpawn, Quaternion.identity);
    28.     }
    29.  
    30.     // Box Collider set up with a exit trigger function
    31.     void OnTriggerExit(Collider other)
    32.     {
    33.         // Removes prefabs on exit of Collider
    34.         Destroy (worldClone);
    35.         Destroy (coinClone);
    36.     }
    37. }
    This works now without returning an error. However, it generates the coins but doesn't show them in the world. When I pause the game and look at the coins in the hierarchy, it displays them but they are all hidden in the game instance, unless I tick them all while game is paused. I had this once before but cant remember how I resolved this now!!
     
  13. ninjacupcake83

    ninjacupcake83

    Joined:
    Mar 10, 2015
    Posts:
    55
    Stand down! I have now Solved it... For now! :S
     
  14. manlaikin1994

    manlaikin1994

    Joined:
    May 15, 2015
    Posts:
    179
    idk if my idea of generate ground is correct or not

    for wall collision, i think just add tag and use trigger function can do it

    btw, how do u generate ur ground, i mean your idea?
     
  15. ninjacupcake83

    ninjacupcake83

    Joined:
    Mar 10, 2015
    Posts:
    55
    I made my ground using my previously made Tileset asset which is now available on the Unity Asset Store. It is a set of modular building blocks that snap together to form different terrains/area. You can get examples of my tilesets in use by visiting my blog in my signature link.

    I then prebuild the levels to a design I like and then create a prefab which is then instantiated into the editor. Once Player reaches the end of this world it has already cloned it ahead of the player so that anybody playing the game does not even know that ground was not there in the first place! Creating an endless runner...

    Your idea generates the ground correctly, just needs that collider for the walls as stated previously.
     
  16. blizzy

    blizzy

    Joined:
    Apr 27, 2014
    Posts:
    775
    This sounds like you did not set up tags to go with your colliders, and actually check them. Even if one of the world's colliders collides with another world collider, it shouldn't trigger anything.
     
  17. ninjacupcake83

    ninjacupcake83

    Joined:
    Mar 10, 2015
    Posts:
    55
    @blizzy I was calling the same instance at a location of z-388 - which happened to be the end of my last world prefab. But then the next time I hit that collider it would place the next instance at z388 - right on top of already located and due to the trigger it just triggered itself over and over again. Problem was solved by adding an offset to my instantiate script.
     
  18. manlaikin1994

    manlaikin1994

    Joined:
    May 15, 2015
    Posts:
    179
    didn't u need the collider to detect the end of world?
     
  19. ninjacupcake83

    ninjacupcake83

    Joined:
    Mar 10, 2015
    Posts:
    55
    Yes, there is a collider set up towards the end of the level which once entered, calls another instance of the level prefab. On exit of collider this then destroys previous instance of the world. This reduces the amount of systems resources used to run the game on different platforms for example.
     
  20. manlaikin1994

    manlaikin1994

    Joined:
    May 15, 2015
    Posts:
    179
    then it look same as me...
    i mean the method
     
  21. ninjacupcake83

    ninjacupcake83

    Joined:
    Mar 10, 2015
    Posts:
    55
    Aren't you randomly generating a set amount of building blocks?

    Mine is just calling the same prefab over and over, infinitely until the player causes game over. So only one instantiate call. Where as I think you are randomly generating your level.
     
  22. manlaikin1994

    manlaikin1994

    Joined:
    May 15, 2015
    Posts:
    179
    the different between us is generate randomly

    but the generate method and destroy method are same
     
  23. manlaikin1994

    manlaikin1994

    Joined:
    May 15, 2015
    Posts:
    179
    lol i am guessing what method you use
     
  24. ninjacupcake83

    ninjacupcake83

    Joined:
    Mar 10, 2015
    Posts:
    55
    The same, yes! But your method is - I think - more complex than a simple instantiate 1 prefab, which is what I am doing. :)
     
  25. manlaikin1994

    manlaikin1994

    Joined:
    May 15, 2015
    Posts:
    179
    its very easily actually
    public gameObject[] prefs;
    int index = Random.range(0, prefs.length);
    Instaniate(prefs[index], tp, tr);
     
  26. ninjacupcake83

    ninjacupcake83

    Joined:
    Mar 10, 2015
    Posts:
    55
    What style are you aiming for? Platform? Era etc.? I really do like the torch effect so much!
     
  27. manlaikin1994

    manlaikin1994

    Joined:
    May 15, 2015
    Posts:
    179
    no planning actually.
    Just use some time to do a simple style sample and hope it can help you only
     
  28. manlaikin1994

    manlaikin1994

    Joined:
    May 15, 2015
    Posts:
    179
    How do you do the jump?
    did u add rigibody to ur player??
    and make him fall?

    since when i am adding the rigibody to the player, players' position and rotation will keep chaning and i dk how to solve it
     
  29. ninjacupcake83

    ninjacupcake83

    Joined:
    Mar 10, 2015
    Posts:
    55
    Added a char controller and then added this to my player move:

    Code (CSharp):
    1. // Make Player Jump
    2.         if (player.isGrounded)
    3.         {
    4.             // if player is on the ground, we normally don't want to move him vertically
    5.             moveDirection.y = 0;
    6.  
    7.             // but if the jump button is pressed, then we do want him moving vertically
    8.             if (Input.GetButton ("Jump"))
    9.             {
    10.                 moveDirection.y = jumpSpeed;
    11.             }
    12.         }
    13.         else
    14.         {
    15.              // if player is not on the ground, then apply gravity to him
    16.              moveDirection.y -= gravity * Time.deltaTime;
    17.         }