How do i make my cube stop in that exact position?

Hi everyone, I’m beginner who’s trying to create a maze game in a 3d space. I wrote a script to detect forks that uses raycast and tells when the distance from left or right changes and then stops the cube (maybe a little tricky but i couldn’t find better solutions). The problem now is that the cube stops sometimes before sometimes after the fork as you can see in the image. The funciton is called in FixedUpdate, while in update there is the “check for swipe” function (it’s a mobile game). Are there any fixes or better solutions to detect forks? I would really be thankful if someone could fix this :slight_smile: .

void FixedUpdate()
{
	if(isMoving){
		coveredDistance = (cubeTransform.position - startPos).magnitude;
		if(coveredDistance > 0.95f && coveredDistance < distanceBeforeCollision - 0.8f)
		{
			CheckForks();
		}
	}
}
void SetRayTrace(){ 
        startPos = cubeTransform.position;
        frontRay = new Ray (cubeTransform.position, moveDirection[idx]);
        Physics.Raycast(frontRay, out RaycastHit hit);
        distanceBeforeCollision = (startPos - hit.point).magnitude;
        StartCoroutine(Move());
    }
    
    IEnumerator Move(){
	isMoving = true;
	if(distanceBeforeCollision > 2.4f){
		calibration = 27;
	}
	else{
		calibration = 40;
	}
        rb.AddRelativeForce(moveDirection[idx] * distanceBeforeCollision * calibration * Time.deltaTime, ForceMode.Impulse);
        if(coveredDistance >= distanceBeforeCollision - 0.4f) //When touches wall stops
        {
		Debug.Log(coveredDistance);
		coveredDistance = 0;
            rb.velocity = Vector3.zero;
		isMoving = false;
		yield break;
        }
        yield return new WaitForFixedUpdate();
	if(isMoving){
		yield return Move();
	}
	else{
		yield break;
	}
    }

void CheckForks()
{
	if(distanceBeforeCollision > 2.4f){ //trying to put an offset to fix the position but doesnt work
		rayOrigin = cubeTransform.position - moveDirection[idx] * 0.20f;
	}
	else{
		rayOrigin = cubeTransform.position;
	}
	
	leftRay = new Ray (rayOrigin, Quaternion.AngleAxis(-90, Vector3.up) * moveDirection[idx]);
	rightRay = new Ray (rayOrigin, Quaternion.AngleAxis(90, Vector3.up) * moveDirection[idx]);

	Physics.Raycast(leftRay, out RaycastHit lHit);
	Physics.Raycast(rightRay, out RaycastHit rHit);
	
	if((lHit.point - rayOrigin).magnitude > 0.5f || (rHit.point - rayOrigin).magnitude > 0.5f)
	{
		coveredDistance = 0;
		StopCoroutine(Move());
		isMoving = false;
		StartCoroutine(Freeze());
	}
}

IEnumerator Freeze(){ //Only solution to completely stop the cube motion
	rb.constraints = RigidbodyConstraints.FreezeAll;
	yield return new WaitForEndOfFrame();
	rb.constraints = RigidbodyConstraints.None;
	rb.constraints = RigidbodyConstraints.FreezeRotation;
}

Is the maze pre-build or procedurally generated?

If it’s pre-build, just create a MovingCube C# class, let it have parameters such as StartPosition, MoveDistance, MoveSpeed, MoveDirection etc. and change initial values by hand. Then, create a collider at each fork and toggle on isTrigger.
Create a C# script that let’s the cube stop when colliding with said trigger collider and then make the cube change direction or whatever you want at will.

If you are not educated on colliders, I suggest you watch a youtube video, those will play a big role in this kind of games.

If it’s procedurally generated you could have prefabs with those colliders attached.
I also heard of a so called nav mesh (navigation mesh) you could read into, but that is not of my current knowledge.

The colliders should be very small, so they collide at the exact middle of the fork.

Thank you I will look into that(the maze is generated every time I hit play)