I have developed a script for morphs, like dragons and such, that makes their limbs dynamic. The code I made is called MorphAnimator V2 (or MAV2 for short). It works by anchoring the player, gathering the positions of the morphs arms and legs relative to the morph's middle, then it creates a "fake arm", re-sizes the character's arms and legs, then welds the fake-arm to the original for collision fixes. Finally, since re-sizing limbs breaks joints, it re-creates Motor6Ds and sets the C0 of them to the positions it gathered. This works GREAT! But, there is one problem I am having with it: The Motor6D's joint location has been moved. In your ROBLOXian, the point of rotation is on the top of the block. After morphing, it is transferred to the center of the block. Does anyone know how to fix it?
Here's the Pre-code. It has a LocalScript inside, and the Vector3Values inside of the LocalScript.
db = false toucher = nil function FindHumanoid(model) --Instead of searching for the name, search for a humanoid instance f = false for _, v in ipairs(model:GetChildren()) do if v:IsA("Humanoid") then f = true return v end end if not f then return nil end end function GrabOffsets() local main = script.Parent.Parent local arm1 = main.Arm1.Middle.Position local arm2 = main.Arm2.Middle.Position local leg1 = main.Leg1.Middle.Position local leg2 = main.Leg2.Middle.Position local core = main.Chest.Middle.Position local offset1 = (core - arm1) local offset2 = (core - arm2) local offset3 = (core - leg1) local offset4 = (core - leg2) local ls = script['LocalScript'] ls.Arm1.Value = offset1 ls.Arm2.Value = offset2 ls.Leg1.Value = offset3 ls.Leg2.Value = offset4 end function onTouch(part) toucher = part.Parent.Name if db then return end --If the debounce is enabled, return to the start of the code and try again if not db then --If debounce is disabled, continue! db = true --Enable the debounce while we're doing this. local human = FindHumanoid(part.Parent) local LimbControl = script:findFirstChild("LocalScript") if human ~= nil then GrabOffsets() local Clone = LimbControl:Clone() Clone.Parent = workspace:findFirstChild(toucher) Clone.Disabled = false --Enable the code end end wait(1) db = false --Disable the debounce toucher = nil --Erase toucher data end script.Parent.Touched:connect(onTouch) --Fire the onTouch function when someone touches.
Here's the LocalScript
Limbs = {} JointNames = {"Left Shoulder", "Right Shoulder", "Left Hip", "Right Hip"} t = 2 function WeldMorphLimbs(limb, part) local WELD = Instance.new("Weld") WELD.Part0 = limb WELD.Part1 = part WELD.Parent = limb WELD.C0 = CFrame.new(0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1) end function NewJoint(part, Torso, n) local a = Instance.new("Motor6D", Torso) a.Name = JointNames[n] a.Part0 = Torso a.Part1 = part part.Anchored = false end function GUI(val) local a = Instance.new("ScreenGui", game.Players.LocalPlayer.PlayerGui) local b = Instance.new("Message", a) if val == 1 then b.Text = 'In the next few seconds, your body is gonna do some weird stuff!' wait(t/2) b.Text = 'Calculating...' wait(t/4) b.Text = 'Gathering collision...' wait(t/4) b.Text = 'Computing welds, moves, and animations...' wait(t/4) elseif val == 2 then b.Text = 'Moving body CFrame to get you un-stuck...' wait(1) b.Text = 'Animating...' wait(0.5) b.Text = "Removing properties of humanoid legs... (so you don't do the falling animation)" wait(1) b.Text = 'Complete!' wait(0.5) end a:Destroy() end base = script.Parent BodyParts = {base["Left Arm"], base["Right Arm"], base["Left Leg"], base["Right Leg"]} function CFUP(a, c, torso) --Gets players unstuck p = base.Arm1 o = base.Arm2 i = base.Leg1 u = base.Leg2 for q,w in ipairs(p:GetChildren()) do if w:IsA("BasePart") then w.Anchored = true end end for q,w in ipairs(o:GetChildren()) do if w:IsA("BasePart") then w.Anchored = true end end for q,w in ipairs(i:GetChildren()) do if w:IsA("BasePart") then w.Anchored = true end end for q,w in ipairs(u:GetChildren()) do if w:IsA("BasePart") then w.Anchored = true end end val = nil if a > c then val = a end if c > a then val = c end if a == c then val = a end GUI(2) human = torso.Parent.Humanoid human.LeftLeg = human.LeftLeg.Part human.RightLeg = human.RightLeg.Part torso.CFrame = CFrame.new(torso.Position.X, torso.Position.Y + val+2, torso.Position.Z) FinalMove(BodyParts[1].Parent) end function WeldNewLimbs() GUI(1) a = base.Arm1.Middle.Size b = base.Arm2.Middle.Size c = base.Leg1.Middle.Size d = base.Leg2.Middle.Size MIDS = { base.Arm1.Middle, base.Arm2.Middle, base.Leg1.Middle, base.Leg2.Middle } r = #Limbs m = Limbs for j = 1, r do BodyParts[j].Anchored = true if j == 1 then m[j].Size = a elseif j == 2 then m[j].Size = b elseif j == 3 then m[j].Size = c elseif j == 4 then m[j].Size = d end BodyParts[j].Size = m[j].Size NewJoint(BodyParts[j], BodyParts[j].Parent.Torso, j) local weld = Instance.new("Weld") weld.Part0 = m[j] weld.Part1 = BodyParts[j] weld.Parent = m[j] weld.C0 = CFrame.new(0, 0, 0) m[j].Parent = BodyParts[j] WeldMorphLimbs(BodyParts[j], MIDS[j]) end CFUP(a.Y, c.Y, BodyParts[1].Parent.Torso) end function CreateNewLimbs() for i = 1, 4 do local a = Instance.new("Part") a.FormFactor = "Custom" a.Size = Vector3.new(1, 2, 1) --^ All limbs are that size ^-- Limbs[i] = a a.Transparency = 1 end WeldNewLimbs() end function FinalMove(playrobot) --Don't blame me! This was inspired by PlayRobot's morph magic :( for q,w in ipairs(p:GetChildren()) do if w:IsA("BasePart") then w.Anchored = false end end for q,w in ipairs(o:GetChildren()) do if w:IsA("BasePart") then w.Anchored = false end end for q,w in ipairs(i:GetChildren()) do if w:IsA("BasePart") then w.Anchored = false end end for q,w in ipairs(u:GetChildren()) do if w:IsA("BasePart") then w.Anchored = false end end local base = script local arm1 = base["Arm1"].Value local arm2 = base["Arm2"].Value local leg1 = base["Leg1"].Value local leg2 = base["Leg2"].Value lh=playrobot.Torso:findFirstChild("Left Hip") lh.Part0=playrobot.Torso lh.Part1=playrobot:findFirstChild("Left Leg") lh.C0=CFrame.new(leg1.X, -leg1.Y, leg1.Z, 0, 0, -1, 0, 1, 0, 1, 0, 0) rh=playrobot.Torso:findFirstChild("Right Hip") rh.Part0=playrobot.Torso rh.Part1=playrobot:findFirstChild("Right Leg") rh.C0=CFrame.new(leg2.X, -leg2.Y, leg2.Z, 0, 0, 1, 0, 1, 0, -1, 0, 0) ls=playrobot.Torso:findFirstChild("Left Shoulder") ls.Part0=playrobot.Torso ls.Part1=playrobot:findFirstChild("Left Arm") ls.C0=CFrame.new(arm1.X, -arm1.Y, arm1.Z, 0, 0, -1, 0, 1, 0, 1, 0, 0) rs=playrobot.Torso:findFirstChild("Right Shoulder") rs.Part0=playrobot.Torso rs.Part1=playrobot:findFirstChild("Right Arm") rs.C0=CFrame.new(arm2.X, -arm2.Y, arm2.Z, 0, 0, 1, 0, 1, 0, -1, 0, 0) local sign = Instance.new("FunctionalTest") sign.Name = "Ready" sign.Description = "FunctionalTests are awesome like this" sign.Parent = playrobot wait(5) sign:Destroy() end CreateNewLimbs()