以编程方式更改 SCNScene 的 sceneNamed
Change SCNScene's sceneNamed programmatically
我正在尝试用代码更改当前 sceneNamed
,但我的方法似乎有一些问题。首先,新的场景会改变,但我必须触摸或评价对象以改变过程happens.Second,似乎childNodeWithName
根本没有改变!这是我的代码:
- (void)load3DObjectName:(NSString*)name nodeName:(NSString*)nodeName zPhone:(CGFloat)positioniPhone zPad:(CGFloat)positioniPad{
SCNScene * scene = [SCNScene sceneNamed:name];
// retrieve the ship node
SCNNode *trex = [scene.rootNode childNodeWithName:nodeName recursively:YES];
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
trex.position = SCNVector3Make(0, 0, positioniPhone);
} else {
trex.position = SCNVector3Make(0, 0, positioniPad);
}
_the3DScence.scene = scene;
_the3DScence.autoenablesDefaultLighting = YES;
_the3DScence.allowsCameraControl = YES;
_the3DScence.backgroundColor = [UIColor colorWithRed:0.92 green:0.92 blue:0.92 alpha:1.00];
}
// Load default object :
- (void)viewDidLoad {
[self load3DObjectName:@"cube.dae" nodeName:@"cube1" zPhone:-40 zPad:-30];
}
//Trying to change the 3D object with button:
- (IBAction)nextObject:(id)sender {
[self load3DObjectName:@"redCube.dae" nodeName:@"cube2" zPhone:-40 zPad:-30];
}
- (IBAction)changeIt:(id)sender {
[self load3DObjectName:@"dayere.dae" nodeName:@"Sphere" zPhone:-40 zPad:-40];
}
这是源代码:
https://www.dropbox.com/s/rrvbxmrb9wcrnoj/3D%20Objects%20Change.zip?dl=0
Dropbox 版本中的代码不是我上面发布的。这是 Dropbox 版本:
-(无效)viewDidLoad {
[超级viewDidLoad];
// 在加载视图后做任何额外的设置,通常是从 nib。
[自加载3DObjectName:@"cube.dae" nodeName:@"Cube" zPhone:-40 zPad:-40];
}
- (void)didReceiveMemoryWarning {
[超级 didReceiveMemoryWarning];
// 处理任何可以重新创建的资源。
}
- (void)load3DObjectName:(NSString*)name nodeName:(NSString*)nodeName zPhone:(CGFloat)positioniPhone zPad:(CGFloat)positioniPad{
SCNScene * scene = [SCNScene sceneNamed:name];
// 检索船舶节点
SCNNode *node = [scene.rootNode childNodeWithName:nodeName recursively:YES];
如果 ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
node.position = SCNVector3Make(0, 0, positioniPhone);
}
别的 {
node.position = SCNVector3Make(0, 0, positioniPad);
}
_the3DView.scene = 场景;
_the3DView.autoenablesDefaultLighting = 是;
_the3DView.allowsCameraControl = 是;
_the3DView.backgroundColor = [UIColor colorWithRed:0.92 green:0.92 blue:0.92 alpha:1.00];
}
- (IBAction)changeIt:(id)发件人{
[自加载3DObjectName:@"dayere.dae" nodeName:@"Sphere" zPhone:-40 zPad:-40];
}
在我看来,您的第二轮代码运行良好。我注意到您在 Dropbox 示例中加载的 scenes/nodes 与您首先发布的代码中加载的不同。所以这让我觉得您的 DAE 文件中有些东西不是您期望的那样。检查丢失或拼写错误的节点名称。在 childNodeWithName:
和 sceneNamed:
调用之后添加 NSAssert
调用,以确保您确实成功加载了场景并找到了子节点。
SCNScene * scene = [SCNScene sceneNamed:name];
NSAssert(scene, @"failed to load scene named %@", name);
// retrieve the ship node
SCNNode *node = [scene.rootNode childNodeWithName:nodeName recursively:YES];
NSAssert(node, @"couldn't fine child node named %@", nodeName);
如果 NSAsserts 失败,请使用 3D 编辑工具修复 Collada 文件。
另请注意,当您替换 the3DView.scene
时(另外:请不要直接修改实例变量,而是使用访问器方法!),您也在替换相机和照明。所以你应该预料到相机定位会出现抖动。也许你想制作动画?或者对象的 remove/replace 个节点,不影响相机和照明?
当我 运行 将您发布到 Dropbox 的代码时,我看到满屏都是红色。当我缩小并旋转相机时,它看起来像这样:
点击 "Button" 按钮后,我看到了这个:
所以我看过你的项目。问题是:你的场景中没有相机。所以我将每个场景的相机手动放置在相同的距离,并根据需要移动节点。这是现在的样子:
- (void)load3DObjectName:(NSString*)name nodeName:(NSString*)nodeName zPhone:(CGFloat)positioniPhone zPad:(CGFloat)positioniPad
{
SCNScene * scene = [SCNScene sceneNamed:name];
SCNNode *node = [scene.rootNode childNodeWithName:nodeName recursively:YES];
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
{
node.position = SCNVector3Make(0, 0, positioniPhone);
} else {
node.position = SCNVector3Make(0, 0, positioniPad);
}
SCNCamera *cam = [[SCNCamera alloc] init];
cam.xFov = 35;
cam.yFov = 35;
cam.zFar = 5000;
cam.zNear = 0;
SCNNode *camNode = [[SCNNode alloc] init];
camNode.camera = cam;
camNode.position = SCNVector3Make(0, 0, 400);
[scene.rootNode addChildNode:camNode];
_the3DView.pointOfView = camNode;
_the3DView.scene = scene;
_the3DView.autoenablesDefaultLighting = YES;
_the3DView.allowsCameraControl = YES;
_the3DView.backgroundColor = [UIColor colorWithRed:0.92 green:0.92 blue:0.92 alpha:1.00];
}
我还更改了您的对象位置以进行测试:
- (IBAction)changeIt:(id)sender
{
[self load3DObjectName:@"dayere.dae" nodeName:@"Sphere" zPhone:-340 zPad:-340];
}
还有这个:
- (void)viewDidLoad
{
[super viewDidLoad];
[self load3DObjectName:@"cube.dae" nodeName:@"Cube" zPhone:-40 zPad:-40];
}
最后但同样重要的是,屏幕截图:
我正在尝试用代码更改当前 sceneNamed
,但我的方法似乎有一些问题。首先,新的场景会改变,但我必须触摸或评价对象以改变过程happens.Second,似乎childNodeWithName
根本没有改变!这是我的代码:
- (void)load3DObjectName:(NSString*)name nodeName:(NSString*)nodeName zPhone:(CGFloat)positioniPhone zPad:(CGFloat)positioniPad{
SCNScene * scene = [SCNScene sceneNamed:name];
// retrieve the ship node
SCNNode *trex = [scene.rootNode childNodeWithName:nodeName recursively:YES];
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
trex.position = SCNVector3Make(0, 0, positioniPhone);
} else {
trex.position = SCNVector3Make(0, 0, positioniPad);
}
_the3DScence.scene = scene;
_the3DScence.autoenablesDefaultLighting = YES;
_the3DScence.allowsCameraControl = YES;
_the3DScence.backgroundColor = [UIColor colorWithRed:0.92 green:0.92 blue:0.92 alpha:1.00];
}
// Load default object :
- (void)viewDidLoad {
[self load3DObjectName:@"cube.dae" nodeName:@"cube1" zPhone:-40 zPad:-30];
}
//Trying to change the 3D object with button:
- (IBAction)nextObject:(id)sender {
[self load3DObjectName:@"redCube.dae" nodeName:@"cube2" zPhone:-40 zPad:-30];
}
- (IBAction)changeIt:(id)sender {
[self load3DObjectName:@"dayere.dae" nodeName:@"Sphere" zPhone:-40 zPad:-40];
}
这是源代码: https://www.dropbox.com/s/rrvbxmrb9wcrnoj/3D%20Objects%20Change.zip?dl=0
Dropbox 版本中的代码不是我上面发布的。这是 Dropbox 版本:
-(无效)viewDidLoad { [超级viewDidLoad]; // 在加载视图后做任何额外的设置,通常是从 nib。 [自加载3DObjectName:@"cube.dae" nodeName:@"Cube" zPhone:-40 zPad:-40]; } - (void)didReceiveMemoryWarning { [超级 didReceiveMemoryWarning]; // 处理任何可以重新创建的资源。 } - (void)load3DObjectName:(NSString*)name nodeName:(NSString*)nodeName zPhone:(CGFloat)positioniPhone zPad:(CGFloat)positioniPad{ SCNScene * scene = [SCNScene sceneNamed:name]; // 检索船舶节点 SCNNode *node = [scene.rootNode childNodeWithName:nodeName recursively:YES]; 如果 ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) { node.position = SCNVector3Make(0, 0, positioniPhone); } 别的 { node.position = SCNVector3Make(0, 0, positioniPad); } _the3DView.scene = 场景; _the3DView.autoenablesDefaultLighting = 是; _the3DView.allowsCameraControl = 是; _the3DView.backgroundColor = [UIColor colorWithRed:0.92 green:0.92 blue:0.92 alpha:1.00]; } - (IBAction)changeIt:(id)发件人{ [自加载3DObjectName:@"dayere.dae" nodeName:@"Sphere" zPhone:-40 zPad:-40]; }
在我看来,您的第二轮代码运行良好。我注意到您在 Dropbox 示例中加载的 scenes/nodes 与您首先发布的代码中加载的不同。所以这让我觉得您的 DAE 文件中有些东西不是您期望的那样。检查丢失或拼写错误的节点名称。在 childNodeWithName:
和 sceneNamed:
调用之后添加 NSAssert
调用,以确保您确实成功加载了场景并找到了子节点。
SCNScene * scene = [SCNScene sceneNamed:name];
NSAssert(scene, @"failed to load scene named %@", name);
// retrieve the ship node
SCNNode *node = [scene.rootNode childNodeWithName:nodeName recursively:YES];
NSAssert(node, @"couldn't fine child node named %@", nodeName);
如果 NSAsserts 失败,请使用 3D 编辑工具修复 Collada 文件。
另请注意,当您替换 the3DView.scene
时(另外:请不要直接修改实例变量,而是使用访问器方法!),您也在替换相机和照明。所以你应该预料到相机定位会出现抖动。也许你想制作动画?或者对象的 remove/replace 个节点,不影响相机和照明?
当我 运行 将您发布到 Dropbox 的代码时,我看到满屏都是红色。当我缩小并旋转相机时,它看起来像这样:
点击 "Button" 按钮后,我看到了这个:
所以我看过你的项目。问题是:你的场景中没有相机。所以我将每个场景的相机手动放置在相同的距离,并根据需要移动节点。这是现在的样子:
- (void)load3DObjectName:(NSString*)name nodeName:(NSString*)nodeName zPhone:(CGFloat)positioniPhone zPad:(CGFloat)positioniPad
{
SCNScene * scene = [SCNScene sceneNamed:name];
SCNNode *node = [scene.rootNode childNodeWithName:nodeName recursively:YES];
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
{
node.position = SCNVector3Make(0, 0, positioniPhone);
} else {
node.position = SCNVector3Make(0, 0, positioniPad);
}
SCNCamera *cam = [[SCNCamera alloc] init];
cam.xFov = 35;
cam.yFov = 35;
cam.zFar = 5000;
cam.zNear = 0;
SCNNode *camNode = [[SCNNode alloc] init];
camNode.camera = cam;
camNode.position = SCNVector3Make(0, 0, 400);
[scene.rootNode addChildNode:camNode];
_the3DView.pointOfView = camNode;
_the3DView.scene = scene;
_the3DView.autoenablesDefaultLighting = YES;
_the3DView.allowsCameraControl = YES;
_the3DView.backgroundColor = [UIColor colorWithRed:0.92 green:0.92 blue:0.92 alpha:1.00];
}
我还更改了您的对象位置以进行测试:
- (IBAction)changeIt:(id)sender
{
[self load3DObjectName:@"dayere.dae" nodeName:@"Sphere" zPhone:-340 zPad:-340];
}
还有这个:
- (void)viewDidLoad
{
[super viewDidLoad];
[self load3DObjectName:@"cube.dae" nodeName:@"Cube" zPhone:-40 zPad:-40];
}
最后但同样重要的是,屏幕截图: