Quantcast
Channel: Answers by "Dreamblur"
Viewing all articles
Browse latest Browse all 56

Answer by Dreamblur

$
0
0
Here's an incomplete answer: using UnityEngine; using System.Collections; public class SnapAndAlignScript : MonoBehaviour { private Transform thisTransform; private Vector3 originOfRaycastForNeighboringCubeDetection; private Vector3[] dirOfRaycastForNeighboringCubeDetection; private RaycastHit[] raycastHitForNeighboringCubeDetection = new RaycastHit[6]; private float fLengthOfRaycastForNeighboringCubeDetection = 3f; private float fDistToNearestNeighboringCubeFace = 1000f; private Vector3 dirOfFaceFromWhereNearestNeighboringCubeWasDetected; private Transform nearestNeighboringCubeTransform; private Vector3 dirOfNormalOfFaceOfNearestNeighboringCubeToMatch; private int nSharedIndex; private float fSizeOfCube = 1f; private void Awake() { thisTransform = transform; dirOfRaycastForNeighboringCubeDetection = new Vector3[6] {-Vector3.right, Vector3.right, -Vector3.up, Vector3.up, -Vector3.forward, Vector3.forward}; } private void Update() { if(Input.GetKeyDown(KeyCode.P)) { SnapAndAlign(); } } private void SnapAndAlign() { originOfRaycastForNeighboringCubeDetection = thisTransform.position; // STEP 1 for(int i = 0; i < 6; i++) // detect neighboring cubes within a certain distance from the center of the released cube { Physics.Raycast(originOfRaycastForNeighboringCubeDetection, thisTransform.TransformDirection(dirOfRaycastForNeighboringCubeDetection[i]), out raycastHitForNeighboringCubeDetection[i], fLengthOfRaycastForNeighboringCubeDetection); // get the shortest raycast to find the nearest face if((raycastHitForNeighboringCubeDetection[i].collider != null) && (fDistToNearestNeighboringCubeFace > raycastHitForNeighboringCubeDetection[i].distance)) { nSharedIndex = i; fDistToNearestNeighboringCubeFace = raycastHitForNeighboringCubeDetection[i].distance; } } // store the transform of the nearest neighboring cube nearestNeighboringCubeTransform = raycastHitForNeighboringCubeDetection[nSharedIndex].collider.transform; // STEP 2 // store the direction of the face from where the nearest neighboring cube was detected dirOfFaceFromWhereNearestNeighboringCubeWasDetected = dirOfRaycastForNeighboringCubeDetection[nSharedIndex]; // STEP 3 // store the direction of the face opposite to the normal of the surface hit by the raycast dirOfNormalOfFaceOfNearestNeighboringCubeToMatch = -nearestNeighboringCubeTransform.InverseTransformDirection(raycastHitForNeighboringCubeDetection[nSharedIndex].normal); // STEP 4 thisTransform.position = nearestNeighboringCubeTransform.position; // STEP 5, STEP 6 thisTransform.rotation.SetFromToRotation(thisTransform.TransformDirection(dirOfFaceFromWhereNearestNeighboringCubeWasDetected), nearestNeighboringCubeTransform.TransformDirection(dirOfNormalOfFaceOfNearestNeighboringCubeToMatch)); // STEP 7 thisTransform.Translate(-dirOfFaceFromWhereNearestNeighboringCubeWasDetected * fSizeOfCube); } } Here's how the principle works: 1. Send out a raycast along all 6 local axes of the released cube to find the nearest neighboring non-moving cube. 2. Store the "direction" of the face of the released cube that "found" the nearest non-moving cube. 3. Store the "direction" of the face OPPOSITE to the face of the non-moving cube detected by the raycast. 4. Align the centers of both cubes. 5. With the "directions" that you got from steps 2 and 3, you can now get the normals of the faces of the cubes which face the same general direction. 6. Here's where the incompleteness lies. With the normals that you get from Step 5, rotate the released cube so that the 2 normals will "match". Now, from what I can tell, Quaternion.SetFromToRotation is supposed to produce a rotation from one direction to another, which I thought would work for doing this. But it's not producing any rotation so I may have misunderstood what it's for or I may be using it wrong. Regardless, the point is to match those normals. 7. And lastly, move the released cube a number of units in the direction opposite of where the matched normals point to. So the only problem left is producing the rotation given 2 direction vectors. Maybe someone who's better acquainted with Hamiltonian math can help you there. But this would be a general "snapping" algorithm. This only works for cubes of the same size though.

Viewing all articles
Browse latest Browse all 56

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>