I'm very new (2 days) to Roblox and Lua, so don't bite me too hard please.. =)
What I am trying to do is to script VectorForce for the Part I've also instanced from code.
In simulation Attachment and VectorForce did create, but without any expected effect.
Please, look at my script and tell me where do I need to dig.
local sandblock = script.Parent
local sandblock_health = 5
local function blockJump(object)
local jump_att = Instance.new("Attachment", object)
local jump_force = Instance.new("VectorForce", object)
jump_force.ApplyAtCenterOfMass = true
jump_force.Attachment0 = jump_att
jump_force.RelativeTo = Enum.ActuatorRelativeTo.World
jump_force.Force = Vector3.new(10,1000,-10)
jump_force.Enabled = true
-- here: what is the difference between Enabled and Active?
--jump_force.Active = true
end
local function onTouch(object)
--print("К блоку прикоснулся "..object.Name)
if object.Name == "Handle" then
sandblock_health = sandblock_health - 1
print(sandblock_health)
if sandblock_health < 1 then
local sandblock_drop1 = Instance.new("Part", workspace)
sandblock_drop1.Size = Vector3.new(2,2,2)
sandblock_drop1.Position = sandblock.Position + Vector3.new(0,5,-1)
blockJump(sandblock_drop1)
sandblock_drop1.Material = "Metal"
sandblock_drop1.BrickColor = BrickColor.new("Gold")
sandblock_drop1.Name = "Gold"
print("Вы добыли "..sandblock_drop1.Name)
sandblock:Destroy()
end
end
end
sandblock.Touched:Connect(onTouch)
Solved it.
The product of workspace's gravity and part's mass is much higher than 1000 in my Force vector.
Code below works as expected:
jump_force.Force = Vector3.new(10, game.Workspace.Gravity * object.Mass * 1.35, -10)
jump_force.Enabled = true
wait(0.4)
jump_force.Enabled = false
It seems like the issue is that when you made the onTouch function, you had a parameter: object. However when you called the function on a player touching the part, you put no parameter: sandblock.Touched:Connect(onTouch). To fix this, do: sandblock.Touched:Connect(onTouch(<object_parameter>))
Related
It gives me an error when I execute it "Text is not a valid member of Frame". It's a slider script.
--SLIDER:
local SliderFrame = script.Parent.WalkSpeedSlider
local UIS = game:GetService("UserInputService")
local WalkSpeedSlider = script.Parent.WalkSpeedSlider
local SliderFrame = WalkSpeedSlider.SliderFrame
local Slider = SliderFrame.Slider
local WalkspeedReset = SliderFrame.Reset
local WalkspeedDragging = false
local WalkSpeedDisplay = SliderFrame.WalkSpeedNum
Slider.MouseButton1Down:Connect(function()
WalkspeedDragging = true
end)
UIS.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
WalkspeedDragging = false
end
end)
UIS.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement then
if WalkspeedDragging == true then
local MouseL = UIS:GetMouseLocation()
local RelativePos = MouseL-SliderFrame.AbsolutePosition
local percent = math.clamp(RelativePos.X/SliderFrame.AbsoluteSize.X,0,1)
Slider.Position = UDim2.new(percent,0,0,0)
game.Players.LocalPlayer.Character:FindFirstChildWhichIsA("Humanoid").WalkSpeed = math.round(percent*120)
WalkSpeedDisplay.Text = math.round(game.StarterPlayer.CharacterWalkSpeed)
end
end
end)
I was trying to make a slider which I succeeded, but I wanted my textbox which is WalkSpeedDisplay to be able to change to the speed that I put with the slider, but WalkSpeedDisplay.Text gives me an error "Text is not a valid member of Frame" and I don't know why.
Frames don't have a property known as text. If you want to add text to a frame, insert a text label in the frame and customize it to how you want.
I may be wrong about this, it would be helpful to see all the children and parents of the frame.
Also you probably shouldn't use a variable name two times, such as you did with SliderFrame.
while true do
wait(1)
local randomnumber = math.random(18,150)
local x = math.random(1,50)
local Pointgiver = game.ReplicatedStorage.Points:Clone()
Pointgiver.Parent = game.Workspace
Pointgiver.Position = Vector3.new(randomnumber,0.5,x)
Pointgiver.Transparency = 0
end
local pointgiver = game.Workspace:WaitForChild("Points")
pointgiver.ClickDetector.Mousetouch:Connect(function()
pointgiver:Destroy()
end)
as you see, im using a waitforchild function which waits for a part to spawn and doesnt give errors thats like "There is no part named "Points" "
but it wont destroy it, sorry if that didnt make sense
ClickDetector has no function named Mousetouch, instead, you should be using MouseClick which fires whenever the player clicks the respective Part. Also your code which listens for the ClickDetector.MouseClick is after the while loop and as such, it will never run as you keep calling the while loop repeatedly, and never break out of it.
while true do
task.wait(1)
local randomnumber = math.random(18,150)
local x = math.random(1,50)
local Pointgiver = game.ReplicatedStorage.Points:Clone()
Pointgiver.Position = Vector3.new(randomnumber,0.5,x)
Pointgiver.Transparency = 0
PointGiver.ClickDetector.MouseClick:Connect(function()
PointGiver:Destroy()
end)
Pointgiver.Parent = game.Workspace
end
The titles explains it all, I'm trying to make a roblox npc walk around the maze normally, then when it sees the player, it starts running after the player to kill it, I have the NPC, I have the killing part, I just need the code for the NPC walking around normally and the code for the NPC detecting the player then running after them. Thanks! :D
edited: heres my code
debugMode = false
targetNPCs = false
--
h = script.Parent.Parent:WaitForChild("Humanoid")
pathService = game:GetService("PathfindingService")
targetV = script.Parent:WaitForChild("Target")
function closestTargetAndPath()
local humanoids = {}
if targetNPCs then
local function recurse(o)
for _,obj in pairs(o:GetChildren()) do
if obj:IsA("Model") then
if obj:findFirstChild("Humanoid") and obj:findFirstChild("Torso") and obj.Humanoid ~= h and obj.Humanoid.Health > 0 and not obj:findFirstChild("ForceField") then
table.insert(humanoids,obj.Humanoid)
end
end
recurse(obj)
end
end
recurse(workspace)
else
for _,v in pairs(game.Players:GetPlayers()) do
if v.Character and v.Character:findFirstChild("HumanoidRootPart") and v.Character:findFirstChild("Humanoid") and v.Character.Humanoid.Health > 0 and not v:findFirstChild("ForceField") then
table.insert(humanoids,v.Character.Humanoid)
end
end
end
local closest,path,dist
for _,humanoid in pairs(humanoids) do
local myPath = pathService:ComputeRawPathAsync(h.Torso.Position,humanoid.Torso.Position,500)
if myPath.Status ~= Enum.PathStatus.FailFinishNotEmpty then
-- Now that we have a successful path, we need to figure out how far we need to actually travel to reach this point.
local myDist = 0
local previous = h.Torso.Position
for _,point in pairs(myPath:GetPointCoordinates()) do
myDist = myDist + (point-previous).magnitude
previous = point
end
if not dist or myDist < dist then -- if true, this is the closest path so far.
closest = humanoid
path = myPath
dist = myDist
end
end
end
return closest,path
end
function goToPos(loc)
h:MoveTo(loc)
local distance = (loc-h.Torso.Position).magnitude
local start = tick()
while distance > 4 do
if tick()-start > distance/h.WalkSpeed then -- Something may have gone wrong. Just break.
break
end
distance = (loc-h.Torso.Position).magnitude
wait()
end
end
while wait() do
local target,path = closestTargetAndPath()
local didBreak = false
local targetStart
if target and h.Torso then
targetV.Value = target
targetStart = target.Torso.Position
roaming = false
local previous = h.Torso.Position
local points = path:GetPointCoordinates()
local s = #points > 1 and 2 or 1
for i = s,#points do
local point = points[i]
if didBreak then
break
end
if target and target.Torso and target.Health > 0 then
if (target.Torso.Position-targetStart).magnitude < 1.5 then
local pos = previous:lerp(point,.5)
local moveDir = ((pos - h.Torso.Position).unit * 2)
goToPos(previous:lerp(point,.5))
previous = point
end
else
didBreak = true
break
end
end
else
targetV.Value = nil
end
if not didBreak and targetStart then
goToPos(targetStart)
end
end
I won't provide any code as you have not shown any efforts to solve that problem.
Enter "roblox npc" into www.google.com. Click the second hit:
https://developer.roblox.com/en-us/articles/Moving-NPCs-Between-Points
This covers the walking around part and also links this
https://developer.roblox.com/en-us/articles/Pathfinding
which covers more complex movements.
The seeing part is done with ray casting
https://developer.roblox.com/en-us/articles/Raycasting
If you can cast a ray from the NPC to your player calculate a path to that player and attack.
I coded out some functions in a ModuleScript to be executed by another script. Here is the code
local module = {}
wavepause = game.ReplicatedStorage.Values.WavePauseLength.Value
trollanoid = game.ReplicatedStorage.Trollanoid
spawnpoints = workspace.Test1.Spawns:GetChildren()
function trollanoidsummon()
local chosenspawn = math.random(#spawnpoints)
local clone = trollanoid:Clone().Parent == workspace.Zombies
clone.HumanoidRootPart.CFrame = chosenspawn.CFrame
end
module.Wave1 = function()
trollanoid()
wait(1)
trollanoid()
wait(1)
trollanoid()
wait(1)
trollanoid()
end
return module
What I expected was the NPC trollanoids to appear on the map, but instead I got this error in the output:
17:50:19.011 ServerScriptService.WaveModule:14: attempt to call a Instance
value - Server - WaveModule:14
I dont know what I did wrong, please help me fix this. Any help is appreciated
The error message is telling you what's wrong:
You're trying to call an object. The only things you can call in Lua are functions and objects with the __call metamethod.
You are calling an object. Like mentioned above, you can only call functions and objects with __call metamethod.
Try this:
local module = {}
wavepause = game.ReplicatedStorage.Values.WavePauseLength
trollanoid = game.ReplicatedStorage.Trollanoid
spawnpoints = workspace.Test1.Spawns:GetChildren()
function trollanoidsummon()
local chosenspawn = spawnpoints[math.random(#spawnpoints)]
local clone = trollanoid:Clone().Parent = workspace.Zombies
clone.HumanoidRootPart.CFrame = chosenspawn.CFrame
end
module:SpawnNPC(amount, threshold)
threshold = threshold or 1
amount = amount or 4
for i = 1, amount do
if wavepause.Value then break end;
trollanoidsummon()
wait(threshold)
end
end
return module
To use the module you would do this:
local spawner = require(modulescriptpath);
spawner:SpawnNPC(5, 1);
I made a few minor changes. Let me know if you need help with any :)
I'm trying to make a cutscene sorta thing for a dorr in roblox studio. My solution was to set up a collision detector on the door which would then make a gui template and set its parent to the playergui component.
I did this using the code
local afterIntoTransform = script.Parent.Parent.DoorUnion.Position.Z -6
local afterOutwardsTransform = script.Parent.Parent.DoorUnion.Position.Z + 6
local debounce = false
local function executeFadeSceneAndTpPlayer(player)
local fadeScene = Instance.new("ScreenGui")
local fadeSceneFrame = Instance.new("Frame")
fadeScene.Name = "fadeScene"
fadeSceneFrame.Name = "fadeFrame"
fadeSceneFrame.Size = UDim2.new(1,0,1,0)
fadeSceneFrame.Parent = fadeScene
fadeSceneFrame.BorderSizePixel = 0
fadeSceneFrame.BackgroundColor3 = Color3.new(1, 1, 1)
fadeSceneFrame.BackgroundTransparency = 1
print(game.Players:GetPlayerFromCharacter(player).Name)
fadeScene.Parent = game.Players:GetPlayerFromCharacter(player).PlayerGui
for i = 0, 20, 1 do
fadeSceneFrame.BackgroundTransparency -= 0.05
wait(0.01)
end
player.HumanoidRootPart.Position = Vector3.new(player.HumanoidRootPart.Position.X, player.HumanoidRootPart.Position.Y, afterOutwardsTransform)
for i = 0, 20, 1 do
fadeSceneFrame.BackgroundTransparency += 0.05
wait(0.01)
end
fadeScene:Destroy()
end
script.Parent.Touched:Connect(function(hit)
if not debounce then
debounce = true
executeFadeSceneAndTpPlayer(hit.Parent)
wait(0.2)
debounce = false
end
end)
It tells me: Attempted to index nil with name on line 15.
It works sometimes and sometimes doesnt but recently Ive noticed a trend that I can walk into the door then out again and then it breaks. I haven't coded in a while so I'm a little rusty but I hope I can get some help.
You are running into the same issue as this person : Roblox - attempt to index nil with 'leaderstats'
You are not accounting for the fact that the Touched event fires for every single part that touches it, and some of those parts might not belong to a player.
You can protect against this error by making sure that the object belongs to a player before you call executeFadeSceneAndTpPlayer()
script.Parent.Touched:Connect(function(hit)
local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
if not plr then
return
end
if not debounce then
debounce = true
executeFadeSceneAndTpPlayer(hit.Parent)
wait(0.2)
debounce = false
end
end)