Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Please Fix Terrain Auto Connect

Discussion in 'World Building' started by gilley033, May 7, 2021.

  1. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,181
    My use case is simple. I stream in and out terrains at runtime as the player moves around the world.

    I don't use Auto Connect, because it's terrible and causes performance issues when you have a large number of terrain in the scene (owing to the fact that every terrain has its neighbors reset within a single frame). Instead, I connect my neighbors manually at runtime using the SetNeighbors method, calling the method at most once per frame, because frankly I don't think it's a big deal if the seems between some terrains are showing for a millisecond.

    Unfortunately, the Unity AutoConnect method is called any time a new terrain is added to the scene (and probably removed as well), and the first thing that this method does is clear the neighbors of all active terrains in the scene, even if they do not utilize the AutoConnect property.

    Not only does this method produce 2KB of garbage every time it is called, it invalidates the neighbors of terrain that do not need to be invalidated (terrain whose neighbors have not changed), so I am left with two options. Let those terrain have seems, or completely re-neighbor every terrain in the scene after adding/removing terrain (rather than my current and desired method of only resetting the neighbors of terrain that have been added, or those affected by a new terrain add/remove).

    Or there is a third choice. Unity, please fix this method to factor in the possibility that no terrain are using the Auto Connect option. If there aren't any, exit the AutoConnect method early!!

    And on the off chance that there is a very good reason for you guys doing things this way, please let me know. But as far as I can see, there is no good reason and it's just an oversight.

    This issue is present on all versions of Unity up to 2022.2.3f1 (and probably later versions, though I haven't checked). Please fix it for all LTS versions, it is a very simple addition of maybe ten lines of code!

    @XiaoxiLiu
    @wyattt_

    You two seem to be the most active on here, so I hope you don't mind me @ING you . . .
     
    Last edited: May 7, 2021
  2. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,181
    Darn, no response at all from a Unity Dev?
     
  3. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,181
    Bumping again. If anyone can suggest something to get this to the attention of a Unity employee, please let me know!
     
  4. thephox1982

    thephox1982

    Joined:
    Jan 21, 2022
    Posts:
    20
    I don't think anyone at Unity cares unless you have a paid version, this is typical nature of business.

    From what I can tell from the very poor documentation for terrain tools api..
    You need to setup at least one terrain tile in the editor, it can be disabled even according to the docs.
    Then you must set neighbors for each and every terrain tile to a terrain instance, you can't leave ANY of them null which is stupid because there will always be an outside edge..
    Then it should just work? That is the documentation saying this.. as it stands that is the instructions!

    However, I have had this not work PERIOD by following all of the instructions.
    Heck, I even included "using UnityEngine.TerrainUtils" and calling TerrainUtility.AutoConnect() on Update which seems to do absolutely nothing. Also I made sure all tiles were same groupingID.. it all works flawless in editor mode but not during runtime.

    I am using 2021.2 and my conclusion is this is not even a feature yet and still only works in the editor mode only and someone contributed to early to the API documentation because absolutely none of it works in runtime!

    I have searched up and down Google to see if anyone else has had luck but it seems no one is even bothering to try and use this stuff yet and all the people asking get the same answers but no results from those answers. Basically the consensus is as long you have the one piece of terrain in your scene, all tiles same groupingID and all have neighbors set then it just works, but yet it never does!

    I have however during debugging noticed that something other than my own code resets terrain neighbors to null after frame 2, so frame 3 onwards, no terrain tile knows about it's neighbors anymore thus stitching can't occur. I seen a bug report about this for 2020 edition which claims to have been fixed but no versions I try 2020 onward have this fix, so not sure what is up with that!

    So we're all still waiting, no one can use this feature if it even exists yet. Perhaps someone who has a paid version of Unity will eventually complain about it and it will get the needed love. But then again, they probably have it fixed in the paid versions having a different code base and just didn't care to port it to free edition.
     
  5. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,181
    So they have finally made a little bit of progress with Auto Connect. You can check out my other thread towards the end for some more information:

    https://forum.unity.com/threads/what-is-terrain-neighbor-for.612760/#post-7816473

    In short, you should be able to use the manual Set Neighbors method on these versions of Unity:

    2019.4.33f1
    2020.3.23f1
    2021.1.0a1 and above

    There is still an issue where the internal Auto Connect method is still called and it produces garbage, even in situations where no Terrain utilize Auto Connect, but now this method will only clear the neighbors of a terrain if it is using Auto Connect.

    You can have null terrain as one or more of the neighbors, that should not cause any issues. On other versions of Unity where Auto Connect was aggressively clearing neighbors, you would need to wait until after frame 2 to set the terrain neighbors manually (which is kind of what you described). That is no longer when using one of the versions listed.

    My advice for receiving support is to file bug reports. It is the only official avenue Unity consistently responds to, and I have had great luck using this system.
     
    chadfranklin47 and TerraUnity like this.
  6. chadfranklin47

    chadfranklin47

    Joined:
    Aug 11, 2015
    Posts:
    221
    @gilley033 Hey, sucks to see how long you had to wait for progress on this issue. I'm using 2020.3.32 and Unity still seems to be clearing my terrain neighbors upon entering play mode. This is with no terrains having Auto-Connect enabled. If I set the neighbors in edit mode and hit play, the neighbors are cleared. I've found though that if I set ALL the terrain neighbors at runtime (sometime after Start()), then add a terrain and just set the neighbors for that single terrain and its adjacent terrains, everything seems to work as expected. I'll have to do some more tests tomorrow.

    I also wanted to ask if you found that you need to call
    terrain.Flush();
    and
    Terrain.SetConnectivityDirty();
    after setting your terrain neighbors.
     
    Last edited: Apr 2, 2022
  7. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,181
    Yes, it was very frustrating, it turned out it was kind of my fault though; I tried to use these forums as a means for getting it fixed but once I went down the bug report path, Unity fixed things fairly rapidly. It turns out that is really the only approach worth pursuing if you find something that needs to change in the code.

    I'll have to test with 2020.3.32. That would be really sad if the behavior was reintroduced! Have you tried setting the neighbors before or during Start? Do you see the same clearing behavior? The clear method (before) was called on like the first or second frame, so I found you had to set the neighbors on the third frame or higher to avoid them being cleared.

    As for Flush and SetConnectivityDirty, right now I am just using Flush. I'm pretty sure it is required after setting the neighbors, but I could be mistaken. To be honest, I am not sure what SetConnectivityDirty does. It does sound like it's something that should be called based on the description, but *shrug*. Let me know if you figure it out, and I'll do the same.
     
    chadfranklin47 likes this.
  8. chadfranklin47

    chadfranklin47

    Joined:
    Aug 11, 2015
    Posts:
    221
    Ok, setting the neighbors during Start() or Awake() does work fine. In my current workflow, I have several terrains already in the scene and I add new ones as needed. It just seems that I need to call SetNeighbors() for all the existing terrains upon entering play mode (regardless of whether or not they were previously connected in edit mode). After that, only for any added or removed terrains and their neighbors.

    I'm also not seeing anything that looks like "AutoConnect()" in the profiler, so I guess that's good.

    As for Flush() and SetConnectivityDirty() I have not seen any visible difference between having them enabled vs not. That goes for setting neighbors as well as painting, editing heightmaps, etc. I'm thinking it's a good idea to call Flush() anyway though.

    I should be working with this quite a bit, I'll post any new findings of importance.
     
    Last edited: Apr 3, 2022
  9. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,181
    Interesting, I definitely saw an issue when not using Flush, but I'll have to recheck to make sure.