From 313b5becd29ca660768bf51a935e0afd9646b3a8 Mon Sep 17 00:00:00 2001 From: Nathan Lovato Date: Thu, 16 Aug 2018 08:38:14 +0900 Subject: [PATCH] Proof class_name PR by Will, add extra picture --- .../scripting/gdscript/gdscript_basics.rst | 71 ++++++++++++------ .../class_name_editor_register_example.png | Bin 0 -> 6028 bytes .../script_class_nativescript_example.png | Bin .../step_by_step/scripting_continued.rst | 60 ++++++++------- 4 files changed, 79 insertions(+), 52 deletions(-) create mode 100644 getting_started/scripting/gdscript/img/class_name_editor_register_example.png rename {img => getting_started/step_by_step/img}/script_class_nativescript_example.png (100%) diff --git a/getting_started/scripting/gdscript/gdscript_basics.rst b/getting_started/scripting/gdscript/gdscript_basics.rst index e499c5b05..e7827f497 100644 --- a/getting_started/scripting/gdscript/gdscript_basics.rst +++ b/getting_started/scripting/gdscript/gdscript_basics.rst @@ -59,7 +59,7 @@ here's a simple example of how GDScript looks. extends BaseClass - # optional script class with optional icon + # (optional) class definition with a custom icon class_name MyClass, "res://path/to/optional/icon.svg" @@ -868,37 +868,62 @@ Multipatterns: Classes ~~~~~~~ -By default, the body of a script file is an unnamed class and it can -only be referenced externally as a resource or file. Users can also define -an explicit name for a script using the 'class_name' keyword, optionally -followed by a path to an image resource. Named scripts appear in Godot -Engine's editor with their base class icon or the custom defined icon. - -Class syntax is meant to be very compact and can only contain member variables -or functions. Static functions are allowed, but not static members (this is -in the spirit of thread safety, since scripts can be initialized in -separate threads without the user knowing). In the same way, member -variables (including arrays and dictionaries) are initialized every time -an instance is created. - -Below is an example of a class file. +By default, all script files are unnamed classes. In this case, you can only +reference them using the file's path, using either a relative or an absolute +path. For example, if you name a script file ``character.gd`` :: - # Saved as a file named 'myclass.gd'. - - class_name MyClass + # Inherit from Character.gd - var a = 5 + extends res://path/to/character.gd - func print_value_of_a(): - print(a) - - func print_script_three_times(): + # Load character.gd and create a new node instance from it + + var Character = load("res://path/to/character.gd") + var character_node = Character.instance() + +Instead, you can give your class a name to register it as a new type in Godot's +editor. For that, you use the 'class_name' keyword followed. You can add an +optional comma followed by a path to an image, to use it as an icon. Your class +will then appear with its new icon in the editor: + +:: + + # Item.gd + + extends Node + + class_name Item, "res://interface/icons/item.png" + +.. image:: img/class_name_editor_register_example.png + +Here's a class file example: + +:: + + # Saved as a file named 'character.gd'. + + class_name Character + + var health = 5 + + func print_health(): + print(health) + + func print_this_script_three_times(): print(get_script()) print(ResourceLoader.load("res://myclass.gd")) print(MyClass) + +.. note:: Godot's class syntax is compact: it can only contain member variables or + functions. You can use static functions, but not static member variables. In the + same way, the engine initializes variables every time you create an instance, + and this includes arrays and dictionaries. This is in the spirit of thread + safety, since scripts can be initialized in separate threads without the user + knowing. + Inheritance ^^^^^^^^^^^ diff --git a/getting_started/scripting/gdscript/img/class_name_editor_register_example.png b/getting_started/scripting/gdscript/img/class_name_editor_register_example.png new file mode 100644 index 0000000000000000000000000000000000000000..b3a267d5b9b510fe4c9b62934c6fd3c4261a6c6f GIT binary patch literal 6028 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 Common -> Physics Fps. -The function ``_process()``, however, is not synced with physics. Its frame rate is not constant and is dependent +The function ``_process()``, however, is not synced with physics. Its frame rate is not constant and is dependent on hardware and game optimization. Its execution is done after the physics step on single-threaded games. A simple way to test this is to create a scene with a single Label node, @@ -67,7 +67,7 @@ with the following script: text = str(accum) # 'text' is a built-in label property. .. code-tab:: csharp - + public class CustomLabel : Label { private float _accum; @@ -99,11 +99,11 @@ which are enemies: add_to_group("enemies") .. code-tab:: csharp - + public override void _Ready() { base._Ready(); - + AddToGroup("enemies"); } @@ -118,7 +118,7 @@ all enemies can be notified about its alarm sounding by using get_tree().call_group("enemies", "player_was_discovered") .. code-tab:: csharp - + public void _OnDiscovered() // This is a purely illustrative function. { GetTree().CallGroup("enemies", "player_was_discovered"); @@ -137,7 +137,7 @@ calling var enemies = get_tree().get_nodes_in_group("enemies") .. code-tab:: csharp - + var enemies = GetTree().GetNodesInGroup("enemies"); The :ref:`SceneTree ` class provides many useful methods, @@ -153,7 +153,7 @@ Notifications Godot has a system of notifications. These are usually not needed for scripting, as it's too low-level and virtual functions are provided for most of them. It's just good to know they exist. For example, -you may add an +you may add an :ref:`Object._notification() ` function in your script: @@ -226,7 +226,7 @@ follows, can be applied to nodes: pass .. code-tab:: csharp - + public override void _EnterTree() { // When the node enters the _Scene Tree_, it becomes active @@ -270,7 +270,7 @@ the notification system. Creating nodes -------------- -To create a node from code, call the ``.new()`` method, like for any +To create a node from code, call the ``.new()`` method, like for any other class-based datatype. For example: @@ -289,7 +289,7 @@ other class-based datatype. For example: public override void _Ready() { base._Ready(); - + _sprite = new Sprite(); // Create a new sprite! AddChild(_sprite); // Add it as a child of this node. } @@ -348,7 +348,7 @@ first one is to load the scene from your hard drive: var scene = load("res://myscene.tscn") # Will load when the script is instanced. .. code-tab:: csharp - + var scene = (PackedScene)ResourceLoader.Load("res://myscene.tscn"); // Will load when the script is instanced. @@ -373,7 +373,7 @@ the active scene: add_child(node) .. code-tab:: csharp - + var node = scene.Instance(); AddChild(node); @@ -382,20 +382,17 @@ kept loaded and ready to use so that you can create as many instances as desired. This is especially useful to quickly instance several enemies, bullets, and other entities in the active scene. -Script Classes --------------- +Register Scripts as Classes +--------------------------- -Godot has a "Script Class" feature to register individual scripts with the -Editor. By default, unnamed scripts are only accessible by loading the file -directly. Users name the script and give it an optional icon. These name-script -pairings are then supplied to scripting languages in Godot. The named scripts -that derive Node or Resource will show up in their respective creation dialogs -in the Editor. +Godot has a "Script Class" feature to register individual scripts with the +Editor. By default, you can only access unnamed scripts by loading the file +directly. -At this time... - -- Only GDScript and NativeScript (C++ and other GDNative-powered languages) can register scripts. -- Only GDScript creates global variables for each named script. +You can name a script and register it as a type in the editor with the +``class_name`` keyword followed by the class's name. You may add a comma and an +optional path to an image to use as an icon. You will then find your new type in +the Node or Resource creation dialog. .. tabs:: .. code-tab:: gdscript GDScript @@ -406,10 +403,15 @@ At this time... class_name ScriptName, "res://path/to/optional/icon.svg" func _ready(): - var this = ScriptName # script - var cppNode = MyCppNode.new() # instance of a script + var this = ScriptName # reference to the script + var cppNode = MyCppNode.new() # new instance of a class named MyCppNode cppNode.queue_free() .. image:: img/script_class_nativescript_example.png + +.. warning:: In Godot 3.1: + + - Only GDScript and NativeScript, i.e., C++ and other GDNative-powered languages, can register scripts. + - Only GDScript creates global variables for each named script.