Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Raycast Help

In the game that I am making, I want to use raycast to find an object with a rigid body attached to it, but I don’t know what code to write if a rigid body is found, and if so, what to write next. Here’s the code that I have done so far:

-- Fruit & Blobs

—function setup()
-- Create a new craft scene
scene = craft.scene()
scene.physics.gravity = vec3(0, 0, 0)
day = readText(asset.builtin.Environments.Sunny)
env = craft.cubeTexture(json.decode(day))
scene.sky.material.envMap = env
cameraYPos = {x = 0, y = 0, z = 0}
playerXPos = 0
viewer.mode = FULLSCREEN

-- Create a new entity
local e = scene:entity()
body = e:add(craft.rigidbody)
e.model = craft.model(asset.builtin.Primitives.Capsule)
e.x = 0.15
e.y = 0
e.z = -2 
e.scale = vec3(1, 1, 1) / 8

scene.camera.z = -0.1

end

—function touched(touch)
if touch.state == MOVING then
scene.camera.eulerAngles = vec3(0, cameraYPos.y, 0)

    cameraYPos.y = cameraYPos.y + -1
    playerXPos = playerXPos + 1
end

if touch.state == BEGAN then
    scene.physics:raycast(vec3(0, 0, 0), vec3(0, 0, 5), 100)
end

end

—function update(dt)
-- Update the scene (physics, transforms etc)
scene:update(dt)
end

-- Called automatically by codea
—function draw()
update(DeltaTime)

-- Draw the scene
scene:draw()    

end

Comments

  • dave1707dave1707 Mod
    Posts: 9,441

    @Creator27 Heres a raycast example I have. Move the slider to move the raycast line across the circles.

    viewer.mode=STANDARD
    
    
    function setup()    
        parameter.integer("x",-300,WIDTH+300,-300)    
        nbr=15
        tab={}
        for z=1,nbr do
            p1=physics.body(CIRCLE,20)
            p1.type=STATIC
            p1.x=math.random(100,WIDTH-100)
            p1.y=math.random(HEIGHT/2,HEIGHT)
            table.insert(tab,p1)
        end
        stroke(255)
        strokeWidth(2)
        fill(255)
    end
    
    function draw()
        background(40, 40, 50)    
        for z=1,nbr do
            ellipse(tab[z].x,tab[z].y,40)
        end    
        line(WIDTH/2,0,x,1000)   
        size=0    
        ta=physics.raycastAll(vec2(WIDTH/2,0),vec2(x,1000))
        if ta~=nil then
            size=#ta
        end
        text("# crossed "..size,WIDTH/2,200)
    end
    
  • Posts: 104

    @dave1707, thank you for that example. I did, however, forget to mention that it was a 3D Craft game, not like a 2d game. Is there any way to use raycasts properly in a 3D game, and bring back a result like in your example?

  • dave1707dave1707 Mod
    Posts: 9,441

    @Creator27 Look under Craft,Physics for ray cast. It gives you the parameters for 3D. Probably just like what I show for 2D, but for Craft 3D.

  • Posts: 104

    @dave1707, I don’t think it’s the parameters, as I copied a bit of your code and altered it a bit, but I still am baffled on what to do as I’m not the best at fixing problems. At the moment, here’s the code that I have written:

    -- Fruit & Blobs

    —-function setup()
    -- Create a new craft scene
    scene = craft.scene()
    scene.physics.gravity = vec3(0, 0, 0)
    day = readText(asset.builtin.Environments.Sunny)
    env = craft.cubeTexture(json.decode(day))
    scene.sky.material.envMap = env
    cameraYPos = {x = 0, y = 0, z = 0}
    playerXPos = 0
    objectsFound = 0
    parameter.integer("x",-300,WIDTH+300,-300)
    viewer.mode = FULLSCREEN

    —Create a new entity
    local e = scene:entity()
    body = e:add(craft.rigidbody)
    e.model = craft.model(asset.builtin.Primitives.Capsule)
    e.material = craft.material(asset.builtin.Materials.Specular)
    e.x = 0
    e.y = 0
    e.z = -2 
    e.scale = vec3(1, 1, 1) / 8
    
    scene.camera.z = -0.1
    scene.camera.eulerAngles = vec3(0, 180, 0)
    

    end

    —-function touched(touch)
    if touch.state == MOVING then
    scene.camera.eulerAngles = vec3(0, cameraYPos.y, 0)

        cameraYPos.y = cameraYPos.y + -1
        playerXPos = playerXPos + 1
    end
    
    if touch.state == BEGAN then
        ray = scene.physics:raycast(vec3(WIDTH/2,0,0),vec3(x,1000,0))
        if ray ~= nil then
            objectsFound = #ray
        end
    end
    

    end

    —-function update(dt)
    -- Update the scene (physics, transforms etc)
    scene:update(dt)
    end

    -- Called automatically by codea
    function draw()
    update(DeltaTime)

    -- Draw the scene
    scene:draw()    
    text("Found: "..objectsFound, WIDTH/2, 200)
    

    end

  • dave1707dave1707 Mod
    Posts: 9,441

    @Creator27 I’m having trouble getting the ray cast to work in Craft. Once I figure it out I’ll post an example.

  • dave1707dave1707 Mod
    edited August 29 Posts: 9,441

    @Creator27 I got 3D ray cast working. Here’s the example. The one sphere is located at 30,20,10, so move the x,y,z sliders near those values and when the line intersects the sphere, it will show the x,y,z values. Try increasing the size of the second sphere from 2 to a larger value and see different intersect points.

    viewer.mode=STANDARD
    
    function setup()
        parameter.integer("x",0,40)
        parameter.integer("y",0,40)
        parameter.integer("z",0,40)
        fill(255)
        assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")        
        scene = craft.scene()
        skyMaterial=scene.sky.material
        skyMaterial.sky=color(158, 202, 223, 255)
        skyMaterial.horizon=color(98, 166, 114, 255)
        v=scene.camera:add(OrbitViewer, vec3(0,0,0), 300, 0, 1000)
        createSphere(vec3(0,0,0),1)
        createSphere(vec3(30,20,10),2)
    end
    
    function draw()
        update(DeltaTime)
        scene:draw()
        tab=scene.physics:raycast(vec3(0,0,0),vec3(x,y,z),100)
        if tab~=nil then
            text("x= "..tab.point.x//1,WIDTH/2,HEIGHT-100)
            text("y= "..tab.point.y//1,WIDTH/2,HEIGHT-120)
            text("z= "..tab.point.z//1,WIDTH/2,HEIGHT-140)
        end
        scene.debug:line(vec3(0,0,0),vec3(x,y,z)*20,color(255))  
    end
    
    function update(dt)
        scene:update(dt)
    end
    
    function createSphere(p,size)
        sphere1=scene:entity()
        s1=sphere1:add(craft.rigidbody,STATIC)
        sphere1.position=vec3(p.x,p.y,p.z)
        sphere1:add(craft.shape.sphere,size)
        sphere1.model = craft.model.icosphere(size,2)
        sphere1.material = craft.material(asset.builtin.Materials.Specular)
        sphere1.material.diffuse=color(255,0,0)
    end
    
  • edited August 30 Posts: 104

    @dave1707, I have succeeded in making a raycast, but when I copied the code into my project, the text didn’t show up when the raycast hit the sphere. Here’s the code that I’ve done so far:

    -- Laser Game
    
    function setup()
        -- Create a new craft scene
        scene = craft.scene()
        day = readText(asset.builtin.Environments.Sunny)
        env = craft.cubeTexture(json.decode(day))
        scene.sky.material.envMap = env
        startRayCast = false
        parameter.integer("rotation", -10, 10, 0)
    
        -- Create a new entity
        local e = scene:entity()
        body = e:add(craft.rigidbody, STATIC)
        e.model = craft.model(asset.builtin.Primitives.Sphere)
        e.y = 1
        e.z = 1
        e.scale = vec3(1,1,1) / 8
    
        scene.camera.x = 1
        scene.camera.z = -4
    end
    
    -- Called automatically by codea 
    function draw()
        update(DeltaTime)
    
        -- Draw the scene
        scene:draw()    
    
    
    
    
    
        ray2 = scene.physics:raycast(vec3(0, rotation, 0), vec3(1000, 1000, 1000))
        if ray2 ~= nil then
            print("Object found!")
        end
        scene.debug:line(vec3(0, rotation, 0), vec3(0, 0, 3), color(255))
    end
    
    - -function update(dt)
        -- Update the scene (physics, transforms etc)
        scene:update(dt)
    end
    
    - -function touched(touch) 
        if touch.state == MOVING and touch.deltaY > 0 then
            rotation = rotation + 0.01
        end
    
        if touch.state == MOVING and touch.deltaY < 0 then
            rotation = rotation - 0.01
        end
    
    
    end
    

    If you can find any problems as to why it isn’t working, please let me know.
    Thank you :)

  • dave1707dave1707 Mod
    Posts: 9,441

    See the builtin documentation for the raycast parameters. It looks like you’re changing where the raycast starts and the direction is always vec3(1000,1000,1000). So you’re not changing the direction of the raycast.

  • Posts: 104

    @dave1707, I’m not exactly sure what you mean. I don’t really know how to change the direction of the raycast. Are you able to possibly make another example on what you mean?

    Thanks :)

  • dave1707dave1707 Mod
    Posts: 9,441

    @Creator27 Look at my example above. My ray cast starts at vec3(0,0,0) and the direction is vec3(x,y,z) for a distance of 100. So the ray cast is just a direction starting at 0,0,0 and passing through points x,y,z for a distance of 100.

  • Posts: 104

    @dave1707, I have tried to do as you said, but I’ve still had no luck. Is there anyway for you to somehow format my code that I’ve showed you so that it works?

Sign In or Register to comment.