public static GameObject GenerateFall(GameObject fallPrefabItem, Transform parent, Vector3 location, Texture2D image, Texture2D clickImage, float delay, Timeline time, int itemNum, bool playSound)
    {
        GameObject tmp = Instantiate(fallPrefabItem);

        tmp.name  = "Item" + itemNum.ToString().PadLeft(2, '0');
        tmp.layer = 5;
        tmp.transform.GetChild(0).gameObject.layer = 5;
        tmp.transform.GetChild(1).gameObject.layer = 5;
        DisableAllCollidersInObject(tmp);
        tmp.transform.parent        = parent;
        tmp.transform.localPosition = location;
        tmp.GetComponentInChildren <BoxCollider>().enabled   = true;
        tmp.GetComponentInChildren <BoxCollider>().isTrigger = true;
        if (image != null)
        {
            tmp.GetComponentInChildren <MeshRenderer>().material.mainTexture = image;
            flipTexture(tmp);
        }
        FallFromSky script = tmp.GetComponentInChildren <FallFromSky>();

        script.transitionDelay    = delay;
        script.transitionDuration = (float)itemFallTime;
        script.startPos           = new Vector3(script.startPos.x, (float)itemInactiveHeight, script.startPos.z);
        script.time            = time;
        script.mainTexture     = image;
        script.clickTexture    = clickImage;
        script.playSoundEffect = playSound;
        return(tmp);
    }
    void Update()
    {
        if (firstCall)
        {
            //Needs to be run on first update because Start() order isn't promised
            int numChildren = generator.gameObject.transform.childCount;
            List <ClickableObject> clickable = new List <ClickableObject>();
            objectHeldList = new LinkedList <int>();
            for (int i = 0; i < numChildren; i++)
            {
                ClickableObject tmp = generator.gameObject.transform.GetChild(i).GetComponentInChildren <ClickableObject>();
                if (tmp != null)
                {
                    clickable.Add(tmp);
                    tmp.gameObject.transform.parent.gameObject.SetActive(false);
                }
            }
            Shuffle <ClickableObject>(clickable);
            clickableObjects = clickable.ToArray();
            for (int i = 0; i < clickableObjects.Length; i++)
            {
                objectHeldList.AddFirst(i);
            }
            firstCall = false;
        }
        Vector3 comparisonDistance = gameObject.transform.position;

        if (placeWithMouse)
        {
            Vector3 mouse = InputManager.mainManager.mouseWorldPosition;
            comparisonDistance = new Vector3(mouse.x, mousePlaceHeight * 2, mouse.z);
        }

        if (InputManager.mainManager.GetButton(InputManager.ButtonType.NextEvent, InputManager.ButtonState.RisingEdge))
        {
            currentItemTypeIndex = (currentItemTypeIndex + 1) % 3;
            switch (currentItemTypeIndex)
            {
            case 0:
                typeDisplayImage.material = infinityMaterial;
                break;

            case 1:
                typeDisplayImage.material = upMaterial;
                break;

            case 2:
                typeDisplayImage.material = downMaterial;
                break;

            default:
                typeDisplayImage.material = null;
                break;
            }
        }

        else if (InputManager.mainManager.GetButton(InputManager.ButtonType.Place, InputManager.ButtonState.RisingEdge))
        {
            RaycastHit hit;
            var        cameraCenter = targetingCamera.ScreenToWorldPoint(new Vector3(Screen.width / 2f, Screen.height / 2f, targetingCamera.nearClipPlane));
            if (placeWithMouse)
            {
                cameraCenter = InputManager.mainManager.mouseScreenPosition;
            }
            Physics.SphereCast(cameraCenter, 0.5f, targetingCamera.transform.forward, out hit, 1000f, 1 << LayerMask.NameToLayer("UI"));
            int hitIndex = -1;
            if (hit.transform != null)
            {
                GameObject hitObj = hit.transform.gameObject;
                Debug.Log("Hit: " + hitObj.name);
                for (int i = 0; i < clickableObjects.Length; i++)
                {
                    if (hitObj == clickableObjects[i].gameObject)
                    {
                        hitIndex = i;
                    }
                }
            }
            if (hitIndex >= 0 && (!placeWithMouse || clickableObjects[hitIndex].gameObject.GetComponent <MeshRenderer>().isVisible)) //And it is visible, within the min distance, and clickable
            {
                clickableObjects[hitIndex].gameObject.transform.parent.gameObject.SetActive(false);
                objectHeldList.AddFirst(hitIndex);
                // Log item number, event type, location, time,
                //itemLogger.logMessage("Item Picked Up : " + clickableObjects[closestIndex].gameObject.transform.parent.name + " type ");
                Debug.Log(hitIndex);
                audioSrc.pitch = 1f;
                audioSrc.clip  = soundEffect;
                audioSrc.Play();
            }
            else //No object is being picked up, drop the current item
            {
                Debug.Log("No Hit, Placing.");
                if (objectHeldList.Count > 0)
                {
                    int         index            = objectHeldList.First.Value;
                    Texture2D   prevTexture      = clickableObjects[index].mainTexture;
                    Texture2D   prevClickTexture = clickableObjects[index].clickTexture;
                    bool        prevPlaySound    = clickableObjects[index].playSoundEffect;
                    Transform   prevParent       = clickableObjects[index].gameObject.transform.parent.transform.parent;
                    FallFromSky fallScript       = clickableObjects[index].gameObject.GetComponent <FallFromSky>();
                    FlyToSky    flyScript        = clickableObjects[index].gameObject.GetComponent <FlyToSky>();
                    int         prevItemNum      = int.Parse(clickableObjects[index].gameObject.transform.parent.gameObject.name.Substring(4));
                    GameObject  obj;
                    Vector3     placePosition  = transform.position + (transform.forward * placeDistance);
                    bool        validPlacement = true;
                    for (int i = 0; i < clickableObjects.Length; i++)
                    {
                        if (i == index)
                        {
                            continue;
                        }
                        float dist = Vector3.Distance(placePosition, clickableObjects[i].transform.parent.position);
                        //If object is enabled and visible and within the minPlaceDistance, invalidate the placement
                        if (clickableObjects[i].isActiveAndEnabled && clickableObjects[i].GetComponent <MeshRenderer>().isVisible&& dist < minObjectPlaceDistance)
                        {
                            validPlacement = false;                                         //Invalid object placement, do nothing
                        }
                        if (placePosition == clickableObjects[i].transform.parent.position) //As an additional check, if the objects are in precisely the same place, invalidate as well
                        {
                            validPlacement = false;
                        }
                    }
                    if (time.time > 59.99 && currentItemTypeIndex != 0)
                    {
                        Debug.Log("Invalidated Placement Due To Event Type and Time");
                        validPlacement = false;
                    }
                    if (validPlacement)
                    {
                        Debug.Log("Valid Placement");
                        Debug.Log(prevItemNum);
                        objectHeldList.RemoveFirst();
                        // Check boundary conditions
                        Vector3 originalPlacement = placePosition;
                        if (placePosition.x < -18.5f)
                        {
                            placePosition = new Vector3(-18.5f, placePosition.y, placePosition.z);
                        }
                        else if (placePosition.x > 18.5f)
                        {
                            placePosition = new Vector3(18.5f, placePosition.y, placePosition.z);
                        }
                        if (placePosition.z < -18.5f)
                        {
                            placePosition = new Vector3(placePosition.x, placePosition.y, -18.5f);
                        }
                        else if (placePosition.z > 18.5f)
                        {
                            placePosition = new Vector3(placePosition.x, placePosition.y, 18.5f);
                        }
                        if (originalPlacement != placePosition)
                        {
                            Debug.Log("Placed within wall, placement has been shifted.");
                        }
                        if (placeWithMouse)
                        {
                            Vector3 mouse = InputManager.mainManager.mouseWorldPosition;
                            placePosition = new Vector3(mouse.x, mousePlaceHeight, mouse.z);
                        }
                        else
                        {
                            placePosition = new Vector3(placePosition.x, (float)ItemGenerator.itemHeight, placePosition.z);
                        }
                        if (currentItemTypeIndex == 2)
                        {
                            obj = ItemGenerator.GenerateFall(fallPrefabItem, prevParent, placePosition, prevTexture, prevClickTexture, time.time, time, prevItemNum, prevPlaySound);
                        }
                        else if (currentItemTypeIndex == 1)
                        {
                            obj = ItemGenerator.GenerateFly(flyPrefabItem, prevParent, placePosition, prevTexture, prevClickTexture, time.time, time, prevItemNum, prevPlaySound);
                        }
                        else
                        {
                            obj = ItemGenerator.GenerateFoil(foilPrefabItem, prevParent, placePosition, prevTexture, prevClickTexture, time.time, time, prevItemNum, prevPlaySound);
                        }
                        GameObject oldObj = clickableObjects[index].gameObject.transform.parent.gameObject;
                        clickableObjects[index] = obj.GetComponentInChildren <ClickableObject>();
                        DestroyImmediate(oldObj);
                        audioSrc.pitch = 1f;
                        audioSrc.clip  = soundEffect;
                        audioSrc.Play();
                    }
                    else
                    {
                        Debug.Log("No valid placement.");
                    }
                }
            }
        }

        bool nextInputState = InputManager.mainManager.GetButton(InputManager.ButtonType.NextItem, InputManager.ButtonState.RisingEdge);

        if (nextInputState && objectHeldList.Count != 0)
        {
            objectHeldList.AddLast(objectHeldList.First.Value);
            objectHeldList.RemoveFirst();
        }

        if (objectHeldList.Count != 0)
        {
            displayImage.material = clickableObjects[objectHeldList.First.Value].gameObject.GetComponent <MeshRenderer>().material;
        }
        else
        {
            displayImage.material = emptyMaterial;
        }

        if (forceTransparency != 1f)
        {
            Material m = displayImage.material;
            m.SetFloat("_Mode", 2);
            m.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
            m.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
            m.SetInt("_ZWrite", 0);
            m.DisableKeyword("_ALPHATEST_ON");
            m.EnableKeyword("_ALPHABLEND_ON");
            m.DisableKeyword("_ALPHAPREMULTIPLY_ON");
            m.renderQueue = 3000;
        }

        if (InputManager.mainManager.GetButton(InputManager.ButtonType.PickAll, InputManager.ButtonState.RisingEdge))
        {
            for (int i = 0; i < clickableObjects.Length; i++)
            {
                if (clickableObjects[i].gameObject.transform.parent.gameObject.activeSelf)
                {
                    clickableObjects[i].gameObject.transform.parent.gameObject.SetActive(false);
                    objectHeldList.AddFirst(i);

                    audioSrc.pitch = 1f;
                    audioSrc.clip  = multiSoundEffect;
                    audioSrc.Play();
                }
            }
        }
    }