0
\$\begingroup\$

Here's a script:

public float RotationSpeed = 100f;
public float OrbitSpeed = 50f;
public float DesiredMoonDistance;
public Transform target;

public Vector3 axis = Vector3.forward;

void Update () {
    transform.Rotate(Vector3.forward, RotationSpeed * Time.deltaTime);
    transform.RotateAround(target.position, Vector3.forward, OrbitSpeed * Time.deltaTime);

    float currentMoonDistance = Vector3.Distance(target.position, transform.position);
    Vector3 towardsTarget = transform.position - target.position;

    transform.position = transform.position + (DesiredMoonDistance - currentMoonDistance) * towardsTarget.normalized;
}

which makes a continous rotation at DesiredMoonDistance on a Z axis:

enter image description here

The problem with this script is that the rotating object needs a 'tilt' at the start.

If both the objects (the planet and the moon) have the same initial position, the rotation won't start, no matter how big the distance is set, because of this:

Vector3 towardsTarget = transform.position - target.position;
transform.position = transform.position + (DesiredMoonDistance - currentMoonDistance) * towardsTarget.normalized;

towardsTarget becomes (0,0,0) and there's no escape from that black hole.

I'm trying to figure out, how to adjust the script with some if's for a situation, when their position is equal, so I don't have to make stupid moves like moon.transform.translate(.0001f,0f,0f) so it tilt's at the start.

My real goal is to adjust this, so even if I change the DesiredMoonDistance to 0 in the inspector and then increase it, it will unstuck and go to the desired distance.

\$\endgroup\$
1
\$\begingroup\$

If you want to make minimal changes, a simple if statement will do:

void Update () {
  transform.Rotate(Vector3.forward, RotationSpeed * Time.deltaTime);
  transform.RotateAround(target.position, Vector3.forward, OrbitSpeed * Time.deltaTime);

  float currentMoonDistance = Vector3.Distance(target.position, transform.position);
  Vector3 towardsTarget = transform.position - target.position;

  if (currentMoonDistance == 0)
    transform.position += Vector3.right * DesiredMoonDistance;
  else
    transform.position = transform.position + (DesiredMoonDistance - currentMoonDistance) * towardsTarget.normalized;
}

But another solution might be to track revolution in a variable separately, and just apply each frame:

private float OrbitPhase;
void Update () {
    transform.Rotate(Vector3.forward, RotationSpeed * Time.deltaTime);

    OrbitPhase += OrbitSpeed * Time.deltaTime;
    transform.position = target.position + Quaternion.Euler(0, 0, OrbitPhase) * Vector3.up * DesiredMoonDistance;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.