• Register

Absolute Territory is the singleplayer sci-fi space combat action game set in a futuristic setting with space fighters and dogfights. Play in first or third person view. Fly multiple ships and customise their loadouts. Use the in-game level editor to create your own missions. And more! Challenge your piloting skills by creating your own missions. Develop unique scenarios envisioned from your imagination. You decide the difficulty by adjusting the environment and opponents. Fight with the most devastating weapons against lighter opponents or truly test your skills against-all-odds.

Post tutorial Report RSS The player is the centre of the world

Ever wondered how game programmers are able to create large and seemingly endless worlds, yet when you try all your world objects start to shake their booty? Wonder no more.

Posted by on - Basic Client Side Coding

Note: Before I start it must be stated I am using Unity 3D and C# for this tutorial. I expect you to be familiar with the Editor and a fundamental understanding of C#. If you are using another Game Engine or programming language you will need to adapt this code to your situation, which I will not be able to help you with.

Setting the Scene

With that out of the way, first set up your scene. Add in 4 Game Object cubes and position them around. Here I have the player and 3 other game objects representing some awesome object or other set in the game world. They have also been parented to a game object called GameWorld.

Scene1

Moving the Player

Next create a C# script called MoveMe. This will be used to move the player around the game world. Copy and paste the below script over the existing MoveMe.cs code.

MoveMe.cs

using UnityEngine;
using System.Collections;

public class MoveMe : MonoBehaviour {
    Rigidbody rb;
    int velocityDirection;
    Vector3 rotationDirection;


	// Use this for initialization
    void Start () {
        rb = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update() {
        if (Input.GetKeyDown(KeyCode.W)) {
            velocityDirection = 1;
        }
        else if (Input.GetKeyDown(KeyCode.S)) {
            velocityDirection = -1;
        }
        else {
            velocityDirection = 0;
        }

        if (Input.GetKeyDown(KeyCode.D)) {
            rotationDirection.y = 1;
        }
        else if (Input.GetKeyDown(KeyCode.A)) {
            rotationDirection.y = -1;
        }
        else {
            rotationDirection.y = 0;
        }

        if (Input.GetKeyDown(KeyCode.UpArrow)) {
            rotationDirection.x = 1;
        }
        else if (Input.GetKeyDown(KeyCode.DownArrow)) {
            rotationDirection.x = -1;
        }
        else {
            rotationDirection.x = 0;
        }

        if (Input.GetKeyDown(KeyCode.RightArrow)) {
            rotationDirection.z = 1;
        }
        else if (Input.GetKeyDown(KeyCode.LeftArrow)) {
            rotationDirection.z = -1;
        }
        else {
            rotationDirection.z = 0;
        }
    }

    void LateUpdate() {
        if (velocityDirection == 1) rb.AddForce(new Vector3(0, 0, 5), 
ForceMode.Impulse);
        else if (velocityDirection == -1) rb.AddForce(new Vector3(0, 0, -5), 
ForceMode.Impulse);

        if (rotationDirection.y == 1) rb.AddTorque(new Vector3(0, 0.1f, 0), 
ForceMode.Impulse);
        else if (rotationDirection.y == -1) rb.AddTorque(new Vector3(0, -0.1f, 0), 
ForceMode.Impulse);

        if (rotationDirection.x == 1) rb.AddTorque(new Vector3(0.1f, 0, 0), 
ForceMode.Impulse);
        else if (rotationDirection.x == -1) rb.AddTorque(new Vector3(-0.1f, 0, 0), 
ForceMode.Impulse);

        if (rotationDirection.z == 1) rb.AddTorque(new Vector3(0, 0, 0.1f), 
ForceMode.Impulse);
        else if (rotationDirection.z == -1) rb.AddTorque(new Vector3(0, 0, -0.1f), 
ForceMode.Impulse);
    }
}

The first run

There is nothing out of the ordinary with this code. It allows the player to control the GameObject the script is attached to. We can move forward, backwards, left, right and rotate along all three axes.

The player position and rotation is updated in the game world as you would expect.

Attach this script to your player GameObject. Go ahead and run the project to get a feel for how the code works. I’ll be waiting... ;)

You are the centre of the Universe.

Create a new GameObject, this will be used for all our GameManagement. Create a new C# script as shown below. Then attach the script on to the GameManagement.

MoveTheWorld.cs

using UnityEngine;
using System.Collections;

public class MoveTheWorld : MonoBehaviour {
    public GameObject GameWorld; //The GameObject containing all game world objects
    public GameObject CenterOfTheWorldObject; //The player or player controlled object
    private Rigidbody CenterOfTheWorldObjectRigidbody; //Rididbody of the player or player controlled object

	// Use this for initialization
    void Start () {
        CenterOfTheWorldObjectRigidbody = CenterOfTheWorldObject.GetComponent<Rigidbody>();     //Find the rigidbody
    }
	
	// Update is called once per frame
    void Update () {
        //Store the position and keep the object centre of the universe
Vector3 positionChangeFromZero = CenterOfTheWorldObject.transform.position;             CenterOfTheWorldObject.transform.position = new Vector3();

        //Store the rotation velocity and keep the object always facing forward
Vector3 rotationChangeFromZero =
CenterOfTheWorldObjectRigidbody.angularVelocity;
        CenterOfTheWorldObject.transform.eulerAngles = new Vector3();

        //For any GameObjects in the GameWorld update their position relative to the centre objects velocity
        foreach (Transform child in GameWorld.transform) {
            if (child.tag != "Player") {
                child.transform.position -= positionChangeFromZero;
            }
        }

        GameWorld.transform.Rotate(-rotationChangeFromZero);
        CenterOfTheWorldObject.transform.Rotate(rotationChangeFromZero);
    }
}

The second run

Run the program. Move around like your did the first time and noticed the different. Pause and step through the editor and check out the variables. The player position always remains at 0, only it’s rotation changes to mirror the GameWorld rotation. Job done.

A simple explanation

In the update, we store the current player position and angular velocity. Then we zero out the players position and eulerAngle (rotation in degrees).

The foreach goes through every GameObject attached to the GameWorld, the children in other words. For each child found we subtract the position we stored from the player, moving the child object instead of the player object.

We then rotate the GameWorld based on the players’ negated angular velocity and apply the angular rotation back to the player.

Conclusion

The player is truly the centre of the world. This will prevent jittery game objects and the canvas (which happens 1000 metres from Zero, Zero, Zero). You can create vast, seemingly endless words for the player to explore without worrying about on screen objects jumping around the player.

Final note: I haven’t tested this against the Physics engine, that’s on my TODO list. If you try before me, be sure to let me know of the results J

Comments
centaurianmudpig Author
centaurianmudpig

I came back and realised how the player moves may not be what many developers would be doing, myself included, when looking at my game project code.

I made and very simple change which applies Torque to the player game object on it's local axis, rather than the world axis. (I've also included the project file). See this link for more info: Gracegracemedia.wordpress.com

Reply Good karma+2 votes
Post a comment
Sign in or join with:

Only registered members can share their thoughts. So come on! Join the community today (totally free - or sign in with your social account on the right) and join in the conversation.

Follow Report Profile
Icon
Absolute Territory: The Space Combat Simulator
Platforms
Windows
Developer & Publisher
Digitum Software
Engine
Unity
Contact
Send Message
Release date
Game watch
Follow
Tutorial
Browse
Tutorials
Report
Report
Share
Related Games
Related Engines
Unity
Unity Commercial
Related Groups
Digitum Software
Digitum Software Developer & Publisher