Create SKSpriteNode with an Asset Programmatically - swift

I'm attempting to programmatically create an SKSpriteNode and give it a texture that is in my Assets.xcassets folder. I figured this would be a basic procedure, but I seem to be having a lot of troubles.
For a reference, here is my asset catalog with the ground asset I'm trying to set to a SKSpriteNode:
Here's the code to make the sprite node:
sprite.texture = SKTexture(image: UIImage(named: spriteName)!)
sprite.anchorPoint = CGPoint(x: 0, y: 1)
sprite.position = CGPoint(x: 0, y: 0)
referenceNode.addChild(sprite)
The variable "spriteName" in the first line is having the String "ground" passed into it. However, when I load the game, the ground is missing. Just to make sure the nodes were actually there, I commented out the texture code and just gave them size and a visible color. This worked out so I know the problem is definitely in the asset reference, not in the code logic.
Any point in the right direction would be greatly appreciated. If more information is needed, please do ask as specifically as possible :)
Thanks,
Matthew
EDIT:
My original question may have been a bit too complicated. To rephrase in simpler terms:
I have an asset in my asset library called ground. However, when I set the texture of a SKSpriteNode using this code...
sprite.texture = SKTexture(image: UIImage(named: "ground")!)
the texture doesn't show up in app. My question: how do I properly reference the image in my asset library?

It seems like you need to explicitly set the size too:
sprite.texture = SKTexture(imageNamed: "myImage1")
sprite.size = sprite.texture!.size()
..or you can specify the image in init:
let sprite = SKSpriteNode(imageNamed: "myImage1")

Related

How to use SpriteKit Particle File in a project developed with SceneKit?

I'm making a simple ARKit App with SceneKit and need to add some particle effect. Usually I could create a SceneKit Particle File, design some particle effect and use it like this
let smoke = SCNParticleSystem(named: "xxx.scnp", inDirectory: nil)!
let hole = SCNNode()
hole.addParticleSystem(smoke)
But since Xcode12, I can only create a SpritKit Particle File whose suffix is .sks. The code above could not work anymore with this file. I am a newbie in ARKit. May anyone tell me how to integrate the particle effect into my SceneKit project? Thanks a lot.
SpriteKit particles implementation
If you wanna use 2D particles in 3D scene, there are two regular ways to show SpriteKit scenes in SceneKit. The first way is to assign SKScene as material for SceneKit's geometry:
// 2D scene
let skScene = SKScene()
guard let emitter = SKEmitterNode(fileNamed: "sparks.sks")
else { return }
emitter.position = CGPoint(x: 10, y: 25)
emitter.targetNode = skScene
skScene.addChild(emitter)
// 3D scene
let plane = SCNPlane(width: 5, height: 5)
plane.materials.first?.diffuse.contents = skScene
let planeNode = SCNNode(geometry: plane)
sceneView.scene.rootNode.addChildNode(planeNode)
The second way – assign SKScene to virtual surrounding environment of SceneKit.
sceneView.scene.lightingEnvironment.contents = skScene
SceneKit particles implementation
The regular way for working with particles in SceneKit is its native particle system:
let particleSystem = SCNParticleSystem()
particleSystem.birthRate = 50
particleSystem.particleSize = 0.5
particleSystem.particleLifeSpan = 10
particleSystem.particleColor = .green
let particlesNode = SCNNode()
particlesNode.addParticleSystem(particleSystem)
sceneView.scene.rootNode.addChildNode(particlesNode)
P. S.
About deprecated preconfigured SCNP file and its replacement read HERE.
If you want to setup such phenomenon as 3D fire, the best way to do it – do it in Scene graph. For better result use 2 or 3 particle system objects with different parameters.
For better understanding how to setup 3D fire based on png samples (sources) open Apple Motion 5 app scene and click on Inspector button.
Then, try to implement a fire with the same look in SceneKit's Scene graph.
For some unknown reason Apple removed the SCNP (SceneKit particle file) template from the recent XCode editions.
You have the following options:
Download any sample code project from Apple or GitHub that contains one or more .scnp files. Grab the file from there and implement it into your AR-Project. You can still edit the file within XCode as usual. (Particle Systems Editor)
Create your particle system entirely in code.
like so:
let myParticleSystem = SCNParticleSystem()
then you configure everything you want within the instance: myParticleSystem

Change Texture In Scene Editor Programmatically

I've added a color sprite, named "arm" to my Scene Editor but for a bunch of reasons I need to access that color sprite and change the texture programmatically. Another way of stating my goal, I want to link the node to my GameScene swift file and change texture using a texture from an array. Does anyone know how to do this?
First things first, you want to link the sprite node from your GameScene.sks file to your GameScene.swift file.
To do this, in GameScene.swift near the top (under the "class GameScene: SKScene {") use this:
var armNode: SKSpriteNode?
In your didMove(to view:) section do this:
armNode = childNode(withName: "arm") as? SKSpriteNode
Now 3 different ways to change the color/texture of the SKSpriteNode depending on what you are doing:
armNode.colour = UIColor.red
armNode.texture = SKTexture(imageNamed: "your arm image here")
armNode.texture = textureArray[2]
The 3rd version uses a texture from an array of textures

SceneKit shader modifiers

I'm writing a 3D space game using SceneKit and I'm pretty happy with it so far, but I'm starting to hit some limitations and would like some advice.
I have a sphere which represents a star that sits on a point light, and I'd like to add some effects to this to make it look more realistic. I think I should use the sphere's shaderModifiers to do this, but I'm not sure which modifiers I should be looking at i.e. to achieve a lens flare effect. Infact if anyone can give me a clear explanation of the differences between: ShaderModifiers, SCNProgram and SCNTechnique that would be great!
I'd like to draw a 1px circle to represent an orbit. I've tried using a cylinder that is really thin, but this results in some visual artefacts (the ring seems to have gaps at larger distances and break up). Any ideas how I can do this and maintain a nice smooth circle?
The shortest way to have a flare effect for SceneKit models is to use a CoreImage framework's capabilities.
For making a visible orbit use a regular PNG-image technique with premultiplied alpha channel (RGBxA). Look at this link to find out how a png image with orbits looks like (save a file). And if you wanna automatically orient a plane toward a camera use a constraint.
And here's a code:
let orbitsOnPlane = SCNPlane(width: 10, height: 10)
let material = SCNMaterial()
material.diffuse.contents = UIImage(named:"overlayOrbits.png")
orbitsOnPlane.materials = [material]
let orbitNode = SCNNode()
orbitNode.geometry = orbitsOnPlane
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
let constraint = SCNLookAtConstraint(target: orbitNode)
cameraNode.constraints = [constraint]

How to add an image to an ARSCNScene in Swift?

I stumbled upon a roadblock with the development of a Swift playground I'm developing. I want to add an image to my ARSCNScene (ARKit + SceneKit). Not as a background, but as an actual node with positions and all. Does anyone know whether this is possible? I couldn't find anything online. Thanks!
You can easily add UIImage as diffuse material to your SCNPlane. Example:
let image = UIImage(named: "yourImageName")
let node = SCNNode(geometry: SCNPlane(width: 1, height: 1))
node.geometry?.firstMaterial?.diffuse.contents = image
Further, you can modify your node as you like. I hope it helped!
I think I found a solution too for this problem since im having the same issue
Write:
node.geometry?.firstmaterial?.diffuse.contents = #imageLiteral(resourceName: “yourimagename”)
Note that you have to add the image inside the assets first (as an image set of course)

SKPhysicsBody uses only part of SKTexture

I'm using an SKTexture with an image and set the SKPhysicsBody. Like that:
var moleTexture = SKTexture(imageNamed: "moleTop1")
leftPlayer = SKSpriteNode(texture: moleTexture)
leftPlayer.physicsBody = SKPhysicsBody(texture: moleTexture, size: leftPlayer.texture!.size())
Now after I start my game, I noticed that the physicsBody is set wrong. I've activated the showPhysics property and my image looks like that:
As you see, the only thing which is used by SKPhysicsBody is the little part on the middle left(blue border).
How can I change that so that the whole image will be used?
That looks interesting. I believe it will only create an outline (or one shape) and it appears to be starting from the left and because there are no other pixels near enough it calls it done.
I wonder if you get a different result if those pixels are touching. I would try and validate that first. If that is the case you may have to change the texture or use a different variation of the texture for the physical body.
I hope that helps =)