Combining two instantiate scripts (Unity 3D)

97 views Asked by At

I need to combine the following scripts into one script containing two functions, one that instantiates the next prefab in the array and the other that instantiates the previous prefab in the array (it is a virtual tour app). Both should also destroy the current prefab. I could then call the functions via event triggers.

I have this code for the "next Prefab" script.

public GameObject[] Spheres;
    int currentIndex = 0;
    GameObject currentObject;
    public Camera MainCamera;

    void OnMouseDown()
    {
        if (Input.GetMouseButtonDown(0))
            if (gameObject.tag == "ArrowNEXT")
        {
            Vector3 rayOrigin = MainCamera.ViewportToWorldPoint(new Vector3(0.1f, 0.1f, 0));
            RaycastHit hit;

            if (Physics.Raycast(rayOrigin, MainCamera.transform.forward, out hit))
            {
                if (hit.collider != null)
                {
                    {
                            Destroy(currentObject);
                            currentIndex++;
                            if (currentIndex > Spheres.Length - 1) currentIndex = 0;
                            currentObject = Instantiate(Spheres[currentIndex]);
                    }
                }
            }


        }

    }

I need to combine it with the following:

using UnityEngine;


public class RayCastPrevFIX: MonoBehaviour
{
    public GameObject[] Spheres;
    int currentIndex = 0;
    GameObject currentObject;
    public Camera MainCamera;

    void OnMouseDown()
    {
        if (Input.GetMouseButtonDown(0))
            if (gameObject.tag == "ArrowPREV")
            {
            Vector3 rayOrigin = MainCamera.ViewportToWorldPoint(new Vector3(0.1f, 0.1f, 0));
            RaycastHit hit;

            if (Physics.Raycast(rayOrigin, MainCamera.transform.forward, out hit))
            {
                if (hit.collider != null)
                {
                    {
                            Destroy(currentObject);
                            currentIndex--;
                            if (currentIndex < 0) currentIndex = Spheres.Length - 1;
                            currentObject = Instantiate(Spheres[currentIndex]);
                    }
                }
            }


        }

    }
}

How would I go about this? Any help is greatly appreciated.I have this so far:

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

public class SphereSwap : MonoBehaviour
{ 
   public GameObject[] Spheres;
   int currentIndex = 0;
   GameObject currentObject;
   public Camera MainCamera;

   void Next()
   {
       Destroy(currentObject);
       currentIndex++;
       if (currentIndex > Spheres.Length - 1) currentIndex = 0;
       currentObject = Instantiate(Spheres[currentIndex]);
   }

   void Previous()
   {
       Destroy(currentObject);
       currentIndex--;
       if (currentIndex < 0) currentIndex = Spheres.Length - 1;
       currentObject = Instantiate(Spheres[currentIndex]);
   }
}
1

There are 1 answers

5
ChoopTwisk On

You're on the right path, but you could shorten the code as well as use one function for both cases to avoid boilerplate:

using UnityEngine;
public class SphereSwap : MonoBehaviour
{
    public GameObject[] Spheres;
    int currentIndex = 0;
    GameObject currentObject;
    public Camera MainCamera;

    const string ArrowPrevTag = "ArrowPREV";
    const string ArrowNextTag = "ArrowNEXT";


    private void HandleClick(bool next)
    {
        if(Spheres == null || Spheres.Length == 0)
        {
            Debug.Log($"Spheres list is empty, nothing to swap.");
            return;
        }

        Vector3 rayOrigin = MainCamera.ViewportToWorldPoint(new Vector3(0.1f, 0.1f, 0));
        RaycastHit hit;
        if (Physics.Raycast(rayOrigin, MainCamera.transform.forward, out hit))
        {
            if (hit.collider != null)
            {
                // destroy current sphere.
                Destroy(currentObject);
                // go next or previous.
                currentIndex += next ? 1 : -1;

                // circular clamp if overflow
                if (currentIndex < 0)
                    currentIndex = Spheres.Length - 1;
                else if (currentIndex >= Spheres.Length)
                    currentIndex = 0;
                // finally do instantiate.
                currentObject = Instantiate(Spheres[currentIndex]);
            }
        }

    }
    private void OnMouseDown()
    {
        if (Input.GetMouseButtonDown(0))
        {
            // 'CompareTag' is more efficient than gameobject.tag == "sometag"
            if (gameObject.CompareTag(ArrowNextTag))
                HandleClick(true);
            else if (gameObject.CompareTag(ArrowPrevTag))
                HandleClick(false);
        }
    }
}