В SceneKit SCNAction зависает при вызове из обработчика завершения RunAction - PullRequest
0 голосов
/ 17 мая 2019

При вызове SCNAction из обработчика завершения RunAction, похоже, зависает 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

  • Теперь повешено

  • Коснитесь экрана (или поверните устройство в горизонтальное положение), и затем перемещение произойдет в порядке, и DONE MOVEBY будет распечатано.

Я использую C # и Visual Studio для Mac, но подозреваю, что это происходит и с Xcode.

Это ошибка в SceneKit? Как можно обойти это?

Может быть, это та же проблема, что и здесь:

Обработчик завершения SCNAction ожидает выполнения жеста

Ответы [ 2 ]

0 голосов
/ 23 мая 2019

Использование SCNTransaction с ЗавершениеБлок не страдает от той же проблемы, поэтому это прекрасно работает:

        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 - нет, это действительно похоже на ошибку Apple в RunAction.

0 голосов
/ 21 мая 2019

Это происходит потому, что по умолчанию SceneKit не рендерится непрерывно.При нажатии на экран сцена меняется, и новый кадр будет отображаться.Вот почему действие moveBy не запускается сразу после действия rotateBy.

Попробуйте установить для свойства SCNView renderContinuously значение 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
    })
}
...