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()
