- Home /
Rotate an object so its up vector matches a sphere
Hi all,
I currently have an object rotating around a sphere continuously, however, I want the object to align with the sphere and the direction it's going.
For example, I have this spaceship rotating around a planet:
https://i.imgur.com/xZ0CwjA.png
However, it always faces the same direction.
My desired result is something like this:
https://i.imgur.com/fxOQ4AW.png
The spaceships bottom faces towards the sphere, and the spaceship looks the direction of travel.
If anyone could help, that'd be great!
Answer by MarioSantoso · Apr 15, 2018 at 05:33 AM
Apply this script to your ship/shuttle. Do not use rigidbody as we are moving the object manually not using physics.
The ship z axis must be forward and y axis must be up.
Make modifications as you see fit
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Orbit : MonoBehaviour
{
public Transform orbitTarget; // Assign the sphere/planet you want to orbit
public float speed; // how fast the ship is moving
public float distance; // how far the ship will orbit
public bool updateDistance; // check this if you make changes to distance so the dummy's position will be updated
private Transform _directionDummy;
private void Start()
{
InitializeDummy();
}
private void InitializeDummy()
{
// Create a dummy object for the ship to look at, and position the dummy accordingly
if (_directionDummy == null)
{
_directionDummy = new GameObject("_dummy").GetComponent<Transform>();
_directionDummy.parent = orbitTarget;
}
_directionDummy.position = orbitTarget.position;
_directionDummy.rotation = Quaternion.identity;
_directionDummy.localScale = Vector3.one;
_directionDummy.Translate(new Vector3(0, 0, -distance));
}
private void Update()
{
UpdateDummy();
// Move the ship by following the dummy object and make it bottom side always face the sphere
Vector3 _worldUp = transform.position - orbitTarget.position;
transform.LookAt(_directionDummy, _worldUp * 2);
transform.Translate(Vector3.forward * speed * Time.deltaTime, Space.Self);
if (Time.frameCount % 30 == 0)
Debug.Log(Vector3.Distance(transform.position, _directionDummy.position));
}
private void UpdateDummy()
{
// Move the dummy around the sphere
if (updateDistance)
{
updateDistance = false;
Start();
}
_directionDummy.LookAt(orbitTarget, orbitTarget.up);
_directionDummy.Translate(Vector3.right * speed * Time.deltaTime, Space.Self);
}
}
Hey thanks! However, I don't think this is fit for my use-case. All of my objects are created dynamically, and I believe this is a little more complicated for what exactly I'm trying to do.
I'm currently looking at the LookAt
and I didn't realise I could give a vector that defines the up orientation. Is it possible to make the shuttle's bottom face the planet just using that?
This is not complicated at all since you don't have to worry about the mechanics, just assign an orbit target at set the orbit speed and distance.
If you created the object dynamically, then just add the orbit.cs to your object via script.
AddComponenct<Orbit>();
Set the property by script also, for example:
//Assign object to be your orbit target
GetComponent<Orbit>().orbitTarget = "your planet transform";
The ship will then move by itself to the correct position. Do $$anonymous$$d that I didn't put any smoothing to the movement.
@$$anonymous$$ilsnus
That's great, thank you. However one last issue - the object is very twitchy, its rotation keeps switching from looking ahead to looking towards the planet:
http://davidpuetter.com/u/%25pn-2018-04-16_03-32-08.mp4
This is seen with any other object too with the script attached.
That's one hell twitchy ship! Haha.
From the test I did, it shouldn't be doing that unless a modification or another script interfering with the way it works.
If confirmed none of the above cause it, then I can only think that the ship is too close to the dummy object.
Let's test.... By default the dummy object spawned in front of the sphere. Try spawning or placing your ship further away from the sphere and not on the front of it. You can check the dummy position by selecting it in hierarchy and see the gizmo moving in the scene view.
If the ship and the dummy are very close together, you will get that glitch.