mirror of
https://github.com/omegaleo/Tutorials.git
synced 2026-11-08 17:43:27 +00:00
first commit
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
# Normalize EOL for all files that Git considers text files.
|
||||
* text=auto eol=lf
|
||||
@@ -0,0 +1,2 @@
|
||||
# Godot 4+ specific ignores
|
||||
.godot/
|
||||
Generated
+13
@@ -0,0 +1,13 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Rider ignored files
|
||||
/modules.xml
|
||||
/contentModel.xml
|
||||
/.idea.Tutorials.iml
|
||||
/projectSettingsUpdater.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
||||
</project>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<attachedFolders />
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
</component>
|
||||
</project>
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
class_name Ability
|
||||
extends Resource
|
||||
|
||||
@export var name: String
|
||||
@export var power: float
|
||||
@export var throwable: PackedScene
|
||||
|
||||
func _init() -> void:
|
||||
# Initialize your ability here
|
||||
var test: String = get_ability_name()
|
||||
|
||||
# Initialize your packed scene here
|
||||
|
||||
func get_ability_name() -> String:
|
||||
return name
|
||||
@@ -0,0 +1 @@
|
||||
uid://cnjayq2d3r2dq
|
||||
@@ -0,0 +1,16 @@
|
||||
extends Control
|
||||
|
||||
@export var label: RichTextLabel
|
||||
@export var ability: Ability
|
||||
@export var empowered_ability: EmpoweredAbility
|
||||
|
||||
func _enter_tree() -> void:
|
||||
label.text = "-----Regular Ability-----\r\n"
|
||||
label.text += "Name: " + ability.get_ability_name() + "\r\n"
|
||||
label.text += "Power: " + str(ability.power) + "\r\n"
|
||||
label.text += "\r\n"
|
||||
|
||||
label.text += "-----Enhanced Ability-----\r\n"
|
||||
label.text += "Name: " + empowered_ability.get_ability_name() + "\r\n"
|
||||
label.text += "Power: " + str(empowered_ability.power) + "\r\n"
|
||||
label.text += "Power (after multiplier): " + str(empowered_ability.get_power())
|
||||
@@ -0,0 +1 @@
|
||||
uid://sos2jppfpm05
|
||||
@@ -0,0 +1,7 @@
|
||||
class_name EmpoweredAbility
|
||||
extends Ability
|
||||
|
||||
@export var power_multiplier: float
|
||||
|
||||
func get_power() -> float:
|
||||
return power * power_multiplier;
|
||||
@@ -0,0 +1 @@
|
||||
uid://xhcrf1lvfvc6
|
||||
@@ -0,0 +1,5 @@
|
||||
class_name EnhancedArea2D
|
||||
extends Area2D
|
||||
|
||||
@export var entity_name: String
|
||||
signal TestSignal(input: String)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cyrakc1tyy74o
|
||||
@@ -0,0 +1,10 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Tutorials.addons.custom_inspector_tools.InspectorPlugins;
|
||||
|
||||
[Tool]
|
||||
public partial class TestBoxTest : Node2D
|
||||
{
|
||||
[TestBox("Field1", "This is a test box for Field1")]
|
||||
[Export] public int Field1 = 42;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://dkgneigm55ij7
|
||||
@@ -0,0 +1,7 @@
|
||||
<Project Sdk="Godot.NET.Sdk/4.6.0">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net9.0</TargetFramework>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,19 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2012
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tutorials", "Tutorials.csproj", "{7E42B83A-A25D-4FD2-A8FC-BC16565A2C33}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
ExportDebug|Any CPU = ExportDebug|Any CPU
|
||||
ExportRelease|Any CPU = ExportRelease|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7E42B83A-A25D-4FD2-A8FC-BC16565A2C33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7E42B83A-A25D-4FD2-A8FC-BC16565A2C33}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7E42B83A-A25D-4FD2-A8FC-BC16565A2C33}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
|
||||
{7E42B83A-A25D-4FD2-A8FC-BC16565A2C33}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
|
||||
{7E42B83A-A25D-4FD2-A8FC-BC16565A2C33}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
|
||||
{7E42B83A-A25D-4FD2-A8FC-BC16565A2C33}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,143 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using Tutorials.addons.custom_inspector_tools.InspectorPlugins;
|
||||
|
||||
namespace Tutorials.addons.custom_inspector_tools;
|
||||
|
||||
#if TOOLS
|
||||
[Tool]
|
||||
public partial class CustomInspectorPlugin : EditorPlugin
|
||||
{
|
||||
private readonly List<EditorInspectorPlugin> _customPlugins = new();
|
||||
private bool _pluginsBuilt = false;
|
||||
private bool _inspectorPluginsAdded = false;
|
||||
|
||||
private EditorSelection _selection;
|
||||
private bool _refreshingInspector = false;
|
||||
|
||||
public override void _EnterTree()
|
||||
{
|
||||
base._EnterTree();
|
||||
|
||||
if (!_pluginsBuilt)
|
||||
{
|
||||
BuildPlugins();
|
||||
_pluginsBuilt = true;
|
||||
}
|
||||
|
||||
_selection = EditorInterface.Singleton.GetSelection();
|
||||
_selection.SelectionChanged += OnSelectionChanged;
|
||||
}
|
||||
|
||||
private void OnSelectionChanged()
|
||||
{
|
||||
if (!_inspectorPluginsAdded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
RefreshInspectorForCurrentSelection();
|
||||
}
|
||||
|
||||
private void RefreshInspectorForCurrentSelection()
|
||||
{
|
||||
if (_refreshingInspector)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_refreshingInspector = true;
|
||||
|
||||
try
|
||||
{
|
||||
GodotObject objToInspect = null;
|
||||
|
||||
foreach (var node in _selection.GetSelectedNodes())
|
||||
{
|
||||
if (node is not null)
|
||||
{
|
||||
objToInspect = node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Drop old inspector UI, then rebuild for the selected object.
|
||||
EditorInterface.Singleton.InspectObject(null);
|
||||
|
||||
if (objToInspect is not null)
|
||||
{
|
||||
EditorInterface.Singleton.InspectObject(objToInspect);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_refreshingInspector = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void BuildPlugins()
|
||||
{
|
||||
_customPlugins.Clear();
|
||||
|
||||
// Add new plugins here as you create them.
|
||||
_customPlugins.Add(new TestBoxInspectorPlugin());
|
||||
}
|
||||
|
||||
public override void _EnablePlugin()
|
||||
{
|
||||
base._EnablePlugin();
|
||||
|
||||
try
|
||||
{
|
||||
if (_inspectorPluginsAdded)
|
||||
return;
|
||||
|
||||
foreach (var plugin in _customPlugins)
|
||||
{
|
||||
AddInspectorPlugin(plugin);
|
||||
GD.Print($"Added inspector plugin: {plugin.GetType().Name}");
|
||||
}
|
||||
|
||||
_inspectorPluginsAdded = true;
|
||||
|
||||
RefreshInspectorForCurrentSelection();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
GD.PrintErr($"Error enabling CustomInspectorPlugin: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public override void _DisablePlugin()
|
||||
{
|
||||
try
|
||||
{
|
||||
RemoveAllInspectorPlugins();
|
||||
|
||||
EditorInterface.Singleton.InspectObject(null);
|
||||
RefreshInspectorForCurrentSelection();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
GD.PrintErr($"Error disabling CustomInspectorPlugin: {ex.Message}");
|
||||
}
|
||||
base._DisablePlugin();
|
||||
}
|
||||
|
||||
private void RemoveAllInspectorPlugins()
|
||||
{
|
||||
if (!_inspectorPluginsAdded)
|
||||
return;
|
||||
|
||||
foreach (var plugin in _customPlugins)
|
||||
{
|
||||
RemoveInspectorPlugin(plugin);
|
||||
GD.Print($"Removed inspector plugin: {plugin.GetType().Name}");
|
||||
}
|
||||
|
||||
_inspectorPluginsAdded = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1 @@
|
||||
uid://dxmsbkgfqf1kh
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace Tutorials.addons.custom_inspector_tools.InspectorPlugins;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class TestBoxAttribute : Attribute
|
||||
{
|
||||
public string Identifier { get; }
|
||||
public string Text { get; }
|
||||
|
||||
public TestBoxAttribute(string identifier, string text)
|
||||
{
|
||||
Identifier = identifier;
|
||||
Text = text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://c0rv1g5ikjgrm
|
||||
@@ -0,0 +1,153 @@
|
||||
#if TOOLS
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Godot;
|
||||
using Microsoft.VisualBasic.CompilerServices;
|
||||
|
||||
namespace Tutorials.addons.custom_inspector_tools.InspectorPlugins;
|
||||
|
||||
[Tool]
|
||||
public partial class TestBoxInspectorPlugin : EditorInspectorPlugin
|
||||
{
|
||||
private const bool DEBUG_LOGS = true;
|
||||
|
||||
// What object are we looking at?
|
||||
private ulong _currentObjectId = 0;
|
||||
|
||||
private readonly HashSet<string> _identifiersInjectedForCurrentObject = new();
|
||||
|
||||
public override bool _CanHandle(GodotObject @object)
|
||||
{
|
||||
if (@object is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var objectId = @object.GetInstanceId();
|
||||
if (DEBUG_LOGS)
|
||||
{
|
||||
GD.Print($"[TestBoxInspectorPlugin] _CanHandle called for object with ID {objectId}");
|
||||
}
|
||||
|
||||
var type = @object.GetType();
|
||||
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
if (property.GetCustomAttribute<TestBoxAttribute>() is not null)
|
||||
{
|
||||
if (DEBUG_LOGS)
|
||||
{
|
||||
GD.Print($"[TestBoxInspectorPlugin] Found property with TestBoxAttribute: {property.Name}");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var field in fields)
|
||||
{
|
||||
if (field.GetCustomAttribute<TestBoxAttribute>() is not null)
|
||||
{
|
||||
if (DEBUG_LOGS)
|
||||
{
|
||||
GD.Print($"[TestBoxInspectorPlugin] Found field with TestBoxAttribute: {field.Name}");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool _ParseProperty(GodotObject @object, Variant.Type type, string name, PropertyHint hintType, string hintString,
|
||||
PropertyUsageFlags usageFlags, bool wide)
|
||||
{
|
||||
if (@object is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var objectId = @object.GetInstanceId();
|
||||
|
||||
if (_currentObjectId != objectId)
|
||||
{
|
||||
_currentObjectId = objectId;
|
||||
_identifiersInjectedForCurrentObject.Clear();
|
||||
|
||||
if (DEBUG_LOGS)
|
||||
{
|
||||
GD.Print($"[TestBoxInspectorPlugin] New object selected with ID {_currentObjectId}. Cleared injected identifiers.");
|
||||
}
|
||||
}
|
||||
|
||||
var objectType = @object.GetType();
|
||||
const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic;
|
||||
|
||||
var property = objectType.GetProperty(name, flags);
|
||||
var field = objectType.GetField(name, flags);
|
||||
|
||||
if (property is null && field is null && name.Contains("_"))
|
||||
{
|
||||
// Godot mangles property names with underscores, so we need to check for that.
|
||||
var unmangledName = name.Replace("_", "");
|
||||
property = objectType.GetProperty(unmangledName, flags);
|
||||
field = objectType.GetField(unmangledName, flags);
|
||||
}
|
||||
|
||||
var member = (MemberInfo)property ?? field;
|
||||
|
||||
if (member is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var testBoxAttribute = member.GetCustomAttribute<TestBoxAttribute>();
|
||||
if (testBoxAttribute is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_identifiersInjectedForCurrentObject.Add(testBoxAttribute.Identifier))
|
||||
{
|
||||
if (DEBUG_LOGS)
|
||||
{
|
||||
GD.Print($"[TestBoxInspectorPlugin] Injecting TestBox for identifier '{testBoxAttribute.Identifier}' on object ID {_currentObjectId}");
|
||||
}
|
||||
|
||||
AddCustomControl(TestBoxControl.Create(testBoxAttribute.Text));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DEBUG_LOGS)
|
||||
{
|
||||
GD.Print($"[TestBoxInspectorPlugin] Already injected TestBox for identifier '{testBoxAttribute.Identifier}' on object ID {_currentObjectId}. Skipping.");
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[Tool]
|
||||
public partial class TestBoxControl : PanelContainer
|
||||
{
|
||||
public static TestBoxControl Create(string text)
|
||||
{
|
||||
var control = new TestBoxControl();
|
||||
control.SizeFlagsHorizontal = SizeFlags.ExpandFill;
|
||||
|
||||
var label = new RichTextLabel()
|
||||
{
|
||||
Text = text,
|
||||
FitContent = true,
|
||||
ScrollActive = false,
|
||||
BbcodeEnabled = true,
|
||||
SizeFlagsHorizontal = SizeFlags.ExpandFill
|
||||
};
|
||||
control.AddChild(label);
|
||||
return control;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1 @@
|
||||
uid://t0xwv6w6ue8v
|
||||
@@ -0,0 +1,6 @@
|
||||
[plugin]
|
||||
name="Custom Inspector Tools"
|
||||
description="Custom Inspector Tools"
|
||||
author="omegaleo"
|
||||
version="1.0"
|
||||
script="CustomInspectorPlugin.cs"
|
||||
@@ -0,0 +1,36 @@
|
||||
[gd_scene format=3 uid="uid://c2e6p1udf2nyi"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://sos2jppfpm05" path="res://AbilityTest.gd" id="1_0fbet"]
|
||||
[ext_resource type="Resource" uid="uid://bht3xjy7lpe0j" path="res://test ability.tres" id="2_qtu10"]
|
||||
[ext_resource type="Resource" uid="uid://bq0raek4edihm" path="res://empowered test ability.tres" id="3_ee4bf"]
|
||||
[ext_resource type="Script" uid="uid://cyrakc1tyy74o" path="res://EnhancedNode.gd" id="4_ee4bf"]
|
||||
[ext_resource type="Script" uid="uid://dkgneigm55ij7" path="res://TestBoxTest.cs" id="5_kbped"]
|
||||
|
||||
[node name="Control" type="Control" unique_id=498246024 node_paths=PackedStringArray("label")]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_0fbet")
|
||||
label = NodePath("RichTextLabel")
|
||||
ability = ExtResource("2_qtu10")
|
||||
empowered_ability = ExtResource("3_ee4bf")
|
||||
|
||||
[node name="RichTextLabel" type="RichTextLabel" parent="." unique_id=1353651725]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="EnhancedArea2D" type="Area2D" parent="." unique_id=1192052226]
|
||||
script = ExtResource("4_ee4bf")
|
||||
metadata/_custom_type_script = "uid://cyrakc1tyy74o"
|
||||
|
||||
[node name="Node2D" type="Node2D" parent="." unique_id=939302476]
|
||||
script = ExtResource("5_kbped")
|
||||
@@ -0,0 +1,10 @@
|
||||
[gd_resource type="Resource" script_class="EmpoweredAbility" load_steps=2 format=3 uid="uid://bq0raek4edihm"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://xhcrf1lvfvc6" path="res://EmpoweredAbility.gd" id="1_y5vf6"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_y5vf6")
|
||||
power_multiplier = 2.5
|
||||
name = "Empowered Test Ability"
|
||||
power = 5.0
|
||||
metadata/_custom_type_script = "uid://xhcrf1lvfvc6"
|
||||
@@ -0,0 +1 @@
|
||||
<svg height="128" width="128" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="124" height="124" rx="14" fill="#363d52" stroke="#212532" stroke-width="4"/><g transform="scale(.101) translate(122 122)"><g fill="#fff"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 813 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H447l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c3 34 55 34 58 0v-86c-3-34-55-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></g></svg>
|
||||
|
After Width: | Height: | Size: 949 B |
@@ -0,0 +1,37 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cwblvv75nqbb3"
|
||||
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://icon.svg"
|
||||
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
||||
@@ -0,0 +1,28 @@
|
||||
; Engine configuration file.
|
||||
; It's best edited using the editor UI and not directly,
|
||||
; since the parameters that go here are not all obvious.
|
||||
;
|
||||
; Format:
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=5
|
||||
|
||||
[animation]
|
||||
|
||||
compatibility/default_parent_skeleton_in_mesh_instance_3d=true
|
||||
|
||||
[application]
|
||||
|
||||
config/name="Tutorials"
|
||||
run/main_scene="uid://c2e6p1udf2nyi"
|
||||
config/features=PackedStringArray("4.6", "C#")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[dotnet]
|
||||
|
||||
project/assembly_name="Tutorials"
|
||||
|
||||
[editor_plugins]
|
||||
|
||||
enabled=PackedStringArray("res://addons/custom_inspector_tools/plugin.cfg")
|
||||
@@ -0,0 +1,9 @@
|
||||
[gd_resource type="Resource" script_class="Ability" load_steps=2 format=3 uid="uid://bht3xjy7lpe0j"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cnjayq2d3r2dq" path="res://Ability.gd" id="1_p30r6"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_p30r6")
|
||||
name = "Test"
|
||||
power = 5.0
|
||||
metadata/_custom_type_script = "uid://cnjayq2d3r2dq"
|
||||
Reference in New Issue
Block a user