Redot-Engine / redot-engine

Redot Engine – Multi-platform 2D and 3D game engine
https://redotengine.org/
MIT License
4.68k stars 205 forks source link

Node3d variable returns error when populated with a separate node that has its own script. #809

Closed Lex-Tali0nis closed 1 week ago

Lex-Tali0nis commented 1 week ago

Tested versions

v4.3.stable.mono.official [77dcf97d8]

System information

Edition Windows 10 Pro Version 22H2 Installed on ‎09/‎11/‎2021 OS build 19045.5011 Experience Windows Feature Experience Pack 1000.19060.1000.0

Issue description

With a node and its own script, is assigned as a Node3d variable in a different script attached to a different node, if you try and access information from that variable it will return "object reference is not set to an instance of an object " in unique situations. It appears as if an attached script can impede on the access of that scripts node information, when a different script from a different node trys to call on it.

Steps to reproduce

Minimal reproduction project (MRP)

attached : test_1.zip

Spartan322 commented 1 week ago

Could you please provide an MRP?

Lex-Tali0nis commented 1 week ago

Zip ready to run

MrDoboz commented 1 week ago

ScriptB inherits from Node, not Node3D, and when populating the thing variable, it is type of ScriptB, not Node3D, and as Node does not have position, ScriptB won't have it either. That is my theory at least.

Edit: it can't even populate the Node3D variable as it is not Node3D, and can't be casted to Node3D

Lex-Tali0nis commented 1 week ago

If I understand your premise correctly, if a script is attached to a Node3D the attributes of the type "3d" are basically dumped and may/may not now be accessed vie the script.

i.e. if one wanted the position for a Node3D without a script, It could be retrieved from the Node3D type. If the node had a script attached, the position must be cashed in the script and retrieved from inside the script.

To test if the "3d" type is lost, have ScriptB cash the position of NodeB as a variable inside itself, then try and access it from ScriptA as a cashed Node variable instead of a Node3D.

What if one would like to move the node around and sleep the script? seams problematic even if successful. Just have the scripts inherent from whatever the node type it is attached to may be the logical fix. Or can one even access the attributes of a node independently of its script ?

MrDoboz commented 1 week ago

no. it's about inheritance, a crucial part of OOP. a way too quick fix is simply writing ScriptB correctly, that is, replacing the line public partial class ScriptB : Node with public partial class ScriptB : Node3D at the top, as you are planning to attach it to a Node3D, not a Node. The only interesting quirk about Redot is the fact that you can at all attach a script inheriting from Node to any type of node, which might have some uses, but has this major side effect, and for that reason I would recommend avoiding doing this at all costs, or at the very least until you know what you are doing. On a sidenote, you can do a funny little experiment: tell ScriptB to print it's own position. It won't even compile :P

Edit after reading the rest of your comment: you can try to cast the scripted Node to both ScriptB and Node3D if you store it in a Node variable, but I don't think it will work, my guess is it will only cast to ScriptB as you are kinda stuck in "script land" as far as scripts are concerned. but who knows, that might be interesting, because then you can define another Position variable in ScriptB which would be totally different from the one in Node3D which is just so wrong on so many levels. Long story short, just fix your code and it will work. there's nothing wrong with the engine in this case

Lex-Tali0nis commented 1 week ago

Well there ya go. I could have swore I had changed the inheritance type Node3D; I had changed many things trying to isolate the problem (and changed them back, etc) Obviously I missed that. Thanks for the sanity check, apologies for the waste of time.