How to force reimport of texture in godot? - godot

I have a sample.png file which is being changed outside godot
and after it's modified, godot recives a signal and when that signal is received
I want that specific sample.png file to be reimported
I tried this answer but I want to reimport in my script itself not create a plugin for it
(atleast that's what I'm assuming it does)
I also tried this from the documents but I'm not sure how to use it exactly
EditorFileSystem.update_file("res://Assets/sample.png")
so how do I achieve the desired result?

The class EditorFileSystem is intended for plugins.
You would call get_editor_interface() from an EditorPlugin (which would be where you would be writing code if you were making a plugin). And that gives you an EditorInterface object, on which you can call get_resource_filesystem() which gives you an EditorFileSystem object.
So the intended use is something like this:
extends EditorPlugin
func example() -> void:
var editor_file_system := get_editor_interface().get_resource_filesystem()
editor_file_system.scan_sources()
# editor_file_system.update_file("res://icon.png")
By the way, EditorInterface also has a filesystem_changed signal. Although I don't know how reliable it is.
Usually you don't have to do that. When you restore the Godot window, it will scan for changes in the project folder. So you might minimize Godot while you are working on something else and when you bring the Godot window back it will pick on the changes.
In practice, the only situations when I had to use scan or scan_sources was when I had a tool script that write a resource file which should be imported, and I wanted it to reflect right away.
Instead of making a custom plugin, I'll remind you that form a tool script (as long as it is running in the editor) you can simply create an EditorPlugin object. For example:
var ep = EditorPlugin.new()
ep.get_editor_interface().get_resource_filesystem().scan()
ep.free()
I had also shared this example in another answer I wrote for you a while back here, it is under the title "About saving resources from tool scripts".

Related

error: attempt to call function 'is_colliding' in base 'null instance' on a null instance

I've just started making a basic fps in the Godot engine, and I'm currently stuck on making a basic Raycast weapon. I've looked up tutorials from Coding With Tom, Gabaj YT, and multiple others, and yet no matter which one, I always end up writing the same piece of code:
if Raycast.is_Colliding:
and no matter how exactly I copy it down, I always end up with the same error:
error: attempt to call function 'is_colliding' in base 'null instance' on a null instance.
Raycast is a class. And is_colliding is one of its methods. But it is not an static method, you need an instance of Raycast.
Chances are, you do have an instance. If you have been following the tutorials, presumably you have a Raycast node in the scene tree added from the editor, and it is called… let me guess… Raycast. Yes, I do it too. Until it begins to be an issue and I rename it to something more meaningful or go for a different approach, but I digress.
The issue is that you are not referring the Raycast instance. You can reference nodes from your script using $, like this: $Raycast. It is a shorthand for using the get_node method. See Nodes and scene instances. To be clear, what you put after $ is the relative path on the scene tree, so it might not be just the name of the node. Here I'm assuming the node is a direct child of the node that has the script you are writing.
Thus, I would expect code like this:
if $Raycast.is_colliding():
Granted, you will see code that does look like this:
if raycast.is_colliding():
That is because somewhere in the script they have a line that looks something like this:
onready var raycast := $Raycast
Which declares a variable raycast and - on ready - sets it to a reference to the node, and then they can continue using that variable form there. With video tutorials some might skim over that. Here I found it on a Garbaj video on the topic: Godot FPS Hitscan Weapons Tutorial at 1:52

Invoke a function on tool mode script reload

How do I invoke a function every time the Script is loaded or reloaded?
tool
func _reload():
print("Changes have been made and saved! Script has been reloaded")
func _load():
print("Project was just opened! Script has been loaded")
I'm not sure what you mean by reloaded (or why it is an issue), but it probably is one of these:
When you add a Node to the scene tree (or when you enable a plugin, which is adding the EditorPlugin to scene tree of the editor), or when it is loaded (all plugins are loaded when you load the project), the code in _enter_tree will run. Similarly when it is removed (or when the plugin is disabled), the code in _exit_tree will run. Be aware that for tool scripts that you run manually (EditorScript), these don't work. So make a Node (or an EditorPlugin).
There is a signal that will notify when the script of an object changed. It is appropriately named "script_changed". So if you want to handle the situation when the tool script was modified, and thus reloaded, you could connect to that signal. You may also want to take advantage of the of _init, which is the first virtual method that Godot calls (on Nodes you can also use _enter_tree and _ready). The signal "script_changed" is emitted before _init is called in the new script.
If you want to handle when properties of a Node are modified (I'm including this since you mention "changed has been made"), you would have to use setters (with setget), or you could intercept the properties in _set.
Since you mention "Project was just opened", I think you want to make an EditorPlugin, and then you can use _enter_tree and _exit_tree.
I haven't found a way to get a notification when the currently edited scene on the editor is saved. However, saving the scene does not mean tool script are loaded or reloaded in anyway.

Access var from another script in Godot

Node World contains two children- Pe2node and HUD.
Pe2node (Node2D) node has attached pe2.gd script and it has variable - shift.
HUD node (CanvasLayer) has attached HUD.gd script and I want display variable shift from Pe2node. I try some variants, but it don't work at all. I have ready to try autoload but may be there is simple way to get it work.
HUD.gd:
extends CanvasLayer
var fps=0
var shift_hud=0
func _process(delta):
fps = Engine.get_frames_per_second()
$var_fps.text=str(fps)
#shift_hud=get_node("Pe2node").get_variable("shift")
#shift_hud=get_node("Pe2node").shift
#shift_hud=get_node("World/Pe2node").shift
#shift_hud=$World/Pe2node.shift
$var_shift.text=str(shift_hud)
Node World contain 2 children - Pe2node and HUD
This means that Pe2node and HUD are siblings, right?
Let us go over you attempts:
get_node("Pe2node")
This is looking for a "Pe2node" child of the current node, not a sibling.
get_node("World/Pe2node")
And now you are looking for a "Pe2node" child of "World" child of the current node.
$World/Pe2node
Same as above.
You can either go one level up, like this:
get_node("../Pe2node")
Or like this:
$"../Pe2node"
Or you could have an absolute path, that I will not put example of, but if you print the result of calling get_path on the Node you want, it will show the absolute path (it starts with "/root/").
The reason why I often do not advice doing it the way I describe above is because it depends on the relative position of these nodes, which you might not move together, breaking the code.
A better way to do it - without going for the autoload solution - is to export a NodePath:
export var node_path:NodePath
Which you can set to the node you want in the inspector panel. And then we use it to get the node:
get_node(node_path)
This will work as long as the things you are connecting are in the scene tree from the start (you are not trying to get something instanced dynamically). And as long as that is the case, and you only manipulate the scene from the Godot interface, Godot can keep the NodePath updated.
As per the autoload solution, I would suggest to put signals there instead. You can have an autoload with just a signal like this:
extends Node
signal shift_changed(value)
That would be the whole code of the autoload.
You can create that script and then add it as an autoload in the project settings, with some name. I'll be using the name SingalBus.
And then from anywhere emit the signal:
SingalBus.emit_signal("shift_changed", value)
And from anywhere connect to it:
SingalBus.connect("shift_changed", self, "_on_shift_changed")
Which assumes a method something like this:
func _on_shift_changed(value) -> void:
pass
Which means that you no longer need any kind of node path at all, so there is no path that could break. Plus you can update the UI only when the value changes, instead of having it checking all the time. And there might not be something at the other side, so this works for things that are instanced dynamically too.
To be fair, you could put the variables on the autoload instead of the signals. That also works. And in some cases it is useful to put a reference to a Node there.
The advantage of placing the variables there is that it also gives you a single place to place them all, which might also be useful for a save/load feature, and also to keep them around when going from one scene to another.

Can I alter Python source code while executing?

What I mean by this is:
I have a program. The end user is currently using it. I submit a new piece of source code and expect it to run as if it were always there?
I can't find an answer that specifically answers the point.
I'd like to be able to say, "extend" or add new features (rather than fix something that's already there on the fly) to the program without requiring a termination of the program (eg. Restart or exit).
Yes, you can definitely do that in python.
Although, it opens a security hole, so be very careful.
You can easily do this by setting up a "loader" class that can collect the source code you want it to use and then call the exec builtin function, just pass some python source code in and it will be evaluated.
Check the package
http://opensourcehacker.com/2011/11/08/sauna-reload-the-most-awesomely-named-python-package-ever/ . It allows to overcome certain raw edges of plain exec. Also it may be worth to check Dynamically reload a class definition in Python

Matlab GUIDE GUI Handles change in values after using Load() function?

Inside a GUI that I have made using GUIDE in Matlab. I run into a problem where upon using the Load() function to load a .MAT file all my handles change values. This means that if I had a button that I wanted to use on my GUI. My program will believe its handle is for example
handles.button1 =190.082
when in reality the only way I can access that button any more is through a different handle that is unknown. So if its unknown lets see what its new handle must be.
findobj('Tag','button1') = 227.0093
As you can see these numbers are completely different. Why the handles values get changed is beyond me. Since the handles change I can no longer use the set() function as I have written in previous sections of code. For example I have to change
set(handles.button1, 'Enable', 'off');
to
set(findobj('Tag','button1'),'Enable','off');
Does anyone have an explanation as to why this problem occurs when using Load()?
Is there a feasible solution instead of having to find the handle for an object every time you want to use it?
The .MAT file conveniently also had a handles variable in it which overwrote my current handles.

Resources