Group Group Group Group Group Group Group Group Group

Chapter 21, SCNAction reference or value


#1

Hi,
In Chapter 21 in Coded actions we do:

var driveLeftAction: SCNAction!
var driveRightAction: SCNAction!

driveLeftAction = SCNAction.repeatForever(SCNAction.move(by: SCNVector3Make(-2.0, 0, 0), duration: 1.0))
driveRightAction = SCNAction.repeatForever(SCNAction.move(by: SCNVector3Make(2.0, 0, 0), duration: 1.0))

 for node in trafficNode.childNodes {
  // 3 Let vehicle drive towards its facing direction
  if node.eulerAngles.y > 0 {
    node.runAction(driveLeftAction)
  } else {
    node.runAction(driveRightAction)
  }
}

As SCNAction is a subclass of NSObject and it is reference type, so each
node.runAction(driveLeftAction)
will execute the same SCNAction instance.
The question is why when we change speed, we change it for instance used all nodes of the one side:

if node.name?.contains("Bus") == true {
    driveLeftAction.speed = 1.0
    driveRightAction.speed = 1.0
  } else {
    driveLeftAction.speed = 2.0
    driveRightAction.speed = 2.0
  }

It is not changed for both bus and cars?


#2

@chrislanguage Can you please help with this when you get a chance? Thank you - much appreciated! :]


#3

I believe that SCNAction, as an NSObject, does “copy-on-write” semantics, meaning that if you assign it to one node, then change something like the speed, you actually get a new object that is a copy of the old one with the new speed value. So you are actually creating a number of SCNAction objects as you go through the loop.
It is not easy to pin down in documentation that it is copy-on-write, but I have seen that in other code examples and online discussion posts.


#4

@sgerrard Thank you, I understand.
I found, that SCNAction conforms to NSCopying (https://developer.apple.com/documentation/scenekit/scnaction)
So copy of SCNAction can be done. But I couldn’t found any source code of SCNAction to be sure, that it really copy SCNAction object during runAction(_) method