Lookat R6 didnt work

  1. What do you want to achieve?
    I want to make the humanoidrootpart rotate only in the Y axis.
    and how do I make hrp rotate using frames, when looking at the nearest player?
    (I want to make hrp npc facing to the nearest player)

  2. What is the issue?
    The script does not detect the JointBone of hrp, which will be used to rotate the npc Y axis.
    image

  3. What solutions have you tried so far?
    ive tried looking on the other model’s script and most of them are using R15 and neck bone, since im using R6 using Hrp Bone/cframe if that possible

local NPC = script.Parent
local neck = NPC.HumanoidRootPart.RootJoint

function getClosestPlayer()
	local closest_player, closest_distance = nil, 30
	for i, player in pairs(workspace:GetChildren()) do
		if player:FindFirstChild("Humanoid") and player ~= NPC then
			local distance = (NPC.PrimaryPart.Position - player.PrimaryPart.Position).Magnitude
			if distance < closest_distance then
				closest_player = player
				closest_distance = distance
			end
		end
	end
	return closest_player
end

local cframe0 = neck.C0
while true do
	local player = getClosestPlayer()
	if player then
		local is_in_front = NPC.PrimaryPart.CFrame:ToObjectSpace(player.PrimaryPart.CFrame).Z < 0
		if is_in_front then
			local unit = -(NPC.PrimaryPart.CFrame.p - player.PrimaryPart.Position).unit
			neck.C0 = cframe0 * CFrame.new(Vector3.new(0, 0, 0), unit) * CFrame.Angles(0, -math.rad(NPC.PrimaryPart.Orientation.Y), 0)
		end
	end
	wait()
end
2 Likes

we could use unit vector and calculate the angle to rotate only on the y axis and applying the rotation using cframe angles also using task.wait is much better than wait

local NPC = script.Parent
local hrp = NPC:WaitForChild("HumanoidRootPart")
local neck = hrp:WaitForChild("RootJoint")

local function getClosestPlayer()
    local closest_player, closest_distance = nil, 30
    for _, player in pairs(workspace:GetChildren()) do
        if player:FindFirstChild("Humanoid") and player ~= NPC then
            local distance = (hrp.Position - player.PrimaryPart.Position).Magnitude
            if distance < closest_distance then
                closest_player = player
                closest_distance = distance
            end
        end
    end
    return closest_player
end

local cframe0 = neck.C0

while true do
    local player = getClosestPlayer()
    if player then
        local is_in_front = hrp.CFrame:ToObjectSpace(player.PrimaryPart.CFrame).Z < 0
        if is_in_front then
            local targetPosition = player.PrimaryPart.Position
            local direction = (targetPosition - hrp.Position) * Vector3.new(1, 0, 1)
            local unit = direction.Unit
            
            local angle = math.atan2(unit.X, unit.Z)
            
            neck.C0 = cframe0 * CFrame.Angles(0, angle, 0)
        else
            neck.C0 = cframe0
        end
    end
    task.wait(0.1)
end
2 Likes

thx for the help, but i think i might get the wrong axis, how do i change it to other axis, ive tried replacing the Z with Y not working :angst:
btw how do i make it that it doesnt check the player should be infront of the npc to rotate

1 Like

i made a config for you , you can adjust these as much you want i made it support all axes if you set the rotationaxis values to 0 there would be no rotation on that axis for 1 would be full rotation values between 0 and 1 would be partial rotation i currently set it to roatate only on the y axis for example all axes would be x = 1 , y = 1 ,z = 1

local NPC = script.Parent
local hrp = NPC:WaitForChild("HumanoidRootPart")
local neck = hrp:WaitForChild("RootJoint")

local config = {
    rotationAxis = {X = 0, Y = 1, Z = 0},
    maxDistance = 30,
    updateInterval = 0.1,
    checkInFront = false
}

local function getClosestPlayer()
    local closest_player, closest_distance = nil, config.maxDistance
    for _, player in pairs(workspace:GetChildren()) do
        if player:FindFirstChild("Humanoid") and player ~= NPC then
            local distance = (hrp.Position - player.PrimaryPart.Position).Magnitude
            if distance < closest_distance then
                closest_player = player
                closest_distance = distance
            end
        end
    end
    return closest_player
end

local cframe0 = neck.C0

local function getRotationCFrame(direction)
    local rotX = config.rotationAxis.X ~= 0 and CFrame.fromAxisAngle(Vector3.new(1, 0, 0), math.atan2(direction.Y, direction.Z) * config.rotationAxis.X) or CFrame.new()
    local rotY = config.rotationAxis.Y ~= 0 and CFrame.fromAxisAngle(Vector3.new(0, 1, 0), math.atan2(direction.X, direction.Z) * config.rotationAxis.Y) or CFrame.new()
    local rotZ = config.rotationAxis.Z ~= 0 and CFrame.fromAxisAngle(Vector3.new(0, 0, 1), math.atan2(direction.X, direction.Y) * config.rotationAxis.Z) or CFrame.new()
    return rotX * rotY * rotZ
end

while true do
    local player = getClosestPlayer()
    if player then
        local shouldRotate = true
        if config.checkInFront then
            local is_in_front = hrp.CFrame:ToObjectSpace(player.PrimaryPart.CFrame).Z < 0
            shouldRotate = is_in_front
        end
        
        if shouldRotate then
            local targetPosition = player.PrimaryPart.Position
            local direction = (targetPosition - hrp.Position).Unit
            local rotationCFrame = getRotationCFrame(direction)
            neck.C0 = cframe0 * rotationCFrame
        else
            neck.C0 = cframe0
        end
    end
    task.wait(config.updateInterval)
end
2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.