private static void RotateThroughBoard()
    {
        RaycastHit hit;

        if (Physics.Raycast(FirstPersonInteraction.Ray(), out hit, Settings.ReachDistance, Wire.IgnoreWiresLayermask))
        {
            if (hit.collider.tag == "World" || hit.collider.tag == "CircuitBoard")
            {
                SoundPlayer.PlaySoundGlobal(Sounds.FailDoSomething); return;
            }
            GameObject component = ComponentPlacer.FullComponent(hit.collider);
            if (component.transform.parent == null)
            {
                return;
            }
            if (!AllowFlippingOneSidedComponents)
            {
                if (!component.GetComponent <IsThroughComponent>())
                {
                    SoundPlayer.PlaySoundGlobal(Sounds.FailDoSomething); return;
                }
            }

            component.transform.localEulerAngles += new Vector3(0, 0, 180);
            component.transform.Translate(Vector3.up * 0.15f, Space.Self);

            BoxCollider[] colliders = component.GetComponentsInChildren <BoxCollider>();
            StuffPlacer.SetStateOfBoxColliders(colliders, false);

            if (StuffPlacer.GameObjectIntersectingStuffOrWouldDestroyWires(component, true))
            {
                component.transform.localEulerAngles += new Vector3(0, 0, 180);
                component.transform.Translate(Vector3.up * 0.15f, Space.Self);
                StuffPlacer.SetStateOfBoxColliders(colliders, true);
                SoundPlayer.PlaySoundGlobal(Sounds.FailDoSomething);
                return;
            }

            FloatingPointRounder.RoundIn(component);

            StuffPlacer.SetStateOfBoxColliders(colliders, true);

            RedrawCircuitGeometryOf(component);
            DestroyIntersectingConnections(component);
            MegaMeshManager.RecalculateGroupsOf(component);

            SoundPlayer.PlaySoundAt(Sounds.RotateSomething, component);
        }
        else
        {
            SoundPlayer.PlaySoundGlobal(Sounds.FailDoSomething);
        }
    }
    public static void RotateThing(GameObject RotateThis)
    {
        // determines which direction to rotate
        // TODO: use camera.main.transform to rotate stuff left and right rather than clockwise & ccw

        if (RotateThis.tag == "World")
        {
            SoundPlayer.PlaySoundGlobal(Sounds.FailDoSomething);
            return;
        }

        if (RotateThis.tag == "CircuitBoard" || RotateThis.tag == "PlaceOnlyCircuitBoard")
        {
            SoundPlayer.PlaySoundGlobal(Sounds.FailDoSomething);
            return;
        }

        // rotate the full object, not part of it
        // the last check is so that rotating child boards doesn't rotate their parent
        RotateThis = ComponentPlacer.FullComponent(RotateThis);

        Quaternion BeforeRotation     = Quaternion.identity;
        Vector3    AxisToRotateAround = RotateThis.transform.up;

        // everything but wires should rotate around transform.up
        if (RotateThis.tag == "Wire")
        {
            if (RotateThis.GetComponent <SnappedConnection>()) // you cannot rotate snapped connections
            {
                SoundPlayer.PlaySoundGlobal(Sounds.FailDoSomething);
                return;
            }

            AxisToRotateAround = RotateThis.transform.forward;
            StuffConnector.QueueWireMeshRecalculation(RotateThis);

            SoundPlayer.PlaySoundAt(Sounds.RotateSomething, RotateThis);
        }
        else
        {
            BeforeRotation = RotateThis.transform.rotation; // non-wires might be rotated into invalid positions, in which case they should be reverted to their original rotations
        }

        int direction = 1;

        if (Input.GetAxis("Rotate") < 0)
        {
            direction = -1;
        }
        else
        {
            direction = 1;
        }

        if (Input.GetButton("Mod")) // rotate by 22.5 degrees if the mod key is held down
        {
            RotateThis.transform.RotateAround(RotateThis.transform.position, AxisToRotateAround, direction * 22.5f);
        }
        else // ...but normally rotate by 90 degrees
        {
            RotateThis.transform.RotateAround(RotateThis.transform.position, AxisToRotateAround, direction * 90f);
        }

        // the validity of wire placement is never affected when rotating them, but if it's an object, check if it can actually be placed there. If not, revert to original rotation
        if (RotateThis.tag != "Wire")
        {
            BoxCollider[] colliders = RotateThis.GetComponentsInChildren <BoxCollider>();
            StuffPlacer.SetStateOfBoxColliders(colliders, false);

            if (StuffPlacer.GameObjectIntersectingStuffOrWouldDestroyWires(RotateThis, true, true)) // ignore wires
            {
                RotateThis.transform.rotation = BeforeRotation;
                StuffPlacer.SetStateOfBoxColliders(colliders, true);

                SoundPlayer.PlaySoundGlobal(Sounds.FailDoSomething);
                return;
            }

            SoundPlayer.PlaySoundAt(Sounds.RotateSomething, RotateThis);
            StuffPlacer.SetStateOfBoxColliders(colliders, true);
        }

        FloatingPointRounder.RoundIn(RotateThis);

        RedrawCircuitGeometryOf(RotateThis);
        DestroyIntersectingConnections(RotateThis);

        SnappingPeg.TryToSnapIn(RotateThis);

        MegaMeshManager.RecalculateGroupsOf(RotateThis);
    }