Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Make a gameobject's child lerp its position and rotation back to its parent

Discussion in 'Scripting' started by Benji23245, Aug 25, 2023.

  1. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Hello fellow game developers !

    I'm trying to find a way to make a gameobject's child's position and rotation to lerp to its parent's instead of following it instantly.

    I tried doing stuff like this :

    Code (CSharp):
    1. pl.mesh.position = Vector3.Lerp(pl.mesh.position, transform.position, 0.01f);
    But it doesn't work. (The script is on the parent, and pl.mesh is the child's gameobject).

    Can someone help ?

    Thank you !
     
    Last edited: Aug 25, 2023
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    The child position is its local position i.e. relative to the parent. If its at 0,0,0 then it's the same as the parent. Your lerp target should be Vector3.zero

    Is the parent moving? If so, having this as a child doesn't make much sense.
     
  3. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
  4. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Well I got this so far :

    With the oldMeshXX being the value of the pl.mesh.XX at the last frame.

    The rotation part works ! But for the position, I'm not sure what to replace the ----- with ?


    Code (CSharp):
    1. pl.mesh.position = Vector3.Slerp(oldMeshPos, -----, 15f * Time.fixedDeltaTime);
    2. pl.mesh.rotation = Quaternion.Slerp(oldMeshRot, Quaternion.LookRotation(-transform.up, transform.forward), 15f * Time.fixedDeltaTime);
     
  5. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    Ohh I see what you're saying now, but yeah as Melv stated, all you need to be messing with is the child's "localPosition". As if the child were completely on "top" of the parent, it's local position would be (0, 0, 0). So if the child moves away from parent, it'll know exactly which way to go from it's local position(as opposed to Vector3.zero), as direction would just be an inverse of that. Then just lerp that.
     
  6. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    Something like this example, you'll have to play around with it:
    Code (CSharp):
    1.  
    2. void MoveToParent(Transform child)
    3.     {
    4.         float minimumDistance = 1.5f; // to parent
    5.         if (child.localPosition.x > minimumDistance || child.localPosition.z > minimumDistance)
    6.         {
    7.             child.localPosition = Vector3.Slerp(Vector3.zero, child.localPosition, 15f * Time.fixedDeltaTime);
    8.         }
    9.     }
    10.  
     
  7. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Thanks that worked, but it's still lacking a thing, and heck, it's hard to understand how that works.

    I have this for the position setting :

    Code (CSharp):
    1. pl.mesh.localPosition = Vector3.Slerp(Vector3.zero, pl.mesh.localPosition, 15f * Time.fixedDeltaTime);
    The issue is, in reality, I want my child to always be positioned +transform.up * 0.25f - transform.forward * 0.5f relative to the parent ("transform" being the parent transform).

    When I try using these or the child's transform, it gives weird results (that vary depending on the parent rotation).

    Basically, with the code I showed above, I have this (the collider is the parent, the purple model is the child):
    upload_2023-8-25_16-26-17.png

    And I want this (here it's hardcoded) :
    upload_2023-8-25_16-27-24.png

    What should I add to the Slerp's 2nd argument ?
     
    Last edited: Aug 25, 2023
  8. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    Well transform.up is basically a Vector3 position (0,1,0) and forward is a Vector3 direction (?,?,?) depending on what way it's rotated.

    So I'm having trouble understanding what the ultimate goal is, as I feel you may be attacking this problem the wrong way.

    I assumed you had a flying bot of some sort that needs to fly back to it's parent(player). Looking at your pictures however throws me for a loop?
     
    faUnity likes this.
  9. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    It's a climbing action, what you see is the player, climbing on a surface.
    I just want to make the mesh reach the position you see on the 2nd picture with a slerp
     
  10. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    Ok, as I thought, you're approaching this the wrong way. As in, if the parent were to move up by 1, the child would have to move down by 1, and then lerp back to the parent. For an instance as this, that just makes no sense to have them grouped(inherited) together.

    So I'll assume the collider(parent) is a physics material, and does special thinking on what surface material it's on? And is basically like a grab, or push off of said area to move the child upwards?
     
  11. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Hum, yeah ? Basically what you said, when touching surfaces with certain conditions, the climb action script on the parent is enabled.

    I mean, can't this just be done without changing everything ? It's the last thing I need to have it finished :/
     
  12. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    I have to say, I actually don’t understand how your solution work ? It does work, it indeed interpolates the child position to the parent’s but how ?
    The parent position isn’t involved at all there. What does this actually do ?

    Why is it not something like this ?


    Code (CSharp):
    1. child.localPosition = Vector3.Slerp(child.localPosition, parent.localPosition, 15f * Time.fixedDeltaTime);
    2.  
    If I understood better maybe I could find a way to make it work the way it is setup ?

    Thanks a lot for the help !

    EDIT: So I managed to make it work by putting Vector3.back * 0.5f instead of Vector3.zero
    It works flawlessly even though I still don't know why the start is the end and the end the start

    EDIT2: No I saw badly, it actually doesn't work the way I wanted damn.
     
    Last edited: Aug 25, 2023
  13. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728

    Because
    parent.localPosition
    makes no sense, for one.. The childs local is always (0,0,0) from parent, unless you offset it. So if player(parent) is at (123,0,789) in world space(which would be the same as it's local), the child if right on top of him would have a local of (0,0,0) from parent. Because when using hierarchy of objects, that's all they need to know.

    Now am I saying that there would never be a use for a child object to give its world position? No, it might actually be needed in some cases, except yours..

    Thinking on your whole setup, there's no reason for you to have a child or parent move in relation to how the other moves. Unless you were making some real-physics based VR game like "Cliffhanger". You only need one object(the player) and according to what surface he's on moves at a set speed accordingly(or in bursts to pretend like he's climbing).

    You may be thinking of how animations make things "look like" they're actually doing something, but there not. Animations are just pre-recorded mesh movements that only work in a case-by-case basis. So if your trying to approach this action in your game, applying real-life physics to a game, you're gonna do nothing but give yourself headaches.

    Trust me, I know, one of my projects is a human mesh that literally uses it's feet to move, with contact of a load bearing foot. And moves it's body in relation to it's surroundings, along with it's head, arms, and hands. It's the most ambitious project I ever took on, and it's been placed to the far back burner for now(due to headaches), lol...

    But games really use simple logic, and the developer himself is a magician to make you think otherwise, when you see things act like they're really thinking. It's all pre-made, and recorded..

    However, with how crazy AI is getting, it won't be long before I can have AI run my human mesh, just like it's a real boy!

    But just keep it simple for now. :)
     
  14. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    From what I've seen, and the people I talked to, I thought it was a good setup to have a character be a gameobject with children such as the mesh, the sounds, the effects etc.

    It usually works well, and the mesh follows the parent all the time except for this bit because of this :

    This is without any position/rotation lerp on the mesh (I can't lerp the parent position because then the raycasts fire on the wrong places and everything's a mess, and I've already spent too much time on this action for my own sanity) :

    bandicam-2023-08-26-00-05-02-504.gif

    With a rotation lerp I get this :
    bandicam-2023-08-26-00-04-09-781.gif

    And my goal is this (bad quality, but basically it lerps position and rotation) :
    bandicam-2023-08-26-00-08-26-841.gif
     
  15. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    I think I can't use the localPosition of the mesh, I need to save the global position of the mesh on the previous frame, every frame and lerp on this but it doesn't work and I can't figure out why.

    I do this every frame :


    Code (CSharp):
    1. prevMeshPosition = pl.mesh.position;
    2. pl.mesh.position = Vector3.Slerp(prevMeshPosition, transform.position, 15f * Time.fixedDeltaTime);
    Why doesn't this work ? I mean, I'm litterally setting the mesh position regardless of the parent right ? (sort of)

    At some point in time it's at position (x, y, z), I save that in prevMeshRotation, and then say "mesh position is now wherever the prevMeshRotation is + a lerp step to the parent's global position".
    And repeat, again and again.

    Do you know how to make this work somehow ?

    Plus, I do exactly that for the rotation, and it works no problem :


    Code (CSharp):
    1.  Quaternion prevMeshRotation = pl.mesh.rotation;
    2. pl.mesh.rotation = Quaternion.Slerp(prevMeshRotation, Quaternion.LookRotation(-transform.up, transform.forward), 15f * Time.fixedDeltaTime);
    Why is position different ?
     
  16. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    Ok, so I completely misunderstood you, I thought you had the parent using a collider to move with the child staying still, then the child moving to compensate new position(like a hand pulling up a climber up a cliff). So way off on my part, sorry!

    Yes, it's perfectly fine to have a empty gameObject that uses the child mesh as the player in game. I do that all the time.

    So in this case, you already have the parent using the surface normal, awesome! Now all you need to do is actually get the child's world rotation(ironic, I know) so it knows to stand straight up, regardless of incline parent is on. That would be Vector3.up(if the world is normal up/down).

    So you do want to slerp from the (child)world previous rotation, to world up. Except for climbing up a vertical as the example shows, that's almost like a 45 degree angle.
     
  17. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    As far as your child position, that looks fine *
     
  18. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Hey, thanks for all the replies ! Now I have to ask, and I hope I’m not pushing it, but it’s been hours of trying and failing and my eyes genuinely hurt. Would you mind telling me the formula for this please ?
     
  19. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    But you'll notice in that example, the child doesn't move from it's position(from parent), all it does is change its rotation due to the surface angle it's on. Magic!

    It would look very similar to this:
    Code (CSharp):
    1. pl.mesh.rotation = Quaternion.Slerp(parentRotation, Quaternion.Euler(Vector3.up), 15f * Time.fixedDeltaTime);
    I don't have a testable setup right now, so the parentRotation might need changed to something else, but the second parameter definitely needs to be world up(Vector3.up).
     
  20. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    was error, might need to refresh page ^
     
  21. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Uh what ? Well the parent rotate on the wall because I tell it to (I use a raycast and rotate according the the hit) (1st video)

    Then I already lerp the rotation of the child (2nd video)

    And now I need to lerp the position of the child the same way.

    I’m not sure why you tell me to lerp the rotation on ne more time ?
     
  22. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    You want the child standing straight up, when parent is on incline.. right? straight up is Vector3.up.

    You might need to set it from childs last rotation, not parent rotation. Like I said I can't test it on my own side atm
     
  23. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Well no I don’t care about the way he’s standing up ^^
    He’s already properly standing. But I want him to lerp his position
     
  24. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    All lerp or slerp does, is takes the first parameter and gets the difference from the second parameter, then moves it by the third parameter(speed and how much). So true, should be childs last rotation
     
  25. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Basically when the parent snaps on the wall (thanks to a position setting at the raycastHit.point) I want the child to not also be snapped. I want him to lerp from where he was right before the snap to where the parent is now
     
  26. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Ok I must be too dumb or tired, but I don’t get it.

    So what would such a formula look like ?

    pl.mesh.rotation = something ?

    But so I lerp the rotation twice but in different ways ..?
     
  27. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    He's supposed to be face flat when on incline? ok, thought that's what you didn't want..

    I'm not sure why you want the position to change, as the example you show doesn't do that. But you would need to get the childs world position set constantly as a "lastPosition" and when the parent changes it's surface normal, and moves a bit, you'd have to set the childs local position to a offset from the parents new world position, from that childs old world position, subtract that, then make the childs local position that offset. then once the child has that offset(being back where he was) he then slerps from his local position back to (0,0,0) which would be parents current position.

    Which just even thinking that out, confused me, so I'm sure I said something wrong somewhere. It's just an awful lot of mess to do it that way, for something your eye would barely see anyway.
     
  28. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Don’t you see in the 2nd video ? The « head » of the model clearly goes through the wall because the parents snaps down below. If I lerp the position it wouldn’t happen.

    In the 3rd video, it doesn’t happen, so I figured it’s what had to be done ?

    Please mate, you would really do me a favor there, I mean I could finally close the book on that action that took me so much time and effort to do. Leaving it unfinished would be hard on me.

    I’ll try implementing what you last said tomorrow as it’s 1 am here and I’m exhausted. Hope it works. But thanks anyway, I really appreciate the help
     
  29. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    Just don't slerp/lerp the position. the local position should never change. The only thing that changes in that example video is the rotation. Which to be fair is just the surface normal the parent would be anyway. Except of course for a complete vertical, as it shows the character at a 45 degree angle. But the position never moves.

    Yup, attack it again with a fresh mind. :)
     
  30. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    But it has to move. How could a child rotation compensate the parent’s position’s raycastHit.point snap ?
     
  31. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    the raycast should be aiming at a surface, then getting that hit position as a hit.normal, which would be it's direction to stay "up" or "away from" on always. the child technically doesn't need to know this, since it's childed. It moves with the parent.
     
  32. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    Ok, so I literally frame grabbed the example:
    Example_01.png
    As you can see, the parent's up is facing to the right, which would be the surface hit from hit.normal. The character still in the same local position.
    Example_02.png
    Now it was hard to grab the angle change, but the parent normal now rotates on the new surface angle. And since the character was already at a 45 degree angle, this makes the transition seem seamless.
    Example_03.png
    The next frame after that, is still all the same values. But 2 45 angles make a perfect 90, so now the character seems to be aiming world up, but really nothing has changed.

    This would be until the hit surface becomes perfectly horizontal, then the character would go back 45 degrees to seem standing straight up.

    So like I said before, the devs make it seem magic, when it's really simple math. In this particular instance, there really is no change at all, from a vertical to an incline.

    So I'm not sure exactly what it is your trying to recreate, but it's not this scene ^
     
  33. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Are you saying that my stupid eyes saw a lerp when really there isn’t any ?

    Now I’m super confused. On what I have to do.
     
  34. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    I would have to concur. As I've never really seen someone change the childs local position from the parent. That's the whole point of having an object childed, so that positional offset never needs to be calculated, or recalculated.

    I mean, I'm not saying it's impossible to change the childs offset to parent, but I will agree it would be a coding nightmare. As it would take a good amount of coding, and time calculations to make sure everything looks right depending on the distance. Just I, personally, wouldn't want to tackle it. It's always best to make code as simple as possible, and "cheese" it where you can. :)
     
  35. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    No no I found a solution I think. When I set the parent position, I should set the child local position to the opposite and then lerp back to zero but I can’t find the formula to get the vector.

    Now I have to say I tried for like 4 mins this morning so I certainly got it wrong. I didn’t have more time.

    I think I should set the child local position to transform.position - hit.point or something
     
  36. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    So I finally did a quick test, and it looks more like this:
    Code (CSharp):
    1. public class ChildParentMove : MonoBehaviour
    2. {
    3.     public Transform childTrans;
    4.     Vector3 childOriginOffset;
    5.     Vector3 parentLastPos;
    6.  
    7.     void Start()
    8.     {
    9.         childOriginOffset = childTrans.localPosition;
    10.         parentLastPos = transform.position;
    11.         transform.Translate(-1.0f, 0, 0); // move to left 1 unit
    12.         childTrans.localPosition = childOriginOffset + (parentLastPos - transform.position);
    13.     }
    14.  
    15.     void Update()
    16.     {
    17.         if (childTrans.localPosition != childOriginOffset)
    18.         {
    19.             childTrans.localPosition = Vector3.Slerp(childTrans.localPosition, childOriginOffset, 0.01f);
    20.         }
    21.     }
    22. }
    You'll obviously need a bunch of checks, to only run certain parts of this, during certain frames. But, if parent moved by 1 unit, the child gets placed back to where it was originally, then lerps back to the parent. :)
     
  37. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    So I did this, and it doesn't work at all, why ?


    Code (CSharp):
    1. if (my_condition) {
    2.       Quaternion prevRotation = transform.rotation;
    3.       Quaternion newRotation = Quaternion.LookRotation(tangent, wallHit.normal);
    4.       transform.rotation = newRotation;
    5.  
    6.       if (Quaternion.Angle(prevRotation, newRotation) > 0.1f) {
    7.         Vector3 prevPosition = transform.position;
    8.         transform.position = wallHit.point + transform.up * 0.25f;
    9.  
    10.         Vector3 delta = transform.position - prevPosition;
    11.  
    12.         pl.mesh.localPosition -= delta;
    13.       }
    14.     }
    15.  
    16.     pl.mesh.localPosition = Vector3.Slerp(pl.mesh.localPosition, -transform.forward * 0.5f, 5f * Time.deltaTime);
    "my_condition" is executed when reaching a new wall angle. If so, I set the child (pl.mesh)'s position to be what it was minus that delta, and then lerp every frame.

    Please tell me what I did wrong ?

    I tried using this :
    Code (CSharp):
    1. Vector3 delta = transform.TransformVector(transform.position) - transform.TransformVector(prevPosition);
    And now he goes sideways oO

    Maybe it is linked to the fact that the parent is rotated ..?
     
    Last edited: Aug 26, 2023
  38. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    I'm going nuts.

    If I do this :

    Code (CSharp):
    1. child.position = Vector3.one
    for example, I do see my mesh at exactly (1,1,1) in world space.

    If I log
    Code (CSharp):
    1. transform.TransformVector(parentPrevPosition)
    I do see in the log, the value in world space of my parent. So if my parent is at (1,1,1) in world space, I will see (1,1,1) in the log.

    But if I do
    Code (CSharp):
    1. child.position = transform.TransformVector(parentPrevPosition)
    the child yeets f*cking wherever.

    How is that mathematically possible ??

    It appears it's related to the parent rotation. Setting the child.position to transform.TransformVector(parentPrevPosition) gives the desired result only if the rotation of the parent is (0,0,0).

    Why ...?
     
    Last edited: Aug 26, 2023
  39. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    I have no clue why all these new ideas you're trying, that are different than the working example I gave you, aren't working. Can't say.. You're best to just keep debugging, either printing out positions, or using
    Debug.DrawRay()
    or
    Debug.DrawLine()
    to see vectors and directions physically while in Scene Mode.

    Whenever I want to do crazy new stuff, my code is littered with debugs, lol
     
  40. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    But I tried your solution and it didn't work :(
     
  41. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    I got the child to follow lerp, regardless of rotation of parent. So copy this script, and paste it into a debug parent(cube) that has a child(capsule) above it, see what it does, and play with it after the fact. And keep this script as a reference.
    Code (CSharp):
    1. public class ChildParentMove : MonoBehaviour
    2. {
    3.     public Transform childTrans;
    4.     Vector3 childOriginOffset; // normal position on parent
    5.     Vector3 parentLastPos;
    6.     float slerpBy = 0.25f; // 0.00 ~ 1.00 = percent to lerp
    7.  
    8.     public bool rotate;
    9.     [Range(0.1f, 100f)]
    10.     public float speed;
    11.  
    12.     void Start()
    13.     {
    14.         Application.targetFrameRate = 60;
    15.         childOriginOffset = childTrans.localPosition;
    16.         parentLastPos = transform.position;
    17.         //speed = 4; // debug set
    18.         //rotate = true; // debug set
    19.     }
    20.  
    21.     void Update()
    22.     {
    23.         if (rotate)
    24.         {
    25.             transform.Translate(0, 0, speed / 10f);
    26.             transform.Rotate(0, speed, 0);
    27.         }
    28.  
    29.         if (transform.position != parentLastPos)
    30.         {
    31.             Vector3 forwardOffset = parentLastPos - transform.position;
    32.             childTrans.localPosition -= new Vector3(0, 0, Mathf.Abs(forwardOffset.z));
    33.         }
    34.  
    35.         if (childTrans.localPosition != childOriginOffset)
    36.         {
    37.             Vector3 localOffset = Vector3.Slerp(childTrans.localPosition, childOriginOffset, slerpBy);
    38.             childTrans.localPosition = new Vector3(0, childOriginOffset.y, localOffset.z);
    39.             parentLastPos = transform.position;
    40.         }
    41.     }
    42. }
    But after this ^, I have no more ideas.
     
  42. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Ok I think I managed to make it work, thanks !

    I'm facing an issue I just noticed though, for another case.

    The child (like any other object I rotate through code apparently) rotates around its pivot point. How can I make it rotate around its center instead ? I can't find a method for this

    Thanks again for the help !!
     
  43. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Oh well, so apparently the child's pivot was at the feet, so I parented it so that the pivot is at the middle and now it works perfectly, thanks again so much for all your time @wideeyenow_unity !

    For anyone interested, here's my solution :


    Code (CSharp):
    1. if (my_specific_condition) {
    2.       Quaternion prevRotation = transform.rotation;
    3.       Quaternion newRotation = Quaternion.LookRotation(tangent, wallHit.normal);
    4.       transform.rotation = newRotation; // Set new parent rotation to apply parent position change below
    5.  
    6.       if (Quaternion.Angle(prevRotation, newRotation) > 0.1f) {
    7.         Vector3 prevPos = transform.position;
    8.         transform.position = wallHit.point + transform.up * 0.25f;
    9.  
    10.         transform.rotation = prevRotation;// Set back the parent rotation to the previous frame one
    11.         Vector3 offset = prevPos - transform.position; // Calculate the offset in world space
    12.         transform.rotation = newRotation; // Re-apply new rotation to parent
    13.  
    14.         pl.mesh.position = transform.position + offset; // Set the child's world position
    15.       }
    16.     }
    17.  
    18.     pl.mesh.localPosition = Vector3.Slerp(pl.mesh.localPosition, Vector3.zero, 20f * Time.deltaTime); // Lerp back to parent
    19.     pl.mesh.rotation = Quaternion.Slerp(prevMeshRotation, Quaternion.LookRotation(-transform.up, transform.forward), 20f * Time.fixedDeltaTime); // Rotation was so much easier, just lerp to the new parent rotation
     
    wideeyenow_unity likes this.