【问题标题】:Wall collisions in scene kit场景套件中的墙壁碰撞
【发布时间】:2015-08-14 04:36:57
【问题描述】:

我正在尝试编写一个游戏,其中一个节点可以移动但被一系列墙壁所包含 - 基本上是一个迷宫游戏。为了让基本的事情顺利进行,我将 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];
}

知道为什么盒子节点不会被墙挡住吗?

问题可能是盒子节点需要像车辆这样的力来推动才能让墙壁停下来?

【问题讨论】:

    标签: objective-c scenekit


    【解决方案1】:

    您要完成的工作有点棘手。用kinematicBody 来设想它是不可能的。

    您可以保留它,但您需要根据位置/边界框自己伪造碰撞,或者在物理世界中监听交叉点。

    您还可以更改为与其他动态对象交互的动态主体。但是,在moveBox 函数中,您使用SCNActions 来移动Box。如果您使用的是dynamicBody,它不能以这种方式移动。你必须使用forces

    最后一个选项就是使用SCNConstraint。不是最漂亮的,但如果你的墙不动它就可以了。

    【讨论】:

    • 非常感谢您的建议。我喜欢让物理世界处理所有事情的想法,但要移动到特定位置,我必须计算每次移动盒子所需的精确力(如果我决定制作地板,这可能会非常复杂我怀疑不均匀)。
    • 研究 SCNConstraint 方法,这对于有许多不同墙壁的迷宫是否可行? (显然我上面的代码中只有一个,但这只是一个开始工作的测试用例)
    • 这里有一个简单的问题:你只是想移动一个立方体,在四个方向之一,直到它到达墙壁?如果您解释您的最终目标,我可以帮助您找到实现目标的最佳方法。
    • 恐怕没有这么简单的事情。我希望能够点击场景中的某个地方,让立方体在撞到墙上之前尽可能靠近它。立方体不限于仅沿四个方向之一移动,因为它可以以任何角度(至少在平面上的二维)移动,直到撞到墙壁。抱歉,我没想到你会在这里做所有繁重的工作——我只需要朝着正确的方向轻推。目前听起来我将不得不进行交叉路口检查,并计算出在墙壁挡住时停止和定位立方体的逻辑。
    • 没问题!我会仔细考虑并更新我的答案。
    猜你喜欢
    • 1970-01-01
    • 2016-10-26
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    • 2016-04-24
    • 2015-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多