7 Replies
      Latest reply on Aug 20, 2018 5:19 AM by funkytomato
      Devdude Level 1 Level 1 (0 points)

        I need to restrain my agents from going off the screen. I tried the following:

         

        let screenWidth = UIScreen.mainScreen().bounds.width
        let screenHeight = UIScreen.mainScreen().bounds.height
        
        // bottom
        let obstacle1 = GKPolygonObstacle(points: UnsafeMutablePointer([float2(0, 0), float2(Float(screenWidth), 0)]), count: 2)
        // left
        let obstacle2 = GKPolygonObstacle(points: UnsafeMutablePointer([float2(0, 0), float2(0, Float(screenHeight))]), count: 2)
        // right
        let obstacle3 = GKPolygonObstacle(points: UnsafeMutablePointer([float2(Float(screenWidth), 0), float2(Float(screenWidth), Float(screenHeight))]), count: 2)
        // top
        let obstacle4 = GKPolygonObstacle(points: UnsafeMutablePointer([float2(0, Float(screenHeight)), float2(Float(screenWidth), Float(screenHeight))]), count: 2)
        
        let obstacles = [obstacle1, obstacle2, obstacle3, obstacle4]
        
        // set the goal for the behaviour of the agent
        agent.behavior?.setWeight(1000000, forGoal: GKGoal(toAvoidObstacles: obstacles, maxPredictionTime: 1))
        

         

        This, however, does not work. The agent has other working goals so it is set up properly. What am I doing wrong?

        • Re: Creating screen boundaries using GKObstacle
          _Agent Level 2 Level 2 (60 points)

          Goals are not a guaranteed thing. I would expect your agents to try to avoid the screen edges, but they will probably overshoot. If you want a guarantee that they don't go off-screen, perhaps you need to add a SpriteKit edge-loop physics body, or just force-set the agents' position to keep them on-screen after they update.

           

          But if an agent isn't even trying to avoid the obstacles, perhaps it would work if the obstacles had some thickness to them rather than simply being lines. I know that goals don't do well with single-element GKPaths.

            • Re: Creating screen boundaries using GKObstacle
              Devdude Level 1 Level 1 (0 points)

              In the Agents, Goals and Behaviors sample app provided by Apple, the agent completely avoids the obstacles, so it is possible. To add some thickness, I have tried this, yet still it doesn't work:

               

              // bottom
              let obstacle1 = GKPolygonObstacle(points: UnsafeMutablePointer([float2(0, 0), float2(Float(screenWidth), 0), float2(Float(screenWidth), 10), float2(0, 10)]), count: 4)
              // left
              let obstacle2 = GKPolygonObstacle(points: UnsafeMutablePointer([float2(0, 0), float2(0, Float(screenHeight)), float2(10, Float(screenHeight)), float2(10, 0)]), count: 4)
              // right
              let obstacle3 = GKPolygonObstacle(points: UnsafeMutablePointer([float2(Float(screenWidth), 0), float2(Float(screenWidth), Float(screenHeight)), float2(Float(screenWidth)-10, Float(screenHeight)), float2(Float(screenWidth)-10, 0)]), count: 4)
              // top
              let obstacle4 = GKPolygonObstacle(points: UnsafeMutablePointer([float2(0, Float(screenHeight)), float2(Float(screenWidth), Float(screenHeight)), float2(Float(screenWidth), Float(screenHeight)-10), float2(0, Float(screenHeight)-10)]), count: 4)
              
            • Re: Creating screen boundaries using GKObstacle
              karim Level 1 Level 1 (0 points)

              Having a similar issue with GKObstacle and GKGoal avoid obstacles... I'm trying to use it for the canonical use: to prevent my agents (enemies) from crossing internal obstacles (walls, pits, and such).

              • Re: Creating screen boundaries using GKObstacle
                devondorset Level 1 Level 1 (10 points)

                Was having a similar issue with agent+rendercomponent butting heads against world boundary in SKScene...

                 

                In simple behaviours with GKGoal 's setting 'toAvoidObstacleswith' maxPredictionTime for value of >10 seems to solve for me.

                 

                I experimented with a few other things like increasing the weight of my avoidObstaclesGoal vs maxSpeed vs wander etc. but always reverting to low value for maxPredictionTime caused problem to reoccour.

                • Re: Creating screen boundaries using GKObstacle
                  ksitech Level 1 Level 1 (0 points)

                  I've tried everything and my Agents still seemed to go through my obstacles.

                   

                  Then I came across a blog that had this:

                  func agentDidUpdate(agent: GKAgent) {
                       if let agent2d = agent as? GKAgent2D {
                            node.position = CGPoint(x: CGFloat(agent2d.position.x), y: CGFloat(agent2d.position.y))
                       }
                  }
                  func agentWillUpdate(agent: GKAgent) {
                       if let agent2d = agent as? GKAgent2D {
                            agent2d.position = float2(Float(node.position.x), Float(node.position.y))
                       }
                  }
                  
                  
                  

                  Where it updated the Agent's position (I also added zRotation) in agentWillUpdate(), and then everything seemed to magically work! Without the need for incredibly high weights and predictionTime values. The behaviors are still relatively stupid about actually avoiding things, but at least it doesn't go through my obstacles anymore.

                  Source of code

                  • Re: Creating screen boundaries using GKObstacle
                    funkytomato Level 1 Level 1 (0 points)

                    Add a seekGoal(self) behaviour to your wander, and you should find the entity does not leave the scene.  Well, it worked for me...