2016-03-29 13 views
0

私は画面をタップするとボックスが浮動から重力の影響を受けて切り替わる簡単なアプリケーションを作ろうとしています。私は箱を空中に浮かせる方法を見つけるように見えない。SceneKitの重力物理

ここにこのコードは、問題の半分の世話をする:

boxNode.physicsBody = [SCNPhysicsBody dynamicBody]; 

これは、空気の外にドロップすると、私が作成したフロアをヒットするボックスが発生します。 SCNPhysicsBodyにこれとは逆のことがありますか?おそらく、オブジェクトを浮かせるか、天井に向かって離れさせてしまうのだろうか?

- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer { 

    if (myBool == false) { 
     myBool = true; 
     NSLog(@"true"); 
    } else { 
     myBool = false; 
     NSLog(@"false"); 
    } 


} 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

// touch recognizer 
    UITapGestureRecognizer *screenTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; 
    [self.view addGestureRecognizer:screenTap]; 

    // create box 
    SCNBox *myBox = [SCNBox boxWithWidth:1.0 height:1.0 length:1.0 chamferRadius:0.1]; 
    SCNNode *boxNode = [SCNNode nodeWithGeometry:myBox]; 
    boxNode.position = SCNVector3Make(0.0, 0.0, 4.0); 
    [myScene.rootNode addChildNode:boxNode]; 



    while (myBool == true) { 

    boxNode.physicsBody = [SCNPhysicsBody dynamicBody]; 

    } 


} 

whileループはしかし動作しない理由を私はよく分からない:

また、私はこのコードを書いています。私は、それがmyBoolが変更されてboxNodeの物理を変更することを検出すると思っていましたが、そうではありません。

答えて

1

viewDidLoadメソッドは、ビューの読み込み時に1回だけ呼び出されます。アプリがmyBool = falseで初期化されている場合、whileループは決して実行されません。しかし、この場合、myBoolがtrueの場合、whileループは実行を停止せず、ビューのロードを妨げ、したがってユーザがジェスチャ認識子を起動するためにビューをタップすることを防止します。

私は以下をテストしていませんが、少なくともあなたには出発点があります。シーンはコードごとにviewDidLoadで作成されます。重要なことに、シーンのphysicsWorldは重力がゼロ(デフォルトでは-9.8)に設定されています。その後、ユーザーがビューをタップして重力をデフォルト値にリセットすると、ボックスが落ちるはずです。

ヘッダファイルGameViewController.h

#import <UIKit/UIKit.h> 
#import <SceneKit/SceneKit.h> 

@interface GameViewController : UIViewController { 
    SCNScene *myScene; 
} 

@end 

GameViewController.m

#import "GameViewController.h" 

@implementation GameViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // create a new scene 
    myScene = [SCNScene scene]; 

    // create box 
    SCNBox *myBox = [SCNBox boxWithWidth:1.0 height:1.0 length:1.0 chamferRadius:0.1]; 
    SCNNode *boxNode = [SCNNode nodeWithGeometry:myBox]; 
    boxNode.position = SCNVector3Make(0.0, 0.0, 4.0); 
    [myScene.rootNode addChildNode:boxNode]; 

    boxNode.physicsBody = [SCNPhysicsBody dynamicBody]; 

    //'disable' scene gravity 
    myScene.physicsWorld.gravity = SCNVector3Make(0, 0, 0); 

    SCNView *scnView = (SCNView *)self.view; 
    scnView.scene = myScene; 
    scnView.allowsCameraControl = YES; 
    scnView.autoenablesDefaultLighting = YES; 
    scnView.backgroundColor = [UIColor blackColor]; 

    // add a tap gesture recognizer 
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; 
    NSMutableArray *gestureRecognizers = [NSMutableArray array]; 
    [gestureRecognizers addObject:tapGesture]; 
    [gestureRecognizers addObjectsFromArray:scnView.gestureRecognizers]; 
    scnView.gestureRecognizers = gestureRecognizers; 
} 

- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer { 
    myScene.physicsWorld.gravity = SCNVector3Make(0, -9.8, 0); 
} 

@end 
+0

ありがとうございます!これは間違いなく役立ちます。 mySceneはhandleSingleTapからアクセスできませんが、mySceneはviewDidLoadで宣言されています。他の場所に宣言することはできますか?申し訳ありません、ここでかなり新しいです。 –

+0

ああ、申し訳ありませんが、インスタンス変数として既に宣言されているmySceneがあると仮定しました。上記を更新します...私のコードスニペットは、とにかく少しの作業が必要でした。 – lock

+0

注:編集されたバージョンでは、クラスインタフェース定義のインスタンス変数として 'myScene'を宣言します。次に、 'viewDidLoad'メソッドでは、この変数にシーンを割り当てて、クラス内のすべての関数(および他のクラス)にアクセスできるようにします。 FWIW私がちょうど出発したら、私はおそらくすぐにスウィフトに行くだろう。 – lock