我在SCNode命中检测方面遇到了一些麻烦。我需要检测在具有SCNNode的场景中触摸了哪个对象,我已经实现了这段代码但是当我触摸对象时它似乎崩溃但是当我触摸其余的sceneView时工作正常。
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first as! UITouch
if(touch.view == self.sceneView){
print("touch working")
let viewTouchLocation:CGPoint = touch.location(in: sceneView)
guard let result = sceneView.hitTest(viewTouchLocation, options: nil).first else {
return
}
if (bottleNode?.contains(result.node))! { //bottleNode is declared as SCNNode? and it's crashing here
print("match")
}
}
}
答案 0 :(得分:5)
这里存在多个问题,现有的答案只针对其中一些问题。
在此方法运行时,您发布的代码中不清楚bottleNode
是否为零。当值为nil时,通过可选(?
中的bottle?.contains
)调用方法会无声地失败 - 导致整个表达式结果换行为其值为nil的Optional - 但是你已经得到了parens和一个力量解开整个表达式,所以nil-unwrap会崩溃。
contains(_:)
不是SCNNode
上的方法。目前还不清楚您的bottleNode
可能是什么类型,甚至可以编写此方法调用而不会出现编译错误......但如果bottleNode
实际上是SCNNode
并且您是&#39 ;我做了一些类型擦除/ Any
- 转换goop以允许调用编译,由于不存在的方法,调用将在运行时失败。
如果您使用bottleNode.contains
行的目标是确定命中测试结果是bottleNode
本身还是其子节点,我建议您定义并使用这样的扩展方法:
extension SCNNode {
func hasAncestor(_ node: SCNNode) -> Bool {
if self === node {
return true // this is the node you're looking for
}
if self.parent == nil {
return false // target node can't be a parent/ancestor if we have no parent
}
if self.parent === node {
return true // target node is this node's direct parent
}
// otherwise recurse to check parent's parent and so on
return self.parent.hasAncestor(node)
}
}
// in your touchesBegan method...
if let bottleNode = bottleNode, result.node.hasAncestor(bottleNode) {
print("match")
}
如果您的目标是确定result.node
是否位于bottleNode
的边界框内或与position
的边界框重叠(无论节点层次结构如何),那么回答这个问题会更复杂一些。 boundingSphere
检查中的var express = require('express');
var app = express();
var serv = require('http').Server(app);
app.get('/', function(req, res) {
res.sendFile(__dirname + '/client/index.html');
});
app.use('/client', express.static(__dirname + '/client'));
serv.listen(2000);
console.log("Server started!");
var io = require('socket.io')(serv,{});
var md5 = require('md5');
var mysql = require('mysql');
var dbconn = mysql.createConnection({
host: "mySERVER",
user: "myUSER",
password: "myPASSWORD",
database: "myDBNAME"
});
dbconn.connect(function(err) {
if (err) throw err; //THE ERROR IS THROWN HERE
});
io.sockets.on("connection", function(socket) {
socket.on("register", function(obj){
var sql = 'INSERT INTO users (name, password) VALUES ("' + obj.name + '", "' + md5(obj.password) + '")';
dbconn.query(sql, function (err, result) {
if (err) throw err;
console.log("Result: " + result);
});
});
});
非常简单,或者如果您正在寻找遏制/重叠,octree可能有帮助。
答案 1 :(得分:4)
可能是,bottleNode
是零。什么线路导致崩溃?在比较之前检查bottleNode
是否存在:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first as! UITouch
if(touch.view == self.sceneView){
print("touch working")
let viewTouchLocation:CGPoint = touch.location(in: sceneView)
guard let result = sceneView.hitTest(viewTouchLocation, options: nil).first else {
return
}
if let bottleNode = bottleNode, bottleNode == result.node { //bottleNode is declared as SCNNode? and it's crashing here
print("match")
}
}
}
答案 2 :(得分:1)
您目前正在测试SCNNode是否“包含”来自hittest结果的节点,而您应该只是比较它们,即if(bottlenode == result.node)......
答案 3 :(得分:1)
您是否真的创建了bottleNode
?如果bottleNode
为nil,则表达式bottleNode?.contains(result.node)
也将为nil,因此当您强行打开它时,它将引发错误。
如果您知道将始终定义bottleNode,则它不应该是可选的。如果您不知道,在使用之前需要检查它是否存在。这应该做你想要的:
if let bottleNode = bottleNode, bottleNode.contains(result.node) {
请注意,如果bottleNode不存在,则此测试将无声地失败。