mirror of
https://github.com/godotengine/godot-docs.git
synced 2026-01-07 02:12:07 +03:00
Merge pull request #1106 from YeldhamDev/gdscript_styling_fix
Fixes for the GDScript styling in various pages
This commit is contained in:
@@ -245,7 +245,7 @@ Example of Dictionary:
|
||||
|
||||
::
|
||||
|
||||
var d = { "name": "john", "age": 22 } # simple syntax
|
||||
var d = {"name": "john", "age": 22} # simple syntax
|
||||
print("Name: ", d["name"], " Age: ", d["age"])
|
||||
|
||||
Dictionaries are also dynamic, keys can be added or removed at any point
|
||||
@@ -271,9 +271,9 @@ easily with dictionaries. Here's a simple battleship game example:
|
||||
var board = {}
|
||||
|
||||
func initialize():
|
||||
board[Vector(1,1)] = SHIP
|
||||
board[Vector(1,2)] = SHIP
|
||||
board[Vector(1,3)] = SHIP
|
||||
board[Vector(1, 1)] = SHIP
|
||||
board[Vector(1, 2)] = SHIP
|
||||
board[Vector(1, 3)] = SHIP
|
||||
|
||||
func missile(pos):
|
||||
|
||||
@@ -287,9 +287,9 @@ easily with dictionaries. Here's a simple battleship game example:
|
||||
|
||||
func game():
|
||||
initialize()
|
||||
missile(Vector2(1,1))
|
||||
missile(Vector2(5,8))
|
||||
missile(Vector2(2,3))
|
||||
missile(Vector2(1, 1))
|
||||
missile(Vector2(5, 8))
|
||||
missile(Vector2(2, 3))
|
||||
|
||||
Dictionaries can also be used as data markup or quick structures. While
|
||||
GDScript dictionaries resemble python dictionaries, it also supports Lua
|
||||
@@ -364,9 +364,9 @@ The range() function can take 3 arguments:
|
||||
|
||||
::
|
||||
|
||||
range(n) (will go from 0 to n-1)
|
||||
range(b, n) (will go from b to n-1)
|
||||
range(b, n, s) (will go from b to n-1, in steps of s)
|
||||
range(n) # will go from 0 to n-1
|
||||
range(b, n) # will go from b to n-1
|
||||
range(b, n, s) # will go from b to n-1, in steps of s
|
||||
|
||||
Some examples:
|
||||
|
||||
@@ -409,7 +409,7 @@ while() loops are the same everywhere:
|
||||
|
||||
var i = 0
|
||||
|
||||
while(i < strings.size()):
|
||||
while i < strings.size():
|
||||
print(strings[i])
|
||||
i += 1
|
||||
|
||||
@@ -472,7 +472,7 @@ checking if the function exists is desirable:
|
||||
::
|
||||
|
||||
func _on_object_hit(object):
|
||||
if (object.has_method("smash")):
|
||||
if object.has_method("smash"):
|
||||
object.smash()
|
||||
|
||||
Then, simply define that method and anything the rock touches can be
|
||||
|
||||
@@ -64,7 +64,7 @@ here's a simple example of how GDScript looks.
|
||||
var a = 5
|
||||
var s = "Hello"
|
||||
var arr = [1, 2, 3]
|
||||
var dict = {"key":"value", 2:3}
|
||||
var dict = {"key": "value", 2:3}
|
||||
|
||||
# constants
|
||||
|
||||
@@ -96,7 +96,7 @@ here's a simple example of how GDScript looks.
|
||||
for i in range(20):
|
||||
print(i)
|
||||
|
||||
while(param2 != 0):
|
||||
while param2 != 0:
|
||||
param2 -= 1
|
||||
|
||||
var local_var2 = param1+3
|
||||
@@ -426,13 +426,13 @@ Starting with Godot 2.1, indices may be negative like in Python, to count from t
|
||||
|
||||
::
|
||||
|
||||
var arr=[]
|
||||
arr=[1, 2, 3]
|
||||
var b = arr[1] # this is 2
|
||||
var c = arr[arr.size()-1] # this is 3
|
||||
var d = arr[-1] # same as the previous line, but shorter
|
||||
arr[0] = "Hi!" # replacing value 1 with "Hi"
|
||||
arr.append(4) # array is now ["Hi", 2, 3, 4]
|
||||
var arr = []
|
||||
arr = [1, 2, 3]
|
||||
var b = arr[1] # this is 2
|
||||
var c = arr[arr.size() - 1] # this is 3
|
||||
var d = arr[-1] # same as the previous line, but shorter
|
||||
arr[0] = "Hi!" # replacing value 1 with "Hi"
|
||||
arr.append(4) # array is now ["Hi", 2, 3, 4]
|
||||
|
||||
GDScript arrays are allocated linearly in memory for speed. Very
|
||||
large arrays (more than tens of thousands of elements) may however cause
|
||||
@@ -456,13 +456,13 @@ Associative container which contains values referenced by unique keys.
|
||||
|
||||
::
|
||||
|
||||
var d={4:5, "a key":"a value", 28:[1,2,3]}
|
||||
var d = {4: 5, "a key": "a value", 28: [1, 2, 3]}
|
||||
d["Hi!"] = 0
|
||||
d = {
|
||||
22 : "Value",
|
||||
"somekey" : 2,
|
||||
"otherkey" : [2,3,4],
|
||||
"morekey" : "Hello"
|
||||
22: "Value",
|
||||
"somekey": 2,
|
||||
"otherkey": [2, 3, 4],
|
||||
"morekey": "Hello"
|
||||
}
|
||||
|
||||
Lua-style table syntax is also supported. Lua-style uses ``=`` instead of ``:``
|
||||
@@ -475,7 +475,7 @@ start with a digit.
|
||||
var d = {
|
||||
test22 = "Value",
|
||||
somekey = 2,
|
||||
otherkey = [2,3,4],
|
||||
otherkey = [2, 3, 4],
|
||||
morekey = "Hello"
|
||||
}
|
||||
|
||||
@@ -483,7 +483,7 @@ To add a key to an existing dictionary, access it like an existing key and
|
||||
assign to it::
|
||||
|
||||
var d = {} # create an empty Dictionary
|
||||
d.Waiting = 14 # add String "Waiting" as a key and assign the value 14 to it
|
||||
d.waiting = 14 # add String "Waiting" as a key and assign the value 14 to it
|
||||
d[4] = "hello" # add integer `4` as a key and assign the String "hello" as its value
|
||||
d["Godot"] = 3.01 # add String "Godot" as a key and assign the value 3.01 to it
|
||||
|
||||
@@ -499,10 +499,10 @@ value upon initialization.
|
||||
|
||||
::
|
||||
|
||||
var a # data type is null by default
|
||||
var a # data type is null by default
|
||||
var b = 5
|
||||
var c = 3.8
|
||||
var d = b + c # variables are always initialized in order
|
||||
var d = b + c # variables are always initialized in order
|
||||
|
||||
Constants
|
||||
~~~~~~~~~
|
||||
@@ -515,10 +515,10 @@ expressions and must be assigned on initialization.
|
||||
const a = 5
|
||||
const b = Vector2(20, 20)
|
||||
const c = 10 + 20 # constant expression
|
||||
const d = Vector2(20, 30).x # constant expression: 20
|
||||
const e = [1, 2, 3, 4][0] # constant expression: 1
|
||||
const f = sin(20) # sin() can be used in constant expressions
|
||||
const g = x + 20 # invalid; this is not a constant expression!
|
||||
const d = Vector2(20, 30).x # constant expression: 20
|
||||
const e = [1, 2, 3, 4][0] # constant expression: 1
|
||||
const f = sin(20) # sin() can be used in constant expressions
|
||||
const g = x + 20 # invalid; this is not a constant expression!
|
||||
|
||||
Enums
|
||||
^^^^^
|
||||
@@ -637,7 +637,7 @@ nature of the tab-based indentation, ``elif`` can be used instead of
|
||||
|
||||
Short statements can be written on the same line as the condition::
|
||||
|
||||
if (1 + 1 == 2): return 2 + 2
|
||||
if 1 + 1 == 2: return 2 + 2
|
||||
else:
|
||||
var x = 3 + 3
|
||||
return x
|
||||
@@ -670,23 +670,23 @@ in the loop variable.
|
||||
::
|
||||
|
||||
for x in [5, 7, 11]:
|
||||
statement # loop iterates 3 times with x as 5, then 7 and finally 11
|
||||
statement # loop iterates 3 times with x as 5, then 7 and finally 11
|
||||
|
||||
var dict = {"a":0, "b":1, "c":2}
|
||||
var dict = {"a": 0, "b": 1, "c": 2}
|
||||
for i in dict:
|
||||
print(dict[i]) # loop provides the keys in an arbitrary order; may print 0, 1, 2, or 2, 0, 1, etc...
|
||||
print(dict[i])
|
||||
|
||||
for i in range(3):
|
||||
statement # similar to [0, 1, 2] but does not allocate an array
|
||||
statement # similar to [0, 1, 2] but does not allocate an array
|
||||
|
||||
for i in range(1,3):
|
||||
statement # similar to [1, 2] but does not allocate an array
|
||||
statement # similar to [1, 2] but does not allocate an array
|
||||
|
||||
for i in range(2,8,2):
|
||||
statement # similar to [2, 4, 6] but does not allocate an array
|
||||
statement # similar to [2, 4, 6] but does not allocate an array
|
||||
|
||||
for c in "Hello":
|
||||
print(c) # iterate through all characters in a String, print every letter on new line
|
||||
print(c) # iterate through all characters in a String, print every letter on new line
|
||||
|
||||
match
|
||||
^^^^^
|
||||
@@ -914,7 +914,7 @@ function.
|
||||
|
||||
::
|
||||
|
||||
# inside a class file
|
||||
# Inside a class file
|
||||
|
||||
# An inner class in this class file
|
||||
class SomeInnerClass:
|
||||
@@ -955,7 +955,7 @@ is done by using the ``export`` keyword::
|
||||
|
||||
extends Button
|
||||
|
||||
export var number = 5 # value will be saved and visible in the property editor
|
||||
export var number = 5 # value will be saved and visible in the property editor
|
||||
|
||||
An exported variable must be initialized to a constant expression or have an
|
||||
export hint in the form of an argument to the export keyword (see below).
|
||||
@@ -1032,11 +1032,11 @@ special export syntax is provided.
|
||||
# Colors
|
||||
|
||||
# Color given as Red-Green-Blue value
|
||||
export(Color, RGB) var col # Color is RGB
|
||||
export(Color, RGB) var col # Color is RGB
|
||||
# Color given as Red-Green-Blue-Alpha value
|
||||
export(Color, RGBA) var col # Color is RGBA
|
||||
export(Color, RGBA) var col # Color is RGBA
|
||||
|
||||
# another node in the scene can be exported too
|
||||
# Another node in the scene can be exported too
|
||||
|
||||
export(NodePath) var node
|
||||
|
||||
@@ -1149,11 +1149,11 @@ illustration of this:
|
||||
|
||||
func _init():
|
||||
# Does not trigger setter/getter
|
||||
myinteger=5
|
||||
myinteger = 5
|
||||
print(myinteger)
|
||||
|
||||
# Does trigger setter/getter
|
||||
self.myinteger=5
|
||||
self.myinteger = 5
|
||||
print(self.myinteger)
|
||||
|
||||
Tool mode
|
||||
@@ -1209,11 +1209,11 @@ declared and connect it to the method of another instance:
|
||||
print("Got callback!")
|
||||
|
||||
func _callback_args(a,b):
|
||||
print("Got callback with args! a: ",a," and b: ",b)
|
||||
print("Got callback with args! a: ", a, " and b: ", b)
|
||||
|
||||
func _at_some_func():
|
||||
instance.connect("your_signal_name",self,"_callback_no_args")
|
||||
instance.connect("your_signal_name_with_args",self,"_callback_args")
|
||||
instance.connect("your_signal_name", self, "_callback_no_args")
|
||||
instance.connect("your_signal_name_with_args", self, "_callback_args")
|
||||
|
||||
It is also possible to bind arguments to a signal that lacks them with
|
||||
your custom values:
|
||||
@@ -1221,7 +1221,7 @@ your custom values:
|
||||
::
|
||||
|
||||
func _at_some_func():
|
||||
instance.connect("your_signal_name",self,"_callback_args",[22,"hello"])
|
||||
instance.connect("your_signal_name", self, "_callback_args", [22, "hello"])
|
||||
|
||||
This is very useful when a signal from many objects is connected to a
|
||||
single callback and the sender must be identified:
|
||||
@@ -1229,11 +1229,11 @@ single callback and the sender must be identified:
|
||||
::
|
||||
|
||||
func _button_pressed(which):
|
||||
print("Button was pressed: ",which.get_name())
|
||||
print("Button was pressed: ", which.get_name())
|
||||
|
||||
func _ready():
|
||||
for b in get_node("buttons").get_children():
|
||||
b.connect("pressed",self,"_button_pressed",[b])
|
||||
b.connect("pressed", self, "_button_pressed",[b])
|
||||
|
||||
Finally, emitting a custom signal is done by using the
|
||||
Object.emit_signal method:
|
||||
@@ -1242,7 +1242,7 @@ Object.emit_signal method:
|
||||
|
||||
func _at_some_func():
|
||||
emit_signal("your_signal_name")
|
||||
emit_signal("your_signal_name_with_args",55,128)
|
||||
emit_signal("your_signal_name_with_args", 55, 128)
|
||||
someinstance.emit_signal("somesignal")
|
||||
|
||||
Coroutines
|
||||
@@ -1259,13 +1259,11 @@ an example:
|
||||
::
|
||||
|
||||
func myfunc():
|
||||
|
||||
print("hello")
|
||||
yield()
|
||||
print("world")
|
||||
|
||||
func _ready():
|
||||
|
||||
var y = myfunc()
|
||||
# Function state saved in 'y'
|
||||
print("my dear")
|
||||
@@ -1286,16 +1284,14 @@ example:
|
||||
::
|
||||
|
||||
func myfunc():
|
||||
|
||||
print("hello")
|
||||
print( yield() )
|
||||
print(yield())
|
||||
return "cheers!"
|
||||
|
||||
func _ready():
|
||||
|
||||
var y = myfunc()
|
||||
# Function state saved in 'y'
|
||||
print( y.resume("world") )
|
||||
print(y.resume("world"))
|
||||
# 'y' resumed and is now an invalid state
|
||||
|
||||
Will print:
|
||||
|
||||
@@ -224,7 +224,7 @@ Next, write a function which will be called when the button is pressed:
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
func _on_button_pressed():
|
||||
get_node("Label").text="HELLO!"
|
||||
get_node("Label").text = "HELLO!"
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
@@ -234,10 +234,6 @@ Next, write a function which will be called when the button is pressed:
|
||||
label.Text = "HELLO!";
|
||||
}
|
||||
|
||||
.. group-tab:: VS
|
||||
|
||||
.. image:: img/signals.png
|
||||
|
||||
Finally, connect the button's "pressed" signal to ``_ready()`` by
|
||||
using :ref:`Object.connect() <class_Object_connect>`.
|
||||
|
||||
@@ -245,7 +241,7 @@ using :ref:`Object.connect() <class_Object_connect>`.
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
func _ready():
|
||||
get_node("Button").connect("pressed",self,"_on_button_pressed")
|
||||
get_node("Button").connect("pressed", self, "_on_button_pressed")
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
@@ -262,10 +258,10 @@ The final script should look like this:
|
||||
extends Panel
|
||||
|
||||
func _on_button_pressed():
|
||||
get_node("Label").text="HELLO!"
|
||||
get_node("Label").text = "HELLO!"
|
||||
|
||||
func _ready():
|
||||
get_node("Button").connect("pressed",self,"_on_button_pressed")
|
||||
get_node("Button").connect("pressed", self, "_on_button_pressed")
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ how many frames per second (FPS) the application is running at:
|
||||
|
||||
func _process(delta):
|
||||
# do something...
|
||||
pass
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
@@ -59,7 +60,7 @@ with the following script:
|
||||
|
||||
extends Label
|
||||
|
||||
var accum=0
|
||||
var accum = 0
|
||||
|
||||
func _process(delta):
|
||||
accum += delta
|
||||
@@ -156,11 +157,11 @@ function in your script:
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
func _notification(what):
|
||||
if (what == NOTIFICATION_READY):
|
||||
print("This is the same as overriding _ready()...")
|
||||
elif (what == NOTIFICATION_PROCESS):
|
||||
var delta = get_process_time()
|
||||
print("This is the same as overriding _process()...")
|
||||
match what:
|
||||
NOTIFICATION_READY:
|
||||
print("This is the same as overriding _ready()...")
|
||||
NOTIFICATION_PROCESS:
|
||||
print("This is the same as overriding _process()...")
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ way:
|
||||
|
||||
::
|
||||
|
||||
var local_pos = Vector2(10,20) # local to Control/Node2D
|
||||
var local_pos = Vector2(10, 20) # local to Control/Node2D
|
||||
var ie = InputEventMouseButton.new()
|
||||
ie.button_index = BUTTON_LEFT
|
||||
ie.position = get_viewport_transform() * (get_global_transform() * local_pos)
|
||||
|
||||
@@ -70,13 +70,13 @@ redrawn if modified:
|
||||
export var texture setget _set_texture
|
||||
|
||||
func _set_texture(value):
|
||||
#if the texture variable is modified externally,
|
||||
#this callback is called.
|
||||
texture=value #texture was changed
|
||||
update() #update the node
|
||||
# if the texture variable is modified externally,
|
||||
# this callback is called.
|
||||
texture = value #texture was changed
|
||||
update() # update the node
|
||||
|
||||
func _draw():
|
||||
draw_texture(texture,Vector2())
|
||||
draw_texture(texture, Vector2())
|
||||
|
||||
In some cases, it may be desired to draw every frame. For this, just
|
||||
call update() from the _process() callback, like this:
|
||||
@@ -110,17 +110,17 @@ Basically, drawing a shape on screen requires it to be decomposed into a certain
|
||||
|
||||
::
|
||||
|
||||
func draw_circle_arc( center, radius, angle_from, angle_to, color ):
|
||||
func draw_circle_arc(center, radius, angle_from, angle_to, color):
|
||||
var nb_points = 32
|
||||
var points_arc = Vector2Array()
|
||||
|
||||
for i in range(nb_points+1):
|
||||
var angle_point = angle_from + i*(angle_to-angle_from)/nb_points - 90
|
||||
var point = center + Vector2( cos(deg2rad(angle_point)), sin(deg2rad(angle_point)) ) * radius
|
||||
points_arc.push_back( point )
|
||||
var angle_point = angle_from + i * (angle_to-angle_from) / nb_points - 90
|
||||
var point = center + Vector2(cos(deg2rad(angle_point)), sin(deg2rad(angle_point))) * radius
|
||||
points_arc.push_back(point)
|
||||
|
||||
for indexPoint in range(nb_points):
|
||||
draw_line(points_arc[indexPoint], points_arc[indexPoint+1], color)
|
||||
for index_point in range(nb_points):
|
||||
draw_line(points_arc[index_point], points_arc[index_point + 1], color)
|
||||
|
||||
Remember the number of points our shape has to be decomposed into? We fixed this number in the nb_points variable to a value of 32. Then, we initialize an empty Vector2Array, which is simply an array of Vector2.
|
||||
|
||||
@@ -139,12 +139,12 @@ We now have a function that draws stuff on the screen: it is time to call in the
|
||||
::
|
||||
|
||||
func _draw():
|
||||
var center = Vector2(200,200)
|
||||
var center = Vector2(200, 200)
|
||||
var radius = 80
|
||||
var angle_from = 75
|
||||
var angle_to = 195
|
||||
var color = Color(1.0, 0.0, 0.0)
|
||||
draw_circle_arc( center, radius, angle_from, angle_to, color )
|
||||
draw_circle_arc(center, radius, angle_from, angle_to, color)
|
||||
|
||||
Result:
|
||||
|
||||
@@ -158,15 +158,15 @@ We can take this a step further and not only write a function that draws the pla
|
||||
|
||||
::
|
||||
|
||||
func draw_circle_arc_poly( center, radius, angle_from, angle_to, color ):
|
||||
func draw_circle_arc_poly(center, radius, angle_from, angle_to, color):
|
||||
var nb_points = 32
|
||||
var points_arc = Vector2Array()
|
||||
points_arc.push_back(center)
|
||||
var colors = ColorArray([color])
|
||||
|
||||
for i in range(nb_points+1):
|
||||
var angle_point = angle_from + i*(angle_to-angle_from)/nb_points - 90
|
||||
points_arc.push_back(center + Vector2( cos( deg2rad(angle_point) ), sin( deg2rad(angle_point) ) ) * radius)
|
||||
var angle_point = angle_from + i * (angle_to - angle_from) / nb_points - 90
|
||||
points_arc.push_back(center + Vector2(cos(deg2rad(angle_point)), sin(deg2rad(angle_point))) * radius)
|
||||
draw_polygon(points_arc, colors)
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ Finally, we must not forget to call the update() function, which automatically c
|
||||
angle_to += rotation_ang
|
||||
|
||||
# we only wrap angles if both of them are bigger than 360
|
||||
if (angle_from > 360 && angle_to > 360):
|
||||
if angle_from > 360 and angle_to > 360:
|
||||
angle_from = wrap(angle_from, 0, 360)
|
||||
angle_to = wrap(angle_to, 0, 360)
|
||||
update()
|
||||
@@ -218,7 +218,7 @@ Also, don't forget to modify the _draw() function to make use of these variables
|
||||
::
|
||||
|
||||
func _draw():
|
||||
var center = Vector2(200,200)
|
||||
var center = Vector2(200, 200)
|
||||
var radius = 80
|
||||
var color = Color(1.0, 0.0, 0.0)
|
||||
|
||||
@@ -238,7 +238,7 @@ In our case, we simply need to multiply our 'rotation_ang' variable by 'delta' i
|
||||
angle_to += rotation_ang * delta
|
||||
|
||||
# we only wrap angles if both of them are bigger than 360
|
||||
if (angle_from > 360 && angle_to > 360):
|
||||
if angle_from > 360 and angle_to > 360:
|
||||
angle_from = wrap(angle_from, 0, 360)
|
||||
angle_to = wrap(angle_to, 0, 360)
|
||||
update()
|
||||
|
||||
@@ -67,9 +67,9 @@ We will just use exported variable for bone length to be easy.
|
||||
|
||||
::
|
||||
|
||||
export var IK_bone="lowerarm"
|
||||
export var IK_bone_length=1.0
|
||||
export var IK_error = 0.1
|
||||
export var ik_bone = "lowerarm"
|
||||
export var ik_bone_length = 1.0
|
||||
export var ik_error = 0.1
|
||||
|
||||
Now, we need to apply our transformations from IK bone to the base of
|
||||
chain. So we apply rotation to IK bone then move from our IK bone up to
|
||||
@@ -78,7 +78,7 @@ current bone again, etc. So we need to limit our chain somewhat.
|
||||
|
||||
::
|
||||
|
||||
export var IK_limit = 2
|
||||
export var ik_limit = 2
|
||||
|
||||
For ``_ready()`` function:
|
||||
|
||||
@@ -94,8 +94,8 @@ Now we can write our chain-passing function:
|
||||
::
|
||||
|
||||
func pass_chain():
|
||||
var b = skel.find_bone(IK_bone)
|
||||
var l = IK_limit
|
||||
var b = skel.find_bone(ik_bone)
|
||||
var l = ik_limit
|
||||
while b >= 0 and l > 0:
|
||||
print( "name":", skel.get_bone_name(b))
|
||||
print( "local transform":", skel.get_bone_pose(b))
|
||||
@@ -107,8 +107,8 @@ And for the ``_process()`` function:
|
||||
|
||||
::
|
||||
|
||||
func _process(dt):
|
||||
pass_chain(dt)
|
||||
func _process(delta):
|
||||
pass_chain(delta)
|
||||
|
||||
Executing this script will just pass through bone chain printing bone
|
||||
transforms.
|
||||
@@ -117,25 +117,28 @@ transforms.
|
||||
|
||||
extends Spatial
|
||||
|
||||
export var IK_bone="lowerarm"
|
||||
export var IK_bone_length=1.0
|
||||
export var IK_error = 0.1
|
||||
export var IK_limit = 2
|
||||
export var ik_bone = "lowerarm"
|
||||
export var ik_bone_length = 1.0
|
||||
export var ik_error = 0.1
|
||||
export var ik_limit = 2
|
||||
var skel
|
||||
|
||||
func _ready():
|
||||
skel = get_node("arm/Armature/Skeleton")
|
||||
set_process(true)
|
||||
func pass_chain(dt):
|
||||
var b = skel.find_bone(IK_bone)
|
||||
var l = IK_limit
|
||||
|
||||
func pass_chain(delta):
|
||||
var b = skel.find_bone(ik_bone)
|
||||
var l = ik_limit
|
||||
while b >= 0 and l > 0:
|
||||
print("name: ", skel.get_bone_name(b))
|
||||
print("local transform: ", skel.get_bone_pose(b))
|
||||
print( "global transform:", skel.get_bone_global_pose(b))
|
||||
b = skel.get_bone_parent(b)
|
||||
l = l - 1
|
||||
func _process(dt):
|
||||
pass_chain(dt)
|
||||
|
||||
func _process(delta):
|
||||
pass_chain(delta)
|
||||
|
||||
Now we need to actually work with target. The target should be placed
|
||||
somewhere accessible. Since "arm" is imported scene, we better place
|
||||
@@ -153,6 +156,7 @@ Then modify ``_ready()`` function to look like this:
|
||||
|
||||
var skel
|
||||
var target
|
||||
|
||||
func _ready():
|
||||
skel = get_node("arm/Armature/Skeleton")
|
||||
target = get_node("target")
|
||||
|
||||
@@ -133,9 +133,9 @@ other objects there. So lets rotate our "upperarm" bone:
|
||||
print("bone transform: ", t)
|
||||
set_process(true)
|
||||
|
||||
func _process(dt):
|
||||
func _process(delta):
|
||||
var t = skel.get_bone_pose(id)
|
||||
t = t.rotated(Vector3(0.0, 1.0, 0.0), 0.1 * dt)
|
||||
t = t.rotated(Vector3(0.0, 1.0, 0.0), 0.1 * delta)
|
||||
skel.set_bone_pose(id, t)
|
||||
|
||||
Now we can rotate individual bones. The same happens for scale and
|
||||
@@ -253,7 +253,7 @@ which does that:
|
||||
set_process(true)
|
||||
var bone = "upperarm"
|
||||
var coordinate = 0
|
||||
func _process(dt):
|
||||
func _process(delta):
|
||||
if Input.is_action_pressed("select_x"):
|
||||
coordinate = 0
|
||||
elif Input.is_action_pressed("select_y"):
|
||||
@@ -296,7 +296,7 @@ The full code for arm control is this:
|
||||
var newpose = newpose.rotated(Vector3(0.0, 0.0, 1.0), ang.z)
|
||||
skel.set_bone_pose(b, newpose)
|
||||
|
||||
func _process(dt):
|
||||
func _process(delta):
|
||||
if Input.is_action_pressed("select_x"):
|
||||
coordinate = 0
|
||||
elif Input.is_action_pressed("select_y"):
|
||||
|
||||
@@ -45,7 +45,7 @@ exists. Example
|
||||
::
|
||||
|
||||
func _draw():
|
||||
if (has_focus()):
|
||||
if has_focus():
|
||||
draw_selected()
|
||||
else:
|
||||
draw_normal()
|
||||
@@ -68,14 +68,14 @@ for example:
|
||||
::
|
||||
|
||||
func get_minimum_size():
|
||||
return Vector2(30,30)
|
||||
return Vector2(30, 30)
|
||||
|
||||
Or alternatively, set it via function:
|
||||
|
||||
::
|
||||
|
||||
func _ready():
|
||||
set_custom_minimum_size( Vector2(30,30) )
|
||||
set_custom_minimum_size(Vector2(30, 30))
|
||||
|
||||
Input
|
||||
-----
|
||||
@@ -104,8 +104,8 @@ Simply override it in your control. No processing needs to be set.
|
||||
|
||||
extends Control
|
||||
|
||||
func _gui_input(ev):
|
||||
if (ev is InputEventMouseButton and ev.button_index==BUTTON_LEFT and ev.pressed):
|
||||
func _gui_input(event):
|
||||
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed:
|
||||
print("Left mouse button was pressed!")
|
||||
|
||||
For more information about events themselves, check the :ref:`doc_inputevent`
|
||||
@@ -120,24 +120,24 @@ exists, but can be checked with the _notification callback:
|
||||
::
|
||||
|
||||
func _notification(what):
|
||||
|
||||
if (what==NOTIFICATION_MOUSE_ENTER):
|
||||
pass # mouse entered the area of this control
|
||||
elif (what==NOTIFICATION_MOUSE_EXIT):
|
||||
pass # mouse exited the area of this control
|
||||
elif (what==NOTIFICATION_FOCUS_ENTER):
|
||||
pass # control gained focus
|
||||
elif (what==NOTIFICATION_FOCUS_EXIT):
|
||||
pass # control lost focus
|
||||
elif (what==NOTIFICATION_THEME_CHANGED):
|
||||
pass # theme used to draw the control changed
|
||||
# update and redraw is recommended if using a theme
|
||||
elif (what==NOTIFICATION_VISIBILITY_CHANGED):
|
||||
pass # control became visible/invisible
|
||||
# check new status with is_visible()
|
||||
elif (what==NOTIFICATION_RESIZED):
|
||||
pass # control changed size, check new size
|
||||
# with get_size()
|
||||
elif (what==NOTIFICATION_MODAL_CLOSED):
|
||||
pass # for modal popups, notification
|
||||
# that the popup was closed
|
||||
match what:
|
||||
NOTIFICATION_MOUSE_ENTER:
|
||||
pass # mouse entered the area of this control
|
||||
NOTIFICATION_MOUSE_EXIT:
|
||||
pass # mouse exited the area of this control
|
||||
NOTIFICATION_FOCUS_ENTER:
|
||||
pass # control gained focus
|
||||
NOTIFICATION_FOCUS_EXIT:
|
||||
pass # control lost focus
|
||||
NOTIFICATION_THEME_CHANGED:
|
||||
pass # theme used to draw the control changed
|
||||
# update and redraw is recommended if using a theme
|
||||
NOTIFICATION_VISIBILITY_CHANGED:
|
||||
pass # control became visible/invisible
|
||||
# check new status with is_visible()
|
||||
NOTIFICATION_RESIZED:
|
||||
pass # control changed size, check new size
|
||||
# with get_size()
|
||||
NOTIFICATION_MODAL_CLOSED):
|
||||
pass # for modal popups, notification
|
||||
# that the popup was closed
|
||||
|
||||
@@ -70,7 +70,7 @@ An example usage:
|
||||
::
|
||||
|
||||
var t = Theme.new()
|
||||
t.set_color("font_color","Label",Color(1.0,1.0,1.0))
|
||||
t.set_color("font_color", "Label", Color(1.0, 1.0, 1.0))
|
||||
|
||||
var l = Label.new()
|
||||
l.set_theme(t)
|
||||
@@ -86,7 +86,7 @@ directly and only for a specific control by using the override API in
|
||||
::
|
||||
|
||||
var l = Label.new()
|
||||
l.add_color_override("font_color",Color(1.0,1.0,1.0))
|
||||
l.add_color_override("font_color", Color(1.0, 1.0, 1.0))
|
||||
|
||||
In the inline help of Godot (in the script tab) you can check which theme options
|
||||
are overrideable, or check the :ref:`Control <class_Control>` class reference.
|
||||
|
||||
@@ -27,17 +27,15 @@ for example:
|
||||
|
||||
::
|
||||
|
||||
func _input(ev):
|
||||
func _input(event):
|
||||
# Mouse in viewport coordinates
|
||||
|
||||
if (ev is InputEventMouseButton):
|
||||
print("Mouse Click/Unclick at: ",ev.position)
|
||||
elif (ev is InputEventMouseMotion):
|
||||
print("Mouse Motion at: ",ev.position)
|
||||
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("Viewport Resolution is: ",get_viewport_rect().size)
|
||||
print("Viewport Resolution is: ", get_viewport_rect().size)
|
||||
|
||||
func _ready():
|
||||
set_process_input(true)
|
||||
|
||||
@@ -23,7 +23,7 @@ Handling it is done as follows (on any node):
|
||||
::
|
||||
|
||||
func _notification(what):
|
||||
if (what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST):
|
||||
if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST:
|
||||
get_tree().quit() # default behavior
|
||||
|
||||
When developing mobile apps, quitting is not desired unless the user is
|
||||
|
||||
@@ -31,8 +31,8 @@ to save them and then tell them all to save with this script:
|
||||
|
||||
::
|
||||
|
||||
var savenodes = get_tree().get_nodes_in_group("Persist")
|
||||
for i in savenodes:
|
||||
var save_nodes = get_tree().get_nodes_in_group("Persist")
|
||||
for i in save_nodes:
|
||||
# Now we can call our save function on each node.
|
||||
|
||||
Serializing
|
||||
@@ -50,27 +50,27 @@ like this:
|
||||
::
|
||||
|
||||
func save():
|
||||
var savedict = {
|
||||
filename=get_filename(),
|
||||
parent=get_parent().get_path(),
|
||||
posx=get_pos().x, #Vector2 is not supported by json
|
||||
posy=get_pos().y,
|
||||
attack=attack,
|
||||
defense=defense,
|
||||
currenthealth=currenthealth,
|
||||
maxhealth=maxhealth,
|
||||
damage=damage,
|
||||
regen=regen,
|
||||
experience=experience,
|
||||
TNL=TNL,
|
||||
level=level,
|
||||
AttackGrowth=AttackGrowth,
|
||||
DefenseGrowth=DefenseGrowth,
|
||||
HealthGrowth=HealthGrowth,
|
||||
isalive=isalive,
|
||||
last_attack=last_attack
|
||||
var save_dict = {
|
||||
filename = get_filename(),
|
||||
parent = get_parent().get_path(),
|
||||
pos_x = get_pos().x, # Vector2 is not supported by JSON
|
||||
pos_y = get_pos().y,
|
||||
attack = attack,
|
||||
defense = defense,
|
||||
current_health = current_health,
|
||||
max_health = max_health,
|
||||
damage = damage,
|
||||
regen = regen,
|
||||
experience = experience,
|
||||
tnl = tnl,
|
||||
level = level,
|
||||
attack_growth = attack_growth,
|
||||
defense_growth = defense_growth,
|
||||
health_growth = health_growth,
|
||||
is_alive = is_alive,
|
||||
last_attack = last_attack
|
||||
}
|
||||
return savedict
|
||||
return save_dict
|
||||
|
||||
This gives us a dictionary with the style
|
||||
``{ "variable_name":that_variables_value }`` which will be useful when
|
||||
@@ -91,13 +91,13 @@ 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
|
||||
func save_game():
|
||||
var savegame = File.new()
|
||||
savegame.open("user://savegame.save", File.WRITE)
|
||||
var savenodes = get_tree().get_nodes_in_group("Persist")
|
||||
for i in savenodes:
|
||||
var nodedata = i.save()
|
||||
savegame.store_line(to_json(nodedata))
|
||||
savegame.close()
|
||||
var save_game = File.new()
|
||||
save_game.open("user://savegame.save", File.WRITE)
|
||||
var save_nodes = get_tree().get_nodes_in_group("Persist")
|
||||
for i in save_nodes:
|
||||
var node_data = i.save()
|
||||
save_game.store_line(to_json(node_data))
|
||||
save_game.close()
|
||||
|
||||
Game saved! Loading is fairly simple as well. For that we'll read each
|
||||
line, use parse_json() to read it back to a dict, and then iterate over
|
||||
@@ -109,30 +109,30 @@ load function:
|
||||
|
||||
# Note: This can be called from anywhere inside the tree. This function is path independent.
|
||||
func load_game():
|
||||
var savegame = File.new()
|
||||
if !savegame.file_exists("user://savegame.save"):
|
||||
return #Error! We don't have a save to load
|
||||
var save_game = File.new()
|
||||
if not save_game.file_exists("user://save_game.save"):
|
||||
return # Error! We don't have a save to load.
|
||||
|
||||
# We need to revert the game state so we're not cloning objects during loading. This will vary wildly depending on the needs of a project, so take care with this step.
|
||||
# For our example, we will accomplish this by deleting savable objects.
|
||||
var savenodes = get_tree().get_nodes_in_group("Persist")
|
||||
for i in savenodes:
|
||||
var save_nodes = get_tree().get_nodes_in_group("Persist")
|
||||
for i in save_nodes:
|
||||
i.queue_free()
|
||||
|
||||
# Load the file line by line and process that dictionary to restore the object it represents
|
||||
savegame.open("user://savegame.save", File.READ)
|
||||
while (!savegame.eof_reached()):
|
||||
var currentLine = parse_json(savegame.get_line())
|
||||
save_game.open("user://savegame.save", File.READ)
|
||||
while not save_game.eof_reached():
|
||||
var current_line = parse_json(save_game.get_line())
|
||||
# First we need to create the object and add it to the tree and set its position.
|
||||
var newobject = load(currentline["filename"]).instance()
|
||||
get_node(currentline["parent"]).add_child(newobject)
|
||||
newobject.set_position(Vector2(currentline["posx"],currentline["posy"]))
|
||||
var new_object = load(current_line["filename"]).instance()
|
||||
get_node(current_line["parent"]).add_child(new_object)
|
||||
new_object.set_position(Vector2(current_line["pos_x"],current_line["pos_y"]))
|
||||
# Now we set the remaining variables.
|
||||
for i in currentline.keys():
|
||||
if (i == "filename" or i == "parent" or i == "posx" or i == "posy"):
|
||||
for i in current_line.keys():
|
||||
if i == "filename" or i == "parent" or i == "pos_x" or i == "pos_y":
|
||||
continue
|
||||
newobject.set(i, currentline[i])
|
||||
savegame.close()
|
||||
new_object.set(i, current_line[i])
|
||||
save_game.close()
|
||||
|
||||
And now we can save and load an arbitrary number of objects laid out
|
||||
almost anywhere across the scene tree! Each object can store different
|
||||
|
||||
@@ -218,7 +218,7 @@ Let's get back to the lobby. Imagine that each player that connects to the serve
|
||||
# Store the info
|
||||
player_info[id] = info
|
||||
# If I'm the server, let the new guy know about existing players
|
||||
if (get_tree().is_network_server()):
|
||||
if get_tree().is_network_server():
|
||||
# Send my info to new player
|
||||
rpc_id(id, "register_player", 1, my_info)
|
||||
# Send the info of existing players
|
||||
@@ -326,7 +326,7 @@ When the server gets the OK from all the peers, it can tell them to start, as fo
|
||||
|
||||
players_done.append(who)
|
||||
|
||||
if (players_done.size() == player_info.size()):
|
||||
if players_done.size() == player_info.size():
|
||||
rpc("post_configure_game")
|
||||
|
||||
remote func post_configure_game():
|
||||
@@ -391,7 +391,7 @@ Example bomb code:
|
||||
::
|
||||
|
||||
for p in bodies_in_area:
|
||||
if (p.has_method("exploded")):
|
||||
if p.has_method("exploded"):
|
||||
p.rpc("exploded", bomb_owner)
|
||||
|
||||
Example player code:
|
||||
@@ -402,7 +402,7 @@ Example player code:
|
||||
stunned = true
|
||||
|
||||
master func exploded(by_who):
|
||||
if (stunned):
|
||||
if stunned:
|
||||
return # Already stunned
|
||||
|
||||
rpc("stun")
|
||||
|
||||
@@ -20,54 +20,49 @@ It will connect and fetch a website.
|
||||
# This simple class can do HTTP requests, it will not block but it needs to be polled
|
||||
|
||||
func _init():
|
||||
|
||||
var err=0
|
||||
var err = 0
|
||||
var http = HTTPClient.new() # Create the Client
|
||||
|
||||
err = http.connect_to_host("www.php.net",80) # Connect to host/port
|
||||
assert(err==OK) # Make sure connection was OK
|
||||
assert(err == OK) # Make sure connection was OK
|
||||
|
||||
# Wait until resolved and connected
|
||||
while( http.get_status()==HTTPClient.STATUS_CONNECTING or http.get_status()==HTTPClient.STATUS_RESOLVING):
|
||||
while http.get_status() == HTTPClient.STATUS_CONNECTING or http.get_status() == HTTPClient.STATUS_RESOLVING:
|
||||
http.poll()
|
||||
print("Connecting..")
|
||||
OS.delay_msec(500)
|
||||
|
||||
assert( http.get_status() == HTTPClient.STATUS_CONNECTED ) # Could not connect
|
||||
assert(http.get_status() == HTTPClient.STATUS_CONNECTED) # Could not connect
|
||||
|
||||
# Some headers
|
||||
|
||||
var headers=[
|
||||
var headers = [
|
||||
"User-Agent: Pirulo/1.0 (Godot)",
|
||||
"Accept: */*"
|
||||
]
|
||||
|
||||
err = http.request(HTTPClient.METHOD_GET,"/ChangeLog-5.php",headers) # Request a page from the site (this one was chunked..)
|
||||
err = http.request(HTTPClient.METHOD_GET, "/ChangeLog-5.php", headers) # Request a page from the site (this one was chunked..)
|
||||
assert(err == OK) # Make sure all is OK
|
||||
|
||||
assert( err == OK ) # Make sure all is OK
|
||||
|
||||
while (http.get_status() == HTTPClient.STATUS_REQUESTING):
|
||||
while http.get_status() == HTTPClient.STATUS_REQUESTING:
|
||||
# Keep polling until the request is going on
|
||||
http.poll()
|
||||
print("Requesting..")
|
||||
OS.delay_msec(500)
|
||||
|
||||
assert(http.get_status() == HTTPClient.STATUS_BODY or http.get_status() == HTTPClient.STATUS_CONNECTED) # Make sure request finished well.
|
||||
|
||||
assert( http.get_status() == HTTPClient.STATUS_BODY or http.get_status() == HTTPClient.STATUS_CONNECTED ) # Make sure request finished well.
|
||||
print("response? ", http.has_response()) # Site might not have a response.
|
||||
|
||||
print("response? ",http.has_response()) # Site might not have a response.
|
||||
|
||||
|
||||
if (http.has_response()):
|
||||
if http.has_response():
|
||||
# If there is a response..
|
||||
|
||||
headers = http.get_response_headers_as_dictionary() # Get response headers
|
||||
print("code: ",http.get_response_code()) # Show response code
|
||||
print("**headers:\\n",headers) # Show headers
|
||||
print("code: ", http.get_response_code()) # Show response code
|
||||
print("**headers:\\n", headers) # Show headers
|
||||
|
||||
# Getting the HTTP Body
|
||||
|
||||
if (http.is_response_chunked()):
|
||||
if http.is_response_chunked():
|
||||
# Does it use chunks?
|
||||
print("Response is Chunked!")
|
||||
else:
|
||||
@@ -79,22 +74,20 @@ It will connect and fetch a website.
|
||||
|
||||
var rb = PoolByteArray() # Array that will hold the data
|
||||
|
||||
while(http.get_status()==HTTPClient.STATUS_BODY):
|
||||
while http.get_status() == HTTPClient.STATUS_BODY:
|
||||
# While there is body left to be read
|
||||
http.poll()
|
||||
var chunk = http.read_response_body_chunk() # Get a chunk
|
||||
if (chunk.size()==0):
|
||||
if chunk.size() == 0:
|
||||
# Got nothing, wait for buffers to fill a bit
|
||||
OS.delay_usec(1000)
|
||||
else:
|
||||
rb = rb + chunk # Append to read buffer
|
||||
|
||||
|
||||
# Done!
|
||||
|
||||
print("bytes got: ",rb.size())
|
||||
print("bytes got: ", rb.size())
|
||||
var text = rb.get_string_from_ascii()
|
||||
print("Text: ",text)
|
||||
|
||||
print("Text: ", text)
|
||||
|
||||
quit()
|
||||
|
||||
@@ -126,7 +126,7 @@ So, let's move our sprite downwards until it hits the floor:
|
||||
extends KinematicBody2D
|
||||
|
||||
func _physics_process(delta):
|
||||
move_and_collide(Vector2(0,1)) # Move down 1 pixel per physics frame
|
||||
move_and_collide(Vector2(0, 1)) # Move down 1 pixel per physics frame
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
@@ -158,7 +158,6 @@ little more like an actual game character:
|
||||
var velocity = Vector2()
|
||||
|
||||
func _physics_process(delta):
|
||||
|
||||
velocity.y += delta * GRAVITY
|
||||
|
||||
var motion = velocity * delta
|
||||
@@ -200,12 +199,11 @@ This adds simple walking support by pressing left and right:
|
||||
var velocity = Vector2()
|
||||
|
||||
func _physics_process(delta):
|
||||
|
||||
velocity.y += delta * GRAVITY
|
||||
|
||||
if (Input.is_action_pressed("ui_left")):
|
||||
if Input.is_action_pressed("ui_left"):
|
||||
velocity.x = -WALK_SPEED
|
||||
elif (Input.is_action_pressed("ui_right")):
|
||||
elif Input.is_action_pressed("ui_right"):
|
||||
velocity.x = WALK_SPEED
|
||||
else:
|
||||
velocity.x = 0
|
||||
|
||||
@@ -38,7 +38,7 @@ but they can be created via code easily. For example:
|
||||
|
||||
# Create a box
|
||||
var b = RectangleShape2D.new()
|
||||
b.set_extents(Vector2(20,10))
|
||||
b.set_extents(Vector2(20, 10))
|
||||
|
||||
The main use for shapes is checking collision/intersection and getting
|
||||
resolution information. Shapes are mostly convex, (except the
|
||||
@@ -91,7 +91,7 @@ against everything in two for loops like this:
|
||||
|
||||
for i in colliders:
|
||||
for j in colliders:
|
||||
if (i.collides(j)):
|
||||
if i.collides(j):
|
||||
do_collision_code()
|
||||
|
||||
But this scales really bad. Let's imagine there are only 100 objects in
|
||||
|
||||
@@ -83,28 +83,28 @@ must be used, for example:
|
||||
func _physics_process(delta):
|
||||
var space_state = get_world().get_direct_space_state()
|
||||
# use global coordinates, not local to node
|
||||
var result = space_state.intersect_ray( Vector2(0,0), Vector2(50,100) )
|
||||
var result = space_state.intersect_ray(Vector2(0, 0), Vector2(50, 100))
|
||||
|
||||
Result is a dictionary. If the ray didn't hit anything, the dictionary will
|
||||
be empty. If it did hit something it will contain collision information:
|
||||
|
||||
::
|
||||
|
||||
if (not result.empty()):
|
||||
print("Hit at point: ",result.position)
|
||||
if not result.empty():
|
||||
print("Hit at point: ", result.position)
|
||||
|
||||
The collision result dictionary, when something hit, has this format:
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
position:Vector2 # point in world space for collision
|
||||
normal:Vector2 # normal in world space for collision
|
||||
collider:Object # Object collided or null (if unassociated)
|
||||
collider_id:ObjectID # Object it collided against
|
||||
rid:RID # RID it collided against
|
||||
shape:int # shape index of collider
|
||||
metadata:Variant() # metadata of collider
|
||||
position: Vector2 # point in world space for collision
|
||||
normal: Vector2 # normal in world space for collision
|
||||
collider: Object # Object collided or null (if unassociated)
|
||||
collider_id: ObjectID # Object it collided against
|
||||
rid: RID # RID it collided against
|
||||
shape: int # shape index of collider
|
||||
metadata: Variant() # metadata of collider
|
||||
}
|
||||
|
||||
# in case of 3D, Vector3 is returned.
|
||||
@@ -131,7 +131,7 @@ collisionobject based node:
|
||||
|
||||
func _physics_process(delta):
|
||||
var space_state = get_world().get_direct_space_state()
|
||||
var result = space_state.intersect_ray( get_global_pos(), enemy_pos, [ self ] )
|
||||
var result = space_state.intersect_ray(get_global_pos(), enemy_pos, [self])
|
||||
|
||||
The extra argument is a list of exceptions, can be objects or RIDs.
|
||||
|
||||
@@ -158,12 +158,11 @@ To obtain it using a camera, the following code can be used:
|
||||
|
||||
const ray_length = 1000
|
||||
|
||||
func _input(ev):
|
||||
if ev is InputEventMouseButton and ev.pressed and ev.button_index==1:
|
||||
|
||||
func _input(event):
|
||||
if event is InputEventMouseButton and event.pressed and event.button_index == 1:
|
||||
var camera = get_node("camera")
|
||||
var from = camera.project_ray_origin(ev.position)
|
||||
var to = from + camera.project_ray_normal(ev.position) * ray_length
|
||||
var from = camera.project_ray_origin(event.position)
|
||||
var to = from + camera.project_ray_normal(event.position) * ray_length
|
||||
|
||||
Of course, remember that during ``_input()``, space may be locked, so save
|
||||
your query for ``_physics_process()``.
|
||||
|
||||
@@ -201,8 +201,10 @@ now, but we can make this method future-proof by returning the size of our
|
||||
|
||||
func get_preset_name(preset):
|
||||
match preset:
|
||||
PRESET_DEFAULT: return "Default"
|
||||
_ : return "Unknown"
|
||||
PRESET_DEFAULT:
|
||||
return "Default"
|
||||
_:
|
||||
return "Unknown"
|
||||
|
||||
|
||||
Here we have the
|
||||
@@ -224,10 +226,11 @@ you do this you have to be careful when you add more presets.
|
||||
match preset:
|
||||
PRESET_DEFAULT:
|
||||
return [{
|
||||
"name": "use_red_anyway",
|
||||
"default_value": false
|
||||
"name": "use_red_anyway",
|
||||
"default_value": false
|
||||
}]
|
||||
_: return []
|
||||
_:
|
||||
return []
|
||||
|
||||
This is the method which defines the available options.
|
||||
:ref:`get_import_options<class_EditorImportPlugin_get_import_options>` returns
|
||||
@@ -287,7 +290,7 @@ method. Our sample code is a bit long, so let's split in a few parts:
|
||||
func import(source_file, save_path, options, r_platform_variants, r_gen_files):
|
||||
var file = File.new()
|
||||
var err = file.open(source_file, File.READ)
|
||||
if (err != OK):
|
||||
if err != OK:
|
||||
return err
|
||||
|
||||
var line = file.get_line()
|
||||
|
||||
@@ -208,13 +208,13 @@ deactivated. The code can be like this::
|
||||
dock = preload("res://addons/my_custom_dock/my_dock.tscn").instance()
|
||||
|
||||
# Add the loaded scene to the docks:
|
||||
add_control_to_dock( DOCK_SLOT_LEFT_UL, dock)
|
||||
add_control_to_dock(DOCK_SLOT_LEFT_UL, 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 scene from the docks:
|
||||
remove_control_from_docks( dock ) # Remove the dock
|
||||
remove_control_from_docks(dock) # Remove the dock
|
||||
dock.free() # Erase the control from the memory
|
||||
|
||||
While the dock position is chosen when adding it, the user is free to move it
|
||||
|
||||
@@ -85,8 +85,8 @@ calling:
|
||||
|
||||
::
|
||||
|
||||
viewport.set_size_override(w,h) #custom size for 2D
|
||||
viewport.set_size_override_stretch(true/false) #enable stretch for custom size
|
||||
viewport.set_size_override(w, h) # custom size for 2D
|
||||
viewport.set_size_override_stretch(true) # enable stretch for custom size
|
||||
|
||||
The root viewport uses this for the stretch options in the project
|
||||
settings.
|
||||
|
||||
Reference in New Issue
Block a user