Script in my cat model. Primary Part is already been set and there are no errors in the output nor any prints/warns. I have made sure the Owner Attribute in the value is set to the players username.
local cat = script.Parent
task.wait(4)
-- Ensure the cat model has a PrimaryPart set
if not cat.PrimaryPart then
warn("PrimaryPart not set for cat model")
return
end
-- Add BodyGyro to the PrimaryPart for orientation
local bodyGyro = Instance.new("BodyGyro")
bodyGyro.MaxTorque = Vector3.new(4000, 4000, 4000) -- Adjust the torque as needed
bodyGyro.P = 3000 -- Adjust the power of the gyro
bodyGyro.Parent = cat.PrimaryPart
-- Add BodyPosition to the PrimaryPart
local bodyPosition = Instance.new("BodyPosition")
bodyPosition.MaxForce = Vector3.new(50000, 50000, 50000) -- Increase the force as needed
bodyPosition.Parent = cat.PrimaryPart
-- Get the Value object with the Owner attribute
local ownerValueObject = cat:FindFirstChild("Value")
if not ownerValueObject then
warn("Value object not found in cat model")
return
end
local rotationOffset = CFrame.Angles(0, math.rad(-80), 0) -- Adjust this angle incrementally (90 degrees initially)
local previousPosition = cat.PrimaryPart.Position
local offset = Vector3.new(2, 2, -2) -- Adjust the offset as needed (2 studs right, 2 studs up, 2 studs behind)
-- Update the cat's orientation to face the direction it is moving
game:GetService("RunService").Stepped:Connect(function()
local ownerName = ownerValueObject:GetAttribute("Owner")
if not ownerName then
return
end
local player = game.Players:FindFirstChild(ownerName)
if not player then
warn("Player not found: " .. ownerName)
return
end
local character = player.Character
if not character then
warn("Character not found for player: " .. ownerName)
return
end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then
warn("HumanoidRootPart not found for player: " .. ownerName)
return
end
local currentPosition = cat.PrimaryPart.Position
local direction = (currentPosition - previousPosition).Unit
if direction.Magnitude > 0 then
direction = Vector3.new(direction.X, 0, direction.Z).Unit
bodyGyro.CFrame = CFrame.lookAt(cat.PrimaryPart.Position, cat.PrimaryPart.Position + direction) * rotationOffset
end
local targetPosition = humanoidRootPart.Position + offset
bodyPosition.Position = targetPosition
previousPosition = currentPosition
end)
if direction.Magnitude > 0 then
direction = Vector3.new(direction.X, 0, direction.Z).Unit
bodyGyro.CFrame = CFrame.lookAt(cat.PrimaryPart.Position, cat.PrimaryPart.Position + direction) * rotationOffset
print("o")
end
It seems something is wrong with if statement as o is not printed
Here, the magnitude of the unit vector is always going to be 1, but regardless your mistake is that you’re getting the unit vector of two identical vectors. At the beginning of your loop, you the past position and current position are identical so the unit vector is undefined, and the magnitude is also undefined so it never reaches that if statement
task.wait(7)
local cat = script.Parent
-- Ensure the cat model has a PrimaryPart set
if not cat.PrimaryPart then
warn("PrimaryPart not set for cat model")
return
end
-- Add BodyGyro to the PrimaryPart for orientation
local bodyGyro = Instance.new("BodyGyro")
bodyGyro.MaxTorque = Vector3.new(4000, 4000, 4000) -- Adjust the torque as needed
bodyGyro.P = 3000 -- Adjust the power of the gyro
bodyGyro.Parent = cat.PrimaryPart
-- Add BodyPosition to the PrimaryPart
local bodyPosition = Instance.new("BodyPosition")
bodyPosition.MaxForce = Vector3.new(50000, 50000, 50000) -- Increase the force as needed
bodyPosition.Parent = cat.PrimaryPart
-- Get the Value object with the Owner attribute
local ownerValueObject = cat:FindFirstChild("Value")
if not ownerValueObject then
warn("Value object not found in cat model")
return
end
local rotationOffset = CFrame.Angles(0, math.rad(-80), 0) -- Adjust this angle incrementally (90 degrees initially)
local previousPosition = cat.PrimaryPart.Position
local offset = Vector3.new(2, 2, -2) -- Adjust the offset as needed (2 studs right, 2 studs up, 2 studs behind)
-- Update the cat's orientation to face the direction it is moving
game:GetService("RunService").Stepped:Connect(function()
local ownerName = ownerValueObject:GetAttribute("Owner")
if not ownerName then
return
end
local player = game.Players:FindFirstChild(ownerName)
if not player then
warn("Player not found: " .. ownerName)
return
end
local character = workspace:FindFirstChild(player.Name)
if not character then
warn("Character not found for player: " .. ownerName)
return
end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then
warn("HumanoidRootPart not found for player: " .. ownerName)
return
end
local currentPosition = cat.PrimaryPart.Position
print("0")
if (currentPosition - previousPosition).Magnitude > 0.01 then
print("1")
local direction = (currentPosition - previousPosition).Unit
direction = Vector3.new(direction.X, 0, direction.Z).Unit
bodyGyro.CFrame = CFrame.lookAt(cat.PrimaryPart.Position, cat.PrimaryPart.Position + direction) * rotationOffset
end
local targetPosition = humanoidRootPart.Position + offset
bodyPosition.Position = targetPosition
previousPosition = currentPosition
end)
task.wait(7)
local cat = script.Parent
-- Ensure the cat model has a PrimaryPart set
if not cat.PrimaryPart then
warn("PrimaryPart not set for cat model")
return
end
-- Add BodyGyro to the PrimaryPart for orientation
local bodyGyro = Instance.new("BodyGyro")
bodyGyro.MaxTorque = Vector3.new(4000, 4000, 4000) -- Adjust the torque as needed
bodyGyro.P = 3000 -- Adjust the power of the gyro
bodyGyro.Parent = cat.PrimaryPart
-- Add BodyPosition to the PrimaryPart
local bodyPosition = Instance.new("BodyPosition")
bodyPosition.MaxForce = Vector3.new(50000, 50000, 50000) -- Increase the force as needed
bodyPosition.Parent = cat.PrimaryPart
-- Get the Value object with the Owner attribute
local ownerValueObject = cat:FindFirstChild("Value")
if not ownerValueObject then
warn("Value object not found in cat model")
return
end
local rotationOffset = CFrame.Angles(0, math.rad(-80), 0) -- Adjust this angle incrementally (90 degrees initially)
local previousPosition = cat.PrimaryPart.Position
local offset = Vector3.new(2, 2, -2) -- Adjust the offset as needed (2 studs right, 2 studs up, 2 studs behind)
-- Update the cat's orientation to face the direction it is moving
game:GetService("RunService").Stepped:Connect(function()
local ownerName = ownerValueObject:GetAttribute("Owner")
if not ownerName then
return
end
local player = game.Players:FindFirstChild(ownerName)
if not player then
warn("Player not found: " .. ownerName)
return
end
local character = workspace:FindFirstChild(player.Name)
if not character then
warn("Character not found for player: " .. ownerName)
return
end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then
warn("HumanoidRootPart not found for player: " .. ownerName)
return
end
local currentPosition = cat.PrimaryPart.Position
if (currentPosition - previousPosition).Magnitude > 0.01 then
local direction = (currentPosition - previousPosition).Unit
direction = Vector3.new(direction.X, 0, direction.Z).Unit
bodyGyro.CFrame = CFrame.lookAt(cat.PrimaryPart.Position, cat.PrimaryPart.Position + direction) * rotationOffset
previousPosition = currentPosition -- Move this line inside the check
end
local targetPosition = humanoidRootPart.Position + offset
bodyPosition.Position = targetPosition
end)
When I unanchored it it worked, but I had to turn collisions back on as it won’t work when its off. Is there away to get it to work without having to turn off collisions?
local cat = script.Parent
-- Ensure the cat model has a PrimaryPart set
if not cat.PrimaryPart then
warn("PrimaryPart not set for cat model")
return
end
-- Add AlignPosition to the PrimaryPart
local alignPosition = Instance.new("AlignPosition")
alignPosition.MaxForce = 50000
alignPosition.Responsiveness = 200
alignPosition.Parent = cat.PrimaryPart
-- Add AlignOrientation to the PrimaryPart
local alignOrientation = Instance.new("AlignOrientation")
alignOrientation.MaxTorque = 4000
alignOrientation.Responsiveness = 200
alignOrientation.Parent = cat.PrimaryPart
-- Define target position and orientation
local targetPosition = Vector3.new(2, 2, -2) -- Adjust the offset as needed
local targetOrientation = CFrame.Angles(0, math.rad(-80), 0)
game:GetService("RunService").Stepped:Connect(function()
-- Update position and orientation targets
alignPosition.Position = targetPosition
alignOrientation.CFrame = targetOrientation
end)
Since the body movers use physics, it needs physics to move.
Anchored makes a part stand still in its position, physics will then have no effect on the part.
Are you trying to make the cat not collide with the player character?
Then you should, rather than disabling collisions, create a collision group for the player and the cat and make these collisiongroups not interact, so they, the cat and the player, do not interact.
To do this easily (without need for much additional scripting), consider using the collision group editor studio plugin.
Add a group for the cat and for the player, make both interact with Default, make them not interact with eachother.
Add the collisiongroup for the cat to the cat and make a script to add the player collision group to the player.
The only issue with this solution is that I am going to have multiple cats in the game and would need to make alot of collision groups. Also I am going to have the same ones repeatedly I don’t know if this would cause any problems?
You can make each cat in the same collision group.
You can make it so the cats don’t touch eachother either if you want to.
Then you just disable collision with the own collision group.
Let’s say you have collision group Cat and Player:
Cat has collision with Default
Cat has no collision with Cat
Cat has no collision with Player
Player has collision with Default
Player has no collision with Cat
Player has collision with Player
Oh yeah, if you’ve played some Roblox games and realise they don’t let characters touch eachother, then the characters are in a collision group that doens’t interact with itself, similar to how the cats in the example I just gave works.
Alright, Do I make separate groups for each cat as they are named something else? Or just make one and call it cat? And what script you meaning to add collision group to player? If there any good tutorial videos on this so i can see a demostration that would be helpful.
First time using collision groups thanks for any help in advanced
You make one group and call it “Cat”, you make another group and call it “Player”.
An example is available in the documentation for Collisions.
I’ll take a little code snippet from there to show you how it would work with your collision groups:
local Players = game:GetService("Players")
local function onDescendantAdded(descendant)
-- Set collision group for any part descendant
if descendant:IsA("BasePart") then
descendant.CollisionGroup = "Player"
end
end
local function onCharacterAdded(character)
-- Process existing and new descendants for physics setup
for _, descendant in character:GetDescendants() do
onDescendantAdded(descendant)
end
character.DescendantAdded:Connect(onDescendantAdded)
end
Players.PlayerAdded:Connect(function(player)
-- Detect when the player's character is added
player.CharacterAdded:Connect(onCharacterAdded)
end)
I got it working! Thanks for your help so far, but when I walk through the cat model the camera acts like it is still a part with collisions. How could I fix this?
The camera uses raycasts using the default collision group as far as I know, I don’t think you can fix this unless you make another collision group for all of the parts in the map, then make this collisiongroup interact with the cat and the default collision group, rather than having the cat interact with the default collision group.
This is far more work though and won’t work along with Terrain.
A better solution would be forking the camera script and make it use a separate collision group that doesn’t interact with the cat collision group, but does interact with the default collision group, but still, that’s a lot of work for a beginner.