It is fairly surprising how many incomplete or rather wrong replies I have found online in this forum, as well as in the Q.A. section and in Gamedev, when looking for a way to implement Lerping, Slerping or MovingToward in relation to a parent, i.e. in local position. I will explain the problem and later ask for you guys to say what do you think of the only solution I could think of (improvements are needed).
Bear with me. I have the following setting: Cube B, the character, is a child of Cube A, the floor. I have to make B move around over the top face of A, using only Lerp, Slerp or MoveToward (other options are excluded here, for the purpose of this question). And it has to move only in terms of local position, i.e. in reference to the parent A.
As I said, many people have asked this before (in the end I link to some of these debates), and replies are usually that one should merely go for it, with the usual line of code to give the final command:
CubeB.transform.localPosition = Vector3.Lerp(CubeB.transform.localPosition , newlocalposition, pct);
However, as we know, in programming, the fact that a resulting number was yielded from a formula does not mean that the desired thing was achieved. That approach to local Lerp/Slerp/MoveToward simply does not work properly for most game purposes. The reason is the following: no matter how big are the X and Z (let’s forget the Y for the sake of simplicity) dimensions of my floor, i.e. the Cube A, the local space of its child Cube B is always 0<X<1 and 0<Z<1. Which, of course, distorts the results when one uses Lerp/Slerp/MoveToward on local coords, since B takes the same amount of time to move over the width or the depth of A, no matter the size of the dimensions of A in global scale! Hence, the movement is accelerated in different magnitudes depending on the axis (even when using MoveToward), because in local scale, the parent dimensions is always 1,y,1 to the children.
For a concrete example, suppose B is located at the lower-left corner of the top face of Cube A and then moves to the lower-right corner and then form there to the up-right corner. That will always mean, in local coords, that Cube B started at X=-.5, Z= -.5 then moved to X= +.5, Z= -.5 and then later from there to X= +.5, X= +.5. No matter the dimensions of Cube A, the parent, in global scale. No matter for instance if Cube A is X=10, z= 200 in global terms, etc. Therefore, the visual effect caused when Learping/Slearping/MovingTowards in local coord is that Cube B would move in much greater velocity when going trough z than when going trough x.
So, all this to ask, beg, implore: does any charitable soul know how can one properly use Lerp/Slerp/MoveToward related to a parent, i.e. in the local space, in local terms? I mean, in a way that, in the end, it does not take the same amount of time for Cube B in my example to move different distances? So far I came up with the following, but I am not sure this is the best/most efficient/elegant way of achieving the desired result (still, it might be of some help for lost souls like mine):
IEnumerator MovingNPC_go(Vector3 newlocalposition)
{
float cubeB_speed= 1.5F;
float cubeA_width = cubeA.GetComponent<Renderer>().bounds.size.x;
float cubeA_depth = cubeA.GetComponent<Renderer>().bounds.size.z;
while (cubeB_localPos != newlocalposition)
{
cubeB_localPos = cubeB.transform.localPosition;
float global_x = Mathf.Lerp(cubeB_localPos.x*cubeA_width,newlocalposition.x*cubeA_width,Time.deltaTime*cubeB_speed);
float global_z = Mathf.Lerp(cubeB_localPos.z*cubeA_depth,newlocalposition.z*cubeA_depth,Time.deltaTime*cubeB_speed);
npc.transform.localPosition = new Vector3(global_x/cubeA_width,cubeB_localPos.y ,global_z/cubeA_depth);
yield return null;
}
}
If anyone could give me a hand here, do not be shy. I would kindly appreciate your kind attention.
PS: examples of former debates on this issue, which either do not address the issue or give fairly mistaken solutions: