如何调用在不同视图控制器中定义的函数?

How to call a function that is defined in a different view controller?

我正在尝试调用名为 "kick" 的函数。里面是我在我制作的这个人身上播放的 CAAnimation。所以通常我会在创建它时在同一个视图控制器中调用该函数。但是因为我有一个 HUD/overlay 场景,所以我的 3D 游戏上显示。 HUD/overlay场景是在不同的视图控制器中制作的,专门用于设置 HUD 我无法让 HUD 视图控制器识别主视图控制器的任何功能。

主视图控制器:
代码:

   class GameViewController: UIViewController, ADBannerViewDelegate, SKPhysicsContactDelegate, SKSceneDelegate, SCNSceneRendererDelegate, SCNPhysicsContactDelegate{

var HUDView: HUD!

required init?(coder: NSCoder) {
    super.init(coder: coder)
}

override func viewDidLoad() {
    super.viewDidLoad()

  //-----Scene-Setup----------
    let scnView = self.view as! SCNView
    scnView.scene = FieldScene
    scnView.playing = true
    scnView.loops = true
    self.HUDView = HUD(size: CGSizeMake(100, 100))
    scnView.overlaySKScene = self.HUDView
    scnView.delegate = self
    scnView.overlaySKScene!.delegate = self
    scnView.overlaySKScene!.userInteractionEnabled = true
    scnView.backgroundColor = UIColor.whiteColor()
    scnView.allowsCameraControl = true
    scnView.showsStatistics = false

    let GuyScene = SCNScene(named: "art.scnassets/The1.dae")
    let Guy: SCNNode = GuyScene!.rootNode.childNodeWithName("Armature", recursively: true)!
    let GuyBody: SCNNode = GuyScene!.rootNode.childNodeWithName("Cube", recursively: true)!
    //----Giveing it a physics---------
    let collisionCapsuleRadius2 = CGFloat(0.1)
    let collisionCapsuleHeight2 = CGFloat(0.1)
    Guy.position = SCNVector3(x: -30.0, y: 30.0, z: 0.0)
    Guy.scale = SCNVector3Make(50, 50, 50)
    Guy.rotation = SCNVector4Make(0, 1, 0, 1 )
    Guy.physicsBody = SCNPhysicsBody(type: .Dynamic, shape:SCNPhysicsShape(geometry: SCNCapsule(capRadius: collisionCapsuleRadius2, height: collisionCapsuleHeight2), options:nil))
    Guy.physicsBody?.affectedByGravity = true
    Guy.physicsBody?.friction = 0 //
    Guy.physicsBody?.restitution = 1 //bounceness of the object
    Guy.physicsBody?.angularDamping = 1 // rotationess
    Guy.physicsBody?.mass = 1
    Guy.physicsBody?.rollingFriction = 0
    scnView.scene!.rootNode.addChildNode(Guy)
    scnView.scene!.rootNode.addChildNode(GuyBody)
    }

     //Ok Kick function gets declared right here


    func Kick() {
    //-----Animate-Guy-----Working-Perfectly-----------
    let KickAnimation = CAAnimation.animationWithSceneNamed("art.scnassets/The1Anima.dae")!
    Guy.addAnimation(KickAnimation, forKey: "Go")
    Guy.removeAnimationForKey("Go", fadeOutDuration: 3.0)
   }


 }

   extension CAAnimation {
class func animationWithSceneNamed(name: String) -> CAAnimation? {
    var animation: CAAnimation?
    if let scene = SCNScene(named: name) {
        scene.rootNode.enumerateChildNodesUsingBlock({ (child, stop) in
            if child.animationKeys.count > 0 {
                animation = child.animationForKey(child.animationKeys.first!)
                stop.initialize(true)
            }
        })
    }
    return animation
 }
}



  //Ok Below is my HUD/Overlayscene which holds the button that i would like call the function in.


  extension GameViewController {
    // was never used
}

 class HUD: SKScene {
//-----------------Controller-Buttons----------------------
var ButtonA = SKSpriteNode(imageNamed:"EnhancedAButton")

  override init(size: CGSize) {
    super.init(size: size)

    //----A-Button--Creation -------------------
    ButtonA.size = CGSize(width: 7, height: 11)
    ButtonA.anchorPoint = CGPointMake(-11.35, -0.6)
    ButtonA.zPosition = 0
    ButtonA.alpha = 0.45
    self.addChild(ButtonA)
    }

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}


   //Ok here is the function I need to put "Kick()"  inside it but when I do it doenst recognize it because the function wasnt declared in this view controller 


func AButtonPressed() {  

}

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    super.touchesBegan(touches, withEvent: event)
    for touch: AnyObject in touches {
        let location1 = touch.locationInNode(self)
        if self.nodeAtPoint(location1) == self.ButtonA {
            AButtonPressed()
            print("AButtonPressed")
        }
    }
 }
}

enter image description here

enter image description here

这实际上是处理此问题的最佳方法。其他方法很混乱,而这是处理它的最解耦的自然方法。如果您有任何问题,请告诉我。

extension GameViewController: GameDelegate {
    func Kick() {
        //-----Animate-Guy-----Working-Perfectly-----------
        let KickAnimation = CAAnimation.animationWithSceneNamed("art.scnassets/The1Anima.dae")!
        Guy.addAnimation(KickAnimation, forKey: "Go")
        Guy.removeAnimationForKey("Go", fadeOutDuration: 3.0)
    }
}

protocol GameDelegate {
    func Kick()
}

class HUD: SKScene {

    var delegate: GameDelegate?

    override init(size: CGSize) {
        super.init(size: size)

        //this calls Kick anywhere in the HUD class
        delegate?.Kick()


        //----A-Button--Creation -------------------
        ButtonA.size = CGSize(width: 7, height: 11)
        ButtonA.anchorPoint = CGPointMake(-11.35, -0.6)
        ButtonA.zPosition = 0
        ButtonA.alpha = 0.45
        self.addChild(ButtonA)
    }
}

在 GameViewController 的 viewDidLoad() 内部的行之后

//below this line
self.HUDView = HUD(size: CGSizeMake(100, 100))
//add in 
self.HUDView.delegate = self

添加完所有这些后,您可以删除不在扩展中的Kick副本。两个控制器都可以访问该功能。