Have you heard of welds before? They basically attach parts together without having to anchor them, but I suggest using motor6ds which are basically the same but allow animations to be played on them.
What about making the NPCs Humanoids? Then they would fall/make contact, you could also then have them jump or do all the other things a humanoid can do.
Add a Humanoid class to your NPC model, then in script.
local human = npc.Humanoid
human.Jump = true
human.WalkSpeed = 4
etc...
I don’t recommend welding because obviously you want animations too, use a motor6d and make part0 the HRP. part1 is every other body part you want to attach to HRP aka part 0. Since HRP is usually the joint.
What about raycasting from the torso towards the floor every few frames to adjust your NPCs height? You can load balance your raycasts over multiple frames and use parallelisation to achieve very good performance that way. Setting up a smaller whitelist of specific parts you want your NPCs to stand on and keeping the raycast length somewhat low can decrease the computation time of raycasts further.
Oh, then you could use alignposition/alignorientation to keep the parts together sort of. Without humanoids, but c’mon now humanoids aren’t that evil. You should just add them.
I had a cube that needed to bounce when a player came near it, I made 3 different scripts to generate the effect using postion, CFrames or tweens using while/for/heartbeat loops (thought about making another one using raycast but I didn’t go there). They all “work” but the easiest one by far was the fourth, which was to just add a humanoid to the cube, assign the rootpart and then say cube.Jump = true.
Also makes it super simple to change walkspeed, jumpheight, walkto, slope control, name plates, hip height, etc… it’s a really handy class even if the enemy is a just cube, a model or almost anything else you want to have walk, jump or otherwise behave like a player/NPC, which really seems like a fit for what you’re trying to do.