# Player to enemy orbits

Hi All,

I’ve been stuck on trying to get a Player ship to orbit around a moving enemy ship (and vice versa).

The easiest way to visualize what I’m trying to achieve is exactly the same way EVE Online approaches a target, and then slowly rotates around a given radius.

It’s figuring out the math that I’ve proven to myself I’m just hopeless at.

I did find some really good info, I found this Reddit - Dive into anything which is an absolute gem, it does exactly what I want with one little problem…it will always rotate around the central world origin. The people in the thread didn’t seem to have this issue.

Unfortunately no amount of tinkering and learning Linear Algebra over the past month has helped me and I’m in a slump here. I know that using RotateAround will not solve my problem, as if the target moves, the ship just moves with it with no real re-orientation happening to re-circularize (almost as if its parented which its not).

I don’t expect any direct answers, but even some advice or mathmatical formulas i can look at which can help me achieve my desired goal, and hey if you post code that’s awesome too!

Code I’m currently using

``````RequireComponent(typeof(Rigidbody))]
public class Orbit : MonoBehaviour
{
public enum OrbitalDirections
{
}

public GameObject OrbitTarget = null;
public GameObject Marker = null;
private Rigidbody rigidBody;

private float Azimuth = 0.0f;
private float Zenith = 0.0f;

public float TurnRate = 0.25f;
public float Velocity = 2.0f;

// Use this for initialization
void Start()
{
if (OrbitTarget == null)
Debug.LogException(new System.Exception(this.name + ": Target Not Set"));
rigidBody = GetComponent<Rigidbody>();

}

// Update is called once per frame
void Update()
{
Azimuth = Mathf.Atan2(transform.position.z, transform.position.x);

Azimuth += (Mathf.PI / 2.0f);
else
Azimuth -= (Mathf.PI / 2.0f);

Zenith = Mathf.Acos(transform.position.y / Vector3.Distance(transform.position, Vector3.zero));

Vector3 markerPosition = Vector3.zero;  // tried changing this to OrbitTarget.transform.position with no joy
markerPosition.x = Radius * Mathf.Cos(Azimuth) * Mathf.Sin(Zenith); // also tried *= with no joy
markerPosition.z = Radius * Mathf.Sin(Azimuth) * Mathf.Sin(Zenith);

if (Marker != null)
Marker.transform.position = markerPosition;

transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(-1 * (transform.position - markerPosition).normalized), Time.deltaTime * TurnRate);
rigidBody.velocity = transform.forward * Velocity;
}
}
``````

Edited: Clarified a bit more on what i’ve tried.

While learning linear Algebra will give you a significant leg up in most methematical Problems in unity, you might get by without it. There’s a neat Little trick you can do:
When you want to enter ‘orbit’ mode, create a ‘master’ game object at the position of the ship you want to Orbit, and a second ‘child’ object at the position of your ship.
Parent the Child that represents your ship to the first one (master). Now all you need to do is make the master follow the enemy ship (you could just parent it to the enemy), and rotate locally the master game object. This will cause the child to Orbit the master at the distance at the time you parented it.
Make you ship follow the position of the second (child) game object, orbiting the enemy. You can even have your ship align correctly by copying the Rotation values (make sure to initially copy your ship’s totation when you create the child object)

2 Likes

Thank you I appreciate it, I’ll give this a go and come back with the results if it is my answer.

Thank you very much the solution works perfectly for my needs, here is what i ended up going with.

``````using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OrbitTest : MonoBehaviour
{
public GameObject PrimaryTarget;    // hard coded via inspector for testing
public GameObject ChaseTarget;      // hard coded via inspector for testing
public float Velocity = 5f;
public float RevolutionSpeed = 20f;

private Vector3 Direction;

private void Start()
{
if(PrimaryTarget==null)
Debug.LogException(new System.Exception(this.name + ": Primary Target Not Set"));

ChaseTarget.transform.SetParent(PrimaryTarget.transform);           // Set the target we will chase (orbit) to be parented to the Primary Target
ChaseTarget.transform.rotation = PrimaryTarget.transform.rotation;  // Ensure rotation matches to prevent errors
}

private void Update()
{
Vector3 Direction = (gameObject.transform.position - ChaseTarget.transform.position).normalized;    // Get direction from us to the chase target

// As long as we are within Radius - Excecute orbital mode
{
ChaseTarget.transform.position = (ChaseTarget.transform.position - PrimaryTarget.transform.position).normalized * Radius + PrimaryTarget.transform.position;    // Some maths (probably don't need this anymore)
ChaseTarget.transform.RotateAround(PrimaryTarget.transform.position, Vector3.up, RevolutionSpeed * Time.deltaTime);     // Rotate around the Primary target, chase target is primarilly for direction facing purposes now
}