0

I cannot get the variables to change when I update them. The method "reCenterYaw" fires when I touch the button and the variable "self.hasYawCenterPointBeenSet" gets updated within the method but when "updateCycle" method comes back around the variable is not showing it was updated. updateCycle is my CADisplaylink driven method. I've tried updating the variables to atomic, referenced them as their instance variables with "_" and with "self." Not sure what is going on.

#import "GameViewController.h"
#import <CoreMotion/CoreMotion.h>
#import <SpriteKit/SpriteKit.h>
#import "HUDOverlay.h"

@interface GameViewController ()
@property (strong, nonatomic) CMMotionManager *motionManager;
@property (strong, nonatomic) CMAttitude *currentAttitude;
@property (strong, nonatomic) SCNNode *cameraNode;
@property (strong, nonatomic) SCNScene *scene;
@property (nonatomic) float roll;
@property (nonatomic) float yaw;
@property (nonatomic) float pitch;

@property (atomic) float yawCenterPoint;
@property (atomic) BOOL hasYawCenterPointBeenSet;

@end

GameViewController* sharedGameViewController = nil;


@implementation GameViewController

+(GameViewController*)sharedController{
    if (sharedGameViewController == nil) {
        sharedGameViewController = [[GameViewController alloc] init];
    }
    return sharedGameViewController;
}


- (void)viewDidLoad
{
    [super viewDidLoad];

    // create a new scene
    //SCNScene *scene = [SCNScene sceneNamed:@"art.scnassets/ship.dae"];
    _scene = [SCNScene new];
    self.hasYawCenterPointBeenSet = NO;

    // create and add a camera to the scene
    _cameraNode = [SCNNode node];
    _cameraNode.camera = [SCNCamera camera];
    [_scene.rootNode addChildNode:_cameraNode];

    // place the camera
    _cameraNode.position = SCNVector3Make(0, 0, 0);

    // create and add a light to the scene
    SCNNode *lightNode = [SCNNode node];
    lightNode.light = [SCNLight light];
    lightNode.light.type = SCNLightTypeOmni;
    lightNode.position = SCNVector3Make(0, 10, 10);
    [_scene.rootNode addChildNode:lightNode];

    // create and add an ambient light to the scene
    SCNNode *ambientLightNode = [SCNNode node];
    ambientLightNode.light = [SCNLight light];
    ambientLightNode.light.type = SCNLightTypeAmbient;
    ambientLightNode.light.color = [UIColor whiteColor];
    [_scene.rootNode addChildNode:ambientLightNode];


    // retrieve the SCNView
    SCNView *scnView = (SCNView *)self.view;
    scnView.delegate = self;
    scnView.playing = YES;


    // set the scene to the view
    scnView.scene = _scene;

    scnView.overlaySKScene = [HUDOverlay sceneWithSize:scnView.frame.size];
    // allows the user to manipulate the camera
    scnView.allowsCameraControl = NO;

    // show statistics such as fps and timing information
    scnView.showsStatistics = YES;

    // configure the view
    scnView.backgroundColor = [UIColor blueColor];

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

    SCNNode *sampleNode = [SCNNode new];
    SCNPlane *samplePlane = [SCNPlane planeWithWidth:3 height:5];
    SCNMaterial *angryFrontMaterial = [SCNMaterial material];
    angryFrontMaterial.diffuse.contents = [UIImage imageNamed:@"angryfront110.png"];

    sampleNode.geometry = samplePlane;
    sampleNode.geometry.firstMaterial = angryFrontMaterial;
    sampleNode.position = SCNVector3Make(0, 0, -10);

    [_scene.rootNode addChildNode:sampleNode];
//  SCNAction *moveToCamera = [SCNAction moveTo:SCNVector3Make(0, 0, -10) duration:10];
//  [sampleNode runAction:moveToCamera];


    [self setupRotationGrid];
    [self setupMotionCapture];

    displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateCycle)];
    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

//This is the update loop for the sceneView.  When the view updates per frame this is where the logic goes
-(void)renderer:(id<SCNSceneRenderer>)aRenderer updateAtTime:(NSTimeInterval)time{

}

-(void)updateCycle{

    _currentAttitude = _motionManager.deviceMotion.attitude;
    _roll = _currentAttitude.roll + (.5 * M_PI);
    _yaw = _currentAttitude.yaw;
    _pitch = _currentAttitude.pitch;

    _cameraNode.eulerAngles = SCNVector3Make(-_roll, _yaw, _pitch);
    //NSLog(@"yawCenterPoint = %d", _hasYawCenterPointBeenSet);

    if (self.hasYawCenterPointBeenSet == NO) {
        _yawCenterPoint = _yaw;
        self.hasYawCenterPointBeenSet = YES;
        NSLog(@"Yawcenter point set to %f", _yawCenterPoint);
    }
    //NSLog(@"Roll: %f  Yaw: %f  Pitch: %f", _roll, _yaw, _pitch);

}

-(void)setupRotationGrid {
    double radius = 30;
    double numberOfItems = 8;
    SCNGeometry *geometry = [SCNBox boxWithWidth:4.5 height:8 length:3.25 chamferRadius:0.5];

    double x = 0.0;
    double z = radius;
    double theta = (M_PI)/(numberOfItems/2);
    double incrementalY = (M_PI)/(numberOfItems*2);

    SCNNode *nodeCollection = [SCNNode node];
    nodeCollection.position = SCNVector3Make(0, 4, 0);

    for (int index = 1; index <= numberOfItems; index++) {
        x = radius * sin(index*theta);
        z = radius * cos(index*theta);
        SCNNode *node = [SCNNode node];
        node.geometry = geometry;
        node.position = SCNVector3Make(x, 0, z);
        float rotation = incrementalY * index;
        node.rotation = SCNVector4Make(0, 1, 0, rotation);
        [nodeCollection addChildNode:node];
    }

    [_scene.rootNode addChildNode:nodeCollection];
}

- (void) handleTap:(UIGestureRecognizer*)gestureRecognize
{
    // retrieve the SCNView
    SCNView *scnView = (SCNView *)self.view;

    // check what nodes are tapped
    CGPoint p = [gestureRecognize locationInView:scnView];
    NSArray *hitResults = [scnView hitTest:p options:nil];

    // check that we clicked on at least one object
    if([hitResults count] > 0){
        // retrieved the first clicked object
        SCNHitTestResult *result = [hitResults objectAtIndex:0];

        // get its material
        SCNMaterial *material = result.node.geometry.firstMaterial;

        // highlight it
        [SCNTransaction begin];
        [SCNTransaction setAnimationDuration:0.5];

        // on completion - unhighlight
        [SCNTransaction setCompletionBlock:^{
            [SCNTransaction begin];
            [SCNTransaction setAnimationDuration:0.5];

            material.emission.contents = [UIColor blackColor];

            [SCNTransaction commit];
        }];

        material.emission.contents = [UIColor redColor];

        [SCNTransaction commit];
    }
}

-(void)reCenterYaw{
    self.hasYawCenterPointBeenSet = NO;
    NSLog(@"Tapped recenter");
}


-(void)setupMotionCapture{

    _motionManager = [[CMMotionManager alloc] init];
    _motionManager.deviceMotionUpdateInterval = 1.0/60.0;
    if (_motionManager.isDeviceMotionAvailable) {
        [_motionManager startDeviceMotionUpdates];
        _currentAttitude = _motionManager.deviceMotion.attitude;
    }

//  if (!_hasYawCenterPointBeenSet) {
//      _yawCenterPoint = _currentAttitude.yaw;
//      _hasYawCenterPointBeenSet = YES;
//  }



}


- (BOOL)shouldAutorotate
{
    return YES;
}

- (BOOL)prefersStatusBarHidden {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        return UIInterfaceOrientationMaskLandscape;
    } else {
        return UIInterfaceOrientationMaskAll;
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}



@end

1 Answers1

1

I figured it out. I had created a singleton so that I could reference the view controller from the sprite kit hud class. The problem is that I load the view controller from the storyboard and then later, from the hud class init, I instantiate a new view controller because the "sharedViewController" never got initiated by the storyboard load. So, I just created a view controller property on the hud class and set it to self from the view controller did load code.