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";
}
}
Answer by gashraf · Aug 07, 2018 at 03:17 PM
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:
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
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
Find references to objects only once in Start(), and not every frame in Update()
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 :)
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!
O$$anonymous$$G! That's exactly what I needed! Thanks a lot @gashraf,, it's perfect! I do not have enough words to thank you. Thanks also for the tips, it will help me a lot to program better. I'm sorry for being still noob, I'm more from artistic area and recently started to venture into program$$anonymous$$g. Surely, as soon as the game is ready you will be the first to know;). I wanted to know if I have your permission to add your name to game credits as a contributor.
You are most welcome jupt001! I am glad this solution works for you. Please feel free to add my name :) Good luck!
Answer by gashraf · Aug 01, 2018 at 08:22 PM
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 gashraf, thank you very much for the answer. It almost worked, but my scrolling world is different from that one you mentioned.
I have a quad with a scrolling script using $$anonymous$$eshRenderer and $$anonymous$$aterial to give the illusion of flight.
On the screen I have a box collider which limits the y position of the player, so he does not fully reach the top of the screen, and this box collider is a little above the half of the screen. That's why I used Time.deltaTime, because I need that the meters keep counting even if the player collides with the box collider, and I initially had discarded the startPos also because of this reason.
Any idea of how can I implement a script that works under these conditions?
Answer by gashraf · Aug 03, 2018 at 08:07 PM
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);
}
Hello gashraf, sorry for the delay in answering. Unfortunately it did not fit with what I need. I modified your previous script and got an awesome result, but I'm having another problem now. The velocity of meters degrease is too high and I don't know how could I control it. 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.
Answer by jupt001 · Aug 05, 2018 at 06:24 PM
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);
}
It is quite hard for me to visualize the way you have set up your mechanics. What is TouchControls.start$$anonymous$$eters doing? Is multiplier achieving acceleration over a period of forward motion? To what object is this script attached? $$anonymous$$ainly, I am not being able to understand how multiplying a time-accumulated value to the player's current position is going to give an accurate result.
It will be good if you can share a link to a simplified outline/setup of your unity project as a .unitypackage to allow me to give you a solution that will work :)
http://bit.ly/2v$$anonymous$$eaLp
Here is a placeholder example of this. I need the distance traveled to be counted according to the time because the goal is to count how many meters he has flown during the game.
Thanks a lot for trying to help me, sorry if it has become complicated. TouchControls is a script with "touch buttons" to activate the spaceship's movement. And start$$anonymous$$eters is a variable that allows the counting of meters only when the flight button is pressed
Your answer
Follow this Question
Related Questions
Why my counting method is stucked on the beginning? 1 Answer
Problem with counting front flips 1 Answer
Fade Material's Transparency Based on Distance 3 Answers
Scaling Crosshair 0 Answers
Missing GameObject, help!! 0 Answers