I want to use point picker to pick (get) coordinates of my points in a point cloud. That is why I want to set QPickingSettings to PointPicking but it seems that cannot be done. Events sent to method mouse_event are of type QPickEvent and NOT QPickPointEvent. What am I doing wrong?
self.picker = Qt3DRender.QObjectPicker(self)
picking_settings = Qt3DRender.QPickingSettings(self.picker)
picking_settings.setFaceOrientationPickingMode(
Qt3DRender.QPickingSettings.FrontAndBackFace)
# set QObjectPicker to PointPicking:
picking_settings.setPickMethod(
Qt3DRender.QPickingSettings.PointPicking)
picking_settings.setPickResultMode(
Qt3DRender.QPickingSettings.NearestPick)
picking_settings.setWorldSpaceTolerance(.5)
self.picker.setHoverEnabled(True)
self.picker.setDragEnabled(True)
def mouse_event(e):
# do something
# e should be QPickPointEvent type
pass
self.picker.moved.connect(mouse_event)
self.picker.pressed.connect(mouse_event)
self.picker.clicked.connect(mouse_event)
self.picker.released.connect(mouse_event)
self.addComponent(self.picker)
I'm not familiar with the python API, but you should not create your own instance of QPickingSettings but use the one that exists as a property of the instance of QRenderSettings (that is a singleton).
If you're using the Qt3DWindow from Qt3DExtras, it will provide an accessor to the QRenderSettings instance.
Otherwise, you'll need to create an instance of QRenderSettings and add it as a component of an entity. By convention we tend to use the root of the scene graph.
Related
I'm trying to check if a certain node type has a property
without actually needing to make an instance of it
like this:
print("z_index" in Position2D);
Classes in ClassDB
If we are talking about a build-in class (not a custom class that you created, but one that is part of Godot), you can use ClassDB to get the property:
var properties := ClassDB.class_get_property_list("Position2D")
Classes from Godot Scripts
If the class is not in ClassDB (which is the case custom classes), but you have the script, you can use the script to get the property list:
var properties := preload("res://custom_class.gd").get_script_property_list()
If you don't have the script, perhaps you can find it. This code uses the hidden project setting "_global_script_classes" to find the path of the script for a class given the name_of_class you are looking for, and loads it:
if ProjectSettings.has_setting("_global_script_classes"):
for x in ProjectSettings.get_setting("_global_script_classes"):
if x.class == name_of_class:
return load(x.path)
Addendum: This is no longer available in Godot 4.
Other classes
However, the above approach will not work for every type of script. In those cases, I'm afraid the best way is to instance it. You can still get the properties from the instance and cache them (perhaps put them in a dictionary) so that you are not creating a new instance every time you need to query:
var properties := (CustomClass.new()).get_property_list()
Query the properties
Regardless of how you got the property list, you can query them the same way. For example this code looks for a property with name "z_index" and gets its type:
var found := false
var type := TYPE_NIL
for property in properties:
if property.name == "z_index":
found = true
type = property.type
break
prints(found, type)
The type is a Variant.Type constant.
Theraot's answer is correct, since it provides a way to check attributes without creating an instance of a node/gdscript.
You can also check the properties of an existing instance of a node/scene by doing this:
if "attribute_name" in thing:
pass # do stuff here
Practical example; During a signal triggered by two Area2Ds colliding, check if one node's attribute item_type is set:
func _on_area_2d_area_entered(area):
if "item_type" in area:
print(area["item_type"])
Suppose I define "Class original:" and create a class attribute "one = 4." Then I create an instance of the class "First = original()." My understanding is that First now contains a pointer to original and "First.one" will return "4." However, suppose I create "Second = original()" and then set "Second.one = 5." What exactly happens in memory? Does a new copy of Class original get created with a class attribute of 5?
I've created a Class original with class attribute one. I then created two instances of this class (First and Second) and verified that id(First.one) and id(Second.one) are pointing to the same place. They both return the same address. However, when I created Third=original() and set Third.one = 5 and then check id(Thrid.one) it appears to be pointing somewhere else. Where is it pointing and what happened? When I check original.one it still returns "4" so obviously the original object is not being modified. Thanks.
It appears you are asking about a piece of code similar to this:
class Original:
def __init__(self, n):
self.one = n
first = Original(4)
second = Original(4)
third = Original(5)
print(id(first.one))
# 140570468047360
print(id(second.one))
# 140570468047360
print(id(third.one))
# 140570468047336
Suppose I define "Class original:" and create a class attribute "one = 4." Then I create an instance of the class "First = original()." My understanding is that First now contains a pointer to original
No. The variable references the instance you created, not the class. If it referenced the class, there would be no way for you to get at the instance you just created.
The instance will, somewhere in its object header, of course contain a pointer to its class. Without that pointer, method lookup wouldn't be possible, since you wouldn't be able to find the class from the instance.
and "First.one" will return "4."
Yes. The attribute one of first contains a pointer to the object 4 (which is an instance of the class int).
[Note that technically, some Python implementations will perform an optimization and actually store the object 4 directly in the attribute instead of a pointer to the object. But that is an internal implementation detail.]
However, suppose I create "Second = original()" and then set "Second.one = 5." What exactly happens in memory? Does a new copy of Class original get created with a class attribute of 5?
No. Why would you need a separate copy of the class? The methods are still the same for both instances. In fact, that is precisely the reason why methods in Python take the instance as their first argument! That way, there need only be one method. (This is actually the same in every OO language, except that in most other languages, this argument is "invisible" and only accessible using a special keyword like self in Ruby, Smalltalk, Self, and Newspeak or this in Java, C#, and Scala.)
I've created a Class original with class attribute one. I then created two instances of this class (First and Second) and verified that id(First.one) and id(Second.one) are pointing to the same place. They both return the same address. However, when I created Third=original() and set Third.one = 5 and then check id(Thrid.one) it appears to be pointing somewhere else.
It is not quite clear to me what your question is here. first.one and second.one both point to 4, so they both point to the same ID since they both point to the same object. third.one points to 5, which is obviously a different object from 4, so naturally, it has a different ID.
It is, in fact, one of the requirement of IDs that different objects that exist at the same time must have different IDs.
Where is it pointing and what happened?
Again, it is not quite clear what you are asking.
It is pointing at 5, and nothing happened.
When I check original.one it still returns "4" so obviously the original object is not being modified.
Indeed, it isn't. Why would it be?
I have an EnemySpawner Blueprint Class that does:
EnemySpawner has a Spline Component named "Path" which the Spawned Enemy must follow. For it, Enemy's Blueprint has another Spline Component named "Enemy Path" that must be initialized by the Enemy Spawner at the moment of the creation, as does in the screenshot above.
But, in my Enemy, if I try to access to "EnemyPath", I get the following error:
Blueprint Runtime Error: Accessed None trying to read property
PathActor from function: 'ExecuteUbergraph_Enemy' from node:
DestroyActor in graph: EventGraph in object: Enemy with description:
Accessed None trying to read property PathActor
So, in other words, Null Pointer Exception.
If, for example, in the Enemy's Blueprint I do (with testing purposes):
The Actor Owner of the Spline Component isn't destroyed.
Even if I try to assign all the Owner actor, not only the Spline Component, it doesn't work either.
I've also tried to print something in screen after the "SpawnActor Enemy" node of EnemySpawner and in the "Event BeginPlay" node of Enemy, and I've checked that obviously the print in EnemySpawner happens first, so the only problem is that the variable isn't really assigned.
The last thing I've tried is to destroy the Spline's Owner right after the "Set" node, directly in EnemySpawner blueprint, by getting it from the Spawned enemy, and to my surprise, it's destroyed!
So, some idea about what's the properly way of doing this?
You can set any variable in a BP actor with an "Expose on Spawn" flag (in the details panel when the variable is selected in the BP editor) which will add a pin for a value to pass into it when using the SpawnActorFromClass node. Make sure you set the variable(s) "Editable" as well.
I think maybe we are doing this wrong.
In straight up C++ you create a class, create the variables, modify the variables by creating a function & passing by ref.
I think that if the Blueprint is a class ( which it is), and if the variable is a variable (which it is), you can't really expect to assign a value to it without calling a function that does it... Then again for all i know maybe the engine does do it for you...
I'm trying to create a blood effect in my game, to achieve this I need to test whether or not the blood particle hit another instance from an array. I already have the array set up and a way to test if the object is in the array but when i do this:
platform = instance_position(x, y, all);
It will target the blood particle itself while I want the instance underneath. Is there any way of ignoring the blood particle and instead looking at the instance underneath it? I can't change the depth because I do want it to be in the front.
Thanks for your time :)
If you are checking for collision with one particular object or instance, you can use the object name or instance ID in place of the all keyword. Example:
var ins = instance_position(x, y, objWall);
If any instances of objWall are detected, the ID of the first of those instances will be returned. If you use an instance ID instead, only that single instance will be checked for.
If you need to check for multiple different instances, you could loop through the array, performing one check per instance ID and stopping the loop if one of them is found.
If you need to check for multiple object types, you could assign a Parent to those objects and then do a check for the parent. Example: Make four objects, objBallParent, objFootball, objBouncyBall, objCannonBall. In the Object Properties of each ball, set objBallParent as the Parent object.
if ( instance_exists(objBallParent ) {
// Do something
}
var closest = instance_nearest(x, y, objBallParent);
The code above only checks for the parent object, but the functions will be satisfied by any instances of the child objects as well. In this case, if there is an instance of objFootball in the room, that will count as an instance of objBallParent existing, and it can also be returned by the instance_nearest function.
When checking for collisions with objBallParent, any of the three child objects would be accepted by the check.
I have two sequence item class a_packet and its extended class called bad_packet.
By default, a_packet type is used.
Trying to override a_packet instance with bad_packet, I am able to do it successfully by using set_inst_override_by_name in my uvm test,
factory.set_inst_override_by_name("a_packet","bad_packet", "*");
Now my question is: what if I don't want to use "*", how to know the full hierarchical path of the sequence item instance?
I was trying to utilise get_full_name() from inside the sequence item, right after it is received by the driver, to know the exact hierarchical path. It displayed:
uvm_test_top.env.a_agt.a_seqr.a_sequence.a_packet
But when I replaced the * with above path, the overriding is not happening.
factory.set_inst_override_by_name("a_packet","bad_packet","uvm_test_top.env.a_agt.a_seqr.a_sequence.a_packet");
Did I do something wrong?
Where you create your packet, you'll need to to specify the full path to the corresponding call to create(..):
packet = a_packet::type_id::create("packet", , get_full_name());
If you were using the uvm_do macro, you'll have to change to using the explicit sequence API:
packet = a_packet::type_id::create("packet", , get_full_name());
start_item(packet);
// ... randomize ...
finish_item(packet);
Idea is from this DVCon Paper, section IV.A.