ClampMagnitude while ignoring a direction
Hi, I've spent quite some time on this problem while looking at other answers, but I haven't been able to find a solution to this problem. I need to limit movement in 2 direction (transform.forward and transform.right) to a certain radius, while allowing free movement in 1 direction (transform.up). I needed to use transform.up because the movement is not in global up but local up instead. It should be noted that I'm setting the movement using transform.position instead of rigidbody.
My current code is:
Vector3 offset = updateTransform.position - initPos;
transform.position = initPos + Vector3.ClampMagnitude(offset, maxDistance);
initPos is the center of the circle
I would greatly appreciate any hints and help to this problem.
Thank you.
Other things I tried:
Vector2 localHand = new Vector2(updateTransform.InverseTransformPoint(transform.position).y, updateTransform.InverseTransformPoint(transform.position).z);
Vector2 localInit = new Vector2(initPos.transform.InverseTransformPoint(transform.position).y, initPos.transform.InverseTransformPoint(transform.position).z);
Vector2 localOffset = localHand - localInit;
Vector3 TrueLocalOffset = new Vector3(updateTransform.InverseTransformPoint(transform.position).x - initPos.transform.InverseTransformPoint(transform.position).x, localOffset.x, localOffset.y);
transform.localPosition = initPos.transform.InverseTransformPoint(transform.position) + TrueLocalOffset;
It still didn't work
Can't really figure out, what you're trying to do. Maybe you're trying to make something move like it traveles a vertical tube (bounded by its radius)? In this case you could try clamping the magnitude of your flat (which lies on XZ-plane) 2-D vector with Vector2.ClampMagnitude and then add to this the Y component (the amount your GameObject has traveled along Y axis) as a new 3-D vector.
Thanks for replying @LevBronstein. You're right, what I needed to do was to make object travel in a vertical tube. But the tube can rotate so I need to do the calculation in the local space. The question has been answered somewhere else. Here's the finished code for anyone else that might need it:
// Convert global start position to local space
var localInitPos = transform.InverseTransformPoint(initPos);
// Only consider position in XZ-space
var localInitPosXz = new Vector2(localInitPos.y, localInitPos.z);
var localDestPos = transform.InverseTransformPoint(updateTransform.position);
var localDestPosXz = new Vector2(localDestPos.y, localDestPos.z);
var offsetXz = localDestPosXz - localInitPosXz;
// Clamp the offset to the radius we want
var clampedOffsetXz = Vector2.ClampMagnitude(offsetXz, maxRadius);
// Add the offset to initPos to get the clamped target position
var clampedPosXz = localInitPosXz + clampedOffsetXz;
// Convert back to 3D, since we're in local space our current y is just 0
var localClampedPos = new Vector3(localDestPos.x, clampedPosXz.x, clampedPosXz.y);
// Apply as global position, applying in local space gets a bit tricky
transform.position = transform.TransformPoint(localClampedPos);
Your answer
Follow this Question
Related Questions
How to SHOOT an object on a curved path without using Rigidbody 2 Answers
My gameobject movement is slightly jumpy... why? 1 Answer
How to disable diagonal Vector3 movement of non-player object using MoveTowards? 1 Answer
Air Control While Jumping? 1 Answer
Animations are not playing with certain directions? 1 Answer