Calculate UP Distance Displacement for 3D Infinity Runner Game

Hi guys, I’m a little noob with programming and need some help with an issue.

I’m doing an infinity runner 3D space shooter where my character only moves on the Y Up axis and can rotate his spaceship 360 degrees to move left and right like a rocket.

I made a distance script counter where it shows the distance that the player traveled flying upwards when he press the fly button, but I need some help with only counts the distance if he is “going up” , because the script still counts the distance even if the ship is flying down or is flying sideways.

So the question is: how to write for the distance counter script only counts meters if the spaceship is flying up?

Here is my script

public class distanceCounter : MonoBehaviour {

Text mtTxt;

[SerializeField]
private float distance;

[SerializeField]
private GameObject player;

[SerializeField]
private float curPos;

void Start () 
{
	
	mtTxt = GetComponent<Text> ();

	curPos = player.transform.position.y;
}

void Update () 
{

	if (TouchControls.startMeters == true) 
	{

		distance += Time.deltaTime * curPos;

	}


	mtTxt.text = "Meters:  " + distance + " m";

}

}

Hi,
I am assuming that curPos is capturing the position of the player (ship) at the start of the game. So what you need is a sense of how much the player has flown up. I am not sure how you implement your infinite scrolling world, so I am assuming that when your spaceship goes “up”, your camera also goes “up” with it and new content keeps getting generated (higher and higher from ground level). If that is the case, then you should be calculating the distance as follows:

private float startPos, curPos;
 void Start () 
 {
     
     mtTxt = GetComponent<Text> ();
     startPos = player.transform.position.y;
     distance = 0f;
 }

void Update () 
 {
     if (TouchControls.startMeters == true) 
     {
         curPos = player.transform.position.y;
         distance = Mathf.Max(0f, curPos - startPos);
     }
 
     mtTxt.text = "Meters:  " + distance + " m";
 }

Hi jupt001,

A simple solution then would be to add distance only if your player is pressing the forward or the up key; i.e. he is progressing further. You would then conditionally add distance as a notion of time he spends clicking the up button, and likewise deducting distance when he clicks the down button.

So lets assume you have an Update function in the Player’s rocket script which is as follows:

public float rocketSpeed = 10f;
private float distanceSoFar = 0f;

void Update()
{
       float move = Input.GetAxis("Vertical");

       if(move != 0) 
                distanceSoFar += rocketSpeed*Time.deltaTime*Mathf.sign(move);
}

This is the closest to what I need. I just need help to figure out how to control the velocity of meters degrease when the player stop pressing the fly button and start falling.

Example: When player reaches 100 meters and stop pressing “fly btn” he starts to fall and the meters counter decreases but it does so fast like -70 meters and I want that it decreases just -20 meters from the player’s last position and not -70 meters like it is happening.

	private float multiplier;

	private int distance;

	private GameObject player;

	private float curPos;


void Update () 
	{

		    curPos = player.transform.position.y;
			multiplier += Time.deltaTime * 0.06f;

			if (TouchControls.startMeters == true) 
			{
			
			distance = (int)Mathf.Max(0f, curPos * multiplier);

			}

Dear @jupt001,

Thank you for sending across the setup. It helped me wrap my head around to what you actually wanted to achieve, and how to do it. Pls find the updated package with new code here

The main logic for the movement is placed now in BGScroller script which is also responsible for scrolling the canvas. The dot product helps to project the local up vector of the rocket to the global Y axis to get a sense of whether it is headed up or down. The distance update is done only when fly button is pressed. I also added a test update function in TouchControls for testing with arrows on PC. Pls. turn the testingForNonTouchDevices variable to false before testing on your touch device.

I took the liberty of cleaning up your code and putting in lots of comments to help you write better code for future projects. A summary of some of these ideas are:

  1. Keep GUI scripts simple… only related to GUI and not some calculation involving some other scene objects. Do those calculations in scripts attached to the scene objects themselves, and then pass on a reference to the script or object concerned to the GUI script
  2. Avoid use of static variables to pass on information from one class to another. Use them only if these variables are going to be shared across all instances of the script, or if there is only ONE instance, example a single Player
  3. Find references to objects only once in Start(), and not every frame in Update()
  4. See how I am getting a handle to a script from another script (via an object reference, which can be input manually or automatically found by tag), and then accessing public variables of this script

Okay, I know this is a lot to take in, and Rome was definitely not built in one day :slight_smile:

I hope this helps you create a super awesome game, and I look forward to you sharing it with me once you finish it! Good luck buddy!