场景套件中的墙壁碰撞
Wall collisions in scene kit
我正在尝试编写一个节点可以移动但被一系列墙围住的游戏——基本上是一个迷宫游戏。为了让基本的事情顺利进行,我将 Apple 的 SceneKitVehicle 项目 (https://developer.apple.com/library/ios/samplecode/SceneKitVehicle) 拆分为基本元素,并放入一个立方体(下面代码中的框节点)而不是原始代码中的物理车辆。
问题是,我以编程方式移动长方体节点,直到它到达墙壁并且它继续直接穿过墙壁而没有停止。同时,我可以将车辆代码放回原处,当它到达墙壁时确实会停止。
- (void)setupEnvironment:(SCNScene *)scene
{
//floor
SCNNode*floor = [SCNNode node];
floor.geometry = [SCNFloor floor];
floor.geometry.firstMaterial.diffuse.contents = @"wood.png";
SCNPhysicsBody *staticBody = [SCNPhysicsBody staticBody];
floor.physicsBody = staticBody;
[[scene rootNode] addChildNode:floor];
}
- (void)moveBox
{
SCNAction *moveByAction = [SCNAction moveByX:0 y:0 z:-3 duration:0.1];
SCNAction *repeatAction = [SCNAction repeatActionForever:moveByAction];
[_boxNode runAction:repeatAction];
}
- (void)setupSceneElements:(SCNScene *)scene
{
// add walls
SCNNode *wall = [SCNNode nodeWithGeometry:[SCNBox boxWithWidth:400 height:100 length:4 chamferRadius:0]];
wall.geometry.firstMaterial.diffuse.contents = @"wall.jpg";
wall.geometry.firstMaterial.diffuse.contentsTransform = SCNMatrix4Mult(SCNMatrix4MakeScale(24, 2, 1), SCNMatrix4MakeTranslation(0, 1, 0));
wall.geometry.firstMaterial.diffuse.wrapS = SCNWrapModeRepeat;
wall.geometry.firstMaterial.diffuse.wrapT = SCNWrapModeMirror;
wall.geometry.firstMaterial.doubleSided = NO;
wall.castsShadow = NO;
wall.geometry.firstMaterial.locksAmbientWithDiffuse = YES;
wall.position = SCNVector3Make(0, 50, -92);
wall.physicsBody = [SCNPhysicsBody staticBody];
[scene.rootNode addChildNode:wall];
}
- (SCNNode *)setupBox:(SCNScene *)scene
{
SCNBox *boxgeo = [[SCNBox alloc] init];
boxgeo.height = 5;
boxgeo.width = 5;
boxgeo.length = 5;
SCNNode *box = [SCNNode nodeWithGeometry:boxgeo];
box.position = SCNVector3Make(0, 0, -30);
boxPosition = box.position;
box.rotation = SCNVector4Make(0, 1, 0, M_PI);
box.physicsBody = [SCNPhysicsBody kinematicBody];
[scene.rootNode addChildNode:box];
return box;
}
- (SCNScene *)setupScene
{
// create a new scene
SCNScene *scene = [SCNScene scene];
//global environment
[self setupEnvironment:scene];
//add elements
[self setupSceneElements:scene];
//setup box
_boxNode = [self setupBox:scene];
[self moveBox];
//create a main camera
_cameraNode = [[SCNNode alloc] init];
_cameraNode.camera = [SCNCamera camera];
_cameraNode.camera.zFar = 500;
_cameraNode.position = SCNVector3Make(0, 60, 50);
_cameraNode.rotation = SCNVector4Make(1, 0, 0, -M_PI_4*0.75);
[scene.rootNode addChildNode:_cameraNode];
return scene;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
SCNView *scnView = (SCNView *) self.view;
scnView.backgroundColor = [SKColor blackColor];
SCNScene *scene = [self setupScene];
scnView.scene = scene;
scnView.scene.physicsWorld.speed = 4.0;
scnView.pointOfView = _cameraNode;
scnView.delegate = self;
[super viewDidLoad];
}
知道为什么盒子节点不会被墙挡住吗?
问题可能是盒子节点需要像车辆一样由力推动才能让墙停下来吗?
您要完成的任务有点棘手。用 kinematicBody
.
设想它的方式不可能移动一个盒子并使其对物理相互作用做出反应
你可以保留它,但你需要根据 position/bounding 框自己伪造碰撞,或者监听物理世界中的交叉点。
您还可以更改为与其他动力学对象交互的动态物体。但是,在 moveBox
函数中,您使用 SCNAction
s 来移动 Box。如果您使用的是 dynamicBody
,它 不能 那样移动。你必须使用 forces.
最后一个选项就是简单地使用 SCNConstraint
。不是最漂亮的,但如果你的墙不动,它就可以了。
我正在尝试编写一个节点可以移动但被一系列墙围住的游戏——基本上是一个迷宫游戏。为了让基本的事情顺利进行,我将 Apple 的 SceneKitVehicle 项目 (https://developer.apple.com/library/ios/samplecode/SceneKitVehicle) 拆分为基本元素,并放入一个立方体(下面代码中的框节点)而不是原始代码中的物理车辆。
问题是,我以编程方式移动长方体节点,直到它到达墙壁并且它继续直接穿过墙壁而没有停止。同时,我可以将车辆代码放回原处,当它到达墙壁时确实会停止。
- (void)setupEnvironment:(SCNScene *)scene
{
//floor
SCNNode*floor = [SCNNode node];
floor.geometry = [SCNFloor floor];
floor.geometry.firstMaterial.diffuse.contents = @"wood.png";
SCNPhysicsBody *staticBody = [SCNPhysicsBody staticBody];
floor.physicsBody = staticBody;
[[scene rootNode] addChildNode:floor];
}
- (void)moveBox
{
SCNAction *moveByAction = [SCNAction moveByX:0 y:0 z:-3 duration:0.1];
SCNAction *repeatAction = [SCNAction repeatActionForever:moveByAction];
[_boxNode runAction:repeatAction];
}
- (void)setupSceneElements:(SCNScene *)scene
{
// add walls
SCNNode *wall = [SCNNode nodeWithGeometry:[SCNBox boxWithWidth:400 height:100 length:4 chamferRadius:0]];
wall.geometry.firstMaterial.diffuse.contents = @"wall.jpg";
wall.geometry.firstMaterial.diffuse.contentsTransform = SCNMatrix4Mult(SCNMatrix4MakeScale(24, 2, 1), SCNMatrix4MakeTranslation(0, 1, 0));
wall.geometry.firstMaterial.diffuse.wrapS = SCNWrapModeRepeat;
wall.geometry.firstMaterial.diffuse.wrapT = SCNWrapModeMirror;
wall.geometry.firstMaterial.doubleSided = NO;
wall.castsShadow = NO;
wall.geometry.firstMaterial.locksAmbientWithDiffuse = YES;
wall.position = SCNVector3Make(0, 50, -92);
wall.physicsBody = [SCNPhysicsBody staticBody];
[scene.rootNode addChildNode:wall];
}
- (SCNNode *)setupBox:(SCNScene *)scene
{
SCNBox *boxgeo = [[SCNBox alloc] init];
boxgeo.height = 5;
boxgeo.width = 5;
boxgeo.length = 5;
SCNNode *box = [SCNNode nodeWithGeometry:boxgeo];
box.position = SCNVector3Make(0, 0, -30);
boxPosition = box.position;
box.rotation = SCNVector4Make(0, 1, 0, M_PI);
box.physicsBody = [SCNPhysicsBody kinematicBody];
[scene.rootNode addChildNode:box];
return box;
}
- (SCNScene *)setupScene
{
// create a new scene
SCNScene *scene = [SCNScene scene];
//global environment
[self setupEnvironment:scene];
//add elements
[self setupSceneElements:scene];
//setup box
_boxNode = [self setupBox:scene];
[self moveBox];
//create a main camera
_cameraNode = [[SCNNode alloc] init];
_cameraNode.camera = [SCNCamera camera];
_cameraNode.camera.zFar = 500;
_cameraNode.position = SCNVector3Make(0, 60, 50);
_cameraNode.rotation = SCNVector4Make(1, 0, 0, -M_PI_4*0.75);
[scene.rootNode addChildNode:_cameraNode];
return scene;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
SCNView *scnView = (SCNView *) self.view;
scnView.backgroundColor = [SKColor blackColor];
SCNScene *scene = [self setupScene];
scnView.scene = scene;
scnView.scene.physicsWorld.speed = 4.0;
scnView.pointOfView = _cameraNode;
scnView.delegate = self;
[super viewDidLoad];
}
知道为什么盒子节点不会被墙挡住吗?
问题可能是盒子节点需要像车辆一样由力推动才能让墙停下来吗?
您要完成的任务有点棘手。用 kinematicBody
.
你可以保留它,但你需要根据 position/bounding 框自己伪造碰撞,或者监听物理世界中的交叉点。
您还可以更改为与其他动力学对象交互的动态物体。但是,在 moveBox
函数中,您使用 SCNAction
s 来移动 Box。如果您使用的是 dynamicBody
,它 不能 那样移动。你必须使用 forces.
最后一个选项就是简单地使用 SCNConstraint
。不是最漂亮的,但如果你的墙不动,它就可以了。