Hello again developer forums! I’m having an issue with my bullet code displaying the error ServerScriptService.Framework - Server:74: attempt to index nil with 'CFrame' - Server - Framework - Server:74
and it is driving me crazy, I’ve done as much as my tiny brain will let me so I’m handing it over to you. I will be providing two scripts along with the place as a download file. The first is the local script that gets the viewmodel and bullet location + rotation, and then the server script which actually sets up the bullet.
Get back to me if anyone has a solution!
Local Script:
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local camera = game.Workspace.CurrentCamera
local aimCF = CFrame.new()
local mouse = player:GetMouse()
local isAiming = false
local isShooting = false
local isReloading = false
local canShoot = true
local debounce = false
local currentSwayAMT = 0
local swayAMT = 0.6
local aimSwayAMT = -0.2
local swayCF = CFrame.new()
local lastCameraCF = CFrame.new()
local currentSlot = 1 -- starting slot
local lastSlot = 0
local maxSlots = 3
local fireAnim = nil
local particle
local flash
local bigFlash
local timer
local bobOffset = CFrame.new()
local inventoryOpen = false
local framework = {
inventory = {
"Rocket Launcher";
"Paintball Gun";
"Sword";
};
module = nil;
viewmodel = nil;
currentSlot = 1;
}
local hud = player.PlayerGui:WaitForChild("GameUI")
function deleteViewmodel()
for i, v in pairs(camera:GetChildren()) do
if v:IsA("Model") then
v:Destroy()
end
end
end
function setInventory()
framework.inventory[1] = "Paintball Gun"
framework.inventory[2] = "Rocket Launcher"
framework.inventory[3] = "Sword"
end
setInventory()
function Shoot()
trigger()
end
function loadSlot(Item)
local viewmodelFolder = game.ReplicatedStorage.ViewModels
local moduleFolder = game.ReplicatedStorage:WaitForChild("Modules")
isShooting = false
deleteViewmodel()
if moduleFolder then
framework.module = require(moduleFolder:WaitForChild(Item))
if viewmodelFolder:FindFirstChild(Item) then
framework.viewmodel = viewmodelFolder:FindFirstChild(Item):Clone()
framework.viewmodel.Parent = camera
end
if framework.viewmodel and framework.module and character then
local rarity = framework.module.rarity
-- animation
fireAnim = Instance.new("Animation")
fireAnim.Parent = framework.viewmodel
fireAnim.Name = "Fire"
fireAnim.AnimationId = framework.module.fireAnim
fireAnim = framework.viewmodel.AnimationController.Animator:LoadAnimation(fireAnim)
-- sound
game.ReplicatedStorage.Events.LoadSlot:FireServer(framework.module.fireSound)
flash = framework.viewmodel.HumanoidRootPart.Muzzel.flash
bigFlash = framework.viewmodel.HumanoidRootPart.Muzzel.bigFlash
hud.gun.Icon.Image = framework.module.icon
hud.gun.Icon.ImageColor3 = hud.gun:WaitForChild(rarity).Value
end
end
end
local function refreshList()
local raritys = player.PlayerGui.GunSelector.List
local listOfWepons = player.PlayerGui.GunSelector.List.List:GetChildren()
local frame = player.PlayerGui.GunSelector.List
if inventoryOpen then
frame.Position = UDim2.new(1, -50 ,0.5, 0)
else
frame.Position = UDim2.new(1.2, 0 ,0.5, 0)
end
for i, v in pairs(listOfWepons) do
if v:IsA("Frame") then
if v.Name ~= "Empty" then
local module = require(game.ReplicatedStorage.Modules:WaitForChild(v.Name))
v.Icon.id.Text = v.Name
v.Icon.Image = module.icon
v.Icon.ImageColor3 = raritys:WaitForChild(module.rarity).Value
v.ammo.Text = module.maxAmmo
if table.find(framework.inventory, v.Name) then
v.addToInventory.Active = false
v.addToInventory.ImageTransparency = 0.75
v.removeFromInventory.Active = true
v.removeFromInventory.ImageTransparency = 0
else
v.addToInventory.Active = true
v.addToInventory.ImageTransparency = 0
v.removeFromInventory.Active = false
v.removeFromInventory.ImageTransparency = 0.5
end
end
end
end
end
player.PlayerGui:WaitForChild("GunSelector"):WaitForChild("List"):WaitForChild("Refresh").MouseButton1Click:Connect(function()
print("click")
refreshList()
end)
player.PlayerGui:WaitForChild("GunSelector"):WaitForChild("List"):WaitForChild("inventoryButton").MouseButton1Click:Connect(function()
if inventoryOpen then
inventoryOpen = false
else
inventoryOpen = true
end
refreshList()
end)
RunService.RenderStepped:Connect(function()
local rot = camera.CFrame:ToObjectSpace(lastCameraCF)
local X, Y, Z = rot:ToOrientation()
swayCF = swayCF:Lerp(CFrame.Angles(math.sin(X) * currentSwayAMT, math.sin(Y) * currentSwayAMT, 0), .1)
lastCameraCF = camera.CFrame
if framework.viewmodel and framework.module then
hud.gun.Icon.id.Text = framework.inventory[framework.currentSlot]
hud.ammo.amount.Text = framework.module.ammo .. "/" .. framework.module.maxAmmo
end
if humanoid then
local movementOffset = CFrame.new()
if framework.viewmodel ~= nil and framework.module ~= nil then
if humanoid.MoveDirection.Magnitude > 0 and humanoid:GetState() ~= Enum.HumanoidStateType.Freefall then
if isReloading == true then
bobOffset = bobOffset:Lerp(CFrame.new(math.cos(tick() * 4) * .05, -humanoid.CameraOffset.Y/1, 0) * CFrame.Angles(0, math.sin(tick() * -4) * -.05, math.cos(tick() * -4) * .05), .005)
else
if isAiming == true then
bobOffset = bobOffset:Lerp(CFrame.new(math.cos(tick() * 4) * .05, -humanoid.CameraOffset.Y/3, 0) * CFrame.Angles(0, math.sin(tick() * -4) * -.05, math.cos(tick() * -4) * .05), .005)
else
bobOffset = bobOffset:Lerp(CFrame.new(math.cos(tick() * 4) * .05, -humanoid.CameraOffset.Y/3, 0) * CFrame.Angles(0, math.sin(tick() * -4) * -.05, math.cos(tick() * -4) * .05), humanoid.WalkSpeed/45)
end
end
end
else
bobOffset = bobOffset:Lerp(CFrame.new(0, -humanoid.CameraOffset.Y/3, 0), .1)
end
end
for i, v in pairs(camera:GetChildren()) do
if v:IsA("Model") then
v.PrimaryPart.CFrame = (camera.CFrame * swayCF * aimCF * bobOffset)
--updateCameraShake()
end
end
if isAiming and framework.viewmodel ~= nil and framework.module.canAim then
local offset = framework.viewmodel.AimCamera.CFrame:ToObjectSpace(framework.viewmodel.PrimaryPart.CFrame)
aimCF = aimCF:Lerp(offset, framework.module.aimSmooth)
currentSwayAMT = aimSwayAMT
else
local offset = CFrame.new()
aimCF = aimCF:Lerp(offset, .2)
currentSwayAMT = swayAMT
end
-- HUD
if hud and moduleFolder == moduleFolder then
if framework.module.ammo < framework.module.maxAmmo/4 then
hud.ammo.Icon.ImageColor3 = Color3.fromRGB(255, 0, 0)
else
hud.ammo.Icon.ImageColor3 = Color3.new(1, 1, 1)
end
if isReloading == true then
hud.ammo.Icon.reload.Visible = true
hud.ammo.Icon.ImageTransparency = 0.75
else
hud.ammo.Icon.reload.Visible = false
hud.ammo.Icon.ImageTransparency = 0
end
end
end)
local function updateWeapon(slot)
if isReloading == true then
isReloading = false
canShoot = true
end
if isReloading == false then
framework.currentSlot = slot
loadSlot(framework.inventory[currentSlot])
end
refreshList()
end
updateWeapon(1)
-- SLOT CHANGING
local function changeSlot(howMuch)
currentSlot += howMuch
if currentSlot > maxSlots then
currentSlot = 1
elseif currentSlot < 1 then
currentSlot = maxSlots
end
updateWeapon(currentSlot)
end
local function setSlot(whatSlot)
if framework.currentSlot ~= whatSlot then
currentSlot = whatSlot
end
updateWeapon(currentSlot)
end
local function reload()
if isReloading == false and framework.module.maxAmmo ~= 0 and framework.module.ammo ~= framework.module.maxAmmo then
canShoot = false
isReloading = true
wait(framework.module.reloadTime)
if isReloading == true then
framework.module.ammo = framework.module.maxAmmo
end
canShoot = true
isReloading = false
end
end
-- SHOOTING --
local function fireWeapon()
if isReloading == true and framework.module.ammo ~= 0 then
isReloading = false
canShoot = true
end
if character and framework.viewmodel and framework.module and framework.module.ammo ~= 0 and debounce == false and isReloading == false and canShoot == true and framework.module.maxAmmo ~= 0 then
game.ReplicatedStorage.Events.Shoot:FireServer(framework.viewmodel.Muzzle.Position, mouse.Hit.p)
fireAnim:Play()
character.Torso.FireSound:Play()
framework.module.ammo -= 1
debounce = true
wait(framework.module.fireRate)
debounce = false
elseif character and framework.viewmodel and framework.module and debounce == false and framework.module.maxAmmo == 0 then
game.ReplicatedStorage.Events.Shoot:FireServer(framework.viewmodel.Muzzle.Position, mouse.Hit.p)
fireAnim:Play()
character.Torso.FireSound:Play()
debounce = true
wait(framework.module.fireRate)
debounce = false
end
end
local function trigger()
if isReloading == true and canShoot == false and framework.module.ammo ~= 0 then
isReloading = false
canShoot = true
end
if framework.module.fireMode == "Semi" then
fireWeapon()
end
if framework.module.fireMode == "Full Auto" then
isShooting = true
end
end
local oldCamCF = CFrame.new()
function updateCameraShake()
local newCamCF = framework.viewmodel.FakeCamera.CFrame:ToObjectSpace(framework.viewmodel.PrimaryPart.CFrame)
camera.CFrame = camera.CFrame * newCamCF:ToObjectSpace(oldCamCF)
oldCamCF = newCamCF
end
-- INPUTS --
--UserInputService.MouseIconEnabled = false
UserInputService.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.One then
setSlot(1)
end
if input.KeyCode == Enum.KeyCode.Two then
setSlot(2)
end
if input.KeyCode == Enum.KeyCode.Three then
setSlot(3)
end
if input.UserInputType == Enum.UserInputType.Gamepad1 then
if input.KeyCode == Enum.KeyCode.ButtonL1 then
changeSlot(1)
end
end
if input.UserInputType == Enum.UserInputType.Gamepad1 then
if input.KeyCode == Enum.KeyCode.ButtonR1 then
changeSlot(-1)
end
end
if input.UserInputType == Enum.UserInputType.MouseButton3 then
print("middleButton")
end
if input.UserInputType == Enum.UserInputType.MouseButton2 then
isAiming = true
end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
if character and framework.viewmodel and framework.module then
trigger()
end
end
if input.UserInputType == Enum.UserInputType.Gamepad1 then
if input.KeyCode == Enum.KeyCode.ButtonL2 then
isAiming = true
end
end
if input.UserInputType == Enum.UserInputType.Gamepad1 then
if input.KeyCode == Enum.KeyCode.ButtonR2 then
trigger()
end
end
-- RELOAD
if input.KeyCode == Enum.KeyCode.R then
reload()
end
if input.UserInputType == Enum.UserInputType.Gamepad1 then
if input.KeyCode == Enum.KeyCode.ButtonX then
reload()
end
end
end)
UserInputService.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton2 then
isAiming = false
end
if input.UserInputType == Enum.UserInputType.Gamepad1 then
if input.KeyCode == Enum.KeyCode.ButtonL2 then
isAiming = false
end
end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
isShooting = false
end
if input.UserInputType == Enum.UserInputType.Gamepad1 then
if input.KeyCode == Enum.KeyCode.ButtonR2 then
isShooting = false
end
end
end)
mouse.WheelForward:Connect(function()
changeSlot(1)
end)
mouse.WheelBackward:Connect(function()
changeSlot(-1)
end)
game.ReplicatedStorage.Events.PlayerAdded.OnClientEvent:Connect(function(ply, char)
player = game.Players.LocalPlayer
character = player.Character
humanoid = character:WaitForChild("Humanoid")
setInventory()
framework.module.ammo = framework.module.maxAmmo
framework.module = nil
framework.viewmodel = nil
framework.currentSlot = 1
loadSlot(framework.inventory[currentSlot])
humanoid.Died:Connect(function()
deleteViewmodel()
local isAiming = false
local isShooting = false
local isReloading = false
local canShoot = true
local debounce = false
local currentSwayAMT = 0
local swayAMT = 0.6
local aimSwayAMT = -0.2
local swayCF = CFrame.new()
local lastCameraCF = CFrame.new()
local currentSlot = 1 -- starting slot
local lastSlot = 0
local maxSlots = 3
local fireAnim = nil
local particle
local flash
local bigFlash
local timer
local bobOffset = CFrame.new()
end)
end)
game.ReplicatedStorage.Events.HitEvent.OnClientEvent:Connect(function(ply)
game.SoundService.SoundEffects.Damage:Play()
end)
while wait() do
if isShooting and framework.module.ammo > 0 and isReloading ~= true and canShoot == true then
framework.module.ammo -= 1
fireAnim:Play()
game.ReplicatedStorage.Events.Shoot:FireServer(framework.viewmodel.Muzzle.Position, mouse.Hit.Position)
mouse.Button1Up:Connect(function()
isShooting = false
end)
wait(framework.module.fireRate)
end
end
Server Script:
-- Bullet Pool
local bulletPool = {}
local maxBullets = 150
local bulletTemplate = game.ReplicatedStorage.BulletMesh.Bullet
function setTransparency(trans, model)
for i, v in pairs(model:GetChildren()) do
if v:IsA("Mesh") then
v.Transparency = trans
end
end
end
for i = 1, maxBullets do
local Mbullet = bulletTemplate:Clone()
Mbullet.Name = "PooledBullet"
Mbullet.Parent = game.Workspace
Mbullet:SetAttribute("Avalible", true)
Mbullet.PrimaryPart.CFrame = CFrame.new(0,0,0)
Mbullet:SetAttribute("Visible", false)
setTransparency(1, Mbullet)
table.insert(bulletPool, Mbullet)
end
local function GetBullet()
for _, bullet in ipairs(bulletPool) do
if bullet:GetAttribute("Avalible") then
bullet:SetAttribute("Avalible", false)
bullet:SetAttribute("Visible", true)
setTransparency(0, bullet)
return bullet
end
end
warn("No avalible bullets")
return nil
end
local function ReturnBullet(rBullet)
if rBullet:GetAttribute("Avalible") then return end
rBullet:SetAttribute("Avalible", true)
rBullet:SetAttribute("Visible", false)
rBullet.PrimaryPart.CFrame = CFrame.new(0,0,0)
rBullet.PrimaryPart.LinearVelocity.VectorVelocity = Vector3.zero
setTransparency(1, rBullet)
end
game.ReplicatedStorage.Events.LoadSlot.OnServerEvent:Connect(function(player, Sound)
if player.Character then
for i, v in pairs(player.Character.Torso:GetChildren()) do
if v.Name == "FireSound" then
v:Destroy()
end
end
local fireSound = Sound:Clone()
fireSound.Parent = player.Character.Torso
end
end)
game.ReplicatedStorage.Events.Shoot.OnServerEvent:Connect(function(player, MuzzelPos, MousePos)
if player.Character then
local sound = player.Character.Torso.FireSound
if sound then
sound:Play()
end
local bullet = GetBullet()
if bullet then
bullet.Name = "Bullet"
bullet.Parent = game.Workspace
print(CFrame.new(MuzzelPos, MousePos))
bullet.PrimaryPart.CFrame = CFrame.new(MuzzelPos, MousePos)
local linearVelocity = bullet.PrimaryPart.LinearVelocity
local attachment = bullet.PrimaryPart.Attachment
-- Configure LinearVelocity
linearVelocity.VectorVelocity = bullet.PrimaryPart.CFrame.LookVector * 400
linearVelocity.MaxForce = math.huge
--bullet.PrimaryPart.CFrame = CFrame.new(bullet.PrimaryPart.Position, bullet.PrimaryPart.Position + bullet.PrimaryPart.CFrame.LookVector)
--bullet.RootPart.AlignOrientation.CFrame = bullet.PrimaryPart.CFrame
bullet.RootPart.Trail.Enabled = true
bullet.PrimaryPart.Touched:Connect(function(hit)
bullet.RootPart.Trail.Enabled = false
--ReturnBullet(bullet)
if hit.Parent:FindFirstChild("Humanoid") then
hit.Parent:FindFirstChild("Humanoid"):TakeDamage(10)
game.ReplicatedStorage.Events.HitEvent:FireClient(player, player.Character)
end
end)
end
end
end)
game.Players.PlayerAdded:Connect(function(fplayer)
fplayer.CharacterAdded:Connect(function(fcharacter)
game.ReplicatedStorage.Events.PlayerAdded:FireClient(fplayer, fcharacter)
end)
end)
And lastly, the download file:
Framework Testing Untitled Games Development.rbxl (346.3 KB)