- Home /
Infinity run around something
Hello! I'm trying to implement a something similar to this https://bitbotzgames.itch.io/spacerunner but I stuck with needing of player to run around the planet then jump and get magnitized to other planet. So could you help me by tell how to make player run around planet and magnitize player to it?
Answer by jackmw94 · Jan 19, 2021 at 12:37 PM
It seems as though the player exists in one of two forms of physics / gravity. They will either be inside a planets gravitational zone in which the downwards gravity will be in the vector between the planet centre and the player. Or they will be in empty space where they keep moving in the direction in which they started.
A very important little utility function you'll need for this project is a rotation function for 2d vectors:
// thanks to https://answers.unity.com/questions/1229302/rotate-a-vector2-around-the-z-axis-on-a-mathematic.html
Vector2 Rotate(Vector2 aPoint, float aDegree)
{
float rad = aDegree * Mathf.Deg2Rad;
float s = Mathf.Sin(a);
float c = Mathf.Cos(a);
return new Vector2(
aPoint.x * c - aPoint.y * s,
aPoint.y * c + aPoint.x * s;
);
}
I'd start by getting the planet physics working; have the player run around a given point at a given radius, have jumping work when gravity is towards the planet centre rather than in the global downwards direction. If I were you I would handle the planet running using angles rather than offsets (as you might in usual platformers): when you know the planet's radius, you can find its circumference and then you can find how long it should take the player to move around it and finally from that you can calculate how much angular change they require each time step.
private void MovePlayer(float speed, float planetRadius, Vector2 planetCentre)
{
// speed is in meters per second, say it's 0.5 here
// if the radius of the planet is 10 meters
// then the circumference is PI * diameter = 3.14 * 20 = 62.8
float circumference = Mathf.PI * planetRadius * 2f;
// if the player moves at 0.5 meters per second:
// then the time to orbit the planet will be t = distance / speed
// time = 62.8 / 0.5 = 125.6
float orbitTime = circumference / speed;
// so the angle change each second will be s = 360 / 125.6 = 2.86 degrees
float deltaAngle = 360f / orbitTime;
// need to know planet centre, radius and player's current angle around planet to determine new position
playerAngle += deltaAngle;
transform.position = planetCentre + Rotate(Vector2.up, playerAngle) * planetRadius;
// playerAngle changes in this function so is not passed in as an argument, you can make it a ref argument if you like
}
Then look at hopping between planets; if the player exceeds a planet's gravity zone then they switch to open space physics, if they enter a new planets gravity zone then they'll start falling towards that one.
Finally you can add the obstacles, the hazards shouldn't be too hard; if the player hits them they die. The ones that stop running are a little more interesting.
Thank you very much for replaying and for the work you've done here. I surely will dive into that and try to implement this script in the way I want. Thanks again.
How are you getting on @akilaydin2 ? If you're stuck on anything this still then follow up this comment! If you've solved it and it was due to either my or Llama_w_2Ls's answer, then would you $$anonymous$$d accepting one? Thanks!
Oh, I'm sorry, I dived into work and totally forgot to click the accept button. Your answer is more convenient, so I've accepted it, but the other one is also good and still I pray for you and for the work you're doing on this forum. Thank you.
Answer by Llama_w_2Ls · Jan 19, 2021 at 12:08 PM
After playing the game for about 4 hours, I finally understand how it works!
The main thing you need to do is to rotate the player so that its feet point towards the center of the planet. Then, you can add a force downwards on the player so that it creates some sort of magnetic pull, towards the planet. Pretty nice!
Here's my script:
[RequireComponent(typeof(Rigidbody2D))]
public class PhysicsController : MonoBehaviour
{
Rigidbody2D rb;
Vector2 PlanetCenter;
public Transform Planet;
public float Gravity;
public float MovementSpeed;
public float JumpForce;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
// Gravity
rb.AddForce(transform.up * Gravity);
// Movement
rb.AddForce(-transform.right * MovementSpeed);
if (Input.GetKeyDown(KeyCode.Space))
rb.AddForce(-transform.up * JumpForce);
#region Calculate angle
Vector2 Direction = new Vector2
(
PlanetCenter.x - transform.position.x,
PlanetCenter.y - transform.position.y
);
// Fancy maths stuff:
// https://onlinemschool.com/math/library/vector/angl/#:~:text=The%20cosine%20of%20the%20angle,the%20product%20of%20vector%20magnitude.
// Cosine of look angle = Dot product of vectors / Mulitplication of vector magnitudes
float DotProduct = Vector2.Dot(Vector2.up, Direction);
float MagnitudeUp = Vector2.Distance(Vector2.zero, Vector2.up);
float MagnitudeVelocity = Vector2.Distance(Vector2.zero, Direction);
float CombinedMagnitude = MagnitudeUp * MagnitudeVelocity;
float CosineOfAngle = DotProduct / CombinedMagnitude;
float Angle = Mathf.Acos(CosineOfAngle) * Mathf.Rad2Deg;
#endregion
#region Rotate player
if (transform.position.x < PlanetCenter.x)
transform.rotation = Quaternion.Euler(0, 0, 360 - Angle);
else
transform.rotation = Quaternion.Euler(0, 0, Angle);
#endregion
}
private void OnCollisionEnter2D(Collision2D collision)
{
Planet = collision.collider.gameObject.transform;
PlanetCenter = Planet.position;
}
}
This is the player script. A big chunk of it is some fancy math stuff. Some other things you might want to know is that the planet I have is just a circle collider 2D, with a frictionless physics2D material. The player's rigidbody2D also has a gravity scale of 0, as I want to manually create my own gravity. Finally, the rigidbody's z rotation is locked in the constraints menu of the rigidbody 2D component. Have fun messing around with the movement speed etc. @akilaydin2
Thank you very much for replaying and for the work you've done here. I surely will dive into that and try to implement this script in the way I want. Thanks again.
Your answer
![](https://koobas.hobune.stream/wayback/20220613023554im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
How to prevent my Gravity gun from picking up nothing 2 Answers
How to make player not fall during dash 1 Answer
Applying gravity to simple zombie AI 1 Answer