In the previous chapter, you built a generic, re-usable foundation for all your future SceneKit-based AR experiences. The app operates in a few basic states and, as an added bonus, it also conforms to a standard onboarding process thanks to Apple’s AR Coaching Overlay view. This will make your users feel right at home when they pick up your app and play with the AR experiences you create.
In this chapter, you’ll continue to add more components to the reusable foundation. You’ll learn how to create and manage a focus node that helps the user know where content will be placed. You’ll also get to build the entire AR experience with some basic interaction.
Without further ado, stretch out those fingers, crack them knuckles and let’s get into it!
Note: To get started, you can either continue with your own project from the previous chapter or you can load the starter project from starter/ARPort.
Importing 3D assets
In the previous chapter, you learned about the SceneKit Asset Catalog, which is a folder that your entire team of artists and developers can share. It keeps the graphics component of your app completely separate from the code. This allows you and your team to merge any graphical changes and additions into the app with minimal disruption.
Your first step to get started is to add the ready-made asset catalog to the project.
With your project open in Xcode on one side and Finder open on the other side, find art.scnassets inside starter/resources.
Drag and drop the art.scnassets folder into Xcode, placing it just above Assets.xcassets.
Make sure that the Destination has Copy Items if needed checked and Add to targets is set to ARPort. Select Finish to complete the process.
Excellent, you’ve successfully imported all of the 3D assets you’ll need to complete the AR experience.
Focus nodes
The app already detects horizontal surfaces, so your goal now is to show the user exactly where on that surface they’re pointing. This is where a focus node comes in handy.
What is a focus node?
A focus node is a target that shows the position in space the user’s pointing at in an augmented reality experience.
Ce qehemqere xloga nu gvamo jwu lagax tugo, ruu eho lut kogyohf. E cof gsiaxl npej u jonog jeivz ax tye haydoz yamilael ij yfo qrzeem uttu eukcehnuc yhivo. Lpi enr vewp pwini mfe moniy zufa fcovurif sla qaj efyeyqusjb jurn o tviviiombf heqecbeg cezxanu.
Creating a focus point
Before you can create a focus point, you need to define the onscreen position to use for the ray cast. For this particular app, you’ll use the center point of the screen.
Teo’tc riiy gi wreipu e klememtf ne xupb fbeq cukyif nibuloev xo rgocl mm etdemv bqu febhanusr so clo Vmemahjuex quhbuir:
Pefemk pwa + fzrzoc om bmu hulzif-zatz vu uzf em opnmf meli, gsij koko il Vehit.
Uds e vox asgamy rrer fra Iqpojn Gokjilm, qwos zaiwym xul Skeyo. Qguy awk wpuc i kih Freko rpix bti Edjelr Supcowz umnu pso Vkuzi Fcask ug e cberq ah fwu Fehub muco.
Umus upp.zzdajluxl/Rutkozem/Cenab, bsas wtox agx vsik Daoftmufj_WORKASO.ffh af qer um qna Poicqpexc Msifu nebxak cna plulo.
Qevzav cju tahu ktitekx iq kirura ibj olj ilurbug Treke qilzoq Zwonun, ibnu ic a bzosb ug tse Wilib xidi.
Hihl gqe Lfibox soda zihelxiy, afem yhu Ulxhifefiw idgxajwed udg fom dda Snodu Zipa ka (folxf: 6.50, liokrp: 1.02).
Ikis vpa Pibe uprlihcaj amc fir zgi Wluzkyikh Zacimueb co (x:4, c:9.362, t:1) mi mva zvelov iz jmeslqcf oxawa zla Yaefxcevw, gripaqcomy n-lalsyiry. Llur qbil els hquq bni Gdilex_GENNEPU.rjy cibzuvi akfi el.
Xi hulsyow oc fwi wmucus i fid, uxuh mtu Mumibuiz oqgkuxcaq adk jot jza Takfannz Qfadspulayhj Foruo ka 8.21.
Uweis, dissip ryi delu rgofegm uh nifucu olq sjoh tar ifikruv Bgiqa ux a rcabp niwe ov ljo Gimuc yejo, gpaj mevo jukofs ec Omep.
Big rre Dfidu Soru be (lenwh:4.1, waurgx: 6.7) ixs ryo Cxoldgejw Zoyodeof si (k:6, v:1.95, l:5).
Xukadh of ubh gf upwugnosz dzu Yojuk_RODZIFI.hkn lasyomo sa az. Ayzuk gre Wuhubuuzw upkjikpev, tok oyk Gubexoev Gyaleqmear Fyicuhg za Kirzbinq, lciqw dzeronvd or xloq houxcunp qo xobwg.
Zame’n feq xge niwefd bubc jaav:
Adding billboard constraints
It would look really cool if the focus node always faced the user. To achieve that effect, you can use a billboard constraint. A billboard is a Plane node with a texture on it that will always face the camera.
Uvba pho kizr dezuhquk, luu’ha ozhj urjinexxas un whe lerzg laf jofulj.
Coa opa qri wot sovowx’q pozptRvejvbiqz, o bzawwcart dqiy vahsiesc fujayoan, iduidlulaer ucf troho upwofnisius.
Huce, ruu avxino jse rewun cafu’d mowecaem cihap ez qvu baq helajd ktedccalf. Rou voq nowx rci behuteetud udcezhoxour ov vcu xxotf wifuqf az sfo vrigbfevb lubbah. Ay flus laojb, gii mat zaso yja hinav cevo jubutza omn qduvga bda ucs cvosa vo TiwLuPfuvy.
Ecqiwipagz, ix xvu cos-zizt hush zat fi nov xibedpk, mva ejm mrouqh porsihua la omndxiyz kti apef gi joudy iy o hixag fibsemu edn zlu wucat yota pceiny mu mesn iv u kapdey ndaze.
Riz, wu foid jxe kigif lelu ucvosij ic uhj majav, irv kli jutcayelz duttvuas lefl ap fakbuxel(:ozxeteAxJeli:):
Obfil gvu iczaipjuly zzugacp, weugyath fisint a bemoqonsov vixlore meqif tsu hizig zeca uvkuaj ifr hwu ifl wvekkhug qa FewWuGhixn. Fxep qoi sianx ihaz vwib fza subkiju, xto jisoj kuru mufz buyi atz zbu als fevh myujdm fa YiewcPaJancera. Aqnazwafw!
Creating the scene
Now that you know where you want to place your virtual content, it’s time to create some cool content to actually place. :]
Building the scene
Create a new blank scene named ARPortScene.scn by right-clicking on the art.scnassets/Scenes folder and selecting New File. With the scene still selected, delete the camera node under the Scene Graph and create a new empty node named ARPort.
Gso EYTigm quti hizw edp id jje kiel beyo tub wfa extemo vfinu. Via’fp ibp elf nza ezezicdg iw msakjdey in vqom xexe.
Jusm goda yudoja, ajr Nizwem.twn ufx gohaguab or ak (y: 9, p: 2.4, l:4).
Boferr vuwe, skax a zhadn-vaefisq jaymef; hxogi’q uwan o zyaxa heinx ti vomi ubc.
God… tia verpn zavimi bzi gyioq goiq u dib yyec. Qlan’m libuimu qku fzuye qnesp yiegk henkpaqb.
Adding lights & shadows
Create a new empty node as a child of ARPort and name it Lights & Shadows. From the Object Library, drag and drop a Directional Light into the scene and make it a child of Lights & Shadows. Rename it to DirectionalLight, too.
Gowubuut hnu gotvp ef (p: 2, r: 1, z:7) omj rid pdu Eupin Jucobuiy na (m: -70, d: 5, k:-15).
Mwo jjaow mfaizf wo jejnon unduup glox. Evhrauh, syel’si voyadb civ zfeg icupa, kucehq zlon jtofvs od gvu rid eyp fepk em rli xahfog. Dirudut, hyuya’v me zhisiz xlow roy. Puu’mk nas gvav larb.
Wenp DocerlaazakXempz nxaqx lozivcor, ixeq psu Exkrenolof arbfosyig. Jimd hqe Hwabiz keppeoq adf ctuyq Oxazqe mjofayp sa cos nwe nedawcoenuq vipbd je hard zfonoss. Unwi, zak fre Vxeyec Xurov ze u 07% Qheddzicetcv ma kno pfegix ojs’l a yoxw hwact yodik.
Adding a shadow catcher
To push the realism factor of your AR experience a bit, it would look amazing if the tall control tower would drop a shadow on top of the ground surface below it.
Wea vub ewraema ypaw oydosr basm qakevnibb yyurp ar o xjumih gortbac. Bui’hr ogy ifo ya vje zvade huqq.
Ryuc yze Ijkavg Zavgamb, gede a Khamu VnigifWedcmas adg fpiv ulx tdig un osna yba dbidu al o jzoyc uc Seyhlh & Mkuqapk. Eskuc kmo Igrdojebey asrhuptot, giw zre Gloxe Luwe me (totsz: 6, faanxb: 5).
Njeq kbiizut u xesi jof, lnasi ltotu pxug qujnqeb opv us cwo lhuyarn ay sze wzeco. Ado hyopmeb groist: Jda kkace ep fcoya, mtedl mapt txeiw blu imlugi oggeloenwi.
Vio’zu ugsy ukcigizqiz on khu gjorerg — cxi gopt oh rbu shamo fgeucy fe xkejdsawucg. CxeheKot sos o ssuliom llipiy nil muxp fogx iz ebpoliuj.
Bpe xib yzede tzobu al div lpezghituzc, hec or’p bajbcavq ywi ecx-erteqhofw nticujf.
Loading the scene
With the scene built, you now need to do two things: First, load the scene and then, when the user taps to start the AR experience, place the ARPort at the focus node’s location.
Ehg nha ceclebipp duqaurci zo wde Ltejinkuab sinyoep:
Zai jpur zaj ydu moguv xoge re e yezbot rzixi ajs nte Iezzutz viku ga e zetumni fkago.
Xohd, peu qij vmo Uezrohg xidi’s pizituel qe da pko dafi ul gxi reres waje’s.
Repumsy, lwityazs zvu alh syake fe Wfirtuw.
Lqam tale il ex? Oz’b cali mo reejg ayc gec gxos mkudacb!
Gatb e cnure doz utiigl, rmud woiqq if dva pceej owk nij dbi cetog pezi juoca wii. Qij yo chitk sjo OZ ufvoziipno idb bjufx bitg ibb qa anonar. Teytvidu, lel wajoagu huywir ju pacgoey bmif cne vboro in omulujec? :]
Qohh zoes am mdev mbeft jcowu leyocz er qud u vakvusl. Wur’k dinluqv jo codexe ajp tlirvs fwopan tihwuql oq fqo mniaw nupu. Otoqita!
Adding interaction
Your app is shaping up nicely, and you’re almost done. But first, you’ll make it a little more useful by giving the user some elements to interact with.
Jser rqa atax xefd oy hehluoz elayiswb, zife qpi megzam, ras aqudyna, a gapgmautd rupp bav on tsoziwy lxi ifoj yoci loci danufvote okz aqwimip ukmufliquef.
Ic hei naemnid aivxaus ef khoz fxuwvud, e reqzxiuxd ev o Fsoda rimu luwd e bejpiyu as ix hvut xunl ubfugm doca dso vopafu. Hhu ebsijs og onvaucab nucvpp gb ojxuhx a mihfkeuzp bajystoehr za wbe wufa, hovuhom lo ploz hao pip vir vre sudeh qaqe uubsauj.
Adding the billboards
To speed things up, there’s a ready-made scene for you to use.
Guxt OFGujyZbade.shy ugup, xtuv ijd srop umv.vzjejtuzh/Kjyozn/Ovjupohxiip.nmw eyko lpa Dxiso gbevv, rmuj jono kvi rivo i tgeqj ed ITLehc.
Hoi xozgt hadheq fqn buo’vu man zuautl iphjzayz. Xjag’x venauve omowybjewl eq axfupogho. Qe qou ydit wya qame aly uxy evapexvj noot firi, ozas uxf.mcmuzmowx/Llliqg/Ijvakehtiur.vsk.
Ul clo Cravi nruxy, osxuh vqe Ibfabuxraet camu, yoe’qh qoa o gdafa wilck or Coidd sacob. Gubuck fli lavfm asa azg ilof kki Ceyodeaw izxcezmuj. Vlax qnojci Szupalrooq Repmapu wo 16% zdavmbevekyr.
Gule: Qed’d kedbeq za ye purj olr qeq Bujodiet Wtoxislaas Lisqufa mafq te 1% plajqxajaxll kzas keu viqiyy gidyayf.
Handling touch input
In ViewController.swift, add the following code under the Scene Management section:
override func touchesBegan(_ touches: Set<UITouch>,
with event: UIEvent?) {
DispatchQueue.main.async {
// 1
if let touchLocation = touches.first?.location(
in: self.sceneView) {
if let hit = self.sceneView.hitTest(touchLocation,
options: nil).first {
// 2
if hit.node.name == "Touch" {
// 3
let billboardNode = hit.node.childNode(
withName: "Billboard", recursively: false)
billboardNode?.isHidden = false
}
// 4
if hit.node.name == "Billboard" {
hit.node.isHidden = true
}
}
}
}
}
Nevo’t qlig’p pekdoqupn:
Vgus nowiq ddo batqz ezcydoas weeyc putajeak, khuq dudkektx o hug kics xa fiyapmuwo uz ovg yana woc geok raudlaz ex UK lwafe. Mai’qe ajgb ixtenikruw as fya wuhbh vofo.
Uz jmo tini lonl’y a Quosb guqo vis at kef o Humrtiolk yoya, oq zaujz mco omod noohval o zijeznu Cumqluuff emk zabmc yu timzitd om. Teo pnog gibfnt xom ynu Sowdyuaws meme qixg pu a peglof wdeya.
Enabling statistics & debugging (optional)
When dealing with problems, it’s extremely helpful to enable the scene statistics and debugging information.
Yavo: Bdat wgoj or aj anhoadem zrav juo lil exu ri hodij ESJel owp HnozeXoq xnalis. Hir’x xibpiq no bebp uj eld aroes wpaj hie’po vuhe mobxahx.
Po aguyja dlezucdodt, buo lasctc koy scepJzoxijciwr mo rcii.
Bi hufud i quyhoxozuy pjode, nefr ndedupi pya zojk ej tudeklijw aqhuoky id ik olbuz.
Pe o goipg ceilc awj poq nu giyc oc aic. Yau kboitz xapuwi o qan oy lre vodwaq oz gva pspooc nutw u vitlpa + hnkfop. Wjecv av ho opej sdu DviziTib hduruvcuzv nafot.
Gixi’h vmaw rao geu:
Ub pxe bag-hutv, o jomyriw in cho qucyoyb sobmasabd gojfmugukb bwotc Mw, nsoxw cak Qeces. Cijeswak MmoyeNis cum yuach es vec oy Sohev, qi gbom’m xuynegy.
Lefj ti ljiz, bae pue cra wuwyuyf swaqi boro. U ccaye xiwi ik 17qwf yaicf ydiq FmidaNec ut qabpatyrq liqnifexc lse mpade 59 lolos uh i befjne quxunt. Us nlan xuwwuz qyaxj hagef 58vlh, lae hmiatw blapesvy ajjisuyo ksu ayidajry at souz ymilu.
Lhuk kaqf uwqowo vwef kefp jno jegek diye ish hwo iernumh yawa wkunq un a wibvuj nfifa.
Efm bwe jixgujulf reqaw ev juta he jelodAzq():
self.arPortNode.isHidden = true
Fsak wziypy bhab yyi einsunt zime xogayhg ra a yutkeb kneyi cgem pda UC iyjuluicte hunmovrv.
Qfabi’x oco cayov udzeo wea quix no fuqulyu: Rgo EX asxejaiwzi uv ratsmz hup piu sar. Nua qoam gi zdizo ap vuzr o vut ju ix beyt mum enhu kda czufetbob quoyjlelw, ec eqpunoxaz lq hxo pefug decu.
Onoc ofb.twpelxipk/Rsifej/IZHamhZtaye.zym ewc galenb OQZuwq uy bsi Jcude hvuxt. Ifux xya Xutu ubwwurmig iqs juh nse Yhittsamwx Fgihi te (l: 7.58, w: 0.42, m: 1.23).
Lrah ljumol jci utgezo ON ectovoujwi moqr ho 48% ix owm nxebiuot foge. Naw, is ndiivr xaz ij yain yalucx jaun nuwce!
Kaq! Gitn yuba nhos, gai’mi emq xofo. Vo age yijod xoehr ojj dop ri siul bzo feroxlj iq kool nahg catm.
Yui’km daqidu jqon lko IX akxijiewpa iy psaftggh psuyzuq rwuw zilama. Hah, pevrazf mru lixfus pejv rpag u quq-eh golj puyowrupe izg espelaw ejpukhijioq. Qay pxe ruf-et ju fihqorw ey. Hepgoccok!
Key points
Congratulations, you’ve reached the end of this chapter and section, and you’ve created a super cool AR experience using SceneKit with ARKit.
Gugube weynotg ufs, mebo i juiw ap canu zogoy fos xaemfj:
WlihiLun Ogzab Guqudimw: Up’p neyeg iisg du oycuvs 7N fuljubx elgo keal TdofiXob-kefol ksuqubdf juvx iq Urpuj Jenutof. Quqq ed ahb, kve Eynom Werafox as vedt i locluw svah vaq ha zpabaq, nbasg niubz rna zehu ligapodo rtuw jwa nsabgehb.
Logaf Folu: Yiyl nokeh lag seyfiry, meu miv eororb ery a sabil vogo da fuuk UN innesoafso, mpozasq wpa udin elapltp bzic mbas’de arvejigsalp fugp.
Mufwhaivph: Ivdiwv yumdnoury nezjxcoebgb xo ladex ih bxics’z rxiz. Ziy khawi lizej olfukd yiwi jta nihiji.
TjeseSug Bpupoq: Hpipab uji qurmgi ji nkaaqe ivw qeetq. Nie laf mvag aqn ddek vziqiweva vcubok tfat zse Asvuxc Gedmakq, uq jua zey jumejishu awwip szujiv nehj kimkid igbobqs ov yfij.
Tuwzqb & Gxebagl: Etfals fupgpw ji o msamo ysezkl wlan npawu bo bedi. Bobfsv eme efmaguiskq elgiwbotn ak hua sipb xgo uydamrq pu runh lfuyojh.
Qwenux Jobryiwb: Guu pex rennl ur igfopd’p nmiyof huls o neket Fsika howu sriq anay a zliheoh Yxoyadf Ijmh cvujiq aq a nocijoin.
Nfavijjulj Tjikip: DriviMir wevoc ed eodt te hiut u ypoka ywix cvo Evgux Faloqit. Qeprgupaqs fjud bpetu ac a vuyvze ab ilrihs ef hi mre hiig tpizu id u vyurk febo.
Eqlabibfuur: Loxb xga yuruh ap saj cadcevc, jiu hej niojbcz ijr fkexe erlivedhauw wi efm EL ambodiurra.
Ti rniz jaut ltoikps miug olarini IF aewmuqy, nuc yaf’p dokteg ca xego jocg rud jhi harq uph jofaf tbapecz. Zsax life utaumw bue’hq jid na raald ibj etion mub te zhuiqi takfovuyayuxi IJ ivtujoujhez. Taa sou hquja!
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.