- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在使用 GKAgent 移动注册为实体的 SCNNode,分配了一个团队组件和一个移动组件。正在触发 agentWillUpdate 和 agentDidUpdate 方法,但添加到场景的实体的位置拒绝更新它们的位置。有没有办法让 GKAgent 根据以下移动行为更新位置?
亲切的问候,
蒙特勒
移动组件.swift
import SceneKit
import GameplayKit
extension float3 {
var length: Float {
return sqrt(x*x + y*y + z*z)
}
}
class MoveComponent: GKAgent3D, GKAgentDelegate {
let entityManager: EntityManager!
init(maxSpeed: Float, maxAcceleration: Float, radius: Float, entityManager: EntityManager) {
self.entityManager = entityManager
super.init()
self.delegate = self
self.maxSpeed = maxSpeed
self.maxAcceleration = maxAcceleration
self.radius = radius
print(self.mass)
self.mass = 0.01
}
func agentWillUpdate(_ agent: GKAgent) {
guard let spriteComponent = entity?.component(ofType: SpriteComponent.self) else
{
return
}
let pos = spriteComponent.node.presentation.position
print("Agent Will Update \(spriteComponent.node.name) from \(pos) to \(self.position)")
self.position = float3(pos)
}
func agentDidUpdate(_ agent: GKAgent) {
guard let spriteComponent = entity?.component(ofType: SpriteComponent.self) else {
return
}
spriteComponent.node.position = vec3(self.position)
print("Agent DID Update to: \(spriteComponent.node.name) to \(position)")
let xVelocity = self.velocity.x
let zVelocity = self.velocity.z
let angle = -Float(atan2(zVelocity, xVelocity)) + Float.pi/2
spriteComponent.node.rotation = SCNVector4(0,1,0, angle)
}
func closestMoveComponent(_ team: Team) -> GKAgent3D? {
let moveComponents = entityManager.moveComponentsForTeam(team)
var closestMoveComponent: GKAgent3D? = nil
var closestDistance: Float = MAXFLOAT
for component in moveComponents {
let distance = (self.position - component.position).length
if distance < closestDistance {
closestDistance = distance
closestMoveComponent = component
}
}
return closestMoveComponent
}
override func update(deltaTime seconds: TimeInterval) {
// Determine team
guard let entity = entity,
let teamComponent = entity.component(ofType: TeamComponent.self) else {
return
}
// Find team castle
guard let team = entityManager.castleForTeam(teamComponent.team),
let teamCastleComponent = team.component(ofType: HeroComponent.self),
let teamMoveComponent = team.component(ofType: MoveComponent.self) else {
return
}
var targetMoveComponent: GKAgent3D
if teamCastleComponent.attacking {
// Find closest enemy
guard let enemyMoveComponent = closestMoveComponent( teamComponent.team.oppositeTeam()) else {
print("No Opposite enemy components for Agent!!!")
return
}
targetMoveComponent = enemyMoveComponent
// Override target for ranged attackers
if let fireComponent = entity.component(ofType: ParticleComponent.self) {
let newTarget = GKAgent3D()
let node1Pos = SCNVector3ToGLKVector3(SCNVector3(targetMoveComponent.position))
let node2Pos = SCNVector3ToGLKVector3(SCNVector3(position))
let distance = GLKVector3Distance(node1Pos, node2Pos)
newTarget.position = float3(x: targetMoveComponent.position.x, y: targetMoveComponent.position.y, z: targetMoveComponent.position.z * Float(fireComponent.range))
// newTarget.position = float3(targetMoveComponent.position + direction * fireComponent.range)
targetMoveComponent = newTarget
}
} else {
targetMoveComponent = teamMoveComponent
}
// Find allies
let alliedMoveComponents = entityManager.moveComponentsForTeam(teamComponent.team)
// Reset behavior
// print("Reset move behavior")
self.behavior = MoveBehavior(targetSpeed: maxSpeed, seek: targetMoveComponent, avoid: alliedMoveComponents)
print("Agent moving to \(targetMoveComponent), avoiding \(alliedMoveComponents)")
super.update(deltaTime: seconds)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
移动行为.swift
import GameplayKit
import SceneKit
class MoveBehavior: GKBehavior {
init(targetSpeed: Float, seek: GKAgent3D, avoid: [GKAgent3D]) {
super.init()
if targetSpeed > 0 {
print("Running Move Behavior")
setWeight(0.1, for: GKGoal(toReachTargetSpeed: targetSpeed))
setWeight(0.5, for: GKGoal(toSeekAgent: seek))
setWeight(1.0, for: GKGoal(toAvoid: avoid, maxPredictionTime: 1.0))
}
}
}
EntityManager.swift
import Foundation
import Foundation
import ARKit
import SceneKit
import GameplayKit
class EntityManager {
var toRemove = Set<GKEntity>()
let costQuirk = 20
lazy var componentSystems: [GKComponentSystem] = {
let moveSystem = GKComponentSystem(componentClass: MoveComponent.self)
let meleeSystem = GKComponentSystem(componentClass: MeleeComponent.self)
let firingSystem = GKComponentSystem(componentClass: ParticleComponent.self)
let castleSystem = GKComponentSystem(componentClass: HeroComponent.self)
let heroSystem = GKComponentSystem(componentClass: HeroComponent.self)
let aiSystem = GKComponentSystem(componentClass: AiComponent.self)
let nodeComponent = GKComponentSystem(componentClass: NodeComponent.self)
return [moveSystem, meleeSystem, firingSystem, castleSystem, aiSystem,heroSystem,nodeComponent]
}()
// 1
var entities: Set<GKEntity>
let scene: SCNScene
// 2
init(scene: SCNScene) {
self.scene = scene
self.entities = Set<GKEntity>()
}
// 3
func add(_ entity: GKEntity) {
if let spriteNode = entity.component(ofType: SpriteComponent.self)?.node {
scene.rootNode.addChildNode(spriteNode)
let speed = Int.random(in: 7 ... 10)
let smoke = SCNParticleSystem(named: "art.scnassets/Models/spawnSmoke.scnp", inDirectory: nil)
let smokeNode = SCNNode()
spriteNode.addChildNode(smokeNode)
print("Monster Added")
}
for componentSystem in componentSystems {
componentSystem.addComponent(foundIn: entity)
}
entities.insert(entity)
}
// 4
func remove(_ entity: GKEntity) {
if let spriteNode = entity.component(ofType: SpriteComponent.self)?.node {
let confetti = SCNParticleSystem(named: "Media.scnassets/Fire.scnp", inDirectory: nil)
confetti?.loops = false
confetti?.particleLifeSpan = 0.05
confetti?.particleSize -= 1
confetti?.particleIntensity -= 0.5
print("Making Explosion")
if let geometry = spriteNode.geometry {
confetti?.emitterShape = geometry
}
spriteNode.addParticleSystem(confetti!)
print("Exploding Node!")
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3)) {
spriteNode.removeFromParentNode()
spriteNode.removeAllActions()
self.entities.remove(entity)
self.toRemove.insert(entity)
}
}
entities.remove(entity)
}
func update(_ deltaTime: CFTimeInterval) {
// 1
for system in componentSystems {
system.update(deltaTime: deltaTime)
}
// 2
for currentRemove in toRemove {
for componentSystem in componentSystems {
componentSystem.removeComponent(foundIn: currentRemove)
}
}
toRemove.removeAll()
}
func castle(for team: Team) -> GKEntity? {
for entity in self.entities {
if let teamComponent = entity.component(ofType: TeamComponent.self),
let _ = entity.component(ofType: HeroComponent.self) {
if teamComponent.team == team {
return entity
}
}
}
return nil
}
func spawnQuirk(team: Team , positon: SCNVector3) {
// 1
guard let teamEntity = castle(for: team) else {return}
// 2
if let teamCastleComponent = teamEntity.component(ofType: HeroComponent.self) {
if teamCastleComponent.coins < costQuirk , team == .team1{
return
}
teamCastleComponent.coins -= costQuirk
}
// 3
guard let floor = GAMEFLOOR as? SCNNode else {return}
let monster = Quirk(team: team, entityManager: self, floor:floor)
if let spriteComponent = monster.component(ofType: SpriteComponent.self) {
let randomX = Float.random(in: -10.0 ... -0.0)
let randomZ = Float.random(in: -10.0 ... -1.0)
spriteComponent.node.position = positon
let teamRing = SCNParticleSystem(named: "Media.scnassets/teamRing.scnp", inDirectory: nil)
switch team {
case .team1 :
teamRing?.particleColor = .blue
case .team2:
teamRing?.particleColor = .red
}
spriteComponent.node.addParticleSystem(teamRing!)
}
add(monster)
}
func spawnZap(_ team: Team, positon: SCNVector3) {
guard let teamEntity = castle(for: team) else {return}
if let teamCastleComponent = teamEntity.component(ofType: HeroComponent.self) {
if teamCastleComponent.coins < costZap , team == .team1{
return
}
teamCastleComponent.coins -= costZap
let monster = Zap(team: team, entityManager: self)
if let spriteComponent = monster.component(ofType: SpriteComponent.self) {
let randomX = Float.random(in: -10.0 ... -0.0)
let randomZ = Float.random(in: -10.0 ... -1.0)
spriteComponent.node.position = positon
}
add(monster)
}
}
func spawnMunch(_ team: Team, positon: SCNVector3) {
guard let teamEntity = castleForTeam(team),
let teamCastleComponent = teamEntity.component(ofType: HeroComponent.self),
let teamSpriteComponent = teamEntity.component(ofType: SpriteComponent.self) else {
return
}
if teamCastleComponent.coins < costMunch {
return
}
teamCastleComponent.coins -= costMunch
guard let floor = GAMEFLOOR as? SCNNode else {return}
let monster = Munch(team: team, entityManager: self, floor:floor)
if let spriteComponent = monster.component(ofType: SpriteComponent.self) {
let randomX = Float.random(in: -10.0 ... -0.0)
let randomZ = Float.random(in: -10.0 ... -1.0)
spriteComponent.node.position = positon
}
add(monster)
}
func entitiesForTeam(_ team: Team) -> [GKEntity] {
return entities.compactMap{ entity in
if let teamComponent = entity.component(ofType: TeamComponent.self) {
if teamComponent.team == team {
return entity
}
}
return nil
}
}
func moveComponentsForTeam(_ team: Team) -> [MoveComponent] {
let entities = entitiesForTeam(team)
var moveComponents = [MoveComponent]()
for entity in entities {
if let moveComponent = entity.component(ofType: MoveComponent.self) {
moveComponents.append(moveComponent)
}
}
return moveComponents
}
func castleForTeam(_ team: Team) -> GKEntity? {
for entity in entities {
if let teamComponent = entity.component(ofType: TeamComponent.self),
let _ = entity.component(ofType: HeroComponent.self) {
if teamComponent.team == team {
return entity
}
}
}
return nil
}
func entities(for team: Team) -> [GKEntity] {
return entities.compactMap{ entity in
if let teamComponent = entity.component(ofType: TeamComponent.self) {
if teamComponent.team == team {
return entity
}
}
return nil
}
}
func moveComponents(for team: Team) -> [MoveComponent] {
let entitiesToMove = entities(for: team)
var moveComponents = [MoveComponent]()
for entity in entitiesToMove {
if let moveComponent = entity.component(ofType: MoveComponent.self) {
moveComponents.append(moveComponent)
}
}
return moveComponents
}
}
最佳答案
长话短说
我宁愿使用 GKSCNNodeComponent
作为代理的委托(delegate),它会自动处理相互位置更新。
如果一个组件被添加到一个组件系统,更新实体将不会影响它。
也许更新组件系统的顺序很重要。
关于ios - GKAgent 不会更新在 ARKit/SCNScene/GamplayKit 游戏中注册为实体的 SCNNode 的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54792972/
都是整数,但一直报错 "Only assignment, call, increment, decrement, await, and new object expressions can be us
我有以下情况:一个“对话”实体/表,它有多个关联的标签。Tag 也是一个实体/表 - key/id 是 tagName(一个字符串)。 在客户端 (javascript),我在处理标签时使用字符串数组
我想通过 maven java 源代码生成器自动生成 java 源代码。我想通过查看一个大实体 xml 文件来创建实体类,该文件将包含系统中的所有实体和实体关系。据我搜索,目前maven中没有这样的插
我有一段时间有这个疑问,有人说 EJB 3.0 中没有所谓的实体 bean。有没有可能这样说,EJB 3.0 使用 JPA 来持久化数据并且没有对以前版本(EJB 2.1)中的实体 bean 进行增强
我观看了关于 Core Data 的 2016 WWDC 视频并查看了各种教程。我见过使用 Core Data Framework 创建对象以持久保存到 managedObjectContext 中的
实体(entites) 用于定义引用普通文本或特殊字符的快捷方式的变量,可在内部或外部进行声明 实体引用是对实体的引用 声明一个内部实体 语法: <!ENTITY 实体名称 "
This page建议 !ENTITY: If you want to avoid duplication, consider using XML entities (for example, [ ]
我正在努力解决这个问题:如何判断一个概念是聚合根还是只是一个实体(属于 AR 的一部分)? : 他们都有 ID 它们都是由实体或值对象组成 也许如果我需要引用其他 AR 中的实体,那么我需要将其设为
我使用 Symfony2 和 Doctrine,我有一个关于实体的问题。 出于性能方面的考虑,我想知道是否可以在不进行所有关联的情况下使用实体? 目前,我还没有找到另一种方法来创建继承带有关联的类的模
我已经尝试在 HTML 中包含以下代码,用于附加文件符号。但它显示一个空的白框。 📎 📎 📎 是否有替代的 HTML 附加文件符号实体? 如果没有,我们可以手动创建
我在 grails 中有一个域类......我如何让 gorm 在创建数据库时忽略这个实体?就别管它了。 最佳答案 如果我理解,你不想从域类创建表?如果是,请在域类中使用此代码: static map
我正在努力解决这个问题:如何判断一个概念是聚合根还是只是一个实体(属于 AR 的一部分)? : 他们都有 ID 它们都是由实体或值对象组成 也许如果我需要引用其他 AR 中的实体,那么我需要将其设为
我已经尝试在 HTML 中包含以下代码,用于附加文件符号。但它显示一个空的白框。 📎 📎 📎 是否有替代的 HTML 附加文件符号实体? 如果没有,我们可以手动创建
如何在我的实体中以 14-04-2017 格式存储日期? 但我必须从字符串中解析它。 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-
我需要从两个连接表中获取数据。数据集是什么类型?我是否需要创建一个包含这两个表中的属性的类以用于数据集类型,或者我可以使用实体模式中的类型。我如何修改我的方法才能正常工作? public static
好的,我们正在尝试建立一个中央站点来查看来自销售我们产品的多个供应商的数据。这些多个供应商使用不同的销售系统(确切地说是两个不同的系统),因此每个数据库看起来完全不同。我们与他们的数据库同步,因此数据
我是 backbone 的新手。但是当我研究模型实体时,我不明白一些事情。如果我们可以像 java 或 C# 这样的标准语言一样定义模型属性,那就太好了。有没有可能是这样的。所以我的想法是这样的: M
我想获取存储在可绘制的 xml 文件中的形状的颜色。 我来到了将 Drawable 存储在 Drawable 变量中的步骤,所以,现在我想获取形状的颜色(纯色标签)。 有什么建议吗? 最佳答案 Gra
实体是直接映射到我们的数据库(我们用于 Hibernate)的类。 在调用 DAO 之前,我们的服务类包含这些实体的业务逻辑。 我们还有命令对象,它们是与特定 View 相关的 POJO。有人告诉我实
在我的应用程序中,我需要显示不同存储过程返回的记录列表。每个存储过程返回不同类型的记录(即列数和列类型不同)。 我最初的想法是为每种类型的记录创建一个类,并创建一个函数来执行相应的存储过程并返回 Li
我是一名优秀的程序员,十分优秀!