So I’ve been trying to make something in VR where you can pick up items, and I’ve been experimenting with this.
I’ve been trying to use BodyPositions, AlignPositions, etc, but I can’t seem to make it look good…
What happens: https://gyazo.com/7d59f16c58d9e332a2d3eae4e3429de3
I’m using BodyPositions for this.
Code:
local UserInputService = game:GetService("UserInputService")
local StarterGUI = game:GetService("StarterGui")
local VRService = game:GetService("VRService")
local CurrentCamera = workspace.CurrentCamera
UserInputService.InputBegan:Connect(function(k)
print((k.KeyCode == Enum.KeyCode.Unknown and "it dont have one tho") or k.KeyCode or "it dont have one tho")
end)
if VRService.VREnabled == true then
warn("VR is enabled")
repeat game:GetService("RunService").Heartbeat:Wait() local PCallSuccess = pcall(function() StarterGUI:SetCore("VRLaserPointerMode", 0) StarterGUI:SetCore("VREnableControllerModels", false) end) until PCallSuccess
game.Players.LocalPlayer.CameraMaxZoomDistance = .5
game.Players.LocalPlayer.CameraMode = Enum.CameraMode.LockFirstPerson
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Hands = ReplicatedStorage:WaitForChild("oculusHands"):Clone()
local handL = Hands:WaitForChild("handL")
local handR = Hands:WaitForChild("handR")
local gripL = handL:WaitForChild("Grip")
local gripR = handR:WaitForChild("Grip")
local gripPalmL = gripL:WaitForChild("LeftHand"):WaitForChild("Palm")
local gripPalmR = gripR:WaitForChild("RightHand"):WaitForChild("Palm")
local handPalmL = handL:WaitForChild("LeftHand"):WaitForChild("Palm")
local handPalmR = handR:WaitForChild("RightHand"):WaitForChild("Palm")
local usingGrip = false
Hands.Parent = workspace
handL:SetPrimaryPartCFrame(VRService:GetUserCFrame(Enum.UserCFrame.LeftHand))
handR:SetPrimaryPartCFrame(VRService:GetUserCFrame(Enum.UserCFrame.RightHand))
local Focused = false
UserInputService.TextBoxFocused:Connect(function() Focused = true end) UserInputService.TextBoxFocusReleased:Connect(function() Focused = false end)
UserInputService.InputBegan:Connect(function(input)
if not Focused then
if input.KeyCode == Enum.KeyCode.ButtonB then
VRService:RecenterUserHeadCFrame()
elseif input.KeyCode == Enum.KeyCode.ButtonR1 then
for _,v in pairs(workspace:GetDescendants()) do
if v:IsA("BasePart") then
if v:FindFirstChild("CanBePickedUp") and v:FindFirstChild("Attach") then
if v:FindFirstChild("CanBePickedUp").Value == true then
if v.Anchored == false then
if (handR.PrimaryPart.CFrame.Position - v.CFrame.Position).Magnitude <= 5 then
spawn(function()
v.Position = handR.PrimaryPart.CFrame.Position + (handR.PrimaryPart.CFrame.UpVector)
local attachmentToUse = ((usingGrip == true and gripPalmR) or (usingGrip == false and handPalmR))
local CanCollide = v.CanCollide
local PickedUp = true
v.CanCollide = false
local Align = Instance.new("BodyPosition", v)
Align.MaxForce = Vector3.new(100000, 100000, 100000)
Align.P = 100
Align.D = 1
local Connect
Connect = UserInputService.InputEnded:Connect(function(input)
if input.KeyCode == Enum.KeyCode.ButtonR1 then
PickedUp = false
Connect:Disconnect()
return
end
end)
repeat game:GetService("RunService").RenderStepped:Wait() Align.Position = (CurrentCamera.CFrame * VRService:GetUserCFrame(Enum.UserCFrame.RightHand)).Position + Vector3.new(0, 0, 2) until not PickedUp
Align:Destroy()
v.CanCollide = CanCollide
end)
break
end
end
end
end
end
end
end
end
end)
game:GetService("RunService").RenderStepped:Connect(function()
handL:SetPrimaryPartCFrame((CurrentCamera.CFrame * VRService:GetUserCFrame(Enum.UserCFrame.LeftHand)) * CFrame.Angles(0, math.rad(180), math.rad(90)))
handR:SetPrimaryPartCFrame((CurrentCamera.CFrame * VRService:GetUserCFrame(Enum.UserCFrame.RightHand)) * CFrame.Angles(0, math.rad(180), math.rad(90)))
end)
else
warn("VR is not enabled")
end
Anything that could help will be greatly appreciated!
Wow, that is some seriously deep nesting! I’d recommend combining all those if statements using and as well as breaking that key handler into a separate function.
It seems to me that the force is under dampened. Increasing the D parameter should help. The problem with using a force for this though is that the amount of force required to achieve the same movement behavior will change as the mass of the part increases. You could use the TweenService to tween between the current CFrame and goal CFrame regardless of mass.
I have increased the D parameter before and that just made it go slow motion. I’m trying to make it stay in the hand’s position while still having velocity to be able to throw it.
Hehe, and moving slowly to the correct point would mean that the force is over dampened. There should be a sweet spot, although it may be difficult to find! Reaching that sweet spot makes the motion “critically dampened.” There should be a formula for critical dampening, although I’m not aware of what it is in this case. I’ll have to defer to the community for the formula.
As I said before, I’m trying to make it so it keeps the velocity of the cube when you’re moving your hand around, so when you let go, you can throw it.
Ah, yes, okay. You can simply set the CFrame then every renderstep. To set the velocity when the part is released, you simply have to keep track of the previous known positions over some time (like a tenth of a second). The averaged changes in position over time (weighted by how close they are in time to the actual moment of release) would give a nice velocity.
Store the cframe or position of the last few frames and you could calculate it. Ex lastframepos-thisframepos and just set the velocity (may need to multiply the above value by the mass for a effect).
If you are firm with bodyPositons, you will just have to find that sweet spot by tweaking values.
It’s already seen in the script.
Plus, I’ve moved on to CFrame editing.
I’m trying to get an equation to where I am able to make it throw good without it falling to the ground.
Current:
I find it good to use a bool value because sometimes you can make an item that can be picked up at random times, and can be used for… let’s say, a random number generator.
for _,v in pairs(workspace:GetDescendants()) do
if v:IsA("BasePart") then
if v:FindFirstChild("CanBePickedUp") and v:FindFirstChild("Attach") then
if v:FindFirstChild("CanBePickedUp").Value == true and v.Anchored == false and (handR.PrimaryPart.CFrame.Position - v.CFrame.Position).Magnitude <= 5 then
spawn(function()
v.Position = handR.PrimaryPart.CFrame.Position + (handR.PrimaryPart.CFrame.UpVector)
local attachmentToUse = ((usingGrip == true and gripPalmR) or (usingGrip == false and handPalmR))
local OrigLV = v.CFrame.LookVector
local BeforePosition = v.Position
local CanCollide = v.CanCollide
local PickedUp = true
v.CanCollide = false
v.Anchored = true
local Connect
Connect = UserInputService.InputEnded:Connect(function(input)
if input.KeyCode == Enum.KeyCode.ButtonR1 then
PickedUp = false
Connect:Disconnect()
return
end
end)
repeat game:GetService("RunService").RenderStepped:Wait() BeforePosition = v.Position / 1.2 v.CFrame = CFrame.new(handR.PrimaryPart.CFrame.Position - handR.PrimaryPart.CFrame.UpVector, OrigLV + handR.PrimaryPart.CFrame.UpVector) until not PickedUp
v.CanCollide = CanCollide
v.Anchored = false
v.Velocity = (BeforePosition - v.Position) * 1.5
end)
break
end
end
end
end
I wouldn’t like to mess with CollectionService or whatever it is that uses the tags, because I am trying to keep this simplistic as I might release this as a free model.