Search Unity

Question setting player set distance to object

Discussion in 'Scripting' started by Extra_, May 22, 2023.

  1. Extra_

    Extra_

    Joined:
    Nov 26, 2022
    Posts:
    13
    Hello, I'm making a game and I want to make it so when the player collide with a planet, he start to orbit it and get to a fixed distance from it, I have been stuck for a few days and I have no idea where to begin. help pls?

    Code (CSharp):
    1. public class Movement : MonoBehaviour
    2. {
    3.     [SerializeField] private GameObject lastBestPlanet;
    4.     [SerializeField] private GameObject closestPlanet;
    5.     [SerializeField] private GameObject[] Planets;
    6.     [SerializeField] private float rotatingSpeed = 135f;
    7.     [SerializeField] private float flyingSpeed = 135f;
    8.     [SerializeField] private float minDistance = 6.3f;
    9.     [SerializeField] private Rigidbody2D rb2d;
    10.     [SerializeField] private Vector3 direction;
    11.     [SerializeField] private bool toFreeze = false;
    12.  
    13.     void Start() {
    14.         rb2d = gameObject.GetComponent<Rigidbody2D>();
    15.     }
    16.     void Update()
    17.     {
    18.         getClosestPlanet(getPlanets());
    19.         Rotate();
    20.         if(Input.GetKeyDown(KeyCode.Space)) {
    21.             Jump();
    22.         }
    23.         if(Input.GetKeyDown(KeyCode.Tab)) {
    24.             Debug.Log(getClosestPlanet(getPlanets()));
    25.             toFreeze = true;
    26.         }
    27.     }
    28.  
    29.     void Jump() {
    30.         closestPlanet = getClosestPlanet(getPlanets());
    31.         if (closestPlanet != null) {
    32.             direction = closestPlanet.transform.position - transform.position;
    33.         }
    34.         rb2d.velocity = -1 * (direction.normalized * flyingSpeed * Time.deltaTime);
    35.     }
    36.  
    37.     void Rotate() {
    38.             getPlanets();
    39.             closestPlanet = getClosestPlanet(Planets);
    40.             if (closestPlanet != null) {
    41.                 transform.RotateAround(closestPlanet.transform.position, Vector3.forward, -1 * 1 * rotatingSpeed * Time.deltaTime);
    42.         }
    43.     }
    44.  
    45.     GameObject[] getPlanets() {
    46.         Planets = GameObject.FindGameObjectsWithTag("Planet");
    47.         return Planets;
    48.     }
    49.  
    50.     void snapToNewPlanet() {
    51.         //closestPlanet = getClosestPlanet(getPlanets());
    52.         Debug.Log("Snapped to a new Planet! :D");
    53.         return;
    54.     }
    55.  
    56.     GameObject getClosestPlanet (GameObject[] PlanetsArray)
    57.     {
    58.         GameObject bestPlanet = null;
    59.         float closestDistanceSqr = Mathf.Infinity;
    60.         Vector3 playerPosition = transform.position;
    61.         foreach(GameObject Planet in PlanetsArray)
    62.         {
    63.             Vector3 directionToTarget = Planet.transform.position - playerPosition;
    64.             float dSqrToTarget = directionToTarget.sqrMagnitude;
    65.             //Debug.Log(dSqrToTarget);
    66.             if(dSqrToTarget < closestDistanceSqr)
    67.             {
    68.                 closestDistanceSqr = dSqrToTarget;
    69.                 if (closestDistanceSqr <= minDistance) {
    70.  
    71.                     bestPlanet = Planet;
    72.                     if (bestPlanet != null && lastBestPlanet != bestPlanet) {
    73.                         snapToNewPlanet();
    74.                     }
    75.                     lastBestPlanet = Planet;
    76.                    
    77.                 }
    78.             }
    79.         }
    80.         if (bestPlanet == null && toFreeze) {
    81.             Time.timeScale = 0;
    82.             Debug.Log(closestDistanceSqr);
    83.         }
    84.    
    85.         return bestPlanet;
    86.     }
    87. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    Actual orbital dynamics is hard. You would need a solver to predict course and accelerate / decelerate to enter orbit.

    On the other hand if you just want to transition to an orbit instantly, that's easy:

    Upon collision with the desired orbital height, parent the orbiting object to an invisible object colocated at the planet, then rotate that object.
     
  3. Extra_

    Extra_

    Joined:
    Nov 26, 2022
    Posts:
    13
    The object don't collide, he stops around 2m from the planets. also, I want to make it so if he comes from the right down he will start orbiting from the right down. any ideas?
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    I get that. I'm saying make a DIFFERENT collider that is 2m larger than the planet, separated with layers so it collides with nothing else but the inbound to-be-orbited device, then connect it (parenting) and start spinning the inner thing.

    So your planet prefab might look like:

    MyPlanetPrefab
    VisiblePlanet
    SphericalGraphic
    CircleCollider2D for surface
    invisibleOrbitController <--- what slowly spins around at all times
    Invisible orbital Collider <---- what the inbound guy hits and gets parented to