🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

How and Why my world Turns.

posted in Septopus for project Unsettled World
Published October 03, 2018
Advertisement

2dBackSide.thumb.png.b0d9025e0c32492e1f841436da20d6d0.pngContinuing my rewind for Unsettled World:

Time to give some detail on the foundations of my game environment.  The planet I've created and how it mechanically works within Unity.

2dBackSide.thumb.png.b0d9025e0c32492e1f841436da20d6d0.png

Here is a 2d view of the editor interface with the "canvas" highlighted sitting at 0,0,0.  The planet object has a 30000m radius and it is sitting @ 0,-30000,0.

ObjectParentage.png.086d871247f828ca419d423553811bd7.png

The object parentage looks like this.  Generic GameObject "PlanetHolder", non-rendered mesh w/collider "Planet" (used by the procedural terrain system mostly), followed by the camera, player, water sphere and the actually visible surface mesh.  Now, this arrangement may change somewhat, I may figure out a way to combine the "Planet" with the visible surface, but it is how it is for now.  And it works.

planetholderproperties.png.57d3f38267274c0a5c14c5657779d7b9.png

The PlanetController script is responsible for keeping the player and camera close to Origin, 0,0,0.  This is necessary because once your player/camera cross the 10000m distance boundary the underlying floating point mathematics loses enough precision that your meshes begin jumping around the screen.  The PlanetController script contains this logic:


public class PlanetController : MonoBehaviour {

    public GameObject Planet;
    public GameObject Player;
	Rigidbody rb;

	void Start()
	{
		rb = Player.GetComponent<Rigidbody>();
	}
          
    void FixedUpdate()
    {
      if (rb.velocity.magnitude < 1)
      {
          Planet.transform.localRotation = Quaternion.FromToRotation((Player.transform.localPosition - Planet.transform.localPosition).normalized, Vector3.up);
      }
    }
}

Keep in mind I omitted a lot of extra stuff from that code, for example, it doesn't actually run EVERY FixedUpdate, but as a timed event inside the fixed update, every few seconds or so.

Also Important to note, I still have a minor amount of vertical jitter that is caused by the planet sitting at 0,-30000,0.  I am actively working at ways to reduce this, in fact, as I type I'm having more ideas on how to fix the issue.. So keep posted. 

^Solved and NOT related to the size/positioning within the 3D space, see comment below.

The visual look of the planet(Before the procedural code kicks off and repaints it with textures/objects).  Is a split up version of the planet mesh(will be split up MUCH more than this eventually)..  And the water is a simple sphere object(also broken up and non-visible sections removed) with a water texture.

visiblesurface.thumb.png.fa2c8332b60d4575eade5113cad21ae4.png

My Gravity "system" is also very simple(Just a script, like this one, attached to the objects that need gravity applied to them):


public class GravControl : MonoBehaviour
{
    public GameObject planet;
    private Rigidbody rb;
    public Vector3 upVector;

    void Start()
    {
        if (planet == null)
        {
            planet = GameObject.Find("Planet");
        }
        rb = GetComponent<Rigidbody>();

        Vector3 upVector = (transform.position - planet.transform.position);

        transform.rotation = Quaternion.FromToRotation(transform.up, upVector) * transform.rotation;
    }

    void FixedUpdate()
    {
        upVector = (transform.position - planet.transform.position).normalized;

        rb.AddForce(-upVector * 9.81f, ForceMode.Acceleration);
    }

}

I may incorporate this into a "controller" type script that isn't attached to every object at some point for simplicity, but for now, it works just fine.

So that, just a few pics and sentences, well summarizes at least 2 or 3 solid weeks of 8+ hour days... hahaha!

0 likes 0 comments

Comments

Septopus

As it turns out, the vertical jitter I thought I still had was caused by the fact I was continuously adding the acceleration force in my gravity script while the player character was already on the ground. 


if (!isGrounded)
                    rb.AddForce(-upVector * 9.81f, ForceMode.Acceleration);

Solves the last of the jitters.  "bool isGrounded" is provided by GetComponent<> to the character controller script.  It maintains such data for numerous and hopefully obvious reasons.

The funny thing is, this was already included in previous versions of this code..  Gotta keep an eye on what I scrap when trying to fix other things or simplify.

October 04, 2018 01:37 AM
Stragen
2 hours ago, Septopus said:

Solves the last of the jitters.  "bool isGrounded" is provided by GetComponent<> to the character controller script.  It maintains such data for numerous and hopefully obvious reasons.

Are you calling GetComponents on every update/fixedupdate for the controller script?

If so, i'm going to get in before the optimization junkies do - GetComponent isnt very 'elegant' in how it collects components from targets, looking at your code above you have your rigidbody getter in the start(), my first assumption is that you have these kind of references captured in the controller script in their relevant awake/start functions, but its worth an ask...

October 04, 2018 03:53 AM
Septopus
39 minutes ago, Stragen said:

Are you calling GetComponents on every update/fixedupdate for the controller script?

Not anywhere that I've bothered to pay attention. lol. 

A few get through here and there, but I've not spent any time specifically on optimizations either.  Still in the get it working phase... Unless the optimization is required to meet minimum functional operation, I usually wait until I have time to go back and look at it as a whole.

 

October 04, 2018 04:47 AM
Septopus

Edited post with a better code example. ;)

October 04, 2018 05:34 PM
Awoken

I'm assuming in Unity the physics is based on scale?  I know you're talking about problems with jitteryness at large scales, is there something preventing you from scaling everything down?

On another note, assuming you plan on making a large detailed world with thousands of assets, are you wanting to go through the hassle of rotating all of those things every-time your one camera moves?  I can't imagine the head-ache that would also create for keeping track of entity, NPC and such positions.  Is this even a worry for you? 

October 04, 2018 10:41 PM
Septopus
54 minutes ago, Awoken said:

I'm assuming in Unity the physics is based on scale?  I know you're talking about problems with jitteryness at large scales, is there something preventing you from scaling everything down?

I don't think the physics are based on scale, though they might be, so don't quote me. 

However in my search for the last jitter bug the other day I scaled everything down to .5 and moved the planet center to 9000m this resulted in all rendered content being within the 10000m limit.  The jitters went away, I suppose, but (I believe) the lack of floating point precision started expressing itself in the mesh colliders no longer being very sensitive to collisions at all, it was a glorious disaster. ;) 

So I put everything back and discovered my problem was due to the application of acceleration forces while the rigidbody was already grounded.  I'm not sure Unity handles acceleration 100% by the book. heh..  Either way that was solved and I'm still breaking the 10000m barrier by having my planet's center @ 0,-30000,0.  My assumption is that this is working ONLY because the planet center NEVER moves EVER, it only rotates.  And the Parent object that holds it there never changes it's position or orientation either. 

It is my present theory that as long as you aren't constantly changing the LARGE objects position AND your rendered scene is well within the 10000m range, you can break the rule to some degree of magnitude without causing jitters.

54 minutes ago, Awoken said:

On another note, assuming you plan on making a large detailed world with thousands of assets, are you wanting to go through the hassle of rotating all of those things every-time your one camera moves?  I can't imagine the head-ache that would also create for keeping track of entity, NPC and such positions.  Is this even a worry for you? 

This system relies 100% on the parent/child relationships that are described above, the "game world or the player/camera 0,0,0" doesn't begin until you get to the "Planet" object.  That object is the parent of the entire game world's coordinate system.  All items are tracked according to their "localPosition" which is the position relative to the planet's rotation/position.  This means that the game logic (almost)never has to interact with the translated coordinates and that the game engine handles propagating and calculating the positions/rotations of everything except the Planet as part of its core functionality. 

The player, the camera and every instantiated object starts out as a child of "Planet" and then sometimes gets placed further down the tree depending on what/where it is. 

There are certainly limits to what Unity can handle when it comes to child counts(I haven't found out how many children a single parent object can hold) but with long parent/child chains I bumped across a few barriers there during development of the procedural terrain system.  Thankfully I also managed to get that under control by dynamically combining smaller object families into larger ones(fewer parents, more children).  I guess I'll be covering most of this stuff in a blog post about the procedural terrain system so..  That's enough rambling. 

So, short answer?  No, it's not really a worry for me. :D

 

October 05, 2018 12:14 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement