Поскольку вы не предоставили никакого кода (пожалуйста, сделайте это в следующий раз), я собираюсь предоставить решение, которое должно указать вам правильное направление.
Давайте начнем с создания PathItem Class
, котороемы будем использовать, чтобы составить полный путь, например, строку из них:
/// Path Item Node
class PathItem: SCNNode{
/// Creates A PathItem
///
/// - Parameters:
/// - size: CGFloat (Defaults To 20cm)
/// - texture: UIColour
/// - position: SCNVector3
init(size: CGFloat = 0.2, texture: UIColor, position: SCNVector3){
super.init()
//1. Create Our Path Geometry
let pathGeometry = SCNPlane(width: size, height: size)
//2. Assign The Colour To The Geoemtry
pathGeometry.firstMaterial?.diffuse.contents = texture
//3. Assign The Geometry, Position The Node & Rotate The Node So It Is Horizontal
self.geometry = pathGeometry
self.position = position
self.eulerAngles.x = GLKMathDegreesToRadians(-90)
}
required init?(coder aDecoder: NSCoder) { fatalError("Path Item Coder Has Not Been Implemented") }
}
Теперь, сделав это, давайте создадим func
, который создаст линию PathItem
(путь).
Сначала создайте глобальную переменную, например, которая ссылается на размер каждого PathItem
:
let pathItemSize: CGFloat = 0.2
Затем мы создаем нашу функцию, которая чередует цвет каждого PathItem
, а также предоставляет имуникальный name
или индекс, который мы будем использовать позже в нашей анимации:
/// Create A Path With A Number Of Elements
///
/// - Parameter numberOfElements: Int
/// - Returns: PATH (SCNNode)
func createdPathOfSize(_ numberOfElements: Int) {
var pathColour: UIColor!
//2. Loop Through The Number Of Path Elements We Want & Place Them In A Line
for pathIndex in 0 ..< numberOfElements{
//a. Position Each Peice Next To Each Other Based On The Index
let pathPosition = SCNVector3(0, -0.2, -pathItemSize * CGFloat(pathIndex+1))
//b. Alternate The Colour Of Our Path
if pathIndex % 2 == 0 { pathColour = UIColor.white } else { pathColour = UIColor.black }
//c. Create Our Path Item With A Unique Index We Can Use For Animating
let pathItem = PathItem(texture: pathColour, position: pathPosition)
pathItem.name = String(pathIndex)
//d. Set It To Hidden Initially
pathItem.isHidden = true
//e. Add It To Our Scene
self.augmentedRealityView.scene.rootNode.addChildNode(pathItem)
}
}
Чтобы сгенерировать Path
, мы можем теперь сделать что-то вроде этого:
override func viewDidLoad() {
super.viewDidLoad()
//1. Set Up Our ARSession
augmentedRealityView.session = augmentedRealitySession
sessionConfiguration.planeDetection = .horizontal
augmentedRealityView.debugOptions = .showFeaturePoints
augmentedRealitySession.run(sessionConfiguration, options: [.resetTracking, .removeExistingAnchors])
//2. Create A Path Of 10 PathItems
createdPathOfSize(10)
}
При этом яиметь следующее Global variables
:
@IBOutlet var augmentedRealityView: ARSCNView!
let augmentedRealitySession = ARSession()
let sessionConfiguration = ARWorldTrackingConfiguration()
Теперь мы сгенерировали наш Путь, нам нужно его анимировать!
Чтобы обеспечить немного разнообразия, давайте создадим Enum
, который мы можем использоватьсоздавать различные PathAnimations:
/// Path Item Animation
///
/// - UnHide: UnHides The Path Item
/// - FadeIn: Fades The Path Item In
/// - FlipIn: Flips The Path Item In
enum AnimationType{
case UnHide
case FadeIn
case FlipIn
}
Нет, так как мы будемсоздание некоторых анимаций позволяет создать еще 2 глобальные переменные, которые будут использоваться для запуска нашей анимации на таймере и отслеживания того, где мы находимся:
var pathAnimationTimer: Timer?
var time: Int = 0
Теперь давайте создадим нашу функцию анимации:
/// Animates The Laying Of The Path
///
/// - Parameters:
/// - numberOfElements: Int
/// - animation: AnimationType
func animatePathElements(_ numberOfElements: Int, withAnimation animation: AnimationType ){
//1. If We Are Flipping The PathItems In We Need To 1st Unhide Them All & Rotate Them To A Vertical Postions
if animation == .FlipIn {
let pathItems = self.augmentedRealityView.scene.rootNode.childNodes
pathItems.forEach({ (pathItemToAnimate) in
pathItemToAnimate.isHidden = false
pathItemToAnimate.eulerAngles.x = GLKMathDegreesToRadians(0)
})
}
//2. Create Our Time Which Will Run Every .25 Seconds
pathAnimationTimer = Timer.scheduledTimer(withTimeInterval: 0.25, repeats: true) { timer in
//3. Whilst Our Time Doesnt Equal The Number Of Path Items Then Continue Our Animation
if self.time != numberOfElements{
//a. Get The Current Node Remembering Each One Has A Unique Name (Index
guard let pathItemToAnimate = self.augmentedRealityView.scene.rootNode.childNode(withName: "\(self.time)", recursively: false) else { return }
//b. Run The Desired Animation Sequence
switch animation{
case .UnHide:
//Simply Unhide Each PathItem
pathItemToAnimate.isHidden = false
case .FadeIn:
//1. Unhide The Item & Sets It's Opacity To 0 Rendering It Invisible
pathItemToAnimate.isHidden = false
pathItemToAnimate.opacity = 0
//2. Create An SCNAction To Fade In Our PathItem
let fadeInAction = SCNAction.fadeOpacity(to: 1, duration: 0.25)
pathItemToAnimate.runAction(fadeInAction)
case .FlipIn:
//Simply Rotate The Path Item Horizontally
pathItemToAnimate.eulerAngles.x = GLKMathDegreesToRadians(-90)
}
self.time += 1
}else{
//4. Our Animation Has Finished So Invalidate The Timer
self.pathAnimationTimer?.invalidate()
self.time = 0
}
}
}
Затем нам нужно добавить это в конец нашей функции createPathOfSize следующим образом:
/// Create A Path With A Number Of Elements Which Can Be Animated
///
/// - Parameter numberOfElements: Int
/// - Returns: PATH (SCNNode)
func createdPathOfSize(_ numberOfElements: Int) {
var pathColour: UIColor!
//1. Loop Through The Number Of Path Elements We Want & Place Them In A Line
for pathIndex in 0 ..< numberOfElements{
//a. Position Each Peice Next To Each Other Based On The Index
let pathPosition = SCNVector3(0, -0.2, -pathItemSize * CGFloat(pathIndex+1))
//b. Alternate The Colour Of Our Path
if pathIndex % 2 == 0 { pathColour = UIColor.white } else { pathColour = UIColor.black }
//b. Create Our Path Item With A Unique Index We Can Use For Animating
let pathItem = PathItem(texture: pathColour, position: pathPosition)
pathItem.name = String(pathIndex)
//c. Set It To Hidden Initially
pathItem.isHidden = true
//d. Add It To Our Scene
self.augmentedRealityView.scene.rootNode.addChildNode(pathItem)
}
//2. Animate The Path
animatePathElements(10, withAnimation: .FlipIn)
}
А вот полный пример:
import UIKit
import ARKit
//----------------------
//MARK: - Path Animation
//----------------------
/// Path Item Animation
///
/// - Show: UnHides The Path Item
/// - FadeIn: Fades The Path Item In
enum AnimationType{
case UnHide
case FadeIn
case FlipIn
}
//-----------------
//MARK: - Path Item
//-----------------
/// Path Item Node
class PathItem: SCNNode{
/// Creates A PathItem
///
/// - Parameters:
/// - size: CGFloat (Defaults To 20cm)
/// - texture: UIColour
/// - position: SCNVector3
init(size: CGFloat = 0.2, texture: UIColor, position: SCNVector3){
super.init()
//1. Create Our Path Geometry
let pathGeometry = SCNPlane(width: size, height: size)
//2. Assign The Colour To The Geoemtry
pathGeometry.firstMaterial?.diffuse.contents = texture
//3. Assign The Geometry, Position The Node & Rotate The Node So It Is Horizontal
self.geometry = pathGeometry
self.position = position
self.eulerAngles.x = GLKMathDegreesToRadians(-90)
}
required init?(coder aDecoder: NSCoder) { fatalError("Path Item Coder Has Not Been Implemented") }
}
class ViewController: UIViewController {
typealias PATH = SCNNode
@IBOutlet var augmentedRealityView: ARSCNView!
let augmentedRealitySession = ARSession()
let sessionConfiguration = ARWorldTrackingConfiguration()
var pathPlaced = false
let pathItemSize: CGFloat = 0.2
var pathAnimationTimer: Timer?
var time: Int = 0
//----------------------
//MARK: - View LifeCycle
//----------------------
override func viewDidLoad() {
super.viewDidLoad()
//1. Set Up Our ARSession
augmentedRealityView.session = augmentedRealitySession
sessionConfiguration.planeDetection = .horizontal
augmentedRealityView.debugOptions = .showFeaturePoints
augmentedRealitySession.run(sessionConfiguration, options: [.resetTracking, .removeExistingAnchors])
//2. Create A Path Of 10 Path Items
createdPathOfSize(10)
}
//---------------------------------
//MARK: - Path Creation & Animation
//---------------------------------
/// Animates The Laying Of The Path
///
/// - Parameters:
/// - numberOfElements: Int
/// - animation: AnimationType
func animatePathElements(_ numberOfElements: Int, withAnimation animation: AnimationType ){
if animation == .FlipIn {
let pathItems = self.augmentedRealityView.scene.rootNode.childNodes
pathItems.forEach({ (pathItemToAnimate) in
pathItemToAnimate.isHidden = false
pathItemToAnimate.eulerAngles.x = GLKMathDegreesToRadians(0)
})
}
pathAnimationTimer = Timer.scheduledTimer(withTimeInterval: 0.25, repeats: true) { timer in
//1. Whilst Our Time Doesnt Equal The Number Of Path Items Then Continue Our Animation
if self.time != numberOfElements{
guard let pathItemToAnimate = self.augmentedRealityView.scene.rootNode.childNode(withName: "\(self.time)", recursively: false) else { return }
//2. Run The Desired Animation Sequence
switch animation{
case .UnHide:
pathItemToAnimate.isHidden = false
case .FadeIn:
pathItemToAnimate.isHidden = false
pathItemToAnimate.opacity = 0
let fadeInAction = SCNAction.fadeOpacity(to: 1, duration: 0.3)
pathItemToAnimate.runAction(fadeInAction)
case .FlipIn:
pathItemToAnimate.eulerAngles.x = GLKMathDegreesToRadians(-90)
}
self.time += 1
}else{
self.pathAnimationTimer?.invalidate()
self.time = 0
}
}
}
/// Create A Path With A Number Of Elements Which Can Be Animated
///
/// - Parameter numberOfElements: Int
/// - Returns: PATH (SCNNode)
func createdPathOfSize(_ numberOfElements: Int) {
var pathColour: UIColor!
//1. Loop Through The Number Of Path Elements We Want & Place Them In A Line
for pathIndex in 0 ..< numberOfElements{
//a. Position Each Peice Next To Each Other Based On The Index
let pathPosition = SCNVector3(0, -0.2, -pathItemSize * CGFloat(pathIndex+1))
//b. Alternate The Colour Of Our Path
if pathIndex % 2 == 0 { pathColour = UIColor.white } else { pathColour = UIColor.black }
//b. Create Our Path Item With A Unique Index We Can Use For Animating
let pathItem = PathItem(texture: pathColour, position: pathPosition)
pathItem.name = String(pathIndex)
//c. Set It To Hidden Initially
pathItem.isHidden = true
//d. Add It To Our Scene
self.augmentedRealityView.scene.rootNode.addChildNode(pathItem)
}
//2. Animate The Path
animatePathElements(10, withAnimation: .FlipIn)
}
}
Это должно быть большечем достаточно, чтобы указать вам правильное направление ^ __________ ^.