当前位置: 首页 > 知识库问答 >
问题:

在SceneKit中,当从RunAction的完成处理程序调用时,SCNAction挂起

周云
2023-03-14

从RunAction的完成处理程序调用SCNAction似乎会挂起SceneKit。

触摸事件或旋转设备似乎可以解除挂起的障碍。

繁殖:

1)采取默认的SceneKit项目,你得到的启动与旋转的宇宙飞船。

2) 替换动画代码

ship.RunAction(SCNAction.RepeatActionForever(SCNAction.RotateBy(0, 2, 0, 1)));

与:

        ship.RunAction(SCNAction.RotateBy(0, 2, 0, durationInSeconds: 3.0f), delegate
        {
            Console.WriteLine("DONE ROTATE");
            ship.RunAction(SCNAction.MoveBy(1, 0, 0, durationInSeconds: 3.0f), delegate
            {
                Console.WriteLine("DONE MOVEBY");
            });
        });

3)在模拟器或真实设备上运行(两者问题相同)

4)结果是:

>

  • 宇宙飞船旋转正常

    DONE ROTATE打印出来了OK

    现在它挂起来了

    轻触屏幕(或将设备旋转至横向),然后移动发生OK,并打印出DONE MOVEBY。

    我使用C#和Visual Studio for Mac,但我怀疑它也使用Xcode发生。

    这是SceneKit里的虫子吗?如何解决问题?

    也许这和这里描述的是同一个问题:

    动作完成处理程序等待手势执行

  • 共有2个答案

    翟渝
    2023-03-14

    将SCNTransaction与completionBlock一起使用不会遇到相同的问题,因此这很好:

            SCNTransaction.Begin();
            SCNTransaction.AnimationDuration = 3.0f;
            SCNTransaction.SetCompletionBlock(() =>
            {
                Console.WriteLine("DONE ROTATE");
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 3.0f;
                SCNTransaction.SetCompletionBlock(() =>
                {
                    Console.WriteLine("DONE MOVEBY");
                });
                ship.Position = new SCNVector3(1.0f, 0.0f, 0.0f);
                SCNTransaction.Commit();
            });
            ship.EulerAngles = new SCNVector3(0.0f, (float)Math.PI / 2, 0.0f);
            SCNTransaction.Commit();
    

    (也可以将CABasicAnimation与CAAnimationDelegate一起使用来执行回调。)

    由于SCNTransaction和CABasicAnimation工作,但RunAction不工作,它看起来真的像RunAction中的Apple bug。

    关冠宇
    2023-03-14

    这是因为默认情况下SceneKit不会连续渲染。当点击屏幕时,场景会被改变,一个新的帧会被渲染。这就是为什么moveBy动作不会在RotateBy动作后立即触发。

    尝试设置SCNViewrender免遭连续属性为true这样:

    scnView.rendersContinuously = true
    ship.runAction(SCNAction.rotateBy(x: 0, y: 2, z: 0, duration: 3.0)) {
        print("DONE ROTATE")
        ship.runAction(SCNAction.moveBy(x: 1, y: 0, z: 0, duration: 3.0), completionHandler: {
            print("DONE MOVEBY")
            scnView.rendersContinuously = false
        })
    }
    
     类似资料:
    • 问题内容: 我是Swift和SpriteKit的新手。SpriteKit Actions的许多示例都在Objective C中,在Swift中我无法映射到它,也无法使用。 如果运行SKAction,并且在完成SKAction后又想做其他事情,那么如何在Swift中做到这一点呢? 任何想法将不胜感激。 编辑: 问题答案: 您的完成代码不会被调用,因为您的“死亡”操作将永远运行,这意味着它永远不会结束

    • 我正在制作一个显示化学反应动画的应用程序。每个原子都是一个SCNSphere,并用SCNActions动画。我试图使用runAction()中的完成处理程序在当前操作完成后调用下一个动画,因为每个原子必须进行许多不同的运动。 这只是我为简化过程而编写的一些测试代码,实际代码将在对象数组中循环。 语句工作正常,只有在操作完成后才会调用它,但是新的SCNAction不会触发。我是否遗漏了什么来启动下一

    • 问题内容: 我在Utilities类中使用loadImage方法,并且在通过闭包返回图像时遇到了一些麻烦。基本上因为我的代码可能返回图像或错误,所以在调用该方法时将其分配给image属性是行不通的。 我在类的方法声明中使用的方法是否错误,还是应该以不同的方式调用该方法以预期潜在的不同结果?谢谢 问题答案: 将处理程序添加到您的 loadImage 函数中: 迅捷3 像这样调用func: 斯威夫特2

    • 问题内容: 我有一个字段,我想在其中应用的变体。 该字段与ajax调用绑定在一起,当用户更改输入时,服务器端将处理数据,但是,我不想太频繁地进行调用。 假设用户要输入一个真正的字符串,我希望仅在用户完成将要键入的单词后才能进行呼叫。不过,我不想使用诸如模糊之类的事件。有什么比实现更好的方法呢? 问题答案: 使用在角> 1.3 没有-在标记中: 在您的后备控制器/范围内 然后,您将仅在1000ms不

    • 我目前正在学习swift,几个小时以来我一直在试图理解一个错误。由于查询,我试图从php脚本中获取一个xml文件,我使用一个完成处理程序作为回调来获取这些查询的结果。 问题是我对这些技术感到不舒服,它说缺少论据。 下面是使用完成处理程序的函数: 这是我调用这个函数的一段代码: 这段代码显示有关调用连接的此错误: 我做错了什么?为什么它要两个参数? 非常感谢您的帮助。 埃尔巴托

    • 我在地图中的几个位置进行反向地理编码,并希望将其包装为某种常用方法。我所拥有的是作为工作起点的: 但是,如果我想在我的完成方法中添加另一个参数,将会向我的视图返回错误,如下所示: 如果error为,那么我的将失败,因为错误为nil且访问错误。但我不能这样做,因为参数与完成处理程序不匹配。 因此,如果我有一个nil错误,我将如何调用我的完成处理程序?