如何在屏幕中央添加一个立方体,让它永不离开?
How to add a cube in the center of the screen, and so that it never leaves?
下午好!
我是 SceneKit 的新手。而且我也解决不了这个问题。
我需要让立方体一直在屏幕中央并跟随相机直到找到水平线并站在上面。
我让它留在一个地方
这是我现在的简单代码。
import UIKit
import SceneKit
import ARKit
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene()
let boxGeometry = SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0)
let material = SCNMaterial()
material.diffuse.contents = UIColor.blue
material.specular.contents = UIColor(white: 0.6, alpha: 1.0)
let boxNode = SCNNode(geometry: boxGeometry)
boxNode.geometry?.materials = [material]
boxNode.position = SCNVector3(0,0,-1.0)
scene.rootNode.addChildNode(boxNode)
sceneView.scene = scene
//------------------------------------
// Set the view's delegate
sceneView.delegate = self
// Show statistics such as fps and timing information
sceneView.showsStatistics = true
// Set the scene to the view
sceneView.scene = scene
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a session configuration
let configuration = ARWorldTrackingConfiguration()
// Run the view's session
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Pause the view's session
sceneView.session.pause()
}
}
请帮帮我。不要骂)
这里更新了您的代码,以确保该框始终位于屏幕中央。一旦代码检测到平面,它就会将盒子的父级设置为平面锚点。
这一切都很原始,但应该对你有帮助。如果您希望节点浮动在屏幕中央,请取消注释 willRenderScene
回调中的 SCNTransaction
s。如果希望盒子始终面向用户,可以添加一个lookAtConstraint
import UIKit
import SceneKit
import ARKit
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!
var boxNode: SCNNode? // keep a reference to the cube
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene()
let boxNode = createBox()
scene.rootNode.addChildNode(boxNode)
self.boxNode = boxNode
sceneView.scene = scene
//------------------------------------
// Set the view's delegate
sceneView.delegate = self
// Show statistics such as fps and timing information
sceneView.showsStatistics = true
// Set the scene to the view
sceneView.scene = scene
}
func createBox() -> SCNNode {
let boxGeometry = SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0)
let material = SCNMaterial()
material.diffuse.contents = UIColor.blue
material.specular.contents = UIColor(white: 0.6, alpha: 1.0)
let boxNode = SCNNode(geometry: boxGeometry)
boxNode.geometry?.materials = [material]
return boxNode;
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a session configuration
let configuration = ARWorldTrackingConfiguration()
configuration.planeDetection = .horizontal
// Run the view's session
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Pause the view's session
sceneView.session.pause()
}
// on willRender update the cube's position.
func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {
// get camera translation and rotation
guard let pointOfView = sceneView.pointOfView else { return }
let transform = pointOfView.transform // transformation matrix
let orientation = SCNVector3(-transform.m31, -transform.m32, -transform.m33) // camera rotation
let location = SCNVector3(transform.m41, transform.m42, transform.m43) // camera translation
let currentPostionOfCamera = orientation + location
// SCNTransaction.begin()
if let boxNode = self.boxNode {
boxNode.position = currentPostionOfCamera
}
// SCNTransaction.commit()
}
// detect plances
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard anchor is ARPlaneAnchor else { return }
if let boxNode = self.boxNode {
let newBoxNode = createBox() // create a new node for the center of the screen
self.boxNode = newBoxNode
SCNTransaction.begin()
boxNode.removeFromParentNode()
node.addChildNode(boxNode) // set the current box to the plane.
sceneView.scene.rootNode.addChildNode(newBoxNode) // add the new box node to the scene
SCNTransaction.commit()
}
}
}
extension SCNVector3 {
static func + (left: SCNVector3, right: SCNVector3) -> SCNVector3 {
return SCNVector3Make(left.x + right.x, left.y + right.y, left.z + right.z)
}
}
下午好! 我是 SceneKit 的新手。而且我也解决不了这个问题。
我需要让立方体一直在屏幕中央并跟随相机直到找到水平线并站在上面。 我让它留在一个地方 这是我现在的简单代码。
import UIKit
import SceneKit
import ARKit
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene()
let boxGeometry = SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0)
let material = SCNMaterial()
material.diffuse.contents = UIColor.blue
material.specular.contents = UIColor(white: 0.6, alpha: 1.0)
let boxNode = SCNNode(geometry: boxGeometry)
boxNode.geometry?.materials = [material]
boxNode.position = SCNVector3(0,0,-1.0)
scene.rootNode.addChildNode(boxNode)
sceneView.scene = scene
//------------------------------------
// Set the view's delegate
sceneView.delegate = self
// Show statistics such as fps and timing information
sceneView.showsStatistics = true
// Set the scene to the view
sceneView.scene = scene
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a session configuration
let configuration = ARWorldTrackingConfiguration()
// Run the view's session
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Pause the view's session
sceneView.session.pause()
}
}
请帮帮我。不要骂)
这里更新了您的代码,以确保该框始终位于屏幕中央。一旦代码检测到平面,它就会将盒子的父级设置为平面锚点。
这一切都很原始,但应该对你有帮助。如果您希望节点浮动在屏幕中央,请取消注释 willRenderScene
回调中的 SCNTransaction
s。如果希望盒子始终面向用户,可以添加一个lookAtConstraint
import UIKit
import SceneKit
import ARKit
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!
var boxNode: SCNNode? // keep a reference to the cube
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene()
let boxNode = createBox()
scene.rootNode.addChildNode(boxNode)
self.boxNode = boxNode
sceneView.scene = scene
//------------------------------------
// Set the view's delegate
sceneView.delegate = self
// Show statistics such as fps and timing information
sceneView.showsStatistics = true
// Set the scene to the view
sceneView.scene = scene
}
func createBox() -> SCNNode {
let boxGeometry = SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0)
let material = SCNMaterial()
material.diffuse.contents = UIColor.blue
material.specular.contents = UIColor(white: 0.6, alpha: 1.0)
let boxNode = SCNNode(geometry: boxGeometry)
boxNode.geometry?.materials = [material]
return boxNode;
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a session configuration
let configuration = ARWorldTrackingConfiguration()
configuration.planeDetection = .horizontal
// Run the view's session
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Pause the view's session
sceneView.session.pause()
}
// on willRender update the cube's position.
func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {
// get camera translation and rotation
guard let pointOfView = sceneView.pointOfView else { return }
let transform = pointOfView.transform // transformation matrix
let orientation = SCNVector3(-transform.m31, -transform.m32, -transform.m33) // camera rotation
let location = SCNVector3(transform.m41, transform.m42, transform.m43) // camera translation
let currentPostionOfCamera = orientation + location
// SCNTransaction.begin()
if let boxNode = self.boxNode {
boxNode.position = currentPostionOfCamera
}
// SCNTransaction.commit()
}
// detect plances
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard anchor is ARPlaneAnchor else { return }
if let boxNode = self.boxNode {
let newBoxNode = createBox() // create a new node for the center of the screen
self.boxNode = newBoxNode
SCNTransaction.begin()
boxNode.removeFromParentNode()
node.addChildNode(boxNode) // set the current box to the plane.
sceneView.scene.rootNode.addChildNode(newBoxNode) // add the new box node to the scene
SCNTransaction.commit()
}
}
}
extension SCNVector3 {
static func + (left: SCNVector3, right: SCNVector3) -> SCNVector3 {
return SCNVector3Make(left.x + right.x, left.y + right.y, left.z + right.z)
}
}