👥
【visionOS】Entityを量産する
はじめに
前回は【Swift】visionOSで鬼をカメラの方向へ動かすで鬼をシーンに生成して動かしてみました。
今回は、作成した鬼を量産したいと思います。そこで、またSystemを使ってupdate
関数の中で量産しようと試みました。
しかし、Entity.load()
をするだけだと思ったら生成時にフリーズしてスムーズに量産することができませんでした。
つくったもの
環境
- Xcode Version 15.3
- visionOS 1.1
Entityを複製する
やり方は非常に簡単です。
初期状態はテンプレートとしてEntity.load()
から生成しておき、複製するときはEntity.clone()
[1]することでフリーズせずに量産することができます。
private var oniTemplate: Entity? = nil
func generateOni() -> Entity? {
// テンプレートがないときは作成
if oniTemplate == nil {
if let oni = try? Entity.load(named: "oni") {
oniTemplate = oni
}
}
guard let oniTemplate = oniTemplate else {
fatalError("Oni template is nil.")
}
// テンプレートからクローン生成する
let oni = oniTemplate.clone(recursive: true)
return oni
}
Entityの生成位置を指定
今回は、プレイヤーを中心に鬼を生成したかったのでカメラの距離と方角を計算してランダムに出現するようにしました。
func spawnEnemy(scene: RealityKit.Scene, enemy: Entity?) {
// カメラを取得
guard let device = scene.findEntity(named: "Device") else { return }
let deviceTransform = device.transform
// カメラとentityの高さを合わせる
let devicePosition = SIMD3(deviceTransform.translation.x, 1.5, deviceTransform.translation.z)
if let enemy = enemy {
// カメラを中心に360度ランダムな位置にエネミーを配置
let distance: Float = -5.0 // カメラからの距離
let angle = Float.random(in: 0...360) * (Float.pi / 180) // ランダムな角度(ラジアン)
let x = cos(angle) * distance
let z = sin(angle) * distance
enemy.position = SIMD3<Float>(x, -1.5, z) + devicePosition
contentEntity.addChild(enemy)
}
}
Entityを量産する
最後にSystemを継承したクラスを作り、update関数で先程の2つの関数を呼び出します。
// 次の敵の出現までの時間を管理
private var framesUntilNextSpawn = 0
func update(context: SceneUpdateContext) {
if framesUntilNextSpawn <= 0 {
let newEnemy = generateOni()
spawnEnemy(scene: context.scene, enemy: newEnemy)
// 次の敵の出現までの時間を5から10秒の間ランダムに設定
framesUntilNextSpawn = Int.random(in: 180...300)
} else {
framesUntilNextSpawn -= 1 // 1フレームごとに減少させる
}
}
おわりに
以上、「Entityを量産する」でした。
フリーズしたときはどうしようか悩みましたが、上記の方法が公式サンプルのHappyBeamにあったので解決することができました。
そして、今回の記事で紹介している空間シューティングゲーム「妖怪バスターZ」を日本発売前の2024年5月3日にリリースすることができました!!
ぜひインストールして遊んでみてください。
これからもvisionOSを学びながらこちらのアプリをアップデートしていくのでフィードバックもお待ちしております。
今後もvisionOSについて発信していきますので、この記事が参考になったと思ったらぜひ♡をお願いします。
参考
Discussion