Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by GregoryNeal · Apr 26, 2015 at 08:24 AM · collider2dterrain generationinfinite terrain

Ideas to help fix a bug in my world generation code?

So I've got the basics for 2D infinite persistent world generation. The way I have it set up is this:

Attached to the player is an empty that has a script that handles world generation functionality and the initial spawning of the world, and the information about the current world (world order list and such).

On my world chunk prefabs I have a trigger collider on the front and back. Each has a script that, when the player triggers the collider, determines if it needs to load a previously generated chunk, or create a new one. Then it destroys the chunk on the opposite side of the world, saving it's data to be read if it needs to be regenerated.

The problem is that because I'm using OnTriggerEnter2D, if the player stops inside of a trigger collider, then turns around, the world generation code doesn't initiate because it's not an OnTriggerEnter2D event.

My question is this, y'all got any ideas to fix this?

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image siaran · Apr 26, 2015 at 09:35 AM 0
Share

well, you could use an OnTriggerExit2D event ins$$anonymous$$d maybe, if you move it s.t. they are not located at the very edge, then check which way your player is going

youd get something like

 float colliderXpos;
 void Start(){
 colliderXpos = transform.position.x;
 }
 void OnTriggerExit2D(collider2d col){
 
   if(col.gameobject.tag == "player"){
    if(col.transform.position.x > colliderXpos) SpawnWorldFront();
    else SpawnWorldBack(); 
   }
 }

just make sure that there is some room on the old world object for your player to be exiting it so that he doesn't fall off while the new world data is generated/old data is loaded (or do some smart things in your code that ensure that doesn't happen anyway, that's possible too).

avatar image GregoryNeal · Apr 26, 2015 at 09:58 AM 0
Share

I did this and it works pretty well. There's just an issue when if I stop the player after he left the front trigger but hasn't touched the back trigger of the next chunk, then turns around, I get ground despawning when I don't want it to. This seems like an easier fix than previously though. Thanks for the push in the right direction.

avatar image GregoryNeal · Apr 26, 2015 at 10:33 AM 0
Share

Okay I lied, I can't figure out this one either. This is what I did. I created a bool called inBetween. Everytime I called OnTriggerExit2D and the situation was valid (exiting a front spawner going forward or exiting a back spawner going backwards), I set inBetween = true. Then I had OnTriggerEnter2D set up so that when the player entered a front spawner going backwards or a back spawner going forwards, it set inBetween = false. Then I check to see what value inBetween is before I spawn world chunks. However, since I do all chunk spawning in OnTriggerExit2D (in which inBetween gets set to true as soon as a valid movement happens) nothing spawns. Im trying to figure out a way to refactor my existing code so that I can have my spawning code outside of my OnTriggerExit2D while still depending on inBetween. Or maybe this is a bad way to do it?

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by GregoryNeal · Apr 26, 2015 at 05:27 PM

Here's what I did and fixed the issue (looks a lot nicer too):

  1. First up, I scrapped everything, the code looked like shit and it made me feel bad as a programmer. I also got rid of every single collider that I had attached to my Ground object prefabs, I just left the edge colliders on top so that I could walk on it.

  2. I've added a GroundDetector script whose job is to raycast downward from the player, only looking for the Ground layermask, it reads the instanceID of the ground object, then keeps raycasting at a set interval and comparing the instanceID of the raycast2D gameobject to the previous one. When they are not equal, this is when I know I've left my current ground object.

  3. Now it's pretty easy to get the velocity of my character, with this I know which direction I need to spawn ground. And it calls a script thats a sibling of GroundDetector, called GroundManager. This spawns my ground.

Here is my raycast script if anyone wants to use it:

 using UnityEngine;
 using System.Collections;
 
 public class GroundDetector : MonoBehaviour {
     public LayerMask mask;
     int init;
     float time = 0;
     int currGroundID;
     // Use this for initialization
     void Start () {
         currGroundID = GetGroundID();
         StartCoroutine("RayCastGround",currGroundID);
     }
     
     IEnumerator RayCastGround(int currID){
         while(currGroundID == currID){
             yield return new WaitForSeconds(.01f);
             currID = GetGroundID();
         }
         currGroundID = currID;
         InitiateSpawn();
     }
     
     int GetGroundID(){
         Vector2 pos = new Vector2(transform.position.x,transform.position.y);
         RaycastHit2D hit = Physics2D.Raycast(pos,-Vector2.up,Mathf.Infinity,mask);
         if(hit.collider != null){
             return hit.collider.gameObject.GetInstanceID();
         }
         else{
             return -1;
         }
     }
 
     void InitiateSpawn(){
         //just in case??
         StopCoroutine("RayCastGround");
 
         //tell GroundManager to spawn in front or behind
         float vel = GetComponentInParent<Rigidbody2D>().velocity.x;
         if(vel > 0){
             this.GetComponent<GroundManager>().SpawnInFront();
         }
         else if(vel < 0){
             this.GetComponent<GroundManager>().SpawnInBack();
         }
 
         StartCoroutine("RayCastGround",currGroundID);
     }
 }


Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image siaran · Apr 26, 2015 at 06:03 PM 0
Share

if you're trying to make some kind of 'endless world' game, you should move the world ins$$anonymous$$d of the player, in order to avoid ending up having to deal with floating-point accuracy problems. (or do a floating origin)

Doing this without colliders is better though, that was my first idea but I figured "rewrite all your code to use a completely different method" wasn't the kind of answer you wanted :P

avatar image GregoryNeal · Apr 27, 2015 at 09:29 AM 0
Share

Yea my original code was pretty shit, but a benefit of the new methods I wrote lets me easily pick up everything and move it back to the origin if I get to a certain coordinate.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

20 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Can someone tell me how to create a city similar to EGYPT in unity 5.3.2?? 0 Answers

How to use marching cubes to turn cube terrain into voxel terrain 0 Answers

Changing Terrain tint color via script 1 Answer

Infinite Range, Smooth, Day-Night Cycle 3 Answers

Why does my trigger only fire one time? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges