Why does the script think this Vector3 position is a player? - lua

I'm trying to finish a gun script for a game, and I have scrapped many things. This time, I thought I could finish the script. But then, when I checked output it said that I was trying to use an Instance when I should be using a Vector3. When I looked at it, I soon realized that the script thought it was a player. WHAT IS HAPPENING?
script.Parent.Shoot.OnServerEvent:Connect(function(posofm) --I am using a LocalScript to get the position of the mouse (mouse.Hit.Position)
bullet = Instance.new("Part")
bullet.Parent = workspace
bullet.Size = Vector3.new(0.3,0.3,1)
bullet.BrickColor = BrickColor.Yellow()
bullet.Position = script.Parent.Handle.Position
bullet.CFrame = CFrame.lookAt(bullet.Position,posofm)
bullet.Velocity = bullet.CFrame.LookVector * 90
end)

Take a look at the docs for RemoteEvent.OnServerEvent. The first argument provided to the connection is always the Player that called RemoteEvent:FireServer().
For example :
-- when a LocalScript calls FireServer :
event:FireServer(a, b, c)
-- the server Script receives :
event.OnServerEvent:Connect(function(player, a, b, c) ... end)
So in your case, even though the variable is named posofm, since it is the first argument in the list, it represents the Player object. And the actual position of the mouse is ignored because there's no argument in the function to store it.
So to fix it, all you need to do is add an argument in the connection to represent the player and properly label your arguments :
script.Parent.Shoot.OnServerEvent:Connect(function(player, posofm)

Related

Roblox: how to place a player in a specific position

I'm a newbie developer of roblox.
I'm trying to place a player in a specific position on first load in this way:
In StarterPlayer > StarterPlayerScripts I added a LocalScript with the following code:
local cf = CFrame.new(500, 5, 50)
local Char = game.Players.LocalPlayer
Char.HumanoidRootPart.CFrame = cf
When I click play, nothing happen onload.
What I'm doing wrong?
#ItsJustFunboy is half correct, you do need to use the Model:MoveTo function, but you might have some other issues as well : timing and LocalScripts.
Timing-wise, you have this code in StarterPlayerScripts. These LocalScripts execute when the Player joins the game, not when their character model appears. So it's possible that their character doesn't even exist at the time you're telling it to move. If you want to guarantee that the character model exists at the time you run this code, it needs to be in StarterCharacterScripts.
As for the problem with LocalScripts, they make changes to the world only on your client. Meaning that if you move your character in a LocalScript, then all the other players will still see your character model where it was, not where you moved it. So unless this is intentional, if you want everyone to see this change, you need to move the character model in a server-side Script.
So in a Script in the Workspace or in ServerScriptService, try this :
-- wait for a player to join the game
game.Players.PlayerAdded:Connect(function(player)
-- wait for their character to load into the game
player.CharacterAdded:Connect(function(character)
-- yield the thread for but a moment so that the character can finish loading
wait()
-- move their character
local targetPosition = Vector3.new(500, 5, 50)
character:MoveTo(targetPosition)
end)
end)
use the MoveTo() function:
local plr = game.Players.LocalPlayer
plr.Character:MoveTo(CFrame.new(500, 5, 50))

How do I make a part, which is in Workspace, visible and start moving?

The button, which I'm trying to use, is in StarterGUI. Don't know if it helps. Fairly new to scripting, however saw another post with something similar and used that code. Here is my code inside the LocalScript:
local MarketplaceService = game:GetService("MarketplaceService")
local player = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PurchaseEvent = ReplicatedStorage.PurchaseEvent
local productID = 1218445531
script.Parent.MouseButton1Click:Connect(function()
PurchaseEvent:FireServer(productID)
end)
if MarketplaceService:PlayerOwnsAsset(1218445531) then
--Here is where the thing is supposed to happen
end
First you will need to get a reference to the part, one way is to use something like local part = workspace:WaitForChild("PartName")
In order to make it visible, you need to set the transparency to 0. If you dont want the player walking through the part you may also need to turn collisions on with CanColide. Anchoring the part is also recommend to prevent it from falling.
part.Transparency = 0; -- makes it visible
part.CanColide = true; -- makes sure other objects cant go through this
part.Anchored = true; -- prevents the object from falling
There are many ways to make a part move. If the part is supposed to go from one place to another, and only has one destination, a Tween might be useful (see TweenService).
Another way would be with a Heartbeat loop that changes the position each frame (see RunService.Heartbeat). For example,
local keepMoving = true; -- change this to false to stop moving
local RunService = game:GetService("RunService");
local direction = Vector3.new(0, 1, 0); -- change this to anything you want
while (keepMoving) do
local timePassed = RunService.Heartbeat:Wait(); -- wait one frame, roughly 0.016 of a second.
part.Position += direction * timePassed; -- move the part in the direction
end
This would move part up 1 stud every second.

Fixing my color touch script for my roblox puzzle game

So I have a roblox puzzle game that I have been working on for a while now on based on the arcade classic Q bert where the goal is to change all the colours of the bricks while avoiding enemies and getting a high score but I will be adding some features of my own so it does not get as repetitive such as additional tasks like collecting keys on platforms to unlock the door to the next level and secrets like a diamond that rarely appears once every 10 rounds and collecting one gives the player an extra dude and 10 million points.
This is how the game looks so far https://streamable.com/na46cu
The issue I am having as you can see is that the colours do in fact change but when I jump on it again it changes back to the first colour it changes to which in this case is green but I want it to stay on the first colour and make it so that it does not change until the player jumps on the brick again and later on in the game I want it to become more complex and puzzle like as the game goes on like in this example [https://www.youtube.com/watch?v=9eXJWiNXpOo][2] .
I have tried a few things like adding timers ,debounces and even separate scripts alltogether none of which have worked out for me so far and I of course went out looking for a question from somebody else that had a similar problem but so far I have been struggling to find anybody else that has the same problem.
local module = {} --module for the modulescript and for loop is created
local CollectionService = game:GetService("CollectionService")
for _, part,brick in pairs (CollectionService:GetTagged("blocks"))
do
part.Touched:Connect(function(hit) --Part connects with the touched property to the function with the parameter hit
if (hit.Parent:FindFirstChild("Humanoid"))
then
part.BrickColor = BrickColor.new ("Bright green")
wait (2)
part.BrickColor = BrickColor.new ("Eggplant")
-- local sound = workspace.Sound -- use "local sound = workspace.Sound", if there is already a sound object in the workspace
--sound.SoundId = "rbxassetid://4797903038" --replace quoted text with whatever sound id you need to use
--sound:Play()
end
end)
end
-- end)
--end
return module
I am not the best programmer but I do know the basics of programming and I have tried out various programming languages like Python and c++ all of which are not all that hard to understand once you know the basics of it all but finding out the solution to the problem is the really tricky part and so is bug fixing and troubleshooting.
I do know I could try a simple debounce system but that still does not solve the problem and it only makes it so the code only runs once and slows it down.
I have been asking all over the place for a solution to this problem but I never got an answer to it so I am trying on good old Stackoverflow for once to see if this will be the place where I get the help I need.
this should work, try it
local module = {} --module for the modulescript and for loop is created
local CollectionService = game:GetService("CollectionService")
local DidParts = {} -- Initializing another table to check if the part is already in it
for _, part,brick in pairs(CollectionService:GetTagged("blocks")) do
part.Touched:Connect(function(hit) --Part connects with the touched property to the function with the parameter hit
if hit.Parent:FindFirstChild("Humanoid") then
if table.find(DidParts,part) then
return -- checking if the part isnt in the table if it is then return
end
part.BrickColor = BrickColor.new("Bright green")
wait(2)
part.BrickColor = BrickColor.new("Eggplant")
table.insert(DidParts,part) -- when all the code has finished insert it in the table
-- local sound = workspace.Sound -- use "local sound = workspace.Sound", if there is already a sound object in the workspace
--sound.SoundId = "rbxassetid://4797903038" --replace quoted text with whatever sound id you need to use
--sound:Play()
end
end)
end
-- end)
--end
return module

Tower-Defense Enemy AI movement roblox

can someone help me on how show i move the NPCs through a path, like in the tds game?. I have tried this
local function move()
-- source is an array with all the positions it has to go to
for i=1,#source,1 do
-- This is in case the MoveTo takes more than 8 seconds
local itreached = false
while itreached == false do
npc.Humanoid:MoveTo(source[i].Position)
wait()
npc.Humanoid.MoveToFinished:Connect(function()
itreached = true
end)
end
end
end
and it works to an extend , that when i approach the npc it somehow falls and lags , otherwise if i just run it without a player it works just fine. Are there other techniques, like lerp or tween? I tried using lerp, but i couldn't move the whole model.
video showing the problem
You are running into an issue with network ownership. The Roblox engine decides who is responsible for calculating the positions of objects based on some calculation around who is closest to the object and who has a strong enough machine to do the calculation. For example, desktop computers and laptops tend to have a wider sphere of influence than mobile devices. Anyways, when you walk close it the NPCs, there is a handoff of ownership, and that is causing the NPCs to fall over. So to fix it, you need to call SetNetworkOwner(nil) on the NPC's PrimaryPart so that the part is owned by the server.
npc.PrimaryPart:SetNetworkOwner(nil)
Also, if you want to clean up your code, you can make it entirely driven by events. Once you tell it to start moving, it will select the next target once it arrives.
local targetPos = 1
local function move()
npc.Humanoid:MoveTo(source[targetPos].Position)
end
-- listen for when the NPC arrives at a position
npc.Humanoid.MoveToFinished:Connect(function(didArrive)
-- check that the NPC was able to arrive at their target location
if not didArrive then
local errMsg = string.format("%s could not arrive at the target location : (%s, %s, %s)", npc.Name, tostring(targetPos.X), tostring(targetPos.Y), tostring(targetPos.Z))
error(errMsg)
-- do something to handle this bad case! Delete the npc?
return
end
-- select the next target
targetPos = targetPos + 1
-- check if there are any more targets to move to
if targetPos <= #source then
move()
else
print("Done moving!")
end
end)

What is the paramater equivilant to?

function onTouch(part)
local human = part.Parent:findFirstChild("Humanoid")
if (human == nil) then
return
end
human.Health = human.Health - 10
end
script.Parent.Touched:connect(onTouch)
I'm new to coding in lua, and it is my first time using functions. I want to know what the "part" is equal to so that I can find out how to set up the human variable
local human = part.Parent:findFirstChild("Humanoid")
without using the "part," like what can I plug in so that works without even setting up part, because I want to do something with it in a loop:
local burnaffect = false
--local a = 0
function onTouch(part)
local human = part.Parent:findFirstChild("Humanoid")
if (human == nil and burnaffect == false) then
return
end
a = 0
burnaffect = true
end
script.Parent.Touched:connect(onTouch)
while burnaffect == true do
local part = --????
local human = part.Parent:findFirstChild("Humanoid")
human.Health = human.Health - 10
end
The code may seem confusing but I'm fairly new so I don't know what is best yet.
It looks like what you're trying to do is have a player "set on fire" when they touch a certain brick. The code below does exactly this, and I'll explain it line by line afterwards.
function onTouch(part)
local human = part.Parent:findFirstChild("Humanoid")
if (human == nil) then
return
end
local fire = Instance.new("Fire", part)
while (human.Health > 0) do
human.Health = human.Health - 10
wait(0.1)
end
end
script.Parent.Touched:connect(onTouch)
So, I'll start going through this.
function onTouch(part)
We need to define the function first and give it a name so that we can reference it in the Touched event later. The part parameter is the Part object that touched the script.Parent object and caused the Touched event to fire. So, ROBLOX will automatically call this function whenever something touches your script.Parent and automatically input the Part that touched it as that first parameter, part.
local human = part.Parent:findFirstChild("Humanoid")
This will get the Parent of the Part that touched the block (because if a player is touching the block, it isn't going to give us the Character, it's going to give us an Arm or a Leg in the part variable, because that's the actual Part that touched it, so we need to get that part's Parent. Then, once we have the Parent, we want to get the Humanoid object inside of the Character. Then, we put that Humanoid object inside of the human variable (if we could find one, otherwise we put nil into that human variable).
if (human == nil) then
We want to check if human is nil (which would mean we couldn't find a Humanoid object in the line before this one, which means whatever touched this isn't a real Character, so we'll want to return (which means stop running the function immediately).
local fire = Instance.new("Fire", part)
This line isn't necessary, I added it because I thought if you wanted to simulate burning, this would help. You can leave it out if you'd like. It will create a new Instance of type Fire, and places it inside of the part. That is to say, if a player's Leg touches this part, a Fire will be put inside of that leg, which will make it appear to ignite in flames.
while (human.Health > 0) do
We want to keep looping until the player dies (has a human.Health value of 0 or less) so we tell the loop to keep going while human.Health is greater than 0.
human.Health = human.Health - 10
We'll deincrement the human.Health value by 10, and then wait(0.1), which will cause the script to wait for 1/10 of a second (you can change this to a different number, but it is important to keep it as if you remove it, the loop will run extremely fast and kill the player immediately. If you want this to happen, you can remove the wait, but if you wanted to kill the player immediately, you could just set human.Health = 0 in the first place.
If you have any questions, feel free to ask! Hope this answered your question.
I remember when I used to use Lua for Roblox. The part is the part in the game that gets touched. You need to reference it so you can find the humanoid object it belongs to or lack of so your code can tell if it is a humanoid that touched it or not. Let me know if you have any further questions.

Resources