How to make the part clone iinfront of another torso

  1. What do you want to achieve?
    Trying to make a tool that spawns a laser beam in front of the character torso

  2. What is the issue?
    The laser beam spawns in a different orientation.

  3. What solutions have you tried so far?
    I have tried looking posts related to this post but I couldnt understand most of them. I know I can use lookVector but I just dont know how.

Scripts:

Local scripts:

wait()
local plr = game.Players.LocalPlayer
local char = plr.Character or plr:WaitForChild("Character") or nil
local Events = script.Parent.Events
local Fire = Events.RemoteEvent
local CoolDown = 1
db = false

script.Parent.Activated:Connect(function()
	print("hm")
	local char = plr.Character or plr:WaitForChild("Character")
	if not db then
		db = true
		local x = char.Torso.Position.X
		local y = char.Torso.Position.Y
		local z = char.Torso.Position.Z
		local r1 = char.Torso.Orientation.X
		local r2 = char.Torso.Orientation.Y
		local r3 = char.Torso.Orientation.Z
		local torso = char.Torso
		Fire:FireServer(x,y,z,r1,r2,r3,torso)
		wait(CoolDown)
		db = false
	end
end)

Server Script:

wait()
local Events = script.Parent.Events
local Fire = Events.RemoteEvent

Fire.OnServerEvent:Connect(function(plr,X,Y,Z,R1,R2,R3,TORSO)
	if plr then
		print("e")
		local klone = game.ReplicatedStorage.LaserBeam:Clone()
		klone.Parent = workspace
		klone.Position = Vector3.new(X + 26 ,Y,Z)
		klone.Anchored = true
		klone.CanCollide = false
		print(TORSO.CFrame)
		klone.Orientation = Vector3.new(R1,R2,R3)
		--[[
		klone.CFrame = CFrame.new(TORSO.CFrame.Position, TORSO.CFrame.Position + TORSO.CFrame.lookVector)
		--]]
	end
end)

Any help will be appreciated :slight_smile:

1 Like

Don’t use Position or Orientation properties. Use CFrame instead.

klone.CFrame = TORSO.CFrame

I’d also align it further by positioning its CFrame forwards by half its Z size value, but this will get it to spawn the laser in the same orientation as the torso.

Another note I should mention is that you should parent the instance after you’ve assigned all the properties. The server shouldn’t need to waste performance on trying to replicate each change to all the clients.

1 Like

So I am not sure if you are wanting to make the laser beams automatically despawn or do damage to players but I will show you how to fix this issue.

The first thing I want to address is that you do not need to send all that information to the serverimage

All you need to do is tell the server you wish to fire your gun, and the server can do it’s own security checking to make sure that the player isn’t cheating.

Also, using .Torso is not the best idea unless you know for sure that people playing your game will be using R6 and not R15, as when you try to use .Torso on an R15 player it will give you an error (since their torso is split into UpperTorso and LowerTorso). I’m also not sure if you actually want the laser to emit from the tip of the tool.

So the best way to fix this issue is to use LookVector. Here’s how you would move Part1 5 studs infront of Part2 using LookVector:

local Part1 = workspace.Part1;
local Part2 = workspace.Part2;

Part1.CFrame = Part2.CFrame + (Part1.CFrame.LookVector*5);

Here is the revamped Client script:

(Please excuse my slightly different style of writing code, ; semicolons are not required but I use them anyway)

Client (LocalScript) Script revamp:

wait();
local Player = game.Players.LocalPlayer;
local Character = Player.Character or Player:WaitForChild("Character"); 
local Events = script.Parent.Events;
local Fire = Events.RemoteEvent;
local CoolDown = 1;
local db = false;

script.Parent.Activated:Connect(function()
	Character = Player.Character or Player:WaitForChild("Character");
	if not db and Character then
		db = true;
		Fire:FireServer("Fire");
		wait(CoolDown);
		db = false;
	end
end);

Server Script revamp:

wait()
local Events = script.Parent.Events
local Fire = Events.RemoteEvent

local Distance = 26; -- Was 26
local Offset = 1; -- Offset so the beam does not go through the player

local Beam = game.ReplicatedStorage.LaserBeam;

Fire.OnServerEvent:Connect(function(Player)
	if Player then
		local Character = Player.Character or Player:WaitForChild("Character");
		local H = Character:FindFirstChild("HumanoidRootPart")
		if (Character and H) then
			local CF = H.CFrame; -- Get the CFrame of HumanoidRootPart.
			
			local Clone = Beam:Clone() -- Clone the template
			local S = Clone.Size; -- Grab it's size
			Clone.Size = Vector3.new(0.5, 0.5, 0.5+Distance); -- Make the laser stretch to the proper length.
			Clone.CFrame = CF + (CF.LookVector*((Distance/2)+Offset)) -- Position the laser .
			Clone.Parent = workspace; -- Always set the parent property last, as it is more efficient.
		end
	end
end)

So again, what this line:
Clone.CFrame = CF + (CF.LookVector*((Distance/2)+Offset)) is doing is saying “Okay, set your CFrame to the CFrame of the HumanoidRootPart, and add the LookVector multiplied by the distance.”

The (Distance/2) + Offset is used so that the part is spaced properly from the character.

All you will need to do to make this work is put an empty part in ReplicatedStorage called LaserBeam.

Here's how it looks

2 Likes

Thank you so much for your well detailed, wonderful answer. I was confused with lookVector but I am not anymore. Also I actually never realized that I don’t need to pass all the information like x, y and z axis values.

Thank you again I learned a lot.

@DesiredFlamingFire

Thank you I will keep that in mind.

1 Like

Hey instead of doing Player:WaitForChild(“Character”) you should probably do Player.CharacterAdded:Wait()

.Activated is for a tool so it wouldn’t fire without a Character ( i think ) and you’re not really using the character so why wait for it to exist when activating the tool?

Also I don’t think you should wait for the character to exist on the server since the remoteevent shouldn’t even fire when you do not have a character so you’d change it to

local Character = Player.Character
local H = Character and Character:FindFirstChild("HumanoidRootPart")
if not (Character and H) then return end

Last thing is RemoteEvents and RemoteFunctions WILL ALWAYS pass the player as the first argument so checking if the player exists is unnecessary.

2 Likes

Good to know! I hardly ever use tools so I’m a bit rusty in that area. Was also not aware that there was a characteradded event.

As for the remote event, I’m aware of this, I kind of threw it together on my phone then pasted it into studio on my PC to make sure it at least worked :stuck_out_tongue_winking_eye:

1 Like