Rotate object around moving object

Hello,
I have some spinning cubes I want to follow the player by orbiting around it. I had it working nicely, when the player was too far they would move into range then rotate around the player. The problem is when they are orbiting, and the player moved, they would just follow normally until they were within range again. I tried to fix this with the following script but it tells me I can’t modify the rotate directly so I should store it in a temporary variable. I’m sorry it looks awful I have bastardized it trying to get rid of this error.

void Orbit()
    {
		currentRot += speed * Time.deltaTime;
		Vector3 tempVec = new Vector3(0, currentRot, 0);
		rotate.eulerAngles = tempVec;
		transform.rotation.eulerAngles = tempVec;
		transform.position = rotate * radius + target.position;
    }

If someone could kindly help I would be very appreciative.

Kindest regards!

I'm having trouble understanding what you want. Are they supposed to move in a perfect circle around the player no matter how fast the player is moving? What do you mean by "out of range"?

Exactly that. They need to move in a perfect circle around the player regardless of what the player is doing, I don't care about clipping with other object or other cubes orbiting the player. As for the range, when they get 2 meters from the player's center they begin orbiting, if they are further than 2 meters they close the distance to 2 meters.

Why would they ever be more than one radius away from the player if they're rotating in a perfect circle relative to the player?

2 Answers

2

Try this to orbit a moving target. I didn’t know what type of orbit you were wanting, so I assume you wanted to orbit around the target’s Y (UP) axis.

using UnityEngine;
using System.Collections;

public class OrbitPlayer : MonoBehaviour {

	public Transform target;
	public float orbitDistance = 10.0f;
	public float orbitDegreesPerSec = 180.0f;
	
		// Use this for initialization
	void Start () {
	
	}
	
	void Orbit()
	{
		if(target != null)
		{
			// Keep us at orbitDistance from target
			transform.position = target.position + (transform.position - target.position).normalized * orbitDistance;
			transform.RotateAround(target.position, Vector3.up, orbitDegreesPerSec * Time.deltaTime);
		}
	}
	
	// Update is called once per frame
	void Update () {
		
		// Call from LateUpdate instead...
            // Orbit();
	
	}

    // Call from LateUpdate if you want to be sure your
    // target is done with it's move.
	void LateUpdate () {
		
		Orbit();
	
	}
}

Actually, might be best to call Orbit() from LateUpdate, after your target as done it's move.

Looks promising, I'll give it a go and let you know the results. But one question, what does the ".normalized" do? :EDIT: Unfortunately they still move to my position and start orbiting, but if I move the player they fall out of range and start moving to the player again instead of staying in range and orbiting regardless of speed.

How fast is your player moving? This method does have a flaw if the player is moving relatively fast compared to the orbit speed... but there are tricks to fix that. .normalized returns a normalized version of a Vector3 (magnitude of 1).

The script above only addresses the issue of orbiting a moving target (your original question), regardless of how fast the target is moving - which it should accomplish. It sounded like you already had worked out how to get within orbit range. But yes, you could use a flag to specify if you are within orbit range and, if so, turn on the orbit behavior - not sure why that wouldn't work. There are probably many ways to handle the transition to "catch up" to the target and then start orbiting. It depends on how you want to accomplish that (within a given time, speed, etc.?).

Also editing a comment means it takes it out of the stack so it then makes a big mess and has them unordered. That comment is for your previous post.

I know this is an older topic but since i used this script myself, i thought i’d add to it
to make it so that you can set the distance of the orbit.

using UnityEngine;
using System.Collections;

public class RotateAroundPlayer : MonoBehaviour {

// Use this for initialization
	
	public Transform target;
	public float orbitDistance = 3.0f;
	public float orbitDegreesPerSec = 180.0f;
	public Vector3 relativeDistance = Vector3.zero;
	public bool once = true;
	// Use this for initialization
	void Start () {
		
		if(target != null) 
		{
			relativeDistance = transform.position - target.position;
		}
	}
	
	void Orbit()
	{
		if(target != null)
		{
			// Keep us at the last known relative position
			transform.position = (target.position + relativeDistance);
			transform.RotateAround(target.position, Vector3.up, orbitDegreesPerSec * Time.deltaTime);
			// Reset relative position after rotate
		if (once)
		{
			transform.position *= orbitDistance;
			once = false;
		}
			relativeDistance = transform.position - target.position;
		}
	}
	
	void LateUpdate () {
		
		Orbit();
		
	}
}

That is all

Hi, this doesn't keep the object at the orbit distance. Can you remember what you did to make this work? My objects just stay at the distance they are spawned at. I see that Once is only set to true at the start, is this the cause? Cheers.