Excellent, that solved my texture issues with previous attempts thanks!
 
Complete code for test setup is now below and i can just replace as needed with single phaser texture/image.
Since you are so responsive, maybe you could also hint to if its possible for me to create my SpineGameObject without having an Atlas on first creation? So that i could just provide or apply individual attachments for each of the slots defined in the Skeleton without loading initial atlas?
 
import { SERVER_URL } from "@/data/constants";
import { TINY_GAME } from "@/data/games";
import { Game, Types } from "phaser";
import React, { useEffect, useRef } from "react";
import { GLTexture, RegionAttachment, SpineGameObject, SpinePlugin, TextureRegion } from "@esotericsoftware/spine-phaser";
type Props = {
	children?: React.ReactNode;
};
export function TinyGameScene({ children }: Props) {
	const loaded = useRef(false);
	const [currentGun, setCurrentGun] = React.useState(1);
	const gameRef = useRef<Game | null>(null);
	const sceneRef = useRef<Phaser.Scene | null>(null);
	const spineObjectRef = useRef<SpineGameObject | null>(null);
	const swapGun = () => {
		const spineGameObject = spineObjectRef.current;
		const scene = sceneRef.current;
		const spinePlugin = scene?.spine;
		if (!spineGameObject || !scene || !spinePlugin || !spinePlugin.webGLRenderer?.context) {
			console.error("Spine object, scene or plugin is not available or misconfigured");
			return;
		}
		const slot = spineGameObject.skeleton.findSlot("gun");
		if (!slot || !slot.attachment) {
			console.error("Slot 'gun' not found");
			return;
		}
		const newExternalGun = `external-gun${currentGun}`;
		setCurrentGun((prev) => (prev === 1 ? 0 : 1));
		const phaserTexture = scene.textures.get(newExternalGun).getSourceImage();
		const spineTexture = new GLTexture(spinePlugin.webGLRenderer?.context, phaserTexture as HTMLImageElement | ImageBitmap);
		const region = new TextureRegion();
		region.u2 = region.v2 = 1;
		region.width = region.originalWidth = phaserTexture.width;
		region.height = region.originalHeight = phaserTexture.height;
		region.texture = spineTexture;
		const newAttachment: RegionAttachment = slot.attachment.copy() as RegionAttachment;
		newAttachment.region = region;
		newAttachment.updateRegion();
		slot.setAttachment(newAttachment);
	};
	const addCharacter = () => {
		const sceneObject = sceneRef.current;
		if (!sceneObject) {
			console.error("Scene is not available");
			return;
		}
		const spineObject = sceneObject.make.spine({
			x: 200,
			y: 500,
			scale: 0.5,
			dataKey: "spineCharacter",
			atlasKey: "spineAtlas",
		});
		spineObject.setInteractive();
		spineObjectRef.current = spineObject;
		spineObject.on("pointerdown", (pointer: SpineGameObject) => {
			spineObject.animationState.setAnimation(0, "jump", false);
		});
		spineObject.animationState.addListener({
			complete: (entry) => {
				if (entry.animation?.name === "jump") {
					spineObject.animationState.setAnimation(0, "walk", true);
				}
			},
		});
		spineObject.animationState.setAnimation(0, "walk", true);
		sceneObject.add.existing(spineObject);
	};
	useEffect(() => {
		if (loaded.current) {
			return;
		}
		loaded.current = true;
		function preload(this: Phaser.Scene) {
			if (this.load.spineJson) {
				this.load.spineJson("spineCharacter", `${SERVER_URL}/tiny/character/spineboy-ess.json`);
				this.load.spineAtlas("spineAtlas", `${SERVER_URL}/tiny/character/spineboy-split.atlas`, false);
				this.load.image("external-gun0", `${SERVER_URL}/tiny/character/external-gun0.png`);
				this.load.image("external-gun1", `${SERVER_URL}/tiny/character/external-gun1.png`);
			} else {
				console.error("Spine plugin not available");
			}
		}
		function create(this: Phaser.Scene) {
			sceneRef.current = this;
			addCharacter();
		}
		function update(this: Phaser.Scene) {}
		const config: Types.Core.GameConfig = {
			type: Phaser.AUTO,
			parent: "gamecanvas",
			backgroundColor: TINY_GAME.colours.bright,
			width: "100%",
			antialias: true,
			height: "100%",
			scene: {
				preload,
				create,
				update,
			},
			plugins: {
				scene: [
					{
						key: "SpinePlugin",
						plugin: SpinePlugin,
						mapping: "spine",
					},
				],
			},
		};
		gameRef.current = new Game(config);
		return () => {
			if (gameRef.current) {
				gameRef.current.destroy(true);
				gameRef.current = null;
			}
		};
	}, []);
	return (
		<div className="relative w-full h-full" id="gamecanvas">
			<div className="absolute flex flex-row ">
				<div
					className="px-5 mt-10 cursor-pointer"
					onClick={() => {
						addCharacter();
					}}
				>
					Add character
				</div>
				<div
					className="px-5 mt-10 cursor-pointer"
					onClick={() => {
						swapGun();
					}}
				>
					Test swap
				</div>
			</div>
		</div>
	);
}