• Home
  • About
  • Our Apps
  • Learn
  • Contact
Login

Register

Login
Seemu Apps Seemu Apps
  • Home
  • About
  • Our Apps
  • Learn
  • Contact

Swift ARKit 2D Objects Tutorial

Home ios Swift ARKit 2D Objects Tutorial

Swift ARKit 2D Objects Tutorial

Sep 2, 2017 | Posted by Andrew | ios, swift, tutorial, xcode |

In this tutorial we look at how to add 2D objects with ARKit. We achieve this be making a simple soccer players and also create a simple pong demo! Lets get into it. An on a quick note you need iOS 11 or greater to run ARKit apps.

Our end result will look like the following:

Storyboard Setup

First of all setup the Main.storyboard as follows:

  • ARSCNView with constraints to take up the full screen

Now open up the assistant editor and connect the objects we just place as follows to the ViewController.swift class.

  • ARSCNView to an outlet named sceneView

Setup

Add the viewWillAppear function as follows. This sets up the ARKit session. This allows you to use your camera and look through the world and see augmented reality.

    override func viewWillAppear(_ animated: Bool) {
        let configuration = ARWorldTrackingSessionConfiguration()       
        sceneView.session.run(configuration)
        sceneView.delegate = self
    }

Next up create a new empty Swift file with File–>New–>File. Select Swift file to create a new empty Swift file. Name it “String” and replace the contents of it with the following:

import UIKit
extension String {
    
    func image() -> UIImage? {
        let size = CGSize(width: 30, height: 35)
        UIGraphicsBeginImageContextWithOptions(size, false, 0);
        UIColor.clear.set()
        let rect = CGRect(origin: CGPoint(), size: size)
        UIRectFill(CGRect(origin: CGPoint(), size: size))
        (self as NSString).draw(in: rect, withAttributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 30)])
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

This is a String extension which converts a String to an image. This extension is used to convert emojis ๐Ÿƒ to images. We use these images in our ARKit world for Soccer.

Creating 2D Objects in ARKit

After this go back to our view controller and add the following as class level variables under our sceneView outlet. The ballNode is used to contain our Soccer ball. The Anchors contain the positions of our Soccer “players” – it Anchors them in our ARKit world in a set position.

    var ballNode = SCNNode()
    var anchors: [ARAnchor] = []

Then add the ARSCNViewDelegate to our View Controller as a protocol – this enables the AR Scene View to call some delegate functions in our view controller we use soon:

class ViewController: UIViewController, ARSCNViewDelegate {

Next up add the following made 2D note function. This will take in a UIImage. It will then create a node out of it, rendering it in 2d on a plane. This is achieved by the SCNBillboardConstraint we apply at the end of it. This way no matter what angle we are facing the node with ARKit it will always look the same.

    func make2dNode(image: UIImage, width: CGFloat = 0.1, height: CGFloat = 0.1) -> SCNNode {
        let plane = SCNPlane(width: width, height: height)
        plane.firstMaterial!.diffuse.contents = image
        let node = SCNNode(geometry: plane)
        node.constraints = [SCNBillboardConstraint()]
        return node
    }

Back in viewDidLoad add the following line at the end. This will setup our ball node to use the soccer ball emoji.

ballNode = make2dNode(image: "โšฝ".image()!)

Now add the touchesBegan function. This will be run everytime you tap on the screen. Essentially first of all we see if we already have two anchor objects (These will contain the soccer players). If so we then start a ball bouncing in between them. Other wise we create a new anchor just in front of the user on the screen, and add this to the anchors array.

Ill get to how these anchors then get rendered as a soccer player soon.

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        // If we have 2 soccer players on the screen start bouncing the ball in between them
        if anchors.count > 1 {
            startBouncing()
            return
        }
        
        // Otherwise add a new anchor which contains the soccer player
        if let currentFrame = sceneView.session.currentFrame {
            var translation = matrix_identity_float4x4
            translation.columns.3.z = -0.3
            let transform = simd_mul(currentFrame.camera.transform, translation)
            
            let anchor = ARAnchor(transform: transform)
            sceneView.session.add(anchor: anchor)
            anchors.append(anchor)
        }
    }

Next add the renderer function. This is called from the ARSCNViewDelegate protocol whenever we add an anchor to the screen. So in the above touchesBegan at the end when we call anchors.append, the renderer below will get called. This will add a Node to that anchor that uses the ๐Ÿƒ emoji to display it.

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        let player = make2dNode(image: "๐Ÿƒ".image()!)
        node.addChildNode(player)
    }

Next add the startBouncing function – this will be called once we have added two players on the screen. This will cause the ball node we add in viewDidLoad to bounce between the two players – neat!

    func startBouncing() {
        guard let first = anchors.first, let start = sceneView.node(for: first),
        let last = anchors.last, let end = sceneView.node(for: last)
        else {
            return
        }
        
        if ballNode.parent == nil {
            sceneView.scene.rootNode.addChildNode(ballNode)
        }
        
        let animation = CABasicAnimation(keyPath: #keyPath(SCNNode.transform))
        animation.fromValue = start.transform
        animation.toValue = end.transform
        animation.duration = 1
        animation.autoreverses = true
        animation.repeatCount = .infinity
        ballNode.removeAllAnimations()
        ballNode.addAnimation(animation, forKey: nil)
    }

Now you can run the app, yay! Move around the ARWorld and tap to add a soccer player in the direction you are facing. Then once you have two players tap again to see the soccer ball bouncing in between them.

Now we have done this, lets turn the images into pong paddles and balls. Download the following media set, once done open the file and drag the folders into the Media.xcassets folder in your project

https://www.seemuapps.com/wp-content/uploads/2017/07/Media.xcassets.zip

Now in viewDidLoad set the ballNode to use the ball image as follows, we also set the width and height this time.

        ballNode = make2dNode(image: #imageLiteral(resourceName: "ball"), width: 0.03, height: 0.03)

Then in the render function change the let player line to now use a blue pong paddle.

let player = make2dNode(image: #imageLiteral(resourceName: "paddleblue"))

Then run the app and you will see the beginnings of pong in AR Kit, yay!

let player = make2dNode(image: #imageLiteral(resourceName: "paddleblue"))

download source code

Tags: 2darkitscene view
2
Share

About Andrew

Andrew is a 24 year old from Sydney. He loves developing iOS apps and has done so for two years.

You also might be interested in

Swift ARKit (Augmented Reality) Tutorial

Jul 3, 2017

In this tutorial we take a look at the newly[...]

Welcome

Hi I am Andrew and welcome to Seemu Apps! Have a look around, we provide tutorials for primarily iOS apps.
Bluehost website hosting discount

Seemu’s Studio Setup

Blue Yeti Microphone
Rode Stand
Spider Shock Mount
Mac Keyboard Cover
Screenflow - recording software

Contact Us

We're currently offline. Send us an email and we'll get back to you, asap.

Send Message

Footer

:)

ยฉ 2026 ยท Your Website. Theme by HB-Themes.

  • Home
  • About
  • Our Apps
  • Learn
  • Contact
Prev Next