Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

How do i make this raycast to cast in the right direction? [UPDATE]

Asked by 8 years ago

Hello. So i'm new to raycasting, and i'm having a problem with it. You see, i have an AI and i want him to jump if there's a part in front of him. And i would like to use raycasting. Though i'm not really sure on how do i make a ray that starts somewhere near the torso and ends somewhere in front of the torso. Kinda of like this photo: http://prnt.sc/8llfmp

Though i wasn't successful. The ray wasn't appearing in the front of the torso.

Here's what i got:

local rayStart = script.Parent.Torso.Position - Vector3.new(0,3,0)
local rayLook = rayStart+script.Parent.Torso.CFrame.lookVector
local ray, pos = Ray.new(rayStart,(rayLook-rayStart).unit)
local partOnRay = game.Workspace:FindPartOnRay(ray,script.Parent)

UPDATE: In my script, i created a part that's welded on the character and positioned on the position i wanted. With that, i could shoot the ray without making some bizarre math. Though, i have testing your answers and for some reason the ray is being casted from the part and it goes to the center of the world. I have checked if the part is in the right position and it is and it's also rotated in the correct rotation. Help?

Entire script (Raycasting line: 66):

-------------
--Variables--
-------------

local TC = script.Parent.Configuration.TeamColor.Value
local humanoid = script.Parent.Humanoid
local Pathfinding = game:GetService("PathfindingService")
local target = script.Parent.Target
local torso = script.Parent.Torso

---------------------
--Instance Creation--
---------------------

local rayPart = Instance.new("Part",script.Parent)
rayPart.Transparency = 1
rayPart.Size = Vector3.new(1,1,1)
rayPart.Position = Vector3.new(torso.Position.X,torso.Position.Y-2,torso.Position.Z+1)
rayPart.CanCollide = false
rayPart.Rotation = torso.Rotation
local weld = Instance.new("Weld")
weld.Part0 = torso
weld.Part1 = rayPart
weld.C0 =  CFrame.new()
weld.C1 = rayPart.CFrame:inverse() * torso.CFrame
weld.Parent = torso

-------------
--Functions--
-------------

--Move to Spawn Points
function MoveToSpawnPoint(s)
    --Creates variables and path
    local PF = Pathfinding:ComputeSmoothPathAsync(script.Parent.Torso.Position,s.Position,512)
    local points = PF:GetPointCoordinates()

    --visualizePath(points) 

    --Moves through the path
    local distance;
    local br = false
    for i = 1,#points do
        wait(0)

        --Breakes to:
        --Recreate the path or;
        --To move to an enemy if exists
        if br or target.Value ~= nil then break end

        --Move to the created points
        local count = 0
        repeat
            --Turns br(break) to true if needed
            count=count+1
            if count>20 or target.Value ~= nil then
                br = true
                break
            end
            --Move through the path
            if script.Parent == nil or script.Parent:FindFirstChild("Torso") == nil then
                return
            end
            humanoid:MoveTo(points[math.min(#points,i+1)],nil)

            local start = rayPart.Position
            local finish = (start-rayPart.CFrame.lookVector).unit*15
            local ray = Ray.new(start,finish)
            local partOnRay = game.Workspace:FindPartOnRay(ray,script.Parent)

            local beam = Instance.new("Part", workspace)
            beam.BrickColor = BrickColor.new("Bright red")
            beam.FormFactor = "Custom"
            beam.Material = "Neon"
            beam.Transparency = 0.25
            beam.Anchored = true
            beam.Locked = true
            beam.CanCollide = false

            local distance = (start - finish).magnitude
            beam.Size = Vector3.new(0.3, 0.3, distance)
            beam.CFrame = CFrame.new(start, finish) * CFrame.new(0, 0, -distance / 2)

            if points[i].Y>script.Parent.Torso.Position.Y+2.5 or partOnRay~=nil then
                humanoid.Jump = true
            end

            distance=(points[i]*Vector3.new(1,0,1)-script.Parent.Torso.Position*Vector3.new(1,0,1)).magnitude
            wait()
        until distance<5
    end
end

--Move to Enemy
function MoveToEnemy()
    if target.Value == nil then return end

    if (script.Parent.Torso.Position-target.Value.Torso.Position).magnitude >=10 then
        --Creates variables and path
        local PF = Pathfinding:ComputeRawPathAsync(script.Parent.Torso.Position,target.Value.Torso.Position,50)
        local points = PF:GetPointCoordinates()
        local distance;
        local br = false

        --Move through path
        for i = 1,#points do
            wait(0)
            --Breakes to:
            --Recreate the path; 
            --Move to a spawnpoint when the target doesn't exist or;
            --Move to the enemy without pathfinding
            if br or target.Value == nil then break end

            --Move to created points
            local count = 0
            repeat
                --Turns br(break) to true if needed
                count=count+1
                if target.Value == nil then 
                    br = true
                    break
                end
                if count>20 or (script.Parent.Torso.Position-target.Value.Torso.Position).magnitude <10 then
                    br = true
                    break
                end

                --Move through the path
                humanoid:MoveTo(points[math.min(#points,i+1)],nil)
                if script.Parent == nil or script.Parent:FindFirstChild("Torso") == nil then
                    return
                end
                if points[i].Y>script.Parent.Torso.Position.Y+2.5 then
                    humanoid.Jump = true
                end

                distance=(points[i]*Vector3.new(1,0,1)-script.Parent.Torso.Position*Vector3.new(1,0,1)).magnitude
                wait()
            until distance<5 
        end
    end
    --Move to the enemy without pathfinding if he's close
    if target.Value ~= nil then
        if (script.Parent.Torso.Position-target.Value.Torso.Position).magnitude <10 and target.Value.Humanoid.Health>0 then
            humanoid:MoveTo(target.Value.Torso.Position)
        end
    end
end

-------------
--Task Area--
-------------

while wait(0) do
    --Move to target if it exists
    if script.Parent.Target.Value then
        MoveToEnemy()
    --If theres not any enemy close, then go to the spawn points
    elseif script.Parent.Target.Value == nil and script.Parent.Spawn.Value ~= nil then
        MoveToSpawnPoint(script.Parent.Spawn.Value)
    end
end

3 answers

Log in to vote
0
Answered by
drahsid5 250 Moderation Voter
8 years ago

You're firing a ray below the AI, try firing it in the direction of the torso's lookvector, which is the direction it's facing.

script.Parent:WaitForChild("Torso") --Make sure it works on server mode
while wait() do --A loop
    local rayStart = Ray.new( --A new ray
        script.Parent.Torso.Position, --Orifin
        script.Parent.Torso.CFrame.lookVector*15 --Direction
    )

    local hit,position,normal = game.Workspace:FindPartOnRay(rayStart,script.Parent) --The second paremeter tells it to ignore the AI
    if hit then --if hit isn't nil
        print("The AI has seen an object...") inform the user the AI has seen an object
        if (position - script.Parent.Torso.Position).magnitude <7 then --If the magnitude is low
            print("The AI is close to an object") --inform the user the AI is close
            return --End the function
        end
    end
end

You didn't really offer much code but I can give you some references: Raycasting Magnitude While loop

0
That photo is the way i wanted my ray to be like. Though i used the script and the ray starts at the AI and goes to the center of the world DragonOfWar900 397 — 8y
0
Elaborate? drahsid5 250 — 8y
0
http://prnt.sc/8llfmp. I want my ray to look like this (Without the part. Thats were i want my ray to start and to finish). DragonOfWar900 397 — 8y
0
I don't know what that means but if you want it to go to the center then make the direction Vector3.new(0,0,0) drahsid5 250 — 8y
View all comments (4 more)
0
NO. See that gray part. Thats what i want my RAY to START and FINISH. DragonOfWar900 397 — 8y
0
@Drahsid5 The main problem with this is that you've mistaken the return value of lookVector. Subtracting the torso's position is irrelevant once you have the direction the torso is facing. With this code, you're essentially basing the direction of the ray on its position from the origin, which doesn't really fit the context. Legojoker 345 — 8y
0
@Legojoker did I? Maybe I'm too used to using m.hit drahsid5 250 — 8y
0
Try out my new code drahsid5 250 — 8y
Ad
Log in to vote
0
Answered by
Legojoker 345 Moderation Voter
8 years ago
local tors = script.Parent:WaitForChild("Torso")

-- Make sure the torso in the AI model is rotated to have the front synchronize with the front of the model.

while true do
    wait(1)
    local testRay = Ray.new(tors.Position, tors.CFrame.lookVector*3) -- Change the 3 to your preferred checking distance.
    local potObj, potPosi = game.Workspace:FindPartOnRay(testRay, script.Parent)

    if potObj then
        print("AI is "..(potPosi-tors.Position).magnitude.." studs away from an obstacle.")
    end
end

Make sure your model is oriented correctly, this is the most IMPORTANT aspect since lookVector shoots out from the FRONT face of your model. You can use trigonometry to offset the lookVector, but it shouldn't be necessary for your purposes.

The first argument of Ray.new() is the original position, or the position that the ray is being casted from. The second one is the unit vector that it is being directed towards, multiplied by the number of studs you want it to look. lookVector gives you a unit vector automatically (very convenient) so you can use this, multiply it by your checking distance (I chose 3 studs), and then search for an object and the position of ray disturbance. potPosi is the point the ray made contact with the object, not the potObj's actual position.

Log in to vote
0
Answered by 8 years ago

I figured it out!

local start = rayPart.Position
local finish = (rayPart.CFrame.lookVector).unit*3
local ray = Ray.new(start,finish)
local partOnRay = game.Workspace:FindPartOnRay(ray,script.Parent)

Answer this question