SceneKit Practice - juniverse1103/ARKitStudy GitHub Wiki
SceneKit Practice
1. Scene Preparation
-
ํ๋ก์ ํธ ์์ํ๊ธฐ
SceneKit์ ์ฌ์ฉํ๊ธฐ ์ํด์ ์ฐ์ ์๋ก์ด Swift Project๋ฅผ ์ด์ด์ค๋๋ค.
์์ ๋ณด์ด๋ Application Template ์ค Game ์ ์ ํํ๋ฉด ๊ธฐ๋ณธ์ ์ธ SceneKit์ด ์ ์ฉ๋ ํ ํ๋ ํ๋ก์ ํธ๊ฐ ๋์ค์ง๋ง, ์ด๋ฒ ๋ชฉํ๋ ๋น ํ๋ก์ ํธ์์ Game Template๋ฅผ ๊ทธ๋๋ก ๊ตฌํํด ๋ณด๋๊ฒ์ ๋๋ค.
Single View App ํ ํ๋ ์ ์ ํํด ์ฃผ์ธ์.
-
Single View App ํ ํ๋ ์ ์ ํํ๋ฉด ์์ ๊ฐ์ด ๋น ํ๋ก์ ํธ ํ๋ฉด์ด ๋ํ๋๊ฒ ๋ฉ๋๋ค.
SceneKit์ ์ฌ์ฉํ๊ธฐ ์ํด์ ๊ณ ๋ คํด์ผ ํ ์ฌํญ์ ํฌ๊ฒ ์ธ๊ฐ์ง ์ ๋๋ค.
- View Controller
- Asset
- StoryBoard
์ด ์ค ์ฝ๋๋ฅผ ์์ฑํ๋ ๋๋ถ๋ถ์ ์์ ์ ๋ทฐ ์ปจํธ๋กค๋ฌ์์ ์ด๋ฃจ์ด์ง๋ฉฐ, Asset์๋ ์ ํ๋ฆฌ์ผ์ด์ ๋ด์์ ์ฌ์ฉํ scnํ์ผ๊ณผ ํ ์ค์ณ ํ์ผ์ ๋ฃ์ด์ฃผ๊ณ , ์คํ ๋ฆฌ๋ณด๋์๋ ์์ฑํ 3D Scene์ ๋ ๋๋งํด์ ๋ณด์ฌ์ฃผ๊ธฐ ์ํ SCNView ๊ฐ์ฒด๋ฅผ ๋์์ฃผ๋ ์์ ์ ์ํํด ์ฃผ์ด์ผ ํฉ๋๋ค.
-
SceneKit Catalog ์ถ๊ฐํ๊ธฐ
๊ธฐ์กด ๋น ํ๋ก์ ํธ์ ์์ฑ๋ Asset ํด๋๋ Xcode์์ ์ฌ์ฉ๋๋ ์ด๋ฏธ์ง๋ค์ ๋ณด๊ดํ๊ธฐ ์ํ xcassets ์นดํ๋ก๊ทธ์ ๋๋ค. ์ฐ๋ฆฌ์๊ฒ ํ์ํ ๊ฒ์ SceneKit์ ์ฌ์ฉ๋ .scn ํ์ผ์ ๋ณด๊ดํ scnassets ์นดํ๋ก๊ทธ์ด๋ฏ๋ก, ์๋จ์ ๋ฉ๋ด ๋ฐ์์ File ํญ์ ํด๋ฆญํ ํ New -> File -> SceneKit Catalog ๋ฅผ ํด๋ฆญํด scnassets ์นดํ๋ก๊ทธ๋ฅผ ํด๋ฆญํ์ฌ ์ถ๊ฐํด ์ค๋๋ค.
-
Scene File ์ถ๊ฐํ๊ธฐ
์์ฑ๋ scnassets ํด๋๋ก ์ด๋ํ ํ ์๋จ์ ๋ฉ๋ด๋ฐ์์ ์๋ก์ด ํ์ผ์ ์ด์ด์ฃผ๊ฑฐ๋, command + N ํค๋ฅผ ๋๋ฌ์ฃผ๋ฉด scnassets ํด๋ ๋ด์ ์๋ก์ด .scn ํ์ผ์ด ์์ฑ๋ฉ๋๋ค.
-
Scene object ์ถ๊ฐํ๊ธฐ
Scene์ ์ค๋ธ์ ํธ๋ฅผ ์ถ๊ฐํ๊ธฐ ์ํด์๋ ์ถ๊ฐํ ์ค๋ธ์ ํธ๊ฐ ์์ด์ผ ํฉ๋๋ค. Apple์์ ARKit์ ์ ์ฉํ๊ธฐ ์ํด ์๋กญ๊ฒ ๊ณต๊ฐํ ํ์ผ ํฌ๋งท์ธ usdz ํฌ๋งท ํ์ผ์ ๋ฐ์ ์์ SceneKit์ ์ฌ๋ ค๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
https://developer.apple.com/arkit/gallery/ ์ ๋ค์ด๊ฐ์ ๋ง์์ ๋๋ usdz ํ์ผ์ ๋ฐ์์ต๋๋ค. ์ ๋ ๋ ํธ๋ก TV์ ์ผ๋ ๊ธฐํ ๋๊ฐ์ง ํ์ผ์ ๋ฐ์์ค๋๋ก ํ๊ฒ ์ต๋๋ค.
command + O ํค๋ฅผ ๋๋ฌ ๋ค์ด๋ก๋ ํด๋์์ ํ์ผ์ ์ด์ด .scnassets ํด๋์ ๋ฃ์ด์ค๋๋ค. ์ ๋ .scnassets ํด๋์ practice.scn ํ์ผ์ ๋ง๋ค์ด ์ฃผ์์ต๋๋ค. ์ฐ์ ๋ ํธ๋ก TV ํ์ผ ๋ง์ practice.scn ํด๋์ ์ถ๊ฐํด ์ฃผ๋๋ก ํ๊ฒ ์ต๋๋ค.
2. Storyboard Preparation
-
Scene์ ๋ ๋๋งํด์ ํ์ํด์ค SCNView ๋ฅผ ๋ง๋ค์ด์ฃผ๊ธฐ ์ํด Interface Builder๋ฅผ ์ฌ์ฉํ์ฌ ์คํ ๋ฆฌ๋ณด๋์ SCNView๋ฅผ ์ถ๊ฐํด์ค ํ constraint๋ฅผ safe area ์ ๋ง์ถฐ์ ๋ฃ์ด์ค๋๋ค.
์ด๋ฒ์๋ ARKit๋ฅผ ์ฌ์ฉํ์ง ์๊ณ SceneKit View๋ฅผ ์ฐ์ตํด๋ณผ ๊ณํ์ด๊ธฐ์ SceneKit View๋ฅผ ์ถ๊ฐํด์ค๋๋ค.
Constraint ๋ฅผ Safe Area์ ๋ํ์ฌ ๊ฐ๊ฐ 0์ฉ ๋ฃ์ด์ค๋๋ค.
์คํ ๋ฆฌ๋ณด๋ ์ค๋น๊ฐ ๋๋ฌ์ต๋๋ค.
3. View Controller
- Framework Import
-
import SceneKit
์ฝ๋๋ฅผ ํตํด SceneKit Framework๋ฅผ import ํด ์ค๋๋ค. -
import QuartzCore
์ฝ๋๋ฅผ ํตํด QuartzCore Framework๋ฅผ import ํด ์ค๋๋ค.- QuartzCore๋ ์ด๋ฏธ์ง ํ๋ก์ธ์ฑ๊ณผ ๋น๋์ค ์ด๋ฏธ์ง ์กฐ์์ ์ง์ํ๋ Objective - C ํ๋ ์์ํฌ์ ๋๋ค.
- Core Animation Framework ์ ๋์์ด์ ๋๋ค.
- viewDidLoad ์์ ์ฝ๋๋ฅผ ํตํ Scene ๊ตฌ์ฑ
-
scene ์์ฑํ๊ธฐ: SCNScene ํ์ ๊ฐ์ฒด์ธ scene์ ์ ์ธํด ์ค๋๋ค. ์ด ๋, ์ด๋์ ๋ผ์ด์ ์ ๋ค์๊ณผ ๊ฐ์ด ์์์ ์์ฑํด ์ฃผ์๋ scnassets ํด๋์ ์๋ scn ํ์ผ์ ํฌํจํ์ฌ ์ค๋๋ค.
//create a new scene let scene = SCNScene(named: "art.scnassets/[scene์ ๊ตฌ์ฑํ๊ณ ์ ํ๋ scn ํ์ผ ์ด๋ฆ]")
-
camera ์์ฑํ๊ธฐ: ์นด๋ฉ๋ผ๋ฅผ ๋ถ์ผ node๋ฅผ ๋ง๋ค๊ธฐ ์ํด์ SCNNode ํ์ ๊ฐ์ฒด์ธ cameraNode๋ฅผ ์์ฑํด ์ค๋๋ค.
๊ทธ ํ, cameraNode์ .camera ํ๋กํผํฐ์ SCNCamera()๋ฅผ ์ฌ์ฉํ์ฌ ์นด๋ฉ๋ผ๋ฅผ ๋ถ์ฌ์ค๋๋ค.
scene์ rootNode์ ์์ฑํด์ค cameraNode๋ฅผ ChildNode๋ก์ ์ถ๊ฐํด ์ค๋๋ค.
//create and add a camera to see the scene let cameraNode = SCNNode() cameraNode.camera = SCNCamera() scene.rootNode.addChildNode(cameraNode)
-
์นด๋ฉ๋ผ ์์น์ํค๊ธฐ: cameraNode๋ ํ์ฌ rootNode์ ChildNode์ด๊ธฐ ๋๋ฌธ์, rootNode๋ฅผ ๊ธฐ์ค์ผ๋ก ํ๋ ๊ณต๊ฐ๋ฒกํฐ๋ฅผ ํตํด ์์น์ ๋ณด๋ฅผ ์์ ํด ์ค ์ ์์ต๋๋ค.
cameraNode์ ์์น๋ฅผ ์ ์ ํ๊ฒ ์์ ํด ์ค๋๋ค.
//place the camera cameraNode.position = SCNVector3(x:0,y:0,z:15)
-
์กฐ๋ช ์์ฑํ๊ธฐ: ์กฐ๋ช ์ ๋ถ์ผ node ๋ฅผ ๋ง๋ค๊ธฐ ์ํด์ SCNNode ํ์ ๊ฐ์ฒด์ธ lightNode๋ฅผ ์์ฑํด ์ค๋๋ค.
๊ทธ ํ, lightNode์ .light ํ๋กํผํฐ์ SCNLight()๋ฅผ ์ฌ์ฉํ์ฌ ์กฐ๋ช ์ ๋ถ์ฌ์ค๋๋ค.
ligntNode.light์ .type ํ๋กํผํฐ๋ฅผ ์ด์ฉํด ์กฐ๋ช ์ ํ์ ์ ์ง์ ํด ์ค๋๋ค.
- ์กฐ๋ช
์ ํ์
์ ambient, directional, IES, probe, spot, omni๋ฑ์ด ์์ต๋๋ค.
- Ambient: A light that illuminates all objects in the scene from all directions.
- scene ๋ด์ ๋ชจ๋ ๊ฐ์ฒด๋ฅผ ๋ชจ๋ ๋ฐฉํฅ์ผ๋ก ๋น์ถ๋ ์กฐ๋ช ์ ๋๋ค.
- Directional: A light source with a uniform direction and constant intensity.
- ์ผ์ ํ ์ฑ๋์ ์ ํด์ง ๋ฐฉํฅ์ ๊ฐ๋ ๊ด์์ ๋๋ค.
- IES: A light source whose shape, direction, and intensity of illumination is determined by a photometric profile.
- Photometric profile์ ์ํด ๋ชจ์, ๋ฐฉํฅ, ๊ทธ๋ฆฌ๊ณ ์ฑ๋๊ฐ ์ ํด์ง๋ ๊ด์์ ๋๋ค.
- Probe: A sample of the environment around a point in a scene to be used in environment-based lighting.
- Environment-based lighting์ ์ฌ์ฉ๋๊ธฐ ์ํ scene ๋ด์ ํ ์ ์ ๋๋ฌ์ธ๋ ์ํ ํ๊ฒฝ์ ๋๋ค.
- Spot: A light source that illuminates a cone-shaped area.
- ์๋ฟ ๋ชจ์์ ์์ญ์ ๋น์ถ๋ ๊ด์์ ๋๋ค.
- Omni: An omnidirectional light, also known as a point light.
- ๋ชจ๋ ๋ฐฉํฅ์ผ๋ก ๋น์ ๋น์ถ๋ ์กฐ๋ช ์ ๋๋ค. ์ ๊ด์์ด๋ผ๊ณ ๋ ๋ถ๋ฆฝ๋๋ค.
- Ambient: A light that illuminates all objects in the scene from all directions.
// create and add a light to the scene let lightNode = SCNNode() lightNode.light = SCNLight() lightNode.light!.type = .omni lightNode.position = SCNVector3(x:0,y:10,z:10) scene.rootNode.addChildNode(lightNode)
- ์กฐ๋ช
์ ํ์
์ ambient, directional, IES, probe, spot, omni๋ฑ์ด ์์ต๋๋ค.
-
๊ฐ์ ๋ฐฉ์์ผ๋ก ambient light ์ญ์ ์ถ๊ฐํด์ค๋๋ค.
// create and add an ambient light to the scene let ambientLightNode = SCNNode() ambientLightNode.light = SCNLight() ambientLightNode.light!.type = .ambient ambientLightNode.light!.color = UIColor.darkGray scene.rootNode.addChildNode(ambientLightNode)
-
์ค๋ธ์ ํธ ๋ ธ๋ ์ถ๊ฐํด์ฃผ๊ธฐ: ํ์ฌ ์ฐ๋ฆฌ๊ฐ ๋ค๋ฃจ๊ณ ์๋ scene ๋ณ์๋ .scnassets ํด๋ ๋ด์ practice.scn ํ์ผ์ ๋ํ๋ด๋ SCNScene ์ ๋๋ค. practice.scn ํ์ผ ๋ด์ retrotv ์ค๋ธ์ ํธ๋ฅผ scene ๋ณ์์ rootNode์ childNode์ ์ถ๊ฐํ๋ ์ฝ๋๋ฅผ ์์ฑํ๋๋ก ํ๊ฒ ์ต๋๋ค.
// retrieve the retrotv node let retrotv = scene.rootNode.childNode(withName: "retrotv", recursively: true)!
-
์ค๋ธ์ ํธ ๋ ธ๋์ ์ ๋๋ฉ์ด์ ์ถ๊ฐํ๊ธฐ: ์ค๋ธ์ ํธ ๋ ธ๋์ runAction ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋ ธ๋์ ์ ๋๋ฉ์ด์ ์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ y์ถ์ ๊ธฐ์ค์ผ๋ก ๋ฐ๋ณต๋๋ ํ์ ์ ๋๋ฉ์ด์ ์ ์ถ๊ฐํ๋ ์ฝ๋๋ฅผ ์์ฑํ๋๋ก ํ๊ฒ ์ต๋๋ค.
// animate the 3D object retrotv.runAction(SCNAction.repeatForever(SCNAction.rotateBy(x:0, y:50,z:0,duration:1)))
-
Scene ๋ ๋๋งํ๊ธฐ: ์ฐ๋ฆฌ๊ฐ ๋ง๋ค์ด ์ค scene์ ๋๋ฐ์ด์ค ํ๋ฉด์ ํ์ํ๊ธฐ ์ํ SCNView ํ๋กํผํฐ๋ฅผ ๋ง๋ค์ด ์ฃผ์ด ์์์ ์ ์ธํ scene์ ํ ๋นํด ์ค๋๋ค.
// retrieve the SCNView let scnView = self.view as! SCNView // set the scene to the view scnView.scene = scene
-
Camera control, Statistics, Background color ๋ฑ์ ์ค์ ์ ์ค์ ํด์ค๋๋ค.
// allows the user to manipulate the camera scnView.allowsCameraControl = true // show statistics such as fps and timing information scnView.showStatistics = true // configure the view scnView.backgroundColor = UIColor.black
-
๋ง์ง๋ง์ผ๋ก, TapGestureRecognizer๋ฅผ ์ถ๊ฐํด ์ค๋๋ค.
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:))) scnView.addGestureRecognizer(tapGesture)