How do you clone a MODEL on Roblox? - roblox

I have seen videos and stuff on how to clone things in Roblox, but most of it is just "How to clone parts in Roblox!" and "How to clone OBJECTS in Roblox!" But still is only showing parts. My goal here is to make a system that when you touch a part, your character gets cloned to a position in the workspace, while a cut scene plays. This is like the system used in Mini Toon's game "Piggy" that broke records. I do not need help with any of the cut scene things though, I got that covered.
wait(10)
copy = game.Workspace.YourUsernameHere:clone()
copy.Parent = game.Workspace
copy.Name = "Test"
copy.Posistion = Vector3.new(0, 0, 0)
This is one of the things I have seen. I hope someone can help me with this.

The Archivable property must be set to true in order to clone the player's Character.
wait(10)
game.Workspace.YourUsernameHere.Archivable = true
copy = game.Workspace.YourUsernameHere:clone()
game.Workspace.YourUsernameHere.Archivable = false
copy.Parent = game.Workspace
copy.Name = "Test"
copy:MoveTo(Vector3.new(0, 0, 0))

Use Model:SetPrimaryPartCFrame()

Related

How can I use the new raycast in Roblox Studio?

I am trying to learn how to use the Raycast system in Roblox studio, I don't have enough experience in Roblox studio to understand what's going on here, or rather how I am going to change or update this line of code since this is deprecated.
local function castRay ()
local origin = firePoint.Position
local direction = (mouse.Hit.p - firePoint.Position).Unit
direction = direction * gunSettings.range
local ray = Ray.new(origin, direction)
local hit, pos = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
replicatedStorage.Replicate:FireServer(tool, origin)
local visual = Instance.new("Part")
local length = (pos - origin).Magnitude
Specifically on local hit, pos, this is now deprecated as stated in roblox studio, as well as local ray, now I did research that this kind of code can be used instead of the following two that I just mentioned
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
But the following lines such as length requires pos variable, I don't know how I can move forward thanks to this. So there is no error for now, but I am asking cause I want to implement the new raycast system in this function, and I'm kind of stuck on how to do it, Here is the full code of the function:
local function castRay ()
local origin = firePoint.Position
local direction = (mouse.Hit.p - firePoint.Position).Unit
direction = direction * gunSettings.range
local ray = Ray.new(origin, direction)
local hit, pos = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
replicatedStorage.Replicate:FireServer(tool, origin)
local visual = Instance.new("Part")
local length = (pos - origin).Magnitude
visual.Anchored = true
visual.CanCollide = false
visual.Material = Enum.Material.Neon
visual.Color = gunSettings.rayColor
visual.Size = Vector3.new(gunSettings.raySize.X, gunSettings.raySize.Y, length)
visual.CFrame = CFrame.new(origin, pos)*CFrame.new(0,0,-length/2)
visual.Parent = workspace.Effects
debris:AddItem(visual, gunSettings.debrisTime)
return hit, pos, direction, origin
end
If you look at the docs for WorldRoot:Raycast, you'll see a code sample on how to utilize the new raycast function.
The new API just packages the data a little differently. Rather than passing your ignorelist into the raycast function, you pass it into the RaycastParams object. And all of the data you get back is packaged into a RaycastResult object.
So you can adapt your code simply like this :
local function castRay()
local origin = firePoint.Position
local direction = (mouse.Hit.p - firePoint.Position).Unit * gunSettings.range
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = ignoreList
local raycastResult = workspace:Raycast(origin, direction, raycastParams)
local hit = raycastResult.Instance
local pos = raycastResult.Position
The rest of your code should work just as before.

Roblox; making destroyed parts reappearing

I've made a game where you step on a specific tile this part gets destroyed. I want to make it that after a certain amount of time this destroyed block will reappear, now you might wonder why I just don't make the part invisible and make it lose it's player collision. I have not done this because I don't know how to make the Texture on top of the part transparency 1.
You could make a copy of the part, then do the destruction, and put the copy back into its place after a few seconds:
function onTouched(hit)
-- see if it was a player that touched the part
local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
if (plr == nil) then return end
-- make backup of the part and its parent
local part = workspace.Part
local backup = part:Clone()
local backupParent = part.Parent
part:Destroy() -- do some cool effect for the destruction of it...
spawn(function()
wait(5)
-- put part back in place
backup.Parent = backupParent
backup.Touched:Connect(onTouched)
end)
end
workspace.Part.Touched:Connect(onTouched)
If you just want it to disappear you could also just remove it from the object tree temporarily by setting its Parent to nil:
function onTouched(hit)
local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
if (plr == nil) then return end
local part = workspace.Part
local backupParent = part.Parent
part.Parent = nil
spawn(function()
wait(5)
part.Parent = backupParent
end)
end

Damage player when touching water terrain

I'm trying to decrease a player's health when they touch some water terrain in ROBLOX.
I'm not sure why this doesn't work, but it doesn't. If someone could help me out that would be neat.
while wait() do
local player = game.Workspace.LocalPlayer
local headLoc = game.Workspace.Terrain:WorldToCell(player.Character.Head.Position)
local hasAnyWater = game.Workspace.Terrain:GetWaterCell(headLoc.x, headLoc.y, headLoc.z)
if player.Character.Humanoid.Health ~= 0 then
if hasAnyWater then
player.Character.Humanoid:TakeDamage(0.2)
end
end
end
If you check your output window you'll see why:
LocalPlayer is not a valid member of Workspace
LocalPlayer is in "Players", so you should declare:
local player = game.Players.LocalPlayer
So if you change that, and have it in a LocalScript for example in the StarterPlayerScripts folder, everything works just like you want.
Solved.
local player = game:GetService("Players").LocalPlayer
while wait(0.5) do
local headLoc = game.Workspace.Terrain:WorldToCell(player.Character.LowerTorso.Position) or game.Workspace.Terrain:WorldToCell(player.Character.Torso.Position)
local hasAnyWater = game.Workspace.Terrain:GetWaterCell(headLoc.x, headLoc.y, headLoc.z)
if player.Character.Humanoid.Health ~= 0 then
if hasAnyWater then
player.Character.Humanoid:TakeDamage(8)
end
end
end

I am trying to make NPC that is randomly walking and attacks players

I am trying to make NPC that is randomly walking and attacks players. Can someone help me?
A good starting place for NPCs that walk around and attack players are zombies. I would recommend looking at the R15 Zombie with #### sounds model in the Toolbox. Once you drag it into the Workspace, there is a script in there called Script that is fairly straightforward in how it moves the zombie around to attack other humanoid characters.
Well, that is complex in itself, but if you are new to scripting, it might be best to just get the free-modeled zombie in the toolbox, and then change it's appearance through the explorer window. If you want to go the long route, it might be better to learn how to use the function :MoveTo. The Roblox Developer website provides good info on how to use these things. As for attacking people, just put a script in the arm that damages on touch. Here's something that might work, (put it in the same model as the humanoid):
local larm = script.Parent:FindFirstChild("Left Arm")
local rarm = script.Parent:FindFirstChild("Right Arm")
function findNearestTorso(pos)
local list = game.Players:GetPlayers()
local torso = nil
local dist = 10
local temp = nil
local human = nil
local temp2 = nil
for x = 1, #list do
temp2 = list[x]
if temp2.Character:IsA("Model") then
temp = temp2.Character:FindFirstChild("Torso")
human = temp2.Character:FindFirstChild("Humanoid")
if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then
if (temp.Position - pos).magnitude < dist then
torso = temp
dist = (temp.Position - pos).magnitude
end
end
end
end
return torso
end
while true do
wait(0.1)
local target = findNearestTorso(script.Parent.Torso.Position)
if target ~= nil then
script.Parent.Humanoid:MoveTo(target.Position, target)
end
end
For the damage script, you can use this if you add it to one of the arms:
script.Parent.Touched:connect(function(part)
if part.Parent:FindFirstChild("Humanoid") then
part.Parent.Humanoid:TakeDamage(30)
end
end)

Prevent SKPhysicsBody From Pushing SKSpriteNode Upwards

I currently have two SKSpriteNodes on top of each other like so (The white part is one and the brown round circle part is the other one):
The white part is positioned 1/3 the way down on top of the round brown sprite node. In the picture, the brown round part has a SKPhysicsBody applied to it already as seen by the light blue outline around it. When I add a SKPhysicsBody around the top ovalish white part it pushes it up and not in the position I wanted it.
How can I have a SKPhysics body coving both bodies of sprites but not have the physics bodies push on one another which makes the white part move upwards? I would like the white part to stay in the position it was in the first image.
Thanks for anyone help!
Here's the code I used for the SKPhysicsBody's:
// create, position, scale & add the round body
roundBody = SKSpriteNode( imageNamed: "roundBody" )
roundBody.position = CGPoint( x: 207, y: 70 )
roundBody.zPosition = 1
roundBody.xScale = 0.3
roundBody.yScale = 0.3
// add sprite node to view
self.addChild( roundBody )
// create, position, scale & add the head
theHead!.position = CGPoint( x: 207, y: roundBody.frame.maxY / 1.15 )
theHead!.zPosition = 2
theHead!.xScale = 0.3
theHead!.yScale = 0.3
// setting up a SKPhysicsBody for the round body
roundBody.physicsBody = SKPhysicsBody( circleOfRadius: roundBody.size.width / 4 )
roundBody.physicsBody!.dynamic = true
roundBody.physicsBody!.affectedByGravity = true
roundBody.physicsBody!.allowsRotation = false
roundBody.physicsBody!.pinned = false
// setting up a SKPhysicsBody for the head
theHead!.physicsBody = SKPhysicsBody(circleOfRadius: theHead!.size.width / 2 )
theHead!.physicsBody!.dynamic = true
theHead!.physicsBody!.affectedByGravity = false
theHead!.physicsBody!.allowsRotation = false
theHead!.physicsBody!.pinned = false
I was able to figure out that if you use SKPhysicsJointPin it does the exact thing I needed! (Which was to basically pin a sprite head on it's body and share a physics body)
let joinTogether = SKPhysicsJointPin.jointWithBodyA(
roundBody.physicsBody!,
bodyB:theHead!.physicsBody!,
anchor: GPointMake(CGRectGetMidX(roundBody.frame),
CGRectGetMinY(theHead!.frame)))
scene!.physicsWorld.addJoint(joint)
Hope this helps someone in the future!
If you never want it to move, set it's .dynamic property to false. Then other objects may or may not bounce/collide with it (depending upon their collisionBitMask) but it won't move in response to those collisions.
Your own answer is correct and a better solution but just to explain further.
The reason of the bodies colliding is that by default a physics body's collision bit mask is set to all categories which means it will collide with everything. In your code you are not calling
roundBody.physicsBody?.collisionBitMask = ...
which is why its using the default values.
To change that you could give your body and head a different collisionBitMask.
Im sure you will deal with this sooner or later when you handle collisions
Also as a tip it's a better idea to not force unwrap the physics bodies unless you have too, even though you know they exist. So you should replace your ! with ? whenever possible.