I have a script that lets player move a Rigidbody in my game with a mouse, and I want some objects to snap to other objects' axis (let's say guide) when they are near. So when an object is close to the guide, it will move only along the guide's axis (for example only along guide.transform.up
). My current logic is thet when a raycast hits the guide, it affects the position of an object. So the new position is:
transform.position + Vector3.Scale(guide.transform.position - hit.point, guide.transform.up)
Then I linear interpolate the result to get a smoother movement. It works only when guide.transform.up
is facing up or right in the world space, but also I don't think that Vector3.Scale
is a way to go with it, but I haven't found a method that can do what I'm trying here. Maybe I need to do some math here?
Edit: This is the code used for movement/rotation. It works fine:
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
LayerMask layerMask = LayerMask.GetMask("Default");
if (Physics.Raycast(ray, out RaycastHit hit, Mathf.Infinity, layerMask) || lastTrigger)
{
Vector3 hitPoint = lastTrigger ? triggerHitPoint : hit.point;
rb.MovePosition(Vector3.Lerp(transform.position, GetNewPosition(hitPoint), moveSpeed));
if (!updateRotation && (hit.normal == lastHitNormal || lastTrigger))
{
if (initRotation)
{
targetRotation = GetRotation();
initRotation = false;
}
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotTime);
rotTime += Time.deltaTime * rotationSpeed;
}
else
{
rotTime = 0;
initRotation = true;
updateRotation = false;
}
lastHitNormal = hit.normal;
So 2 functions GetRotation()
and GetNewPosition()
are replaced in child class (a class that should snap to axis when moving) with this:
protected override Vector3 GetNewPosition(Vector3 hitPoint)
{
if (triggered)
{
Vector3 movement = Vector3.Scale(triggerTransform.position - hitPoint, triggerTransform.up);
return initHookPosition + movement;
}
return base.GetNewPosition(hitPoint);
}
protected override Quaternion GetRotation()
{
if (triggered)
{
Quaternion faceUp = Quaternion.FromToRotation(transform.up, triggerTransform.up);
Quaternion faceFront = Quaternion.FromToRotation(transform.right, triggerTransform.right);
transform.up = triggerTransform.up;
return transform.rotation;
}
return base.GetRotation();
}
The rotation is bugged right now, but if I use transform.up = triggerTransform.up
it works as intended, so no big deal.
Here is how it works: video on Google Drive