Warsztaty i wykłady z oprogramowania
Samouczki i rozwój oprogramowania => Inne => Wątek zaczęty przez: TehekCom w Mar 02, 2026, 10:55 AM
WstępVisionOS 2 wraz z iOS 19, ARKit 8, RealityKit 2 i Entity Component System (ECS) stały się jeszcze silniejsze. W 2026 roku aplikacje spatial nie służą już tylko do gier; są używane w edukacji, designie, handlu detalicznym i produktywności.W tym przewodniku stworzymy od zera Aplikację do Wirtualnego Umieszczania Mebli (AR Furniture Placement):- Umieszczanie mebli w rzeczywistym pokoju (wykrywanie płaszczyzn + raycasting)
- Ładowanie modeli 3D w formacie USDZ
- Interakcja użytkownika (przeciąganie, obracanie, skalowanie)
- ImmersiveSpace (tryb pełnoekranowy VR)
- Integracja SwiftUI + RealityKit + ARKit
- Czysta architektura z Entity Component System
WymaganiaXcode 17+ (VisionOS SDK), symulator Vision Pro lub urządzenieNowy projekt → Aplikacja VisionOS (z opcją Immersive Space)1. Struktura ProjektuCytatFurnitureAR/
├── Models/
│ └── FurnitureEntity.swift
├── Views/
│ ├── ContentView.swift
│ ├── PlacementView.swift
│ └── ImmersiveView.swift
├── Components/
│ └── FurnitureComponent.swift
└── FurnitureARApp.swift
2. Entity i Component w RealityKitModels/FurnitureEntity.swiftimport RealityKit
import SwiftUI
struct FurnitureEntity: Entity, HasModel, HasAnchoring {
var model: ModelComponent?
init(usdzName: String) {
super.init()
guard let modelURL = Bundle.main.url(forResource: usdzName, withExtension: "usdz") else {
fatalError("Plik USDZ nie znaleziony: \(usdzName)")
}
do {
let model = try ModelEntity.loadModel(contentsOf: modelURL)
model.generateCollisionShapes(recursive: true)
model.components.set(CollisionComponent(shapes: [.generateBox(size: 1.0)]))
model.components.set(InputTargetComponent())
self.addChild(model)
self.model = model.components[ModelComponent.self]
} catch {
print("Błąd ładowania modelu: \(error)")
}
}
@MainActor required init() {
fatalError("init() has not been implemented")
}
}3. Widok Umieszczania (SwiftUI + ARView)Views/PlacementView.swiftimport SwiftUI
import RealityKit
import ARKit
struct PlacementView: View {
@State private var arView = ARView(frame: .zero)
@State private var selectedFurniture: String? = nil
@State private var placedEntities: [Entity] = []
var body: some View {
ZStack {
ARViewContainer(arView: $arView, placedEntities: $placedEntities)
.ignoresSafeArea()
VStack {
Spacer()
HStack(spacing: 20) {
ForEach(["sofa", "stół", "lampa"], id: \.self) { item in
Button {
selectedFurniture = item
} label: {
Text(item.capitalized)
.padding()
.background(Color.blue.opacity(0.8))
.clipShape(Capsule())
}
}
}
}
.padding(.bottom, 40)
}
.onAppear {
setupAR()
}
.gesture(
DragGesture()
.targetedToAnyEntity()
.onChanged { value in
value.entity.position = value.convert(value.location3D, from: .local, to: .scene)
}
)
.gesture(
TapGesture()
.targetedToAnyEntity()
.onEnded { value in
if let furniture = selectedFurniture {
let newEntity = FurnitureEntity(usdzName: furniture)
newEntity.position = value.convert(value.location3D, from: .local, to: .scene)
arView.scene.addAnchor(newEntity)
placedEntities.append(newEntity)
selectedFurniture = nil
}
}
)
}
func setupAR() {
let config = ARWorldTrackingConfiguration()
config.planeDetection = [.horizontal, .vertical]
config.environmentTexturing = .automatic
arView.session.run(config)
// Wizualizacja płaszczyzn
arView.debugOptions = [.showFeaturePoints, .showAnchorOrigins]
}
}
struct ARViewContainer: UIViewRepresentable {
@Binding var arView: ARView
@Binding var placedEntities: [Entity]
func makeUIView(context: Context) -> ARView {
return arView
}
func updateUIView(_ uiView: ARView, context: Context) {}
}4. Immersive Space (Pełny Tryb VR)Dodaj ImmersiveSpace w FurnitureARApp.swift:import SwiftUI
import RealityKit
@main
struct FurnitureARApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
ImmersiveSpace(id: "ImmersiveFurniture") {
ImmersiveView()
}
.immersionStyle(selection: .constant(.mixed), in: .mixed)
}
}
struct ContentView: View {
@Environment(\.openImmersiveSpace) var openImmersiveSpace
var body: some View {
VStack(spacing: 40) {
Text("Wirtualne Umieszczanie Mebli")
.font(.largeTitle)
Button("Rozpocznij w Trybie Immersyjnym") {
Task {
await openImmersiveSpace(id: "ImmersiveFurniture")
}
}
.buttonStyle(.borderedProminent)
}
}
}
struct ImmersiveView: View {
var body: some View {
RealityView { content in
// Tutaj możesz dodać środowisko 360° lub dodatkowe entity
if let skybox = try? EnvironmentResource.load(named: "skybox") {
content.environment = skybox
}
// Przykładowy anchor
let anchor = AnchorEntity(world: [0, 0, -3])
anchor.addChild(FurnitureEntity(usdzName: "sofa"))
content.add(anchor)
}
}
}5. Dodawanie Modeli USDZXcode → Assets → + → Add Files → Przeciągnij pliki .usdz (na przykład przykładowe modele Apple lub własne eksportowane z Blendera).Przykładowe źródła: Apple AR Quick Look Gallery lub darmowe modele USDZ z Sketchfab.6. Zaawansowane Funkcje (2026)- Śledzenie rąk z gestem pinch (chwyć i puść Entity)
- Dodawanie audio przestrzennego (AudioPlaybackComponent)
- Okno wolumetryczne (WindowGroup + volumetric)
- SharePlay dla wieloużytkownikowego AR
- Projektowanie scen z Reality Composer Pro