I tried to modify Realism 3.0 with my FE Gun Kit and how the muzzle flash doesn’t attach to the gun inside viewmodel?
Server script:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- CloneTrooper1019, 2014
-- Realism Mode (Server Side)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- MAIN DIFFERENCES:
-- The script only takes care of the joint CFrame replication to the serverside.
-- The client script is still the same, but it will Fire to UpdateY when the camera changes at a 0.1 interval
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local updateY = script:WaitForChild("UpdateY")
local origins = {}
local function recordOrigins(...)
for _,joint in pairs{...} do
origins[joint] = { C0 = joint.C0, C1 = joint.C1 }
end
end
local char = script.Parent
local player = game.Players:GetPlayerFromCharacter(char)
local humanoid = char:WaitForChild("Humanoid")
local head = char:WaitForChild("Head")
local torso = char:WaitForChild("Torso")
local root = char:WaitForChild("HumanoidRootPart")
local rootJ = root:WaitForChild("RootJoint")
local lhip = torso:WaitForChild("Left Hip")
local lshoulder = torso:WaitForChild("Left Shoulder")
local rshoulder = torso:WaitForChild("Right Shoulder")
local rhip = torso:WaitForChild("Right Hip")
local neck = torso:WaitForChild("Neck")
local updateY = script:WaitForChild("UpdateY")
rootJ.C0 = CFrame.new(0, 0, 0, -0.95533663, -0.295520246, 0, 0, 0, 1, -0.295520246, 0.95533663, 0)
neck.C0 = CFrame.new(0, 1, 0, -0.955336511, 0.295520216, 0, 0, 0, 1, 0.295520216, 0.955336511, 0)
recordOrigins(neck,lshoulder,rshoulder)
local factors =
{
[neck] = Vector3.new(-1,0,0);
[lshoulder] = Vector3.new(0,0,-1);
[rshoulder] = Vector3.new(0,0,1);
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local function onCameraUpdate(p,camY)
if player == p then
local look = camY
for joint,factor in pairs(factors) do
local origin = origins[joint]
local factor = factor * look
local x,y,z = factor.X, factor.Y, factor.Z
joint.C0 = origin.C0 * CFrame.Angles(x,y,z)
end
neck.C0 = neck.C0 * CFrame.new(0,look/4 - 0.05,0.05 + math.max(0,look/10))
end
end
updateY.OnServerEvent:connect(onCameraUpdate)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Client script:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @CloneTrooper1019, 2015
-- Realism 3 Client
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local c = workspace.CurrentCamera
local rs = game:GetService("RunService")
local self = script.Parent
local char = self.Parent
local charTorso = char:WaitForChild("Torso")
local charHead = char:WaitForChild("Head")
local root = char:WaitForChild("HumanoidRootPart")
local rootJ = root:WaitForChild("RootJoint")
local lshoulder = charTorso:WaitForChild("Left Shoulder")
local rshoulder = charTorso:WaitForChild("Right Shoulder")
local neck = charTorso:WaitForChild("Neck")
local humanoid = char:WaitForChild("Humanoid")
local updateY = self:WaitForChild("UpdateY")
local origins = {}
local factors = {}
local function recordOrigins(...)
for _,joint in pairs{...} do
origins[joint] = { C0 = joint.C0, C1 = joint.C1 }
end
end
rootJ.C0 = CFrame.new(0, 0, 0, -0.95533663, -0.295520246, 0, 0, 0, 1, -0.295520246, 0.95533663, 0)
neck.C0 = CFrame.new(0, 1, 0, -0.955336511, 0.295520216, 0, 0, 0, 1, 0.295520216, 0.955336511, 0)
recordOrigins(neck,lshoulder,rshoulder)
factors =
{
[neck] = Vector3.new(-1,0,0);
[lshoulder] = Vector3.new(0,0,-1);
[rshoulder] = Vector3.new(0,0,1);
}
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Configuration
local config =
{
RelativeOrigin = CFrame.new(0,-1.5,-1);
RelativeRotation = CFrame.new();
}
local function onConfigAdded(child)
if child:IsA("Configuration") and child.Name == "ViewmodelConfig" then
local relativeOrigin = child:WaitForChild("RelativeOrigin").Value
config.RelativeOrigin = CFrame.new(relativeOrigin)
local relativeRotation = child:WaitForChild("RelativeRotation").Value
config.RelativeRotation = CFrame.Angles(relativeRotation.X,relativeRotation.Y,relativeRotation.Z)
end
end
if char:FindFirstChild("ViewmodelConfig") then
onConfigAdded(char.ViewmodelConfig)
else
char.ChildAdded:connect(onConfigAdded)
end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- View Bobbling
local waveScale = 0
local scaleIncrement = 0.05
local active = false
local function glideTorwards(currentValue,targetValue,rate)
if currentValue < targetValue then
return math.min(targetValue,currentValue + rate)
elseif currentValue > targetValue then
return math.max(targetValue,currentValue - rate)
else
return targetValue
end
end
local function getCamBobble()
local goal = active and 0.5 or 0
waveScale = glideTorwards(waveScale,goal,0.05)
local t = math.cos(tick() * 7.85)
return CFrame.new((t/3)*waveScale,math.abs(t/5)*waveScale,0)
end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Build Viewmodel
local limbs = {}
local vm = Instance.new("Model")
vm.Name = "ViewModel"
local h = Instance.new("Humanoid",vm)
h.Name = "VM"
local function newLimb(name,size)
local limb = Instance.new("Part",vm)
limb.FormFactor = "Custom"
limb.Name = name
limb.Size = size
limb.Anchored = true
limb.CanCollide = false
if size.magnitude < 0.4 then
limb.Transparency = 1
end
table.insert(limbs,limb)
return limb
end
local function newJoint(name,p0,p1)
local j = Instance.new("Motor6D",p0)
j.Name = name
j.Part0 = p0
j.Part1 = p1
end
local head = newLimb("Head",Vector3.new())
vm.PrimaryPart = head
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Character Object Tracking
local blackList = {HumanoidRootPart = true; Torso = true; Head = true; Eyes = true; FakeHead = true}
local function watchParticle(realParticle,fakeParticle)
local isTweaking = false
local recTrans = realParticle.Transparency
local cameraCon
local function setTransparency(t)
isTweaking = true
if type(t) == "number" then
t = NumberSequence.new(t)
end
realParticle.Transparency = t
fakeParticle.Transparency = recTrans
isTweaking = false
end
local function onCameraChanged(property)
if property == "CoordinateFrame" then
local isFirstPerson = (c.Focus.p-c.CoordinateFrame.p).magnitude < 1
if isFirstPerson then
setTransparency(1)
else
setTransparency(recTrans)
end
end
end
onCameraChanged("CoordinateFrame")
local function onChanged(property)
if not isTweaking then
if property == "Transparency" then
recTrans = realParticle.Transparency
fakeParticle.Transparency = recTrans
elseif property == "Parent" and not fakeParticle.Parent then
cameraCon:disconnect()
end
end
end
realParticle.Changed:connect(onChanged)
cameraCon = c.Changed:connect(onCameraChanged)
end
local BASE_GRIP = CFrame.new(0,-1,0) * CFrame.Angles(-0.5 * math.pi, 0, 0)
local function trackTool(tool)
-- This is a lot, but I need to make sure I carefully track tools
-- as they can be unpredictable
toolEquipped = true
local cons = {}
local toolGuid = game:GetService("HttpService"):GenerateGUID(false)
local faketool = tool:clone()
local handle = tool:WaitForChild("Handle")
local repHandle = faketool:FindFirstChild("Handle")
local repHandle2 = faketool:FindFirstChild("Handle2")
faketool.Parent = vm
for _,child in pairs(faketool:GetChildren()) do
if child:IsA("Script") or child:IsA("LocalScript") or child:IsA("ModuleScript") or child:IsA("Folder") then
child:Destroy()
end
end
local leftArm = vm:WaitForChild("Left Arm")
local rightArm = vm:WaitForChild("Right Arm")
local function visualUpdate()
local shouldHide = (c.Focus.p-c.CoordinateFrame.p).magnitude < 1
for _,child in pairs(tool:GetChildren()) do
if child:IsA("BasePart") or child:IsA("Part") or child:IsA("MeshPart") or child:IsA("UnionOperation") then
child.LocalTransparencyModifier = shouldHide and 1 or 0
end
end
if repHandle then
repHandle.CFrame = rightArm.CFrame * BASE_GRIP * tool.Grip:inverse()
end
if repHandle and repHandle2 then
repHandle.CFrame = rightArm.CFrame * BASE_GRIP * tool.Grip:inverse()
repHandle2.CFrame = leftArm.CFrame * BASE_GRIP * tool.Grip:inverse()
end
end
rs:BindToRenderStep(toolGuid,201,visualUpdate)
local unequipCon
local function onUnequipped()
toolEquipped = false
unequipCon:disconnect()
rs:UnbindFromRenderStep(toolGuid)
faketool:Destroy()
end
unequipCon = tool.Unequipped:connect(onUnequipped)
end
local function pullObject(child)
if child:IsA("CharacterAppearance") then
child:clone().Parent = vm
elseif child:IsA("Tool") and child.RequiresHandle then
trackTool(child)
elseif child:IsA("BasePart") then
if not blackList[child.Name] then
if vm:FindFirstChild(child.Name) then
vm[child.Name]:Destroy()
end
child.Archivable = true
local fake = child:clone()
fake.Parent = vm
fake.Anchored = true
fake.CanCollide = false
child.AncestryChanged:connect(function ()
if not child:IsDescendantOf(char) then
fake:Destroy()
end
end)
local children = {}
local function registerChild(v)
if not v:IsA("JointInstance") and not v:IsA("Sound") and not v:IsA("TouchTransmitter") then
v.Archivable = true
local fakeChild = v:clone()
fakeChild.Parent = fake
if fakeChild:IsA("ParticleEmitter") then
watchParticle(v,fakeChild)
end
v.Changed:connect(function (property)
if property ~= "Parent" then
pcall(function ()
fakeChild[property] = v[property]
end)
end
end)
children[v] = fakeChild
end
end
local function unregisterChild(v)
if children[v] then
children[v]:Destroy()
end
end
for _,v in pairs(child:GetChildren()) do
registerChild(v)
end
child.ChildAdded:connect(registerChild)
child.ChildRemoved:connect(unregisterChild)
table.insert(limbs,fake)
child.Changed:connect(function (property)
if property ~= "Parent" and property ~= "LocalTransparencyModifier" and property ~= "Anchored" and property ~= "CanCollide" then
pcall(function ()
fake[property] = child[property]
end)
end
end)
end
end
end
for _,child in pairs(char:GetChildren()) do
pullObject(child)
end
char.ChildAdded:connect(pullObject)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Camera Code
if c:findFirstChild("ViewModel") then
c.ViewModel:Destroy()
end
local lastY = 0
local lastUpdate = 0
local player = game.Players.LocalPlayer
local currentRot = CFrame.new()
local abs = math.abs
local min = math.min
local max = math.max
local function inCutsceneMode()
if player:FindFirstChild("CutsceneFlag") then
return player.CutsceneFlag.Value
end
return false
end
local function findAngleBetweenXZVectors(vec2, vec1)
return math.atan2(vec1.X*vec2.Z-vec1.Z*vec2.X, vec1.X*vec2.X + vec1.Z*vec2.Z)
end
local function renderUpdate()
if #vm:GetChildren() < 1 then
if con then
con:disconnect()
con = nil
end
return
end
local cf = c.CoordinateFrame
local look = cf.lookVector.Y
local floored = math.floor(look/0.1) * 0.1
local now = tick()
if lastY ~= floored and (now - lastUpdate) > 0.4 then
lastUpdate = now
lastY = floored
updateY:FireServer(look)
end
for joint,factor in pairs(factors) do
local origin = origins[joint]
local factor = factor * look
local x,y,z = factor.X, factor.Y, factor.Z
joint.C0 = origin.C0 * CFrame.Angles(x,y,z)
end
neck.C0 = neck.C0 * CFrame.new(0,look/4 - 0.05,0.05 + math.max(0,look/10))
local speed = charTorso.Velocity.magnitude
active = (speed > 1) and not charTorso.Anchored
local offset = CFrame.new()
local bobble = getCamBobble()
local cameraPos = c.CoordinateFrame.p
if (c.Focus.p-c.CoordinateFrame.p).magnitude <= 1 and not charTorso.Anchored then
vm.Parent = c
local vmOffset = CFrame.new()
if char:FindFirstChild("vmOffset") then
vmOffset = char.vmOffset.Value
end
for _,part in pairs(limbs) do
local actual = char:FindFirstChild(part.Name)
if actual then
local cf = head.CFrame * charTorso.CFrame:toObjectSpace(actual.CFrame)
if part.Name:find("Leg") then
cf = cf * vmOffset:inverse()
end
part.BrickColor = actual.BrickColor
part.CFrame = cf
else
part.Parent = nil
end
end
local base = (root.CFrame:toObjectSpace(charHead.CFrame)):inverse()
local headRot = base - base.p
local camPos = cf.p
local rot = (cf - camPos)
local desiredRot = rot * config.RelativeOrigin * bobble:inverse() * config.RelativeRotation * headRot * vmOffset * CFrame.new(0,-math.max(0.3,math.abs(look/2)),0)
local angleBetween = findAngleBetweenXZVectors(currentRot.lookVector,rot.lookVector)
currentRot = currentRot:lerp(desiredRot,abs(min(0.9,max(0.1,angleBetween))))
vm:SetPrimaryPartCFrame(CFrame.new(camPos)*currentRot)
else
vm.Parent = nil
currentRot = cf - cf.p - Vector3.new(0,1.5,0)
end
if active then
humanoid.CameraOffset = bobble.p
end
end
rs:UnbindFromRenderStep("Kinematics") -- In case its bound already.
rs:BindToRenderStep("Kinematics",201,renderUpdate)
local function onDied()
rs:UnbindFromRenderStep("Kinematics")
vm:Destroy()
end
humanoid.Died:connect(onDied)
updateY.OnClientEvent:connect(function() end)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------