object:PivotTo(Crame.new(result.Position + result.Normal) causes object to hover

so I have an object that I want to deploy at ground level. when I use:

object:PivotTo(Crame.new(result.Position + result.Normal)

the object hovers a bit above the ground, (maybe one stud high) instead of even with the ground.

Shouldn’t the pivot point be directly flat with the ground?

edit: the pivot point is dead center in the object, I’ve not move d it. “result” is generated from a raycast straight down and hits the baseplate

5 Likes

well are you sure the position is on the ground

1 Like

Yes, “result” is generated from a raycast straight down. its hitting the baseplate. the part hovers a stud above the ground. the parts pivot point is dead center in the part - I haven’t moved it.

Thanks

1 Like

This here is wrong, raycast normal returns the incident at 90 degrees to a surface of the ray target,

What you should do is add the objects half Y size

object:PivotTo(Crame.new(result.Position + object:GetExtenseSize() * Vector3.new(0,0.5,0))
(This is if the object is a model)

1 Like

I’m sorry, FartFella, but I’m not sure what your response meant.

However, we are also making this work for objects that slant in space, so a deployable can be placed on a slant. As such, the 1/2 height won’t totally work, I don’t think?

Thank you for your response.

1 Like

I just thought of a way to do the slant. If you performed your vertical raycast, then cast another ray that’s basically the same as the first one but oriented to the rotation of the part that the first raycast hit. So basically you cast a vertical ray and it hits the baseplate, then it performs another one based on the surface of the baseplate the first raycast hit to determine the slant of the said placed object. Maybe I’m rambling on about something pointless because I haven’t tested this so sorry if this is wrong. I also might be saying something pointless if raycasts automatically do this.

2 Likes

You can use:

object.CFrame = object.CFrame:ToWorldSpace(CFrame.new(0,0.5,0))

Or however much the object needs to be lifted off from the ground.
Use PivotTo() for models, I can provide code for that if needed.

2 Likes

thank you for that, we know how do this part. But the object still will not slant with the ground if it is placed on a hill.

Alright, I will try finding a solution. I will get on Roblox Studio in a moment.

2 Likes

thanks ! let us know if you get it working. we are still researching, but the API is incomplete, no one on youtube seems to be teaching this (as obvious as it is) and the tutorials often don’t work or aren’t clear!

We really appreciate your help!

1 Like

EDIT: I misunderstood your problem, so this might have more than what you need.

I have found a solution to both of your issues. So I will combine them into one. For the issue with the floating, use:

object.CFrame = object.CFrame:ToWorldSpace(CFrame.new(0, x, 0)

or for a model, use

model:PivotTo(model.WorldPivot:ToWorldSpace(CFrame.new(0, x, 0)))

change x to however high you need. These also might need to be tweaked based on how the object is rotated.

For the issue with the raycasting, and putting it where the raycast hits and rotating it right, do this:

object.CFrame = CFrame.new(ray.Position, ray.Position + ray.Normal)

and for models, use

model:PivotTo(CFrame.new(ray.Position, ray.Position + ray.Normal)

I would like to credit the post made by @ExcessEnergy which helped me with this.

Sorry if I did this wrong, I am pretty new to using the devforum.

1 Like

I think a better approach would be to edit the pivot point to the bottom so you can remove the + result.Normal.

1 Like

I know this solution is all over. I’m actually using it in my example above. but it doesn’t work accurately.

have you tried it, as requested?>

1 Like

My apologies for misunderstanding, I very well have tried all of the code I had provided in my previous post and it worked fine. So how exactly is the problem occurring when you use CFrame:ToWorldSpace()? With the code used, what is currently happening to the object?

1 Like

cool, thanks for explaining.

I’ll have to get you screenshots. Might not be ablet to get it til tomorrow or friday.

Thanks !

so when I do it on a slant this happens:

facing downhill, this:

this one is .almost. right, but not:

this one is .almost. right on flat ground, except “look at” rotates the front to face the ground.

the full code I’m using (also edited to first post above.)


local tool = script.Parent
local storage = game.ReplicatedStorage
local u = require(game.Workspace.Utility)
local playerService = game:GetService("Players")
tool.Activated:Connect(function()
    local char: Model = script.Parent.Parent
	local player = playerService:GetPlayerFromCharacter(char)

--untoggle	local teamTag = char:FindFirstChild("TeamTag")
    --local char = script.Parent.Parent

    local deployment = storage:WaitForChild("DeployableModels"):WaitForChild("Spikes"):Clone()
	local head = char:FindFirstChild("Head")
	local origin = (head.Position + (head.CFrame.LookVector.Unit * 5))
	--local origin = char.PrimaryPart.Position
	local direction = Vector3.new(0, -250, 0)
    
	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Exclude
	params.FilterDescendantsInstances = {char}
	params.IgnoreWater = true

    local result = workspace:Raycast(origin, direction, params)
    if result then

		local rootPart = char:WaitForChild("HumanoidRootPart")
		--
--untoggle	player:WaitForChild("DeployableUsed").Value = true
  
		deployment:PivotTo(CFrame.new(result.Position, result.Position + result.Normal))

		deployment.Orientation = Vector3.new((deployment.Orientation.X), char:FindFirstChild("HumanoidRootPart").Orientation.Y , deployment.Orientation.Z)

		
		deployment.Anchored = true

        deployment.Parent = workspace
 		--untoggle u.InsertTag(deployment, "TeamTag", teamTag.Value)
		task.wait(1)
		--tool:Destroy()
		task.wait(15)
		deployment:Destroy()

	end
end)

thanks!

do you have any screenshots of that code working?

this guy was using the same code you provide, and also gets wonky angles instead of the proper result:

just curious if you can show me an example of this working, and then maybe I can apply your workaround

hm. wait…findpartonray is deprecated…isnt it?

1 Like

Yes that’s why I tweaked it a little. Here’s an example of it in action:


Image above is before. The small 1x1x1 stud part represents the ray’s origin. It is facing towards the little red part. The little red part’s CFrame is set to the slant. The slanted part is what intercepts the ray.

Image above is after. (Don’t mind the lighting changes)

Image above is after in detail.

This is the direct code it executes to complete this.


local params = RaycastParams.new()
params.CollisionGroup = "Default"
params.FilterDescendantsInstances = {script.Parent}
params.FilterType = Enum.RaycastFilterType.Include

local ray = workspace:Raycast(script.Parent.Party.Position, script.Parent.Party.CFrame.LookVector * 100, params)

script.Parent.Part.CFrame = CFrame.new(ray.Position, ray.Position + ray.Normal)

The issue with yours is probably how the model/object is composed. Its front needs to represent the front or it will not rotate correctly. And also, with models like these, it is very recommended to set a primary part if one is not already set.

1 Like

After an hour of restless coding, I finally figured out something that half works. I modified your script and had to remove some things so it didn’t error, so you might have to add some stuff back in. Basically, GoPart is just the direction of the ray but I stink at raycasting directions so I did that to be more accurate. I recommend you add that to the tool. It’s the same CFrame as the handle but tilted to the ray’s direction.

This works for the most part it just sometimes will randomly turn left or right 90 degrees so uh… I might be able to fix that later or you can code some sort of way to make sure that doesn’t happen.

local tool = script.Parent
local storage = game.ReplicatedStorage
local playerService = game:GetService("Players")
tool.Activated:Connect(function()
	local char: Model = script.Parent.Parent
	local player = playerService:GetPlayerFromCharacter(char)

	--untoggle	local teamTag = char:FindFirstChild("TeamTag")
	--local char = script.Parent.Parent

	local deployment = storage:WaitForChild("LolPart"):Clone()
	local head = char:FindFirstChild("Head")
	local origin = (head.Position)
	--local origin = char.PrimaryPart.Position
	local direction = script.Parent.GoPart.CFrame.LookVector * 100

	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Exclude
	params.FilterDescendantsInstances = {char}
	params.IgnoreWater = true

	local result = workspace:Raycast(origin, direction, params)
	if result then

		local rootPart = char:WaitForChild("HumanoidRootPart")
		--
		--untoggle	player:WaitForChild("DeployableUsed").Value = true
		deployment:PivotTo(CFrame.new(result.Position, result.Position + result.Normal):ToWorldSpace(CFrame.new(0, 0, -deployment.Size.Z / 2)) * CFrame.Angles(math.rad(-90), math.rad(-90), 0))
		local x,y,z = script.Parent.Handle.CFrame:ToEulerAnglesXYZ()
		deployment.CFrame = deployment.CFrame * CFrame.Angles(0,y,0)
		deployment.Anchored = true

		deployment.Parent = workspace
		deployment.CanCollide = false
		deployment.CanQuery = false
		--untoggle u.InsertTag(deployment, "TeamTag", teamTag.Value)
		task.wait(1)
		--tool:Destroy()
		task.wait(15)
		--deployment:Destroy()

	end
end)
1 Like

Yoyoyoyo! This works. It does make the item hover off the ground a tiny bit, but we are jiggerin with it. We are looking at the new parts in the script, cause I want to learn how this works.

I’ll have a couple questions, hopefully you can answer them!

Thanks bro !

1 Like