Если я назначу звук в Reality Composer, смогу ли я программно остановить его в RealityKit?

Я назначаю звук сцене в Reality Composer, как показано на изображении ниже.

Если я назначу звук в Reality Composer, смогу ли я программно остановить его в RealityKit?

Я хотел бы создать UIButton, который можно нажать, чтобы остановить звук. Могу ли я сделать это?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я создал три действия Reality Composer для бокс-сцены: Play Sound, Spin и Notify. Как видите, циклическое воспроизведение включено.

SwiftUI

Мой код такой же простой. Основные методы stop() предназначены для немедленной остановки звука и анимации. Вторичные методы stop() являются содержимым обработчика завершения для свойства onAction.

import SwiftUI
import RealityKit

struct ContentView : View {
    
    @State var completion: ((Entity?) -> ()) = { _ in }
    @State var arView = ARView(frame: .zero)
    @State var boxScene = try! Experience.loadBox()
    
    var body: some View {
        ZStack {
            ARViewContainer(arView: $arView, boxScene: $boxScene)
               .ignoresSafeArea()
            VStack {
                Button("Stop") {
                    boxScene.steelBox?.stopAllAudio()              // 1
                    boxScene.steelBox?.stopAllAnimations()         // 1
                    print("Actions are stopped.")
                    
                    completion = {
                        $0?.stopAllAudio()                         // 2
                        $0?.stopAllAnimations()                    // 2
                        $0?.scale = [1,15,1]
                        print("Both actions were completely stopped.")
                    }

                    boxScene.actions.occured.onAction = completion
                }
                Spacer()
            }
        }
    }
}

А вот и обычная привязка.

struct ARViewContainer : UIViewRepresentable {
    
    @Binding var arView: ARView
    @Binding var boxScene: Experience.Box
    
    func makeUIView(context: Context) -> ARView {
        arView.scene.anchors.append(boxScene)
        return arView
    }
    func updateUIView(_ view: ARView, context: Context) { }
}

Обратите внимание, что действие Notify является последним в последовательности. Через какое время будут применены вторичные методы stop() (я имею в виду содержимое обработчика завершения), зависит от длительности аудиофайла или анимации (продолжительность моего аудио составляет 14 секунд).

UIKit

Решение UIKit несколько отличается и немного проще.

import UIKit
import RealityKit

class ViewController : UIViewController {       
    @IBOutlet var arView: ARView!
    let boxScene = try! Experience.loadBox()
    var completion: ((Entity?) -> Void)? = { _ in }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let rect = CGRect(x: 50, y: 50, width: 100, height: 50)
        let stopButton = UIButton(frame: rect)
        stopButton.setTitle("Stop", for: .normal)
        stopButton.addTarget(self, 
                           action: #selector(stopPlayingAudioAndAnime), 
                              for: .touchUpInside)
        arView.addSubview(stopButton)
        arView.scene.anchors.append(boxScene)
    }

    @objc private func stopPlayingAudioAndAnime() {            
        boxScene.steelBox?.stopAllAudio()                     // 1
        boxScene.steelBox?.stopAllAnimations()                // 1
        
        completion = { entity in
            entity?.stopAllAudio()                            // 2
            entity?.stopAllAnimations()                       // 2
            print("Completely Stopped")
        }           
        boxScene.actions.occured.onAction = completion
    }
}

П. С.

Однако, если вы будете использовать действие Play Music (другими словами, на основе сцены, а не объекта, как Play Sound действие), вы можете реализовать свою идею следующим образом:

arView.scene.anchors[0].children[0].stopAllAudio()
    
completion = { entity in
    entity?.scene?.anchors[0].children[0].stopAllAudio()
}

Можно ли использовать arView.scene.anchors[0].stopAllAudio()?

kkk 06.01.2023 16:13

Хороший! Дополнительно у меня 2 вопроса: 1) Зачем нужно добавлять .children[0] в код? и 2) Могу ли я использовать .playAudio() для возобновления воспроизведения после остановки?

kkk 06.01.2023 17:10

1) Это иерархия. AnchorEntity не имеет необходимых компонентов. 2) разместить еще один вопрос.

Andy Jazz 06.01.2023 17:14

Другие вопросы по теме