Raycast rotation help

Hi,
I’m making a lego style VR game using the unity XR framework.
I’ve been struggling for quite a while on how to snap the bricks together, but I’ve come up with an idea of using multiple raycasts emitted from the bottom of the bricks and multiple “pin” colliders on the top to set the snapped bricks at the correct locations. I’ve come up with the following script which works fine, just so long as the bricks rotation is width-way around… When I rotate the brick length-way around the coordinates are all messed up…

using UnityEngine;

public class BlockRaycastTest : MonoBehaviour
{
    int layerMask = 1 << 9;
    private Vector3 ray1 = new Vector3(-0.012f, 0, -0.004f);
    private Vector3 ray2 = new Vector3(-0.012f, 0, 0.004f);
    private Vector3 ray3 = new Vector3(-0.004f, 0, -0.004f);
    private Vector3 ray4 = new Vector3(-0.004f, 0, 0.004f);
    private Vector3 ray5 = new Vector3(0.004f, 0, -0.004f);
    private Vector3 ray6 = new Vector3(0.004f, 0, 0.004f);
    private Vector3 ray7 = new Vector3(0.012f, 0, -0.004f);
    private Vector3 ray8 = new Vector3(0.012f, 0, 0.004f);

    public GameObject highlightBrick;

    int i;
    public RaycastHit[] hit;
    public Vector3[] rayPositions;
    FixedJoint joint;

    void Update()
    {
        hit = new RaycastHit[8];
        rayPositions = new Vector3[] { ray1, ray2, ray3, ray4, ray5, ray6, ray7, ray8 };
        i = hit.Length; while (i > 0)
        {
            i--;
            Debug.DrawRay(transform.position + rayPositions[i], transform.TransformDirection(Vector3.down) * 0.01f, Color.green);
            if (Physics.Raycast(transform.position + rayPositions[i], Vector3.down, out hit[i], 0.01f, layerMask))
            {
                Vector3 hitCollider = hit[i].collider.transform.localPosition;
                highlightBrick.transform.parent = hit[i].collider.transform.parent;
                highlightBrick.transform.localPosition = Vector3.zero;

                highlightBrick.transform.localPosition += hitCollider - rayPositions[i];
            }
        }
    }
}

Scene Hierarchy:

XR Rig
2x4_Brick_Prefab (RaycastTest script attached)
. > pin1 (Box Collider (-0.012f, 0, -0.004f))
. > pin2 (Box Collider (-0.012f, 0, 0.004f))
. > pin3 (Box Collider (-0.004f, 0, -0.004f))
. > pin4 (Box Collider (-0.004f, 0, 0.004f))
. > pin5 (Box Collider (-0.004f, 0, 0.004f))
. > pin6 (Box Collider (0.004f, 0, 0.004f))
. > pin7 (Box Collider (0.012f, 0, -0.004f))
. > pin8 (Box Collider (0.012f, 0, 0.004f))
HighlightBrick

You can rotate vectors (around the origin (0,0,0)) by multiplying them by a Quaternion. For Lego you would probably try the four cardinal rotations.

For instance, if you take Vector3.forward (0,0,1) and rotate it by Quaternion.Euler(0,90,0), you end up with Vector3.right (1,0,0):

        Vector3 vector = Vector3.forward;
        Debug.Log( "Before:" + vector);
        Quaternion rotation = Quaternion.Euler( 0, 90, 0);
        vector = rotation * vector;
        Debug.Log( "After:" + vector);

Results in:

5811946--615166--Screen Shot 2020-05-06 at 9.11.22 AM.png

To rotate around another point beside (0,0,0), you subtract the origin, do the rotation, then add the origin.

Hey, thanks for the reply :slight_smile:

How would I go about working that into my script? As I say, at the moment when I hover over a brick with another brick, my code shows a Highlight brick in the correct place. But after I rotate the “Base” brick and hover again, the highlight placement is way off… I also need to work out how to deal with different brick orientations… I’ve spent too long trying to get this to work, I’ve tried so many different ideas… Think I’ve over clouded things too much

Well that is kinda the actual problem, isn’t it!!

I recommend refactoring it in a way that gives you clean functionality boundaries:

  • the ability to check a piece connects at a certain spot (including four rotations)
  • the ability to deconflict pieces that might overlap
  • the ability to link two pieces so that they are “locked together,” however that happens.

I imagine if you start with basic 2x4x3 Lego bricks, you could come up with something that works well.

Once you start adding more complicated shapes, you will have to extend whatever data structure you come up with to define a piece, such as if you have a L-shaped piece.

Either way, like all engineering, start simple, make that work, then grow from there.

I think the reason why my code isn’t working properly is due to the raycast array not rotating with the held brick…

Looks like that to me too. I don’t see you multiplying by the object’s rotation in the original code.