I’m working with RealityView in visionOS and noticed that the content closure seems to run twice, causing content.add to be called twice automatically. This results in duplicate entities being added to the scene unless I manually check for duplicates. How can I fix that? Thanks.
RealityView content.add Called Twice Automatically
I can't reproduce this on my end. I just tried a few of my projects and examples and they are working fine. If I add a print line to the make
closure of RealityView, I only see it print once. When I inspect the entity graph I see what I expect to see. I'm using visionOS 26 Beta 5 and the latest Xcode.
Some other things to think about. You can use a feature in Xcode to capture the entity hierarchy. When you do this, do you see duplicate entities in the same hierarchy or duplicate hierarchies? https://www.gabrieluribe.me/blog/debugging-realitykit-apps-games-visionos
Is there anything higher up in your SwiftUI stack that could be causing your RealityView to be created more than once?
If you can post some example code showing the issue I may be able to provide more useful help
@radicalappdev , Thanks for your answer!
This is a fragment of my code, which has been modified for demonstration.:
RealityView { content in
//...
launchEntity = createLaunchEntity() //This entity maybe creat two or more
content.add(launchEntity)
} update: { content in
//...
}
func createLaunchEntity() -> Entity {
//...
let entity: Entity = Entity()
let launchviewComponent = ViewAttachmentComponent(
rootView: LaunchView()
)
entity.components.set(launchviewComponent) // Creat a UI View to show
//...
print("Has Creat Test!") // It has been output once.
return entity
}
In this code, "Has Creat Test!" It was output once (This is normal.), But I wrote the print content in onAppaer in LaunchView, it was output many times(This is problem).
If anyone knows the cause of the problem and the solution or other ideas about the problem, I hope you can help me. Thank you!
I made a standalone project based on your code check this out. The good news that the entity is not being duplicated. Let's look at the cod first.
struct ImmersiveView: View {
@State var launchEntity = Entity()
var body: some View {
RealityView { content in
print("RealityView Content Loaded!") // Called Once
launchEntity = createLaunchEntity()
content.add(launchEntity)
}
}
func createLaunchEntity() -> Entity {
//...
let entity: Entity = Entity()
entity.name = "Launch Entity"
let launchviewComponent = ViewAttachmentComponent(
rootView: LaunchView()
)
entity.components.set(launchviewComponent)
print("createLaunchEntity was called") // Called Once
return entity
}
}
struct LaunchView: View {
var body: some View {
VStack {
Text("Launch View")
}
.padding()
.onAppear() {
print("Launch view appears!") // Called Twice
}
}
}
When I load this immersive space I see 4 lines in the console
RealityView Content Loaded!
createLaunchEntity was called
Launch view appears!
Launch view appears!
What happened
- RealityView content was called once
- createLaunchEntity
- The onAppear closure in the LaunchView was called twice.
That made me wonder if ViewAttachmentComponent
is calling LaunchView
more than once and yes, that appears to be the case.
When I create the attachment using the attachments closure on RealityView, onAppear is only called once.
var body: some View {
RealityView { content, attachments in
print("RealityView Content Loaded!") // Called Once
content.add(launchEntity)
if let attachment = attachments.entity(for: "Test") {
launchEntity = attachment
content.add(launchEntity)
}
} update: { content, attachments in
} attachments: {
Attachment(id: "Test", {
LaunchView()
})
}
}
So the good news is that we don't see duplicate entities in the graph. The bad news is that ViewAttachmentComponent
is calling the SwiftUI more than once. I suggest you file a bug with Feedback Assistant. In the meantime, you could using RealityView to create attachments. If your view is just presenting data, then I suppose you could just ignore this.
Thanks you @radicalappdev
I have submitted Feedback:
FB19545353