Howdy, Stranger!

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

3D AI Pathfinding

Is there anyway that I can make an entity continuously follow the player around and also make it stop following the player if they are a certain distance away from the player???

Thanks in advance :)

Comments

  • edited September 22 Posts: 1,125

    Yes, probably several ways. A simple one is to have a desired distance from the player, and a distance beyond which the player is ignored. Get the distance between player and entity. If it is greater than the "beyond" distance, do nothing. If it is greater than the "desired" distance, move a bit in the direction of the player. If it is less than the desired distance, either move away or stand still, whichever you prefer.

    A question will arise: what is "toward". If movement is free, that is the entity can move in any direction (as opposed to just N,E,S,W, for example), then the direction toward the player is the normalized value of the vector (playerPosition-entityPosition). That vector has length 1, so you can multiply it by any convenient number to pick how far to move. Multiply it by 2, the entity will move two units toward the player.

    In general, of course, there may be obstacles in the space, walls or such. I prefer to handle those similarly for both player and entity. When either tries to move in some direction, if there's something in the way, I don't let them move. A more sophisticated approach might be, for example, if the entity is trying to move 2 units but there is a wall at 1.5, let it move 1.5 and bonk into the wall.

    It seems that in your game you are trying to use physics to do the moving. I've not done that but the same principles apply.

  • Posts: 141

    @RonJeffries, I will try your two options and see what works.

  • Posts: 130

    If (the distance between the entity and player) < agroRange)
    Move towards player

  • Posts: 141

    @Jarc, thank you for that help. I don’t however, know what to write in order for the enemy to move towards the player. Could you possibly show me an example??

    Thanks :)

  • dave1707dave1707 Mod
    Posts: 9,584

    @Creator27 Try this example. The right sphere will move towards the left sphere as it falls and bounces.

    viewer.mode=FULLSCREEN
    
    function setup()
        assert(OrbitViewer, "Please include Cameras as a dependency")
        fill(255)
        scene = craft.scene()
        skyMaterial=scene.sky.material
        skyMaterial.sky=color(0, 62, 255, 255)
        skyMaterial.horizon=color(99, 255, 0, 255)   
        scene.sun.rotation=quat.eulerAngles(20,45,-30)
        v=scene.camera:add(OrbitViewer, vec3(0,0,0), 100, 0, 200)
        v.rx,v.ry=20,20
        createRect()
        s1=createSphere(-10,30,0)  
        s2=createSphere(-4,30,0)
    end
    
    function draw()
        update(DeltaTime)
        scene:draw()    
        text("Drag your finger on the screen to rotate the cube",WIDTH/2,HEIGHT-100)
        v1=s1.sphere1.position-s2.sphere1.position
        s1.ss.linearVelocity=-v1*3
    end
    
    function update(dt)
        scene:update(dt)
    end
    
    function createRect() 
        diff=8
        c1=scene:entity()
        w=c1:add(craft.rigidbody,STATIC)
        w.restitution=.6
        c1.position=vec3(0,-10,0)
        c1.model = craft.model.cube(vec3(25,10,10))
        c1.model:position(5,-5,diff,5)
        c1.model:position(18,-5,diff,5)
        c1.model:position(10,-5,diff,5)
        c1.model:position(9,-5,diff,-5)
        c1.model:position(14,-5,diff,-5)
        c1.model:position(19,-5,diff,-5) 
        c1:add(craft.shape.model,c1.model)
        c1.material = craft.material(asset.builtin.Materials.Standard)
        c1.material.map = readImage(asset.builtin.Surfaces.Basic_Bricks_AO)
    end
    
    function createSphere(x,y,z)
        local sphere1=scene:entity()
        local s=sphere1:add(craft.rigidbody,DYNAMIC)
        s.restitution=1.5
        sphere1.position=vec3(x,y,z)
        sphere1.model = craft.model.icosphere(.5,5)
        sphere1:add(craft.shape.sphere,.5)
        sphere1.material = craft.material(asset.builtin.Materials.Specular)
        sphere1.material.diffuse=color(255,0,0)
        return({sphere1=sphere1,ss=s})
    end
    
  • edited September 23 Posts: 141

    @dave1707, thank you very much, it works perfectly. Just one problem. Say I wanted 2 red spheres to follow me, when I spawn one sphere, it works fine. But when I spawn another sphere, the first sphere that was spawned stops following me, but the second sphere takes it’s place instead. It also doesn’t allow me to spawn more than one sphere at a time. Is there anyway that I can make every spawned sphere follow, regardless of how many there are and make it so that I can spawn as many spheres as I want??

    Thanks :)

  • dave1707dave1707 Mod
    Posts: 9,584

    You have to put the spheres that are supposed to follow the first sphere in a table so you can calculate the linearVelocity of each sphere individually.

  • Posts: 141

    @dave1707, I’ve tried doing what you said, but it still isn’t working. Every time I try to calculate the linear velocity, it just does the same thing. Could you possibly show me an example of what you mean???

    Thanks :)

  • dave1707dave1707 Mod
    Posts: 9,584

    Here’s a version that uses a table. Tap the screen to cause the red spheres to follow the green sphere. Tap again to unfollow.

    viewer.mode=FULLSCREEN
    
    function setup()
        tab={}
        assert(OrbitViewer, "Please include Cameras as a dependency")
        fill(255)
        scene = craft.scene()
        skyMaterial=scene.sky.material
        skyMaterial.sky=color(0, 62, 255, 255)
        skyMaterial.horizon=color(99, 255, 0, 255)   
        scene.sun.rotation=quat.eulerAngles(20,45,-30)
        v=scene.camera:add(OrbitViewer, vec3(0,0,0), 100, 0, 200)
        v.rx,v.ry=20,20
        createRect()
        s1=createSphere(0,30,0,1) 
        for z=1,5 do
            table.insert(tab,createSphere(math.random(-10,10),math.random(20,35),math.random(-10,10),0))
        end
    end
    
    function draw()
        update(DeltaTime)
        scene:draw()    
        text("Drag your finger on the screen to rotate the cube",WIDTH/2,HEIGHT-100)
        if follow then
            for z=1,#tab do
                v1=s1.sphere1.position-tab[z].sphere1.position
                tab[z].ss.linearVelocity=v1
            end
        end
    end
    
    function update(dt)
        scene:update(dt)
    end
    
    function touched(t)
        if t.state==BEGAN then
            follow=not follow
        end
    end
    
    function createRect() 
        diff=8
        c1=scene:entity()
        w=c1:add(craft.rigidbody,STATIC)
        w.restitution=.6
        c1.position=vec3(0,-10,0)
        c1.model = craft.model.cube(vec3(25,10,10))
        c1.model:position(5,-5,diff,5)
        c1.model:position(18,-5,diff,5)
        c1.model:position(10,-5,diff,5)
        c1.model:position(9,-5,diff,-5)
        c1.model:position(14,-5,diff,-5)
        c1.model:position(19,-5,diff,-5) 
        c1:add(craft.shape.model,c1.model)
        c1.material = craft.material(asset.builtin.Materials.Standard)
        c1.material.map = readImage(asset.builtin.Surfaces.Basic_Bricks_AO)
    end
    
    function createSphere(x,y,z,c)
        local sphere1=scene:entity()
        local s=sphere1:add(craft.rigidbody,DYNAMIC)
        s.restitution=1.5
        sphere1.position=vec3(x,y,z)
        sphere1.model = craft.model.icosphere(.5,5)
        sphere1:add(craft.shape.sphere,.5)
        sphere1.material = craft.material(asset.builtin.Materials.Specular)
        if c==1 then
            sphere1.material.diffuse=color(0,0,255)
        else
            sphere1.material.diffuse=color(255,0,0)
        end
        return({sphere1=sphere1,ss=s})
    end
    
  • Posts: 141

    @dave1707, thank you for that code. Once I figure out what I’m not doing that stops from your example working in my game, everything will work fine.

  • Posts: 141

    @dave1707, everything works fine. Your creativity is incredible, and I am so grateful that you help me out as much as you do :)

  • edited September 24 Posts: 1,379

    @dave1707 I hope this is ok: I modified your demo to have a floor and walls, so that the spheres stay on screen longer, and I made the balls a scootch bigger, so they’re easier to track visually, and I made a little .zip of it for people to be able to instantly open. It’s still fully credited to you.

Sign In or Register to comment.