Unity: Sprite Orbiter

July 5, 2025

Ever wondered how to make sprites spin around an object? Well, here's the way I do it:

Sprite Orbiter

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

public class SpriteOrbiter : MonoBehaviour
{
    public Transform target;
    public Vector3 offset = Vector3.zero;
    public float angle = Mathf.PI / 2f;

    public void ApplyOffset()
    {
        transform.position = target.position + offset;
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        transform.RotateAround(target.position, Vector3.up, angle);
    }
}

This simple script is enough, but we can go further to orchestrate the orbitation of multiple sprites simultaneously.

Sprite Orbit Sorter

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

public class SpriteOrbitSorter : MonoBehaviour
{
    public SpriteRenderer spriteRenderer;
    public float pivotAngle = -90f;
    public Transform target;

    int backSortingOrder = 100;
    int frontSortingOrder = 1;

    // Start is called before the first frame update
    void Start()
    {
        spriteRenderer = GetComponent<SpriteRenderer>();
    }

    // Update is called once per frame
    void Update()
    {
        var v = target.position - transform.position;
        float euler = Vector3.SignedAngle(v, Vector3.right, Vector3.up);

        if (spriteRenderer != null && euler >= pivotAngle)
            spriteRenderer.sortingOrder = backSortingOrder;
        else
            spriteRenderer.sortingOrder = frontSortingOrder;
    }
}

Using the signed angle of the vector between the target and the sprite's position, we can determine whether a sprite is supposed to be in front or behind of an object, and adjust its sorting order accordingly to make it appear to disappear behind said object.

Sprite Orbit Arranger

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

public class SpriteOrbitArranger : MonoBehaviour
{
    public List<GameObject> gameObjects;
    public Transform pivot;
    public Vector3 offset = Vector3.zero;

    public void Arrange()
    {
        float angleOffset = 360f / gameObjects.Count;

        for (int i = 0; i < gameObjects.Count; ++i)
        {
            var obj= gameObjects[i];
            obj.transform.position= pivot.transform.position + offset;
            obj.transform.RotateAround(pivot.transform.position, Vector3.up, angleOffset * i);
        }
    }

    public void AddToOrbit(GameObject obj)
    {
        gameObjects.Add(obj);
    }
}

This script simply distributes sprites around a circle, to achieve even spacing.

Sprite Orbit Controller

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

public class SpriteOrbitController : MonoBehaviour
{
    public List<Sprite> sprites;
    public GameObject spritePrefab;

    SpriteOrbitArranger orbitArranger;
    SpriteOrbiter spriteOrbiter; 

    private void InitOrbitComponents()
    {
        if (!TryGetComponent(out orbitArranger))
            orbitArranger = gameObject.AddComponent<SpriteOrbitArranger>();

        if (!TryGetComponent(out spriteOrbiter))
            spriteOrbiter = gameObject.AddComponent<SpriteOrbiter>();
    }

    private void Start()
    {
        InitOrbitComponents();
    }

    public void SetTarget(Transform target)
    {
        InitOrbitComponents();

        spriteOrbiter.target = target;
        orbitArranger.pivot = target;
    }

    public void ConstructOrbit()
    {
        foreach (var sprite in sprites)
        {
            var obj = Instantiate(spritePrefab, transform);
            obj.GetComponent<SpriteRenderer>().sprite = sprite;

            if (!obj.TryGetComponent(out SpriteRenderer spriteRenderer))
                spriteRenderer = obj.AddComponent<SpriteRenderer>();

            spriteRenderer.sprite = sprite;

            if (!obj.TryGetComponent(out SpriteOrbitSorter sorter))
                sorter = obj.AddComponent<SpriteOrbitSorter>();

            sorter.target = spriteOrbiter.target;
            sorter.pivotAngle = 0f;

            orbitArranger.AddToOrbit(obj);
        }

        orbitArranger.Arrange();
    }
}

Finally, we have the orbit controller, which puts everything together.

Yea, this is just a script dump.

Demo