Apply general code formatting to some pages in the tutorial section

This commit is contained in:
Michael Alexsander
2020-07-08 23:01:07 -03:00
parent bb7b596a6e
commit 1f6d3995e4
19 changed files with 180 additions and 89 deletions

View File

@@ -30,11 +30,12 @@ An ``AudioStreamPlayer`` named ``AudioStreamRecord`` is used for recording.
var effect
var recording
func _ready():
# We get the index of the "Record" bus.
var idx = AudioServer.get_bus_index("Record")
# And use it to retrieve its first effect, which has been defined
# as an "AudioEffectRecord" resource.
# And use it to retrieve its first effect, which has been defined
# as an "AudioEffectRecord" resource.
effect = AudioServer.get_bus_effect(idx, 0)
The audio recording is handled by the :ref:`class_AudioEffectRecord` resource

View File

@@ -40,11 +40,13 @@ Add these two and it's possible to guess almost exactly when sound or music will
var time_begin
var time_delay
func _ready()
time_begin = OS.get_ticks_usec()
time_delay = AudioServer.get_time_to_next_mix() + AudioServer.get_output_latency()
$Player.play()
func _process(delta):
# Obtain from ticks.
var time = (OS.get_ticks_usec() - time_begin) / 1000000.0
@@ -92,6 +94,7 @@ Here is the same code as before using this approach:
func _ready()
$Player.play()
func _process(delta):
var time = $Player.get_playback_position() + AudioServer.get_time_since_last_mix()
# Compensate for output latency.

View File

@@ -43,10 +43,12 @@ Create a Node and attach the following script.
extends Node
# Load the custom images for the mouse cursor.
var arrow = load("res://arrow.png")
var beam = load("res://beam.png")
func _ready():
# Changes only the arrow shape of the cursor.
# This is similar to changing it in the project settings.

View File

@@ -35,6 +35,7 @@ Examples:
if event.is_action_pressed("jump"):
jump()
func _physics_process(delta):
if Input.is_action_pressed("move_right"):
# Move as long as the key/button is pressed.
@@ -78,6 +79,7 @@ attach the following script:
extends Node
func _input(event):
print(event.as_text())
@@ -302,17 +304,19 @@ node:
extends Node
var dragging = false
var click_radius = 32 # Size of the sprite
var click_radius = 32 # Size of the sprite.
func _input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
if (event.position - $Sprite.position).length() < click_radius:
# Start dragging if the click is on the sprite.
if !dragging and event.pressed:
if not dragging and event.pressed:
dragging = true
# Stop dragging if the button is released.
if dragging and !event.pressed:
if dragging and not event.pressed:
dragging = false
if event is InputEventMouseMotion and dragging:

View File

@@ -44,7 +44,7 @@ You can set up your InputMap under **Project > Project Settings > Input Map** an
func _process(delta):
if Input.is_action_pressed("ui_right"):
# Move right
# Move right.
.. code-tab:: csharp
@@ -52,7 +52,7 @@ You can set up your InputMap under **Project > Project Settings > Input Map** an
{
if (Input.IsActionPressed("ui_right"))
{
// Move right
// Move right.
}
}
@@ -184,19 +184,19 @@ The Input singleton has a method for this:
.. code-tab:: gdscript GDScript
var ev = InputEventAction.new()
# set as move_left, pressed
# Set as move_left, pressed.
ev.action = "move_left"
ev.pressed = true
# feedback
# Feedback.
Input.parse_input_event(ev)
.. code-tab:: csharp
var ev = new InputEventAction();
// set as move_left, pressed
// Set as move_left, pressed.
ev.SetAction("move_left");
ev.SetPressed(true);
// feedback
// Feedback.
Input.ParseInputEvent(ev);
InputMap

View File

@@ -29,26 +29,26 @@ for example:
.. code-tab:: gdscript GDScript
func _input(event):
# Mouse in viewport coordinates
# Mouse in viewport coordinates.
if event is InputEventMouseButton:
print("Mouse Click/Unclick at: ", event.position)
elif event is InputEventMouseMotion:
print("Mouse Motion at: ", event.position)
# Print the size of the viewport
# Print the size of the viewport.
print("Viewport Resolution is: ", get_viewport_rect().size)
.. code-tab:: csharp
public override void _Input(InputEvent @event)
{
// Mouse in viewport coordinates
// Mouse in viewport coordinates.
if (@event is InputEventMouseButton eventMouseButton)
GD.Print("Mouse Click/Unclick at: ", eventMouseButton.Position);
else if (@event is InputEventMouseMotion eventMouseMotion)
GD.Print("Mouse Motion at: ", eventMouseMotion.Position);
// Print the size of the viewport
// Print the size of the viewport.
GD.Print("Viewport Resolution is: ", GetViewportRect().Size);
}

View File

@@ -99,6 +99,7 @@ with the main scene of the game:
var time_max = 100 # msec
var current_scene
func _ready():
var root = get_tree().get_root()
current_scene = root.get_child(root.get_child_count() -1)
@@ -111,16 +112,16 @@ progress bar or loading screen.
::
func goto_scene(path): # game requests to switch to this scene
func goto_scene(path): # Game requests to switch to this scene.
loader = ResourceLoader.load_interactive(path)
if loader == null: # check for errors
if loader == null: # Check for errors.
show_error()
return
set_process(true)
current_scene.queue_free() # get rid of the old scene
current_scene.queue_free() # Get rid of the old scene.
# start your "loading..." animation
# Start your "loading..." animation.
get_node("animation").play("loading")
wait_frames = 1
@@ -145,14 +146,15 @@ precise control over the timings.
set_process(false)
return
if wait_frames > 0: # wait for frames to let the "loading" animation show up
# Wait for frames to let the "loading" animation show up.
if wait_frames > 0:
wait_frames -= 1
return
var t = OS.get_ticks_msec()
while OS.get_ticks_msec() < t + time_max: # use "time_max" to control for how long we block this thread
# poll your loader
# Use "time_max" to control for how long we block this thread.
while OS.get_ticks_msec() < t + time_max:
# Poll your loader.
var err = loader.poll()
if err == ERR_FILE_EOF: # Finished loading.
@@ -162,7 +164,7 @@ precise control over the timings.
break
elif err == OK:
update_progress()
else: # error during loading
else: # Error during loading.
show_error()
loader = null
break
@@ -181,12 +183,14 @@ loader.
# Update your progress bar?
get_node("progress").set_progress(progress)
# ... or update a progress animation?
# ...or update a progress animation?
var length = get_node("animation").get_current_animation_length()
# Call this on a paused animation. Use "true" as the second argument to force the animation to update.
# Call this on a paused animation. Use "true" as the second argument to
# force the animation to update.
get_node("animation").seek(progress * length, true)
func set_new_scene(scene_resource):
current_scene = scene_resource.instance()
get_node("/root").add_child(current_scene)
@@ -273,8 +277,10 @@ Example:
queue = preload("res://resource_queue.gd").new()
queue.start()
# Suppose your game starts with a 10 second cutscene, during which the user can't interact with the game.
# For that time, we know they won't use the pause menu, so we can queue it to load during the cutscene:
# Suppose your game starts with a 10 second cutscene, during which the user
# can't interact with the game.
# For that time, we know they won't use the pause menu, so we can queue it
# to load during the cutscene:
queue.queue_resource("res://pause_menu.tres")
start_cutscene()
@@ -282,17 +288,18 @@ Example:
pause_menu = queue.get_resource("res://pause_menu.tres").instance()
pause_menu.show()
# when you need a new scene:
queue.queue_resource("res://level_1.tscn", true) # Use "true" as the second argument to put it at the front
# of the queue, pausing the load of any other resource.
# When you need a new scene:
queue.queue_resource("res://level_1.tscn", true)
# Use "true" as the second argument to put it at the front of the queue,
# pausing the load of any other resource.
# to check progress
# To check progress.
if queue.is_ready("res://level_1.tscn"):
show_new_level(queue.get_resource("res://level_1.tscn"))
else:
update_progress(queue.get_progress("res://level_1.tscn"))
# when the user walks away from the trigger zone in your Metroidvania game:
# When the user walks away from the trigger zone in your Metroidvania game:
queue.cancel_resource("res://zone_2.tscn")
**Note**: this code, in its current form, is not tested in real world

View File

@@ -137,26 +137,26 @@ way to pull the data out of the file as well.
# Note: This can be called from anywhere inside the tree. This function is
# path independent.
# Go through everything in the persist category and ask them to return a
# dict of relevant variables
# dict of relevant variables.
func save_game():
var save_game = File.new()
save_game.open("user://savegame.save", File.WRITE)
var save_nodes = get_tree().get_nodes_in_group("Persist")
for node in save_nodes:
# Check the node is an instanced scene so it can be instanced again during load
# Check the node is an instanced scene so it can be instanced again during load.
if node.filename.empty():
print("persistent node '%s' is not an instanced scene, skipped" % node.name)
continue
# Check the node has a save function
# Check the node has a save function.
if !node.has_method("save"):
print("persistent node '%s' is missing a save() function, skipped" % node.name)
continue
# Call the node's save function
# Call the node's save function.
var node_data = node.call("save")
# Store the save dictionary as a new line in the save file
# Store the save dictionary as a new line in the save file.
save_game.store_line(to_json(node_data))
save_game.close()
@@ -165,7 +165,7 @@ way to pull the data out of the file as well.
// Note: This can be called from anywhere inside the tree. This function is
// path independent.
// Go through everything in the persist category and ask them to return a
// dict of relevant variables
// dict of relevant variables.
public void SaveGame()
{
var saveGame = new File();
@@ -174,24 +174,24 @@ way to pull the data out of the file as well.
var saveNodes = GetTree().GetNodesInGroup("Persist");
foreach (Node saveNode in saveNodes)
{
// Check the node is an instanced scene so it can be instanced again during load
// Check the node is an instanced scene so it can be instanced again during load.
if (saveNode.Filename.Empty())
{
GD.Print(String.Format("persistent node '{0}' is not an instanced scene, skipped", saveNode.Name));
continue;
}
// Check the node has a save function
// Check the node has a save function.
if (!saveNode.HasMethod("Save"))
{
GD.Print(String.Format("persistent node '{0}' is missing a Save() function, skipped", saveNode.Name));
continue;
}
// Call the node's save function
// Call the node's save function.
var nodeData = saveNode.Call("Save");
// Store the save dictionary as a new line in the save file
// Store the save dictionary as a new line in the save file.
saveGame.StoreLine(JSON.Print(nodeData));
}
@@ -240,6 +240,7 @@ load function:
if i == "filename" or i == "parent" or i == "pos_x" or i == "pos_y":
continue
new_object.set(i, node_data[i])
save_game.close()
.. code-tab:: csharp

View File

@@ -55,6 +55,7 @@ efficient for millions of objects, but for a few thousands, GDScript should be f
extends MultiMeshInstance
func _ready():
# Create the multimesh.
multimesh = MultiMesh.new()
@@ -66,6 +67,7 @@ efficient for millions of objects, but for a few thousands, GDScript should be f
multimesh.instance_count = 10000
# Maybe not all of them should be visible at first.
multimesh.visible_instance_count = 1000
# Set the transform of the instances.
for i in multimesh.visible_instance_count:
multimesh.set_instance_transform(i, Transform(Basis(), Vector3(i * 20, 0, 0)))
@@ -88,6 +90,7 @@ efficient for millions of objects, but for a few thousands, GDScript should be f
multimesh.InstanceCount = 1000;
// Maybe not all of them should be visible at first.
multimesh.VisibleInstanceCount = 1000;
// Set the transform of the instances.
for (int i = 0; i < multimesh.VisibleInstanceCount; i++)
{

View File

@@ -91,9 +91,11 @@ This is a simple example of how to create a sprite from code and move it using t
extends Node2D
# VisualServer expects references to be kept around
# VisualServer expects references to be kept around.
var sprite
func _ready():
# Create a canvas item, child of this node.
var ci_rid = VisualServer.canvas_item_create()
@@ -130,9 +132,11 @@ The 3D APIs are different from the 2D ones, so the instantiation API must be use
extends Spatial
# VisualServer expects references to be kept around
# VisualServer expects references to be kept around.
var mesh
func _ready():
# Create a visual instance (for 3D).
var instance = VisualServer.instance_create()
@@ -157,14 +161,16 @@ and moves a :ref:`CanvasItem <class_CanvasItem>` when the body moves.
.. tabs::
.. code-tab:: gdscript GDScript
# Physics2DServer expects references to be kept around
# Physics2DServer expects references to be kept around.
var body
var shape
func _body_moved(state, index):
# Created your own canvas item, use it here.
VisualServer.canvas_item_set_transform(canvas_item, state.transform)
func _ready():
# Create the body.
body = Physics2DServer.body_create()

View File

@@ -51,12 +51,15 @@ when needed:
tool
extends EditorPlugin
var import_plugin
func _enter_tree():
import_plugin = preload("import_plugin.gd").new()
add_import_plugin(import_plugin)
func _exit_tree():
remove_import_plugin(import_plugin)
import_plugin = null
@@ -90,6 +93,7 @@ Let's begin to code our plugin, one method at time:
tool
extends EditorImportPlugin
func get_importer_name():
return "demos.sillymaterial"
@@ -178,8 +182,10 @@ good practice to use an enum so you can refer to them using names.
tool
extends EditorImportPlugin
enum Presets { DEFAULT }
...
Now that the enum is defined, let's keep looking at the methods of an import

View File

@@ -20,16 +20,19 @@ getting a ``plugin.cfg`` file created, and start with our
.. tabs::
.. code-tab:: gdscript GDScript
# MyEditorPlugin.gd
tool
extends EditorPlugin
tool extends EditorPlugin
var plugin: EditorInspectorPlugin
var plugin
func _enter_tree():
# EditorInspectorPlugin is a resource, so we use `new()` instead of `instance()`.
plugin = preload("res://addons/MyPlugin/MyInspectorPlugin.gd").new()
add_inspector_plugin(plugin)
func _exit_tree():
remove_inspector_plugin(plugin)
@@ -53,9 +56,9 @@ overriding or changing existing property editors.
.. code-tab:: gdscript GDScript
# MyInspectorPlugin.gd
extends EditorInspectorPlugin
func can_handle(object):
# Here you can specify which object types (classes) should be handled by
# this plugin. For example if the plugin is specific to your player
@@ -64,6 +67,7 @@ overriding or changing existing property editors.
# In this example we'll support all objects, so:
return true
func parse_property(object, type, path, hint, hint_text, usage):
# We will handle properties of type integer.
if type == TYPE_INT:
@@ -91,9 +95,11 @@ the inspector.
extends EditorProperty
class_name MyIntEditor
var updating = false
var spin = EditorSpinSlider.new()
func _init():
# We'll add an EditorSpinSlider control, which is the same that the
# inspector already uses for integer and float edition.
@@ -108,11 +114,13 @@ the inspector.
spin.set_max(1000)
spin.connect("value_changed", self, "_spin_changed")
func _spin_changed(value):
if (updating):
return
emit_changed(get_edited_property(), value)
func update_property():
var new_value = get_edited_object()[get_edited_property()]
updating = true

View File

@@ -91,12 +91,14 @@ like this:
tool
extends EditorPlugin
func _enter_tree():
# Initialization of the plugin goes here
# Initialization of the plugin goes here.
pass
func _exit_tree():
# Clean-up of the plugin goes here
# Clean-up of the plugin goes here.
pass
.. code-tab:: csharp
@@ -110,12 +112,12 @@ like this:
{
public override void _EnterTree()
{
// Initialization of the plugin goes here
// Initialization of the plugin goes here.
}
public override void _ExitTree()
{
// Clean-up of the plugin goes here
// Clean-up of the plugin goes here.
}
}
#endif
@@ -156,9 +158,11 @@ clicked. For that, we'll need a simple script that extends from
tool
extends Button
func _enter_tree():
connect("pressed", self, "clicked")
func clicked():
print("You clicked me!")
@@ -198,14 +202,16 @@ dialog. For that, change the ``custom_node.gd`` script to the following:
tool
extends EditorPlugin
func _enter_tree():
# Initialization of the plugin goes here
# Add the new type with a name, a parent type, a script and an icon
# Initialization of the plugin goes here.
# Add the new type with a name, a parent type, a script and an icon.
add_custom_type("MyButton", "Button", preload("my_button.gd"), preload("icon.png"))
func _exit_tree():
# Clean-up of the plugin goes here
# Always remember to remove it from the engine when deactivated
# Clean-up of the plugin goes here.
# Always remember to remove it from the engine when deactivated.
remove_custom_type("MyButton")
.. code-tab:: csharp
@@ -219,8 +225,8 @@ dialog. For that, change the ``custom_node.gd`` script to the following:
{
public override void _EnterTree()
{
// Initialization of the plugin goes here
// Add the new type with a name, a parent type, a script and an icon
// Initialization of the plugin goes here.
// Add the new type with a name, a parent type, a script and an icon.
var script = GD.Load<Script>("MyButton.cs");
var texture = GD.Load<Texture>("icon.png");
AddCustomType("MyButton", "Button", script, texture);
@@ -228,8 +234,8 @@ dialog. For that, change the ``custom_node.gd`` script to the following:
public override void _ExitTree()
{
// Clean-up of the plugin goes here
// Always remember to remove it from the engine when deactivated
// Clean-up of the plugin goes here.
// Always remember to remove it from the engine when deactivated.
RemoveCustomType("MyButton");
}
}
@@ -312,23 +318,26 @@ The script could look like this:
tool
extends EditorPlugin
# A class member to hold the dock during the plugin life cycle
# A class member to hold the dock during the plugin life cycle.
var dock
func _enter_tree():
# Initialization of the plugin goes here
# Load the dock scene and instance it
# Initialization of the plugin goes here.
# Load the dock scene and instance it.
dock = preload("res://addons/my_custom_dock/my_dock.tscn").instance()
# Add the loaded scene to the docks
# Add the loaded scene to the docks.
add_control_to_dock(DOCK_SLOT_LEFT_UL, dock)
# Note that LEFT_UL means the left of the editor, upper-left dock
# Note that LEFT_UL means the left of the editor, upper-left dock.
func _exit_tree():
# Clean-up of the plugin goes here
# Remove the dock
# Clean-up of the plugin goes here.
# Remove the dock.
remove_control_from_docks(dock)
# Erase the control from the memory
# Erase the control from the memory.
dock.free()
.. code-tab:: csharp
@@ -350,10 +359,10 @@ The script could look like this:
public override void _ExitTree()
{
// Clean-up of the plugin goes here
// Remove the dock
// Clean-up of the plugin goes here.
// Remove the dock.
RemoveControlFromDocks(dock);
// Erase the control from the memory
// Erase the control from the memory.
dock.Free();
}
}

View File

@@ -29,9 +29,9 @@ This would be a basic setup:
::
# MyCustomGizmoPlugin.gd
extends EditorSpatialGizmoPlugin
func get_name():
return "CustomNode"
@@ -39,17 +39,19 @@ This would be a basic setup:
::
# MyCustomEditorPlugin.gd
tool
extends EditorPlugin
const MyCustomGizmoPlugin = preload("res://addons/my-addon/MyCustomGizmoPlugin.gd")
var gizmo_plugin = MyCustomGizmoPlugin.new()
func _enter_tree():
add_spatial_gizmo_plugin(gizmo_plugin)
func _exit_tree():
remove_spatial_gizmo_plugin(gizmo_plugin)
@@ -69,8 +71,11 @@ method so that it returns ``true`` when the spatial parameter is of our target t
# ...
func has_gizmo(spatial):
return spatial is MyCustomSpatial
# ...
Then we can override methods like :ref:`redraw()<class_EditorSpatialGizmoPlugin_method_redraw>`
@@ -80,10 +85,12 @@ or all the handle related ones.
# ...
func _init():
create_material("main", Color(1, 0, 0))
create_handle_material("handles")
func redraw(gizmo):
gizmo.clear()
@@ -102,6 +109,7 @@ or all the handle related ones.
gizmo.add_lines(lines, get_material("main", gizmo), false)
gizmo.add_handles(handles, get_material("handles", gizmo))
# ...
Note that we created a material in the `_init` method, and retrieved it in the `redraw`
@@ -115,15 +123,19 @@ So the final plugin would look somewhat like this:
extends EditorSpatialGizmoPlugin
const MyCustomSpatial = preload("res://addons/my-addon/MyCustomSpatial.gd")
func _init():
create_material("main", Color(1,0,0))
create_handle_material("handles")
func has_gizmo(spatial):
return spatial is MyCustomSpatial
func redraw(gizmo):
gizmo.clear()
@@ -142,8 +154,9 @@ So the final plugin would look somewhat like this:
gizmo.add_lines(lines, get_material("main", gizmo), false)
gizmo.add_handles(handles, get_material("handles", gizmo))
# you should implement the rest of handle-related callbacks
# (get_handle_name(), get_handle_value(), commit_handle()...)
# You should implement the rest of handle-related callbacks
# (get_handle_name(), get_handle_value(), commit_handle()...).
Note that we just added some handles in the redraw method, but we still need to implement
the rest of handle-related callbacks in :ref:`EditorSpatialGizmoPlugin <class_EditorSpatialGizmoPlugin>`
@@ -165,13 +178,16 @@ for the Spatial nodes we want to target.
# MyCustomGizmoPlugin.gd
extends EditorSpatialGizmoPlugin
const MyCustomSpatial = preload("res://addons/my-addon/MyCustomSpatial.gd")
const MyCustomGizmo = preload("res://addons/my-addon/MyCustomGizmo.gd")
func _init():
create_material("main", Color(1, 0, 0))
create_handle_material("handles")
func create_gizmo(spatial):
if spatial is MyCustomSpatial:
return MyCustomGizmo.new()
@@ -184,12 +200,13 @@ This way all the gizmo logic and drawing methods can be implemented in a new cla
::
# MyCustomGizmo.gd
extends EditorSpatialGizmo
# You can store data in the gizmo itself (more useful when working with handles)
# You can store data in the gizmo itself (more useful when working with handles).
var gizmo_size = 3.0
func redraw():
clear()
@@ -211,8 +228,9 @@ This way all the gizmo logic and drawing methods can be implemented in a new cla
var handles_material = get_plugin().get_material("handles", self)
add_handles(handles, handles_material)
# you should implement the rest of handle-related callbacks
# (get_handle_name(), get_handle_value(), commit_handle()...)
# You should implement the rest of handle-related callbacks
# (get_handle_name(), get_handle_value(), commit_handle()...).
Note that we just added some handles in the redraw method, but we still need to implement
the rest of handle-related callbacks in :ref:`EditorSpatialGizmo<class_EditorSpatialGizmo>`

View File

@@ -33,26 +33,31 @@ all you need to initialize your plugin.
::
# PerlinNoise3D.gd
tool
extends VisualShaderNodeCustom
class_name VisualShaderNodePerlinNoise3D
func _get_name():
return "PerlinNoise3D"
func _get_category():
return "MyShaderNodes"
func _get_description():
return "Classic Perlin-Noise-3D function (by Curly-Brace)"
func _get_return_icon_type():
return VisualShaderNode.PORT_TYPE_SCALAR
func _get_input_port_count():
return 4
func _get_input_port_name(port):
match port:
0:
@@ -64,6 +69,7 @@ all you need to initialize your plugin.
3:
return "time"
func _get_input_port_type(port):
match port:
0:
@@ -75,15 +81,19 @@ all you need to initialize your plugin.
3:
return VisualShaderNode.PORT_TYPE_SCALAR
func _get_output_port_count():
return 1
func _get_output_port_name(port):
return "result"
func _get_output_port_type(port):
return VisualShaderNode.PORT_TYPE_SCALAR
func _get_global_code(mode):
return """
vec3 mod289_3(vec3 x) {
@@ -106,7 +116,7 @@ all you need to initialize your plugin.
return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
}
// Classic Perlin noise
// Classic Perlin noise.
float cnoise(vec3 P) {
vec3 Pi0 = floor(P); // Integer part for indexing.
vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1.
@@ -176,6 +186,7 @@ all you need to initialize your plugin.
}
"""
func _get_code(input_vars, output_vars, mode, type):
return output_vars[0] + " = cnoise(vec3((%s.xy + %s.xy) * %s, %s)) * 0.5 + 0.5" % [input_vars[0], input_vars[1], input_vars[2], input_vars[3]]

View File

@@ -30,6 +30,7 @@ Creating a thread is very simple, just use the following code:
# Third argument is optional userdata, it can be any variable.
thread.start(self, "_thread_function", "Wafflecopter")
# Run here and exit.
# The argument is the userdata passed from start().
# If no argument was passed, this one still needs to
@@ -76,6 +77,7 @@ Here is an example of using a Mutex:
var mutex
var thread
# The thread will start here.
func _ready():
mutex = Mutex.new()
@@ -87,12 +89,14 @@ Here is an example of using a Mutex:
counter += 1
mutex.unlock()
# Increment the value from the thread, too.
func _thread_function(userdata):
mutex.lock()
counter += 1
mutex.unlock()
# Thread must be disposed (or "joined"), for portability.
func _exit_tree():
thread.wait_to_finish()
@@ -120,6 +124,7 @@ ready to be processed:
var thread
var exit_thread = false
# The thread will start here.
func _ready():
mutex = Mutex.new()
@@ -129,6 +134,7 @@ ready to be processed:
thread = Thread.new()
thread.start(self, "_thread_function")
func _thread_function(userdata):
while true:
semaphore.wait() # Wait until posted.
@@ -144,9 +150,11 @@ ready to be processed:
counter += 1 # Increment counter, protect with Mutex.
mutex.unlock()
func increment_counter():
semaphore.post() # Make the thread process.
func get_counter():
mutex.lock()
# Copy counter, protect with Mutex.
@@ -154,6 +162,7 @@ ready to be processed:
mutex.unlock()
return counter_value
# Thread must be disposed (or "joined"), for portability.
func _exit_tree():
# Set exit condition to true.

View File

@@ -58,14 +58,14 @@ shader resource to it. You can access your rendered ``Viewport`` with the built-
.. code-block:: glsl
// Inside the Shader
// Inside the Shader.
uniform sampler2D ViewportTexture;
And you can pass the texture into the shader from GDScript like so:
::
# In GDScript
# In GDScript.
func _ready():
$Sprite.material.set_shader_param("ViewportTexture", $Viewport.get_texture())
@@ -133,7 +133,7 @@ does not matter:
shader_type canvas_item;
//Blurs the screen in the X-direction.
// Blurs the screen in the X-direction.
void fragment() {
vec3 col = texture(TEXTURE, SCREEN_UV).xyz * 0.16;
col += texture(TEXTURE, SCREEN_UV + vec2(SCREEN_PIXEL_SIZE.x, 0.0)).xyz * 0.15;
@@ -151,7 +151,7 @@ does not matter:
shader_type canvas_item;
//Blurs the screen in the Y-direction.
// Blurs the screen in the Y-direction.
void fragment() {
vec3 col = texture(TEXTURE, SCREEN_UV).xyz * 0.16;
col += texture(TEXTURE, SCREEN_UV + vec2(0.0, SCREEN_PIXEL_SIZE.y)).xyz * 0.15;

View File

@@ -97,7 +97,7 @@ different from the one specified in size, by calling:
::
viewport.set_size_override(true, Vector2(width, height)) # Custom size for 2D
viewport.set_size_override(true, Vector2(width, height)) # Custom size for 2D.
viewport.set_size_override_stretch(true) # Enable stretch for custom size.
The root :ref:`Viewport <class_Viewport>` uses this for the stretch options in the project
@@ -155,7 +155,7 @@ it using (for example):
::
# Wait until the frame has finished before getting the texture
# Wait until the frame has finished before getting the texture.
yield(VisualServer, "frame_post_draw")
# You can get the image after this.

View File

@@ -50,11 +50,14 @@ Now add a script to the main node and add the following code:
extends Spatial
var perform_runtime_config = false
onready var ovr_init_config = preload("res://addons/godot_ovrmobile/OvrInitConfig.gdns").new()
onready var ovr_performance = preload("res://addons/godot_ovrmobile/OvrPerformance.gdns").new()
func _ready():
var interface = ARVRServer.find_interface("OVRMobile")
if interface:
@@ -65,7 +68,7 @@ Now add a script to the main node and add the following code:
func _process(_delta):
if !perform_runtime_config:
if not perform_runtime_config:
ovr_performance.set_clock_levels(1, 1)
ovr_performance.set_extra_latency_mode(1)
perform_runtime_config = true