preloaded script doesn't work, the property acessed is like a new object?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By The_Black_Chess_King

I did not understood what happenned. On simple sprite I did:

extends Sprite
var MovePack = preload("res://Movepack.gd).new()

func _process(delta):
    MovePack.move()

and on the Movepack.gd is:

extends Sprite
func move():
    position += Vector2(2,2)
    print(position)

The code works, but the sprite remains in place, while the debug spits:

(2,2)
(4,4)
(6,6)
(8,8)
(10,10)

So it’s moving, but why the sprite that called the preload("res://Movepack.gd).new() does not move? It’s like the script has it’s own position?

Any assistance will be greatly appreciated,

:bust_in_silhouette: Reply From: DDoop

Don’t extend Sprite in Movepack.gd.
What’s happening is you’re basically instantiating an invisible Sprite (with no attached image resource) and moving that object’s position when you call move() on the Movepack object. It moves, but since there’s no visual representation of the object, nothing seems to happen.

Edit: shooting in the dark here but I’m guessing you probably don’t need to put the move function into a separate object. Ideally objects should be self contained (encapsulated) and capable of performing operations on their own properties independently of other objects, except when it’s necessary to interact with another objec. This helps avoid an anti-pattern sometimes referred to as feature envy where one object “envies” (wishes it owned them) another object’s properties or methods and looks at them/modifies them too much.

But if I remove the extends Sprite in that script it returns an error:

error(6,1): The identifier "position" isn't declared in the current scope.

Edit: I see, I was trying to do a inherentance behavior design system through script preloading. Guess I can’t do that. :frowning:

Like I wanted to have separate scripts for each behavior I wanted and would glue them to nodes through preloading.

The_Black_Chess_King | 2020-09-03 23:34

Sorry I phrased my answer poorly. You were correct when you said the script had it’s own position, it got it when it inherited Sprite. All scripts need to inherit from a Godot primitive or a custom class. I think the way you are solving your problem is therefore going to cause headaches, since there’s not a simple way to modify another object’s parameters without having some kind of reference to the object that owns the parameter.

Your Movepack needs a reference to the Sprite so that it can change the Sprite’s position. You could potentially pass that in as an argument to the move() function you’ve written, making it more complicated. Make sure there’s a good reason to do that instead of just performing the movement in the Sprite node.
Edit: sounds like you’re trying to cram too much work into inheritance, don’t do that unless there’s a good reason to break up all your objects’ functionalities (like if you were shuffling them around at runtime or something).
Edit: to be clear the inheritance takes place in the extends line. You could accumulate internal properties and methods by chaining scripts that way, I just think you need to define each one with a class declaration, I’m not sure you can just use a preload call for that.

DDoop | 2020-09-03 23:41

Aha, thanks to your explanation I understood now, I can use even extends Node on the scripts, the variables are edited using a reference to the node calling the func from the preloaded script.

It works, I have the power now!! HAHAHAHA just kidding… it was a simple test case, but I am going to take your advice and try something else, I can see that becoming a problem later.

Big thanks for the clarification though! Thumbs up my dude o/

The_Black_Chess_King | 2020-09-03 23:55

You basically ninja’d all the key points I wanted to communicate, good job :slight_smile:

DDoop | 2020-09-03 23:58