QodotPlugin / qodot-plugin

(LEGACY) Quake .map support for Godot 3.x
MIT License
960 stars 70 forks source link

Rotating point class doesn't rotate object in game #147

Closed RetrocadeMedia closed 2 years ago

RetrocadeMedia commented 2 years ago

This could very well be me missing something, but I'm having some difficulty with rotating point classes. In Trenchbroom, when I rotate a point class it just displaces it around the origin, which I thought was just a strange quirk, but it also seems to do the same thing in Godot as well.

Am I missing some really obvious entity rotater? Is this an issue with Trenchbroom and I should take it up with them? And is there anything I can do about it for now other than just manually rotating and re-placing some objects in Godot?

Shfty commented 2 years ago

Entity rotations in quake maps are represented by the angle (yaw) and mangle (euler angles) properties. When you rotate an entity in TB it will write to one of those, prioritizing mangle if present, and creating angle if neither exists.

As with any other property, these are just key/value pairs that have no special behavior. Qodot purposefully takes an unopinionated approach here: As there are various non-transform ways to use those values, auto-applying them as rotations would be arbitrary.

Thus, how those values are used is the responsibility of the object receiving them.

If your object's script has an export(Dictionary) var properties, QodotMap will populate it at build time. You can mark your script as tool to allow it to run in-editor (being mindful to add Engine.is_editor_hint() checks to prevent the object from performing any runtime work in the editor), and give that dictionary a setget setter in order to run logic when it gets written to. From there, it should be trivial to read from properties["angle"] / properties["mangle"] and set the appropriate transform values.

To get a better idea of how this should look, you can check the source for QodotEntity, which has a premade tool + export + setget setup specifically for this. You can inherit from it to get this functionality for free, but that only works if your node's base class is Spatial and not something more exotic.