carousel script c# for unity3d

Hello guys, i just wanted to share this script with you, it creates a carousel with game objects, hopefully it might help someone save some time, i tried to document it as best as possible.
you can download the script, or the test project(created with unity 5.3.2) i included it at the bottom.

using UnityEngine;
using System.Collections;

//Wissam El Hajj, 2016
//this is a simple script that creates a carousel form game objects
//this script is provided as is without any guarentees
/*
* to use this script just place it on any gameobject in the scene, this element shouldn't have a collider so an empty game object is ideal
* add elements to the carouselObjects array, make sure these items have a collider
* make sure there are no elements with colliders in between the center and the carousel elements
*/
public class CreateCarousel : MonoBehaviour {

    public GameObject[] carouselObjects;//the elements of the carousel
    public bool ResetCenterRotation = true;//do you want to reset the rotation of the carousel center (recommended to be true)
    public float DistanceFromCenter = 10.0f;//the distance from the center of the carousel
    public bool AssumeObject = true; // if true assume the object that is picked, otherwise (false) keep checking what the next item is through raycast.
    public int ChosenObject = 0; //index of the object that is centered in the carousel
    public float speedOfrotation = 0.1f; //the speed in which the carousel rotates: values should be between 0.01f -> 1.0f, zero will stop the rotation


    private static float diameter = 360.0f; //the diameter is always 360 degrees
    private Transform theRayCaster = null; //create an empty transform
    private float Angle = 0.0f; //the angle for each object in the carousel
    private float newAngle = 0.0f; //the calculated angle
    private bool firstTime = true; //used to calculate the offset for the first time


    void Start ()
    {
        Debug.Log(carouselObjects[0].name);//just display the name of the first chosen element in the console
        GameObject raycastHolder = new GameObject ();//create an empty gameobject
        raycastHolder.name = "RaycastPicker"; //rename it to RaycastPicker
        theRayCaster = raycastHolder.transform; // assign the transform of the newlycreated gameobject to the raycast transform variable
        theRayCaster.position = transform.position; // place it at the positon of the carousel center
        if (ResetCenterRotation) {
            transform.rotation = Quaternion.identity;//reset the rotation of the carousel center
        }

        Angle = diameter / (float)carouselObjects.Length;//calculate the angle according to the number of elements
        float ObjectAngle = Angle;//create a temp value that keeps track of the angle of each element
        for (int i = 0; i < carouselObjects.Length; i++) { //loop through the objects
           
            carouselObjects [i].transform.position = this.transform.position;//Reset objects to the postion of the carousel center
            carouselObjects [i].transform.rotation = Quaternion.identity; //make sure their rotation is zero
            carouselObjects [i].transform.parent = this.transform; // make the element child to the carousel center
            carouselObjects [i].transform.position = new Vector3 (this.transform.position.x, this.transform.position.y, this.transform.position.z + DistanceFromCenter);//move each carousel item from the center an amount of "DistanceFromCenter"
            carouselObjects [i].transform.RotateAround (this.transform.position, new Vector3 (0, 1, 0), ObjectAngle);//position the element in their respective locations accordind to the center throufh rotation
            ObjectAngle += Angle;//calculate the next angle value
        }

        //Make sure an element is perfectly centered.
        if (carouselObjects.Length % 2 != 0) {
            float rotateAngle = Angle + Angle / 2;
            transform.eulerAngles = new Vector3 (transform.eulerAngles.x, rotateAngle, transform.eulerAngles.z);
            newAngle = rotateAngle;
        }
        else
        {
            transform.eulerAngles = new Vector3 (transform.eulerAngles.x, Angle, transform.eulerAngles.z);
            newAngle = Angle;
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Correct the carrousel and make sure the first item in the array is the first element in the carousel
        ///
        theRayCaster.position = transform.position;
        string objectName = "";
        RaycastHit hit;
        if (Physics.Raycast(transform.position, -theRayCaster.forward, out hit, DistanceFromCenter ))
        {
            objectName = hit.collider.name;
        }

        if (objectName != carouselObjects [0].name) // only work if the first item presented isn't the first item in the array
        {
            for (int c = 0; c < carouselObjects.Length; c++) //loop through the array
            {
                if (carouselObjects [c].name == objectName)
                {
                    float angleMultiplier = c++; //the array starts with zero so adding 1 to c gives the correct value
                    transform.eulerAngles = new Vector3 (transform.eulerAngles.x, transform.eulerAngles.y + Angle * angleMultiplier, transform.eulerAngles.z); //rotate the carousel to center the first object in the array
                    newAngle = transform.eulerAngles.y; //reset the angle to the newly calculated angle

                    break; //exit the loop so it won't do any unecessary calculations
                }
            }
        }
       ////////////////////////////////////////////////////////////////////////////////////////////////////////
    }
   
    // Update is called once per frame
    void Update ()
    {
        if (AssumeObject == false)
        {
            // use raycast to dynamically check which item is selected not recommended unless necessary
            theRayCaster.position = transform.position;
            RaycastHit hit;
            if (Physics.Raycast (transform.position, -theRayCaster.forward, out hit, DistanceFromCenter)) {
                Debug.Log (hit.collider.name);//display in the console which element is detected
            }
        }

            Quaternion newRotation = Quaternion.AngleAxis (newAngle, Vector3.up); // pick the rotation axis and angle
            transform.rotation = Quaternion.Slerp (transform.rotation, newRotation, speedOfrotation);  //animate the carousel
       
    }

    public void rotateTheCarouselLeft() // call this function to rotate the carousel towards the left
    {
        if (firstTime)// if run the first time calcule the offset
        {
            newAngle = transform.eulerAngles.y;
            newAngle += Angle;
            firstTime = false; // stop this piece of code from running in the future
        }
        else
        {
            newAngle += Angle; //calculate the new angle
        }
        if (AssumeObject == true)//here we check which element is selected and if we reached the start of the array we reset the index
        {
            if (ChosenObject <= 0) {
                ChosenObject = carouselObjects.Length - 1;
            } else {
                ChosenObject--;
            }
            Debug.Log(carouselObjects[ChosenObject].name); //show in the console the name of the selected element
        }
    }
    public void rotateTheCarouselRight()// call this function to rotate the carousel towards the right
    {
        if (firstTime) // if run the first time calcule the offset
        {
            newAngle = transform.eulerAngles.y;
            newAngle -= Angle;
            firstTime = false; // stop this piece of code from running in the future
        }
        else
        {
            newAngle -= Angle; //calculate the new angle
        }
        if (AssumeObject == true) //here we check which element is selected and if we reached the end of the array we reset the index
        {
            if (ChosenObject >= carouselObjects.Length-1) {
                ChosenObject = 0;
            } else {
                ChosenObject++;
            }
            Debug.Log(carouselObjects[ChosenObject].name); //show in the console the name of the selected element
        }
    }
}

2633285–185154–CreateCarousel.cs (7.27 KB)
2633285–185152–Carousel Test.rar (637 KB)

1 Like

Hey man! THANK YOU for sharing this, I hope you have a nice day!

no prob man

I tried this code and your example and when I click the rotate button the white cube just creates a white trail and the whole screen becomes white. doesn’t just rotate to next cube.
Do you have update for this or know how to fix this.

Thanks

I’ve never used this script, but that sounds list a camera clear flags issue (??)

just like larku said its a clear flag issue, not the script. on your camera, click on clear flags, and choose either skybox or solid color, you can also get away with other options if you have another camera that renders a background

Hi, I tried to apply this code. So I created an empty gameobject, attached your script and put my buttons in your array of gameobjects. The problem is that when I run the code my buttons just get deleted from the scene. How do I fix that?

this code is meant to be used with 3d objects and not UI elements like buttons

Hey man, great script! Just ran across this earlier today. Works great. Once I looked at your test project, it all made sense. Saved me a bunch of time, thanks again.

2019 and still usefull, thanks a lot !

hi there. thanks for sharing. My question is how could we bring selected game object or 3d character on zero index or starting point on focus. Because it always started from zero index.

thanks a lot!