SpriteKit

RSS for tag

Drawing shapes, particles, text, images, and video in two dimensions using SpriteKit.

SpriteKit Documentation

Post

Replies

Boosts

Views

Activity

SpriteKit: SKTileMap leaks with `SKTexture(rect: CGRect)` usage
Hello reader, I am facing an issue that I am not able to resolve. I have been able to create a demo project that demonstrates the issue, which I hope enables you to have a look as well and hopefully find a way to resolve it. What is the issue: I am using SKTileMapNode in order to draw tile maps. Instead of using the tilesets as you can use from within the Xcode editor, I prefer to do it all programmatically using tilesheets (for a plethora of reasons that I will leave out of this equation). This is the code of the gameScene: import SpriteKit import GameplayKit class GameScene: SKScene { private let tileSize = CGSize(width: 32, height: 32) override func didMove(to view: SKView) { super.didMove(to: view) let tileSet = createTileSet() let tileMap = SKTileMapNode(tileSet: tileSet, columns: 100, rows: 100, tileSize: tileSize) for column in 0..<tileMap.numberOfColumns { for row in 0..<tileMap.numberOfRows { guard let tileGroup = tileSet.tileGroups.randomElement() else { fatalError() } tileMap.setTileGroup(tileGroup, forColumn: column, row: row) } } addChild(tileMap) } private func createTileSet() -> SKTileSet { let tileSheetTexture = SKTexture(imageNamed: "terrain") var tileGroups = [SKTileGroup]() let relativeTileSize = CGSize(width: tileSize.width/tileSheetTexture.size().width, height: tileSize.height/tileSheetTexture.size().height) for idx in 0...2 { for jdx in 0...2 { let tileTexture = SKTexture(rect: .init(x: CGFloat(idx) * relativeTileSize.width, y: CGFloat(jdx) * relativeTileSize.height, width: relativeTileSize.width, height: relativeTileSize.height), in: tileSheetTexture) let tileDefinition = SKTileDefinition(texture: tileTexture, size: tileSize) let tileGroup = SKTileGroup(tileDefinition: tileDefinition) tileGroups.append(tileGroup) } } let tileSet = SKTileSet(tileGroups: tileGroups) return tileSet } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { presentSceneAgain() } func presentSceneAgain() { if let frame = view?.frame { view?.presentScene(GameScene(size: frame.size), transition: .doorsCloseHorizontal(withDuration: 1.0)) } } } This demo project create a tilemapnode of 100 X 100 tiles. Then, it fills these 10.000 tiles with a random tile from the tilesheet named "terrain.png". This tile sheet contains many tiles, but I only take the 9 tiles (3 X 3) from the lower left corner as a random tile option. Thus, the 10.000 tiles get filled with one of these 9 tiles. So it doesnt look pretty or anything, but that isnt the purpose. Now, to create these 9 tile textures, I use the SKTexture(rectIn:) method on the source texture being "terrain.png". I think the code is quite clear in itself, but so far the explanation. When you run it, you should see the map being rendered. When you tap the scene, the scene will present a new instance of the scene. Not more than that. Now, when you do this, have a look at the RAM usage of the app. You will see it steadily increases over time, each time you click the scene and a new scene is presented. I looked deeper into what is happening, and what I see in the memory graph, is that for every present of the scene that is done, there are 3 SKTexture instances being created that are never released. The first time the scene is rendered, there 11 SKTexture instances allocated (I dont know why there are 11 though. I would expect 10: the source texture and the 9 tile textures). But then as mentioned, after a tap and a new present, I get 14 SKTexture, of which 3 are zombies, see image leak_1. Moreover, Xcode reports multiple additional leaks from Jet and Metal allocations, see image leak_all. As far as I know, the code presented is not retaining any references that it should not, and I suspect this leaks are happening somewhere inside SpriteKit. But I am not able to find exactly where, or how to resolve it. I hope someone can help with this issue.
2
1
198
3w
SKNode.zPosition causes nodes to flicker by reordering them for 1 frame
When running the sample code below, every 3 seconds the middle sprite is replaced by a new one. When this happens, most of the time a flicker is noticeable. When recording the screen and stepping through the recording frame by frame, I noticed that the flicker is caused by a temporary reordering of the nodes’. Below you find two screenshots of two consecutive frames where the reordering is clearly visible. This only happens for a SpriteKit scene used as an overlay for a SceneKit scene. Commenting out buttons.zPosition = 1 or avoiding the fade in/out animations solves the issue. I have created FB15945016. import SceneKit import SpriteKit class GameViewController: NSViewController { let overlay = SKScene() var buttons: SKNode! var previousButton: SKSpriteNode! var nextButton: SKSpriteNode! var pageContainer: SKNode! var pageViews = [SKNode]() var page = 0 override func viewDidLoad() { super.viewDidLoad() let scene = SCNScene(named: "art.scnassets/ship.scn")! let scnView = self.view as! SCNView scnView.scene = scene overlay.anchorPoint = CGPoint(x: 0.5, y: 0.5) scnView.overlaySKScene = overlay buttons = SKNode() buttons.zPosition = 1 overlay.addChild(buttons) previousButton = SKSpriteNode(systemImage: "arrow.uturn.backward.circle") previousButton.position = CGPoint(x: -100, y: 0) buttons.addChild(previousButton) nextButton = SKSpriteNode(systemImage: "arrow.uturn.forward.circle") nextButton.position = CGPoint(x: 100, y: 0) buttons.addChild(nextButton) pageContainer = SKNode() pageViews = [SKSpriteNode(systemImage: "square.and.arrow.up"), SKSpriteNode(systemImage: "eraser")] overlay.addChild(pageContainer) setPage(0) Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { [self] _ in setPage((page + 1) % 2) } } func setPage(_ page: Int) { pageViews[self.page].run(.sequence([ .fadeOut(withDuration: 0.2), .removeFromParent() ]), withKey: "fade") self.page = page let pageView = pageViews[page] pageView.alpha = 0 pageView.run(.fadeIn(withDuration: 0.2), withKey: "fade") pageContainer.addChild(pageView) } override func viewDidLayout() { overlay.size = view.frame.size } } extension SKSpriteNode { public convenience init(systemImage: String) { self.init() let width = 100.0 let image = NSImage(systemSymbolName: systemImage, accessibilityDescription: nil)!.withSymbolConfiguration(.init(hierarchicalColor: NSColor.black))! let scale = NSScreen.main!.backingScaleFactor image.size = CGSize(width: width * scale, height: width / image.size.width * image.size.height * scale) texture = SKTexture(image: image) size = CGSize(width: width, height: width / image.size.width * image.size.height) } }
1
0
231
4w
SCNNode into SKScene is deformed when hit an object
Into a SKScene, I add a SCNSphere as a child of SKShapeNode, as depicted below. When the sphere hit another node (the fence in the example) the sphere is deformed as it were elastic. I didn't found any information about elastic properties. Someone know a way to avoid the deformation? import SwiftUI import SpriteKit import SceneKit @main struct MyApp: App { var body: some Scene { WindowGroup {SpriteView(scene: GameSceneSK(size: UIScreen.main.bounds.size))} } } class GameSceneSK: SKScene { override func sceneDidLoad() { var fencePoints = [ CGPoint(x: 300, y: 0), CGPoint(x: 300, y: 400), CGPoint(x: 0, y: 400) ] let fence = SKShapeNode(points: &fencePoints, count: fencePoints.count) fence.physicsBody = SKPhysicsBody(edgeChainFrom: fence.path!) addChild(fence) let sphereGeometry = SCNSphere(radius: 20) let sphereNode = SCNNode(geometry: sphereGeometry) let sphereScnScene = SCNScene() sphereScnScene.rootNode.addChildNode(sphereNode) let ball3D = SK3DNode(viewportSize: CGSize(width: 40, height: 40)) ball3D.scnScene = sphereScnScene let ball = SKShapeNode(circleOfRadius: 20) ball.physicsBody = SKPhysicsBody(circleOfRadius: 20) ball.addChild(ball3D) physicsWorld.gravity = CGVector(dx: 0.2, dy: 0.2) addChild(ball) } }
2
0
286
Nov ’24
How do I stop a node as it is moving around a UIBezierPath and then restart the moving from where it stopped?
I have an oval UIBezierPath with a moving SKSpriteNode, I stop its motion and record the stopped position. I then restart this motion and want it to restart where it initially stopped. Works great if motion is not stopped. Movement is great around entire oval Path. Also works great as long as this stop-restart sequence occurs along the top half of the oval UIBezierPath. However, I have problems along the bottom half of this Path -- it stops okay, but the restart position is not where it previously stopped. My method to create this oval UIBezierePath is as follows: func createTrainPath() { trainRect = CGRect(x: tracksPosX - tracksWidth/2, y: tracksPosY - tracksHeight/2, width: tracksWidth, height: tracksHeight) // these methods come from @DonMag trainPoints = generatePoints(inRect: trainRect, withNumberOfPoints: nbrPathPoints) trainPath = generatePathFromPoints(trainPoints!, startingAtIDX: savedTrainIndex) } // createTrainPath My method to stop this motion is as follows: func stopFollowTrainPath() { guard (myTrain != nil) else { return } myTrain.isPaused = true savedTrainPosition = myTrain.position // also from @DonMag savedTrainIndex = closestIndexInPath( trainPath, toPoint: savedTrainPosition) ?? 0 } // stopFollowTrainPath Finally, I call this to re-start this motion: func startFollowTrainPath() { var trainAction = SKAction.follow(trainPath.cgPath, asOffset: false, orientToPath: true, speed: thisSpeed) trainAction = SKAction.repeatForever(trainAction) myTrain.run(trainAction, withKey: runTrainKey) myTrain.isPaused = false } // startFollowTrainPath Again, great if motion is not stopped. Movement is great around entire oval Path. Again, no problem for stopping and then restarting along top half of oval .. the ohoh occurs along bottom half. Is there something I need to do within GameScene's update method that I am missing? For example, do I need to reconstruct my UIBezierPath? every time my node moves between the top half and the bottom half and therein account for the fact that the node is traveling in the opposite direction from the top half?
2
0
362
Nov ’24
Does the SpriteView of an SKScene have layers? Unable to get magnifying glass view to work with scene.
I'm trying to make a magnifying glass that shows up when the user presses a button and follows the user's finger as it's dragged across the screen. I came across a UIKit-based solution (https://github.com/niczyja/MagnifyingGlass-Swift), but when implemented in my SKScene, only the crosshairs are shown. Through experimentation I've found that magnifiedView?.layer.render(in: context) in: public override func draw(_ rect: CGRect) { guard let context = UIGraphicsGetCurrentContext() else { return } context.translateBy(x: radius, y: radius) context.scaleBy(x: scale, y: scale) context.translateBy(x: -magnifiedPoint.x, y: -magnifiedPoint.y) removeFromSuperview() magnifiedView?.layer.render(in: context) magnifiedView?.addSubview(self) } can be removed without altering the situation, suggesting that line is not working as it should. But this is where I hit a brick wall. The view below is shown but not offset or magnified, and any attempt to add something to context results in a black magnifying glass. Does anyone know why this is? I don't think it's an issue with the code, so I'm suspecting its something specific to SpriteKit or SKScene, likely related to how CALayers work. Any pointers would be greatly appreciated. . . . Full code below: import UIKit public class MagnifyingGlassView: UIView { public weak var magnifiedView: UIView? = nil { didSet { removeFromSuperview() magnifiedView?.addSubview(self) } } public var magnifiedPoint: CGPoint = .zero { didSet { center = .init(x: magnifiedPoint.x + offset.x, y: magnifiedPoint.y + offset.y) } } public var offset: CGPoint = .zero public var radius: CGFloat = 50 { didSet { frame = .init(origin: frame.origin, size: .init(width: radius * 2, height: radius * 2)) layer.cornerRadius = radius crosshair.path = crosshairPath(for: radius) } } public var scale: CGFloat = 2 public var borderColor: UIColor = .lightGray { didSet { layer.borderColor = borderColor.cgColor } } public var borderWidth: CGFloat = 3 { didSet { layer.borderWidth = borderWidth } } public var showsCrosshair = true { didSet { crosshair.isHidden = !showsCrosshair } } public var crosshairColor: UIColor = .lightGray { didSet { crosshair.strokeColor = crosshairColor.cgColor } } public var crosshairWidth: CGFloat = 5 { didSet { crosshair.lineWidth = crosshairWidth } } private let crosshair: CAShapeLayer = CAShapeLayer() public convenience init(offset: CGPoint = .zero, radius: CGFloat = 50, scale: CGFloat = 2, borderColor: UIColor = .lightGray, borderWidth: CGFloat = 3, showsCrosshair: Bool = true, crosshairColor: UIColor = .lightGray, crosshairWidth: CGFloat = 0.5) { self.init(frame: .zero) layer.masksToBounds = true layer.addSublayer(crosshair) defer { self.offset = offset self.radius = radius self.scale = scale self.borderColor = borderColor self.borderWidth = borderWidth self.showsCrosshair = showsCrosshair self.crosshairColor = crosshairColor self.crosshairWidth = crosshairWidth } } public func magnify(at point: CGPoint) { guard magnifiedView != nil else { return } magnifiedPoint = point layer.setNeedsDisplay() } private func crosshairPath(for radius: CGFloat) -> CGPath { let path = CGMutablePath() path.move(to: .init(x: radius, y: 0)) path.addLine(to: .init(x: radius, y: bounds.height)) path.move(to: .init(x: 0, y: radius)) path.addLine(to: .init(x: bounds.width, y: radius)) return path } public override func draw(_ rect: CGRect) { guard let context = UIGraphicsGetCurrentContext() else { return } context.translateBy(x: radius, y: radius) context.scaleBy(x: scale, y: scale) context.translateBy(x: -magnifiedPoint.x, y: -magnifiedPoint.y) removeFromSuperview() magnifiedView?.layer.render(in: context) //If above disabled, no change //Possible that nothing's being rendered into context //Could it be that SKScene view has no layer? magnifiedView?.addSubview(self) } }
0
0
266
Nov ’24
SKLabelNode keeps jumping back and forth when displaying different numbers with equal number of digits
I'm trying to display a right-aligned timecode in my game. I had expected that digits would all have the same width, but this doesn't seem to be the case in SpriteKit, even though it seems to be the case in AppKit. In SpriteKit, with the default font there is a noticeable difference in width between the digit 1 and the rest (1 is thinner), so whenever displaying a number with the least significant digit 1 all preceding digits shift slightly to the right. This happens even when setting a NSAttributedString with a font that has a fixedAdvance attribute. class GameScene: SKScene { override func didMove(to view: SKView) { let label = SKLabelNode(text: "") view.scene!.addChild(label) // label.horizontalAlignmentMode = .left label.horizontalAlignmentMode = .right var i = 11 Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { _ in label.text = "\(i)" // let font = NSFont(descriptor: NSFontDescriptor(fontAttributes: [.name: "HelveticaNeue-UltraLight", .fixedAdvance: 20]), size: 30)! // let paragraphStyle = NSMutableParagraphStyle() // paragraphStyle.alignment = .right // label.attributedText = NSAttributedString(string: "\(i)", attributes: [.font: font, .foregroundColor: SKColor.labelColor, .paragraphStyle: paragraphStyle]) i += 5 } } } With AppKit, when using SpriteKit's default font HelveticaNeue-UltraLight, this issue doesn't exist, regardless whether I set the fixedAdvance font attribute. class ViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() let font = NSFont(descriptor: NSFontDescriptor(fontAttributes: [.name: "HelveticaNeue-UltraLight"]), size: 30)! // let font = NSFont(descriptor: NSFontDescriptor(fontAttributes: [.name: "HelveticaNeue-Light", .fixedAdvance: 20]), size: 30)! let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.alignment = .right let textField = NSTextField(labelWithString: "") textField.font = font textField.alignment = .right // textField.alignment = .left textField.frame = CGRect(x: 100, y: 100, width: 100, height: 100) view.addSubview(textField) var i = 11 Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { _ in textField.stringValue = "\(i)" // textField.attributedStringValue = NSAttributedString(string: "\(i)", attributes: [.font: font, .paragraphStyle: paragraphStyle]) i += 5 } } } Is there a solution to this problem? I filed FB15553700.
0
0
240
Oct ’24
Shrink the world game
This game is where you can play over 100 games and every game is very different and unique and you can save your favorite game over the 100 in store them and you can store over 100 if you like them all make your wildest dreams that you can search up as games and they could have them Youtubers, you can make good videos with this game, the Creator. :D Hope you enjoy it also I’m a kid so I don’t know how to make an update.
1
0
320
Oct ’24
Using Swift, how do I resize individual SKSpriteNodes for various iPad device sizes?
Using Swift, how do I resize individual SKSpriteNodes for various iPad device sizes? Currently, I use theScene.scaleMode = .resizeFill for scaling the entire SKScene and it works as advertised. Please note that .aspectFill does not solve the challenge described below. My challenge is to resize individual SKSpriteNodes (that are components of the overall SKScene) based on size of the iOS device; for example, iPad Mini <--> iPad Pro Right now, I hard code the sizes of these Nodes. But I realize this is not the optimum approach. Again, hard coding is frowned upon. So I am looking for a more dynamic method that functions based on device size.
0
0
227
Oct ’24
Not getting scroll wheel input
Hi all, I'm new to swift and I've just gotten started by making a simple pong-like game using SpriteKit. I'm trying to use the scroll wheel input to spin an object, however, nothing seems to make this work. From my googling and AI advice the way I've been doing it should, as shown in the snippet below, however debugging suggests the scrollWheel function isn't even being called. #if os(OSX) extension GameScene { override func scrollWheel(with event: NSEvent ) { print("Scroll detected: \(event.scrollingDeltaY)") let scrollDelta = event.scrollingDeltaY self.rotatePaddle(value: scrollDelta) } } #endif I have changed the build targets in Xcode to Mac os, not the designed-for-ipad version of it, and the app does launch and draw sprites correctly as well as detect other mouse or trackpad inputs like mouseDown and rightMouseDown, so it only seems to be this one specific input not working. I've also tried hardware debugging like restarting Xcode and my Mac, but no luck there either. Maybe I've missed something or am doing it completely wrong, so any help would be much appreciated. Thanks heaps
1
0
374
Oct ’24
What triggers Game Mode?
What are the specific characteristics that trigger Game Mode in an iOS game? I have several casual SpriteKit games in the App Store but only one of them triggers Game Mode. What does GCSupportsGameMode do when set to true? Will it trigger Game Mode or will the OS still decide by itself?
2
0
688
Sep ’24
SKTexture initialized with system UIImage has slightly wrong aspect ratio and ignores system symbol color
On macOS, system symbols displays in a SKTexture as expected, with the correct color and aspect ratio. But on iOS they are always displayed in black, and sometimes with slightly wrong aspect ratio. Is there a solution to this problem? import SpriteKit #if os(macOS) import AppKit #else import UIKit #endif class GameScene: SKScene { override func didMove(to view: SKView) { let systemImage = "square.and.arrow.up" let width = 400.0 #if os(macOS) let image = NSImage(systemSymbolName: systemImage, accessibilityDescription: nil)!.withSymbolConfiguration(.init(hierarchicalColor: .white))! let scale = NSScreen.main!.backingScaleFactor image.size = CGSize(width: width * scale, height: width / image.size.width * image.size.height * scale) #else let image = UIImage(systemName: systemImage)!.applyingSymbolConfiguration(.init(pointSize: width))!.applyingSymbolConfiguration(.init(hierarchicalColor: .white))! #endif let texture = SKTexture(image: image) print(image.size, texture.size(), image.size.width / image.size.height) let size = CGSize(width: width, height: width / image.size.width * image.size.height) addChild(SKSpriteNode(texture: texture, size: size)) } }
8
0
643
Sep ’24
Best way to navigate multiple game screens
Good morning everyone, I'm building a simple game (my first game) using SwiftUI and SpriteKit that contains multiple views. I'm writing my game based on a main scene loaded into the GameView using a SpriteView. From there, using buttons, I move from one scene to another using self.scene?.view?.presentScene(...) and also with some cool transitions (.crossFade(withDuration: 0.5))). But I'm not sure if this is the best approach. I would need some guidance because I cannot find any material discussing the best way to create a proper navigation with SpriteKit. Do you have an updated article, tutorial, or reference that I can follow to learn about the best way to implement navigation in a SpriteKit game? What I'm doing right now is working, but I have limitations, for example, if I want to mix SwiftUI views and SpriteKit scenes. I want to add a Credits scene with some text and images that I want to do in SwiftUI and a Statistic scene with some cool graphics to show the players, but I don't know if I can navigate from an SKScene into a View, or if I need a completely different approach. Can I add UI components directly in a SpriteKit scene instead of using a different navigation system and full SwiftUI views? I really appreciate any help you can provide. As you can see, I'm a little bit lost 😅 Thanks a lot in advance 🙏
0
1
410
Aug ’24
How do I set the *static* position of a `SKSpriteNode` so that it tilts toward the `UIBezierPath` as if it were following this Path?
How do I set the static position of a SKSpriteNode so that it tilts toward the UIBezierPath as if it were following this Path? When I first start my App, these Nodes are all aligned in a straight line When I call: var trainAction = SKAction.follow(trainPath.cgPath, asOffset: false, orientToPath: true, speed: thisSpeed) for moving the train, the train + each car will orient its tilt to hug the trainPath. But I want the identical tilt to hug the trainPath for its initial static presentation. How do I do that?
0
0
492
Aug ’24
SpriteKit PPI
Hi, I’m looking for a way to keep some custom buttons in SpriteKit the same physical size (inches) accross iOS devices (or only slightly vary their size so they’re not humongous on large screens). How do I get PPI in Swift? (cannot be library code which doesn’t compile in Swift Playgrounds). I will use PPI for determining total screen size which I will use to determine how to adjust the button sizes while also respecting some physical desirable dimensions for the buttons. I'm only asking for handheld (same distance from eyes to screen) use, so I don't care about Apple TV (longer distance).
2
0
750
Jul ’24
Calling SKAction.follow(..) causes my SKSpriteNode to rotate 90 degrees CW and not stay horizontal as it follows my UIBezierPath?
Calling SKAction.follow(..) causes my SKSpriteNode to rotate 90 degrees CW and not stay horizontal as it follows my UIBezierPath? I have this code (within my GameViewController Class) which implements the following of a SKSpriteNode along a UIBezierPath. ===== Please note that a brilliant contributor solved the above challenge by creating a new Class, e.g., class NewClass: NSObject. Nevertheless, I need the solution to appear in an extension of my GameViewController ===== func createTrainPath() { trackRect = CGRect(x: tracksPosX - tracksWidth/2, y: tracksPosY, width: tracksWidth, height: tracksHeight) trainPath = UIBezierPath(ovalIn: trackRect) } // createTrainPath func startFollowTrainPath() { var trainAction = SKAction.follow( trainPath.cgPath, asOffset: false, orientToPath: true, speed: theSpeed) trainAction = SKAction.repeatForever(trainAction) myTrain.run(trainAction, withKey: runTrainKey) } // startFollowTrainPath func stopFollowTrainPath() { guard myTrain == nil else { myTrain.removeAction(forKey: runTrainKey) savedTrainPosition = getPositionFor(myTrain, orPath: trainPath) return } } // stopFollowTrainPath
2
0
925
May ’24
Orientation of UIImage image is not reflected in SKTexture
I'm trying to add an image in UIImage format to SpritKit's SKSpriteNode. When converting a UIImage into a texture to SKTexture and adding it to SKSpriteNode, the image that takes into account the orientation of the image held by the UIImage is not displayed on the screen. I tried the code below, but the result is identical. Code1: let image: UIImage? let texture: SKTexture = SKTexture(image: image!) ver imageNode = SKSpriteNode(texture: texture) Code2: let image: UIImage? let cgImage = image?.cgImage let ciImage = CIImage(cgImage: cgImage!) let orientedImage = UIImage(cgImage: CIContext(options: nil).createCGImage(ciImage, from: ciImage.extent)!, scale: 0, orientation: image!.imageOrientation) let texture: SKTexture = SKTexture(image: orientedImage) ver imageNode = SKSpriteNode(texture: texture) Code3: let image: UIImage? guard let cgImage = image?.cgImage else { return } let orientedImage = UIImage(cgImage: cgImage, scale: image!.scale, orientation: .up) let texture = SKTexture(image: orientedImage) ver imageNode = SKSpriteNode(texture: texture) Is there a way to ensure that the image orientation is taken into account when displayed?
1
0
762
Apr ’24
How to spawn in particles that don't move
I am trying to make an application for the Vision Pro where the particles don't move but rather stay still so that there is no lag. For example I am trying to spawn in a 100 particles here: I want the particles to remain static but spawning in many causes the simulator to lag. Also is there maybe a way i can get a particle system to follow a specific shape like the one i have in the image. Currently, I have multiple model entities that take on a particle system component for i in 0..<100 { let newEntity = ModelEntity() var particleSystem = particleSystem(color: newColor) newEntity.components.set(particleSystem) newEntity.position = position newEntity.scale = scale stars.append(newEntity) } } func particleSystem(color: UIColor) -> ParticleEmitterComponent { var particles = ParticleEmitterComponent() particles.emitterShapeSize = .init(repeating: 0.02) // make burst smaller particles.emitterShape = .sphere particles.mainEmitter.birthRate = 1 particles.mainEmitter.lifeSpan = 2 particles.mainEmitter.size = 0.02 particles.burstCount = 50 particles.speed = 0.01 particles.mainEmitter.isLightingEnabled = false particles.mainEmitter.color = .constant(.single(color)) return particles }
0
0
783
Mar ’24