I am trying to modify the FPSWalker script to work with a heightmap ie NO collision detection on the terrain as I want to use the heightmaps height to keep the player above the terrain. I have tried a naive modification of the “grounded” condition in the “FixedUpdate” function of the FPSWalker script ie something like:
where “height” is obtained from the heightmap. However, it doesn’t really work It seems “FixedUpdate” is only called if there is a collision (which will not be generated by by a heightmap with no mesh collider)?
FixedUpdate is called for every physics time step, so it is definitely being called.
My quetion is what you expect to happen when you assign true to the grounded variable? It is not seen by the physics system, so setting it to true does not stop the object from falling down.
I am kinda stuck I would really like to integrate the movement of the character with the terrain “properly”. In the sense that I would like to “simulate” a collsion with the terrain as if the character has collided with a mesh which had a collison mesh component attached (which the terrian does not). In the FPSWalker script the character seems to be moved with controller.Move (rather than just setting the position of the transform component). Also controller.Move returns a bunch of (collision?) flags. I can return normal vectors, gradient vectors etc for the terrain at the characters position
Forgive me if I’m misunderstand what you’re trying to do. I’m assuming you’re trying to simulate collisions for your huge HeightMap terrains you’re working on. When all is said and done isn’t “simulating” the collisions in scripting going to be just as much of a performance hit as using the mesh collisions coded into Unity?
As a workaround, how about rendering out the huge, high resolution HeightMaps (256x256) and then using much lower resolution non-rendered duplicate HeightMaps (64x64 or 128x128) for the colliders? You’d get the visual detail of the high polygon terrain and the lower polygon hidden collider mesh(es) would compute much faster.
Every frame check if the character controllers bottom part is below the terrain. If it is use transform.position to warp it back up on top of the terrain.
Make your own character controller that does heightmap based collision detection. Thats probably not so good since then you cant collide with boxes or other colliders anymore.
Feed Unity your heightmap as mesh as colliders before loading. I guess you are splitting up your terrain into parts? In that case just make sure to not pass mesh colliders with huge amounts of polys at once. Eg. no more than 500-1000 triangles. Then the proprocessing will be fast enough to do it at runtime.
Yes. I don’t really want a “huge” terrain (yet anyway) - I have a fixed world size and I just needed to double the mesh resolution near the main character to make decent ground shadows howver, this pushed everything over the edge.
It might be (it depends if the collsison detection is O(1) complexity - which I suspect it is , what with all the pre-processing) - but see my reply to Joachim post below.
I tired this and it doesn’t work. or rather, it will work for your character (since you can’t really see the ground under your own feet), but for other characters (which you can clearly see), using a lower resolution collsion maps results in them walking through the ground or floating above it in those parts of the terrain where the curvature is high .
That is exactly why I was trying to tweak the built in character as I definitely want collision detection with other objects in the scene.
OK - this was the original problem I had with using collision detection on the terrain mesh - the pre-processing takes AGES. It takes ages even on “small” terrains (not just the huge ones), again, I don’t need a huge terrain (just the order of few 60K meshes is fine) but the users would have to wait 2 to 3 minutes for the scene to load which I think is too long. However, I haven’t tried the pre-processing again since I have added the LOD system to the terrain so a hybrid approach might work (simple heightmap no-collisions on distinct meshes and full collision detection on the close mesh).
Are you saying that tiling the terrain into smaller parts (64x64) from this example would cut down on the pre-processing time of the mesh colliders as opposed to pre-processinbg fewer larger parts? 2-3 minutes is way too long, but if you could cut it down to 15-30 seconds that would be acceptable.
Hmmm, what about dynamically creating a low polygon collider mesh around a small circumference from the player as he walks through the terrain using the mesh interface? The dynamically created mesh would conform to the topology of the terrain. If the circumference was small enough it would pick up a small region of polygons that might be able to compute the collision in realtime? Sounds complicated to code, but might be a good way to do this.
I now have a simple LOd system going so it is only about 30% as many polygons. I’ll let you know if there is any big improvement gained buy cutting it up thenpre-processing.
Totally agree.
I did think of this and it is a serious contender - I don’t think it would be too bad to code… but there are other issuses - such as how will projectiles and the like “detect” the terrain (but I have to worry about that as well at the moment anyway) but I’ll keep it as a last resort!
Anyhow, I’ll try the “pre-process smaller bits” first…
OK - this is almost working!! What I have done is splt the terrain into smaller cells with a hi rez set around the player and a low rez set in the distance. As the player moves arround I activate/de-activate the hi/low rez set so that the player is always surround by a hi rez set with low rez in the distance. Now, if I only pre-process the hi rez set it is MUCH quicker (a few secs) as the player moves around there is a bit of a wait (a few secs in the current very large terrain test) as new hi rez cells are activated (and pre-processed). This would be OK as it wouldn’t happend that often, the problem is that when I de-activate a hi rez mesh the again re-activate it (the plaer might move backwards and re-activate a hi rez that has just been de-actiavted) ALL the pre-processing seems to be repeated This can create ( depending on how the player moves around) an unaccptible sequence of “few second” delays.
Thus, the question is: Can I “de-actiavte” a mesh without having it pre-process collision info each time it is re-activated?
If the answe is “you can’t” then I will try just switching off the rendering.
OK - it’s working great!!! Disabling the rendering does the trick and gradually adding more and more collision meshes doesn’t seem to slow the movement. There is a slight delay as the player moves to a region where a new hi rez mesh is added (with collision detection pre-processing) but the delay is not repeated -this doesn’t seem too distracting at the moment
Cool. If the collision meshes aren’t a big performance problem, you could even try pre-processing ALL of them for no delays later. Just as an experiment, anyway.
Hi Morgan,
Trouble is, if there are 88=64 cells (or 1616…), each takes 1 sec, that’s a minute gone. At the moment it takes about 30sec to create the meshes (on a dual 2GHz machine). I am going to save them as .obj’s to see if they load faster than they are created (which they should do), then pre-processing all at once might be viable.
Anyhow, at the moment I am not really trying to hyper-optimize, just checking viability - which I seem to be getting. There are definitly several ways it can be improved - it is just a matter of prioritising - I want to add some contnet to the world at some stage!