# How to increase points per second when speed increases

I am making an endless rider game that is crossed between tron legacy and cube field. I am trying to add a point system were the faster you go the more points you get because you are more likely to die so high risk high reward. I am really stuck on this however. This is my current script which is already connected to a point ui system that works. I am also probably going to post a question later about how to make speed correlate with emission/light intensity.

 public static int movespeed = 1;
public Vector3 userDirection = Vector3.right;

// Update is called once per frame
void Update()
{
transform.Translate(Input.GetAxis("Horizontal") * Time.deltaTime * 50, 0f, Input.GetAxis("Vertical") * Time.deltaTime * 70, 0f);
transform.Translate(userDirection * movespeed * Time.deltaTime * 40);
scorecript.scoreValue += 10;

if (Time.deltaTime > 10)
{
scorecript.scoreValue += 10;

}
if (Time.deltaTime > 11)
{
scorecript.scoreValue += 11;

}

}
This is how I translated MDgrgory's code:

[Tooltip("How fast the character should move with no input, in world units per second")]
public float autoMoveSpeed = 40.0f;
[Tooltip("The direction the character should move with no input")]
public Vector3 autoMoveDirection = Vector3.right;
// Enforce that this is always a unit direction vector, so it doesn't bias our speed.
void OnValidate() { autoMoveDirection = autoMoveDirection.normalized; }

[Tooltip("How much the player can affect the speed in the direction of auto movement")]
public float parallelMoveSpeed = 50f;
[Tooltip("How fast the player can affect the speed perpendicular to the auto movement")]
public float perpendicularMoveSpeed = 70f;

[Tooltip("How many points to earn per second with no input")]
public float scorePerSecondAtDefaultSpeed = 10f;
[Tooltip("How many extra points to earn per second for every extra unit of speed")]
public float extraScorePerVelocityUnit = 1.0f;

// Track how much "loose change" points we've accumulated.
float _scoreAccumulator = 0f;

void Update()
{
// Capture the player's input vector.
Vector3 input = new Vector3(
Input.GetAxis("Horizontal"),
0,
Input.GetAxis("Vertical")
);

// Clamp the input to make sure we don't move faster on diagonals.
input = Vector3.ClampMagnitude(input, 1.0f);

// Extract the portion of the player's input parallel to the auto movement.
float parallelComponent = Vector3.Dot(autoMoveDirection, input);

// Leaving the component perpendicular to the auto movement.
Vector3 perpendicularComponent = (input - parallelComponent * autoMoveDirection);

// Compute how much to increase or decrease our auto movement based on our input.
float extraVelocity = parallelComponent * parallelMoveSpeed;

// Compute our net velocity, combining auto, parallel, and perpendicular movement.
Vector3 velocity = autoMoveDirection * (autoMoveSpeed + extraVelocity)
+ perpendicularComponent * perpendicularMoveSpeed;

// Translate us according to that velocity and the elapsed time.
transform.Translate(velocity * Time.deltaTime, Space.Self);

// Scoring:
// Compute our increased (or reduced) scoring rate based on our forward velocity.
float extraScore = extraVelocity * extraScorePerVelocityUnit;

// Increase our score accumulator based on our current earning rate and time passed.
_scoreAccumulator += (scorePerSecondAtDefaultSpeed + extraScore) * Time.deltaTime;

// Whenever we earn a whole point, send it to the score display as an integer.
int scoreUnits = Mathf.FloorToInt(_scoreAccumulator);
scoreScript.scoreValue += scoreUnits;
// And decrement our accumulator to store just the "spare change".
_scoreAccumulator -= scoreUnits;
}

• I can see from this code that there are some big holes in your understanding of how Unity and C# programming work. I'd strongly recommend working your way through some more introductory Unity/C# tutorials so you can get a grasp of the basics. While answers here can spot-fix one problem at a time, that's not going to be an efficient way to build your understanding or make progress toward a complete game. You'll get a lot more benefit from programming questions on this site if you practice to the point where you can clearly express your intention in code. May 7, 2020 at 12:48

From the code, it looks like...

• You want to move the character forward in some arbitrary direction at a particular speed, automatically, even when the player isn't providing input.

• You want the player to be able to speed up or slow down in that direction by holding toward / away from the direction of movement.

• You want the player to be able to move perpendicular to the direction of automatic movement, potentially at a different speed than they move along the direction of automatic movement.

• You want to give the player more points when they speed up along the automatic movement direction, or fewer points when they slow down in that direction.

• Movement perpendicular to the automatic movement shouldn't affect scoring (so you don't get more points for zig-zagging when there are no obstacles to dodge).

If this is accurate, here's an example of a script that will let you reach these goals, with clear control over each aspect. I've broken it into small steps and commented each line to explain how each part works:

[Tooltip("How fast the character should move with no input, in world units per second")]
public float autoMoveSpeed = 40.0f;
[Tooltip("The direction the character should move with no input")]
public Vector3 autoMoveDirection = Vector3.right;
// Enforce that this is always a unit direction vector, so it doesn't bias our speed.
void OnValidate() { autoMoveDirection = autoMoveDirection.normalized; }

[Tooltip("How much the player can affect the speed in the direction of auto movement")]
public float parallelMoveSpeed = 50f;
[Tooltip("How fast the player can affect the speed perpendicular to the auto movement")]
public float perpendicularMoveSpeed = 70f;

[Tooltip("How many points to earn per second with no input")]
public float scorePerSecondAtDefaultSpeed = 10f;
[Tooltip("How many extra points to earn per second for every extra unit of speed")]
public float extraScorePerVelocityUnit = 1.0f;

// Track how much "loose change" points we've accumulated.
float _scoreAccumulator = 0f;

void Update()
{
// Capture the player's input vector.
Vector3 input = new Vector3(
Input.GetAxis("Horizontal"),
0,
Input.GetAxis("Vertical")
);

// Clamp the input to make sure we don't move faster on diagonals.
input = Vector3.ClampMagnitude(input, 1.0f);

// Extract the portion of the player's input parallel to the auto movement.
float parallelComponent = Vector3.Dot(autoMoveDirection, input);

// Leaving the component perpendicular to the auto movement.
Vector3 perpendicularComponent = (input - parallelComponent * autoMoveDirection);

// Compute how much to increase or decrease our auto movement based on our input.
float extraVelocity = parallelComponent * parallelMoveSpeed;

// Compute our net velocity, combining auto, parallel, and perpendicular movement.
Vector3 velocity = autoMoveDirection * (autoMoveSpeed + extraVelocity)
+ perpendicularComponent * perpendicularMoveSpeed;

// Translate us according to that velocity and the elapsed time.
transform.Translate(velocity * Time.deltaTime, Space.World);

// Scoring:
// Compute our increased (or reduced) scoring rate based on our forward velocity.
float extraScore = extraVelocity * extraScorePerVelocityUnit;

// Increase our score accumulator based on our current earning rate and time passed.
_scoreAccumulator += (scorePerSecondAtDefaultSpeed + extraScore) * Time.deltaTime;

// Whenever we earn a whole point, send it to the score display as an integer.
int scoreUnits = Mathf.FloorToInt(_scoreAccumulator);
scoreScript.scoreValue += scoreUnits;
// And decrement our accumulator to store just the "spare change".
_scoreAccumulator -= scoreUnits;
}

• Thanks for your reply.I appreciate it alot. The script has the correct speed input score system however it moves right automatically instead of forward and when I press the "d" key it goes even faster and earns more points. I have tried to make it go forward however I dont know how. I changed the auto move direction vector3 from right to forward but it still goes right. I switched the horizontal and vertical axises in the script and also changed the horizontal and vertical inputs in the preferences tab but it keeps going right. How can I make it go forward and earn points by goin fast forward? May 8, 2020 at 3:26
• Sounds like you've rotated your view (you didn't show us how you'd set up your scene, so we're forced to just guess). Try Space.Self instead of Space.World May 8, 2020 at 3:38
• Changing it doesnt fix it. It still goes to the right... May 8, 2020 at 5:38
• Looks like you'll want to add the information I mentioned to your question so we're not guessing blind then. May 8, 2020 at 10:55
• Yes. I am not good at C# at all, however I have been able to make a character move and I know how to find the space.World by using the hotkey ctrl + f. So please dont blame the fact that the code keeps going right it on me. I am also much better in other programming languages such as java and since it it is apparently similar to c# I was thinking if giving it a go. Also C++ and html. I am new to the unity engine however and I will link my interpretation of your code in my main question so you can see what is wrong. May 8, 2020 at 23:14

One way to do it, is that you set the userDirection Vector to be the direction of the input added by your forced right going vector. Then the movement speed is the magnitude and after getting that tou normalizing the userDirection. Something like:

userDirection = new Vector3(Input.getAxis("Horisontal"), 0, Input.getAxis("Vertical")) + Vector3.right;
moveSpeed = userDirection.magnitude;
userDirection.Normalize();


You could add a minimum of force to the right no matter the user input by adding

if(userDirection.x < 0.1) userDirection.x = 0.1;


transform.Translate(userDirection * movespeed * Time.deltatime)



Finally you can add points according to some formula depending on speed like:

scorescript.scoreValue += 10*movespeed.


Note: you would probably want to make your movement physics based, by working with Rigidbody (or Rigidbody2D) and as minimum set velocity instead of translating directly on your transform.

• From the code, it looks to me like userDirection is meant to be the forced movement component of the endless runner, separate from the player's ability to move faster or slower relative to that baseline through their own input. I'd recommend preserving that behaviour unless the question asks to change it. May 7, 2020 at 12:49
• Arh yes, good catch. I Will add that May 7, 2020 at 12:52
• I will put up how I took in the code on the main question. However when I try to make it work there is one error saying "(12,35): error CS0428: Cannot convert method group 'Magnitude' to non-delegate type 'int'. Did you intend to invoke the method?" May 7, 2020 at 22:43
• It is just a small m in magnitude May 8, 2020 at 9:43