How to make it such that there are individual scripts for each level in godot game engine? - godot

I am new to the Godot engine so please forgive me if this is a very simple question.
So I am creating a game (2d platformer) that pretty much has the same level layout as every other level. However, each level has a trick to it. Say:
For level 1:
flick the lever (by pressing f) and a portal opens up.
enter the portal and go to next level (level 2)
For level 2:
flick the lever (by pressing f) 5 times and portal opens up.
enter the portal and go to next level (level 3)
For level 3:
flick the lever (by clicking with mouse cursor unlike level 1 and 2) and portal opens up.
enter the portal
etc etc.
So this is the layout for the game I'm developing. Problem is when I duplicate the level, the scripts (for lever, portal etc) don't seem to be "individual" to each level node. Is there a way to make it such that each level node and its sub-nodes (like the lever for level 2 having a separate script to level 1's lever)?
Thanks, and sorry again if this is a stupid question.

There isn't a trick.
This issue has come up in the discussion on the Godot-Proposals repository. Feel to offer your ideas on how to improve Godot there.
Godot is rather flexible on how you organize your project. This also means that keeping the organization you pick is up to you.
First of all, I must mention that scripts do not need to be their own files. On the "Attach Node Script" dialog (which you can open from "Attach Script" on the context menu on Scene) you can select "build-in" script. And this will store the script in the scene file. As a result, if you copy the scene file, you are also copying the script. Although, having the script in a separate file is often preferible for version control, and for using an external editor.
Beyond that, there are a couple tools that will help you:
On the context menu from the FileSystem, you can select "View Owners…". This will show you where resources (including scripts) are used explicitly (references using load or anything dynamic does not count).
On the Project menu, under tools, select "Orphan Resource Explorer…". This will show you any resources (including scripts) that are not used anywhere (again, it ignores dynamic loading, so it might say something you are actually using isn't).
With those tools you can - for example - make a folder for each level (and a folder for resources to be shared across levels, perhaps organized on folders by type), and check if the script on the folder of a level are referenced from the scenes on that same folder and not the folders of the other levels.
Some people prefer to put all the scripts on a single folder regardless of where they are used, and all the scenes on the same folder, and so on. That is somewhat harder to keep track of, but with the tools mentioned above you can check. Perhaps you could have a naming scheme so you can tell for which level each resource is (or if the resource is intended to be reused in multiple levels)?
Consider also:
Signals. For example, you might have identical levers except for what they do. Instead of coding in the script what they do, add a custom signal and connect it form the editor. Again, those signal connections are stored in the scene file. I would, for example, have the counter for how many times the lever is switched in the code connected to the lever instead of having it on the lever itself. By the way, see signal bus and resource based communication.
Exported variables. If you have similar scripts, identify the differences (e.g. to which level a portal goes), and consider turning them and turn them into exported variables (export var) which can be edited from the Inspector. Those variables are stored in the scene file, so they will remain unique even when you duplicate the scene. This also means that if you find an error on the code, you don't have to fix it on two different scripts. However, be aware that if you generalize things that might seem related but actually aren't, you will run into trouble later, so the general advice is to not do it preemptivly.
These also mean that those scripts would no longer be unique of the scene, and you can move them to a common folder for all such scripts and not worry anymore if they are used in - and only in - the correct scene.
By the way, I would like to point you to:
Scene composition: in Godot scenes can have instances of other scenes inside. So you can make scenes for the individual components (e.g. an scene for the portal) and put them together in the level scene. Then these scripts we are talking about do not really belong to a level, but to a component. And that component could be used in multiple scenes without issue (again, with the help of signals and exported variables).
Scene inheritance. What you are doings sounds like you could have a base scene with the common elements, and then create inherited scenes for each level from it (you find the option in the context menu of an existing scene in the FileSystem). The inherited scenes would have everything the base one has, but can add new nodes or change the properties of existing nodes.

There are diffrent approaches you could try to accomplish this.
The first that comes to mind for me is that you implement something like a current state for the diffrent items. So for example add a export variable to track the level you are in (or have it as an global variable somewhere). Then you check this variable in the _ready function and enter the correct state for the according level.
Your lever script would then only have the common functions like opening the portal and starting the flick animation, but the triggers, which call these functions are handled in the diffrent state scripts.
So your lever would look something like this:
extends Node
export(int) var level = 1
var state_paths = [ "path_to_level_1_state", "path_to_level_2_state" ]
var current_state = null
func _ready() -> void:
current_state = load(state_paths[level-1].new()
current_state.enter(self)
# delegate events to the state objects.
func _unhandled_input(event: InputEvent) -> void:
current_state.handle_input(event)
func _process(delta: float) -> void:
current_state.update(delta)
func _physics_process(delta: float) -> void:
current_state.physics_update(delta)
func open_gate() -> void:
$AnimationPlayer.play("flick")
#notify gate to open code..
There are definitly better and much safer ways to store the diffrent state scripts Like creating subnodes in your lever scene which conatin the scripts like done here for the state maschine but I guess this will do for the example.
(path_to_level_1_state is the full path to a script like "res:/scripts/states/lever/level1.gd")
This script could look like this (you can write a base class for all your states which hold the reference to the Item and implement base functions, but I'm not doing this here atm, because I write all this from my phone):
extends Node
var lever = null
func enter(parent) -> void:
lever = parent
func handle_input(event) -> void:
if event is InputEventKey:
if event.pressed and event.scancode == KEY_F:
lever.open_gate()
func update(delta):
pass #nothing to do here bit maybe in another level?
func physics_update(delta):
pass

Related

MRTK increasing pointer extent

I'm trying to extend the maximum depth of the pointers to use in a scene where objects can be further away. I've set the 'pointing extent' setting under the MixedRealityPointerProfile which seems to have no effect.
Am I missing something?
Thanks
Take the official HandTracking project as an example. To increase the pointer extent in Unity, please check the following steps.
In MRTK component, navigate to [Input] -> [Pointers] -> [pointer extent], setting the global maximum extent value.
Then navigate to [Input] -> [Pointers] -> [pointer options] -> [ShellHandRayPointer] and edit this prefab. In ShellHandRayPointer script, change the value of “Pointer Extent” and “Default Pointer Extent”.
If you cannot alter the prefab in package folder, you need to drag it into your self’s Asset folder then select this prefab in MRTK component.
Basic idea is besides changing the global extent value in MRTK, you also need to customize the Pointer profile to make it work. The above steps will modify the hand tracking pointer in HoloLens, and feel free to modify other pointer profiles if necessary.
To be clear, in the common scenario, interacting long distant objects are not recommended because due to small view angle, distant objects have to be extreme large for interactive. It is also recommended to check the document on Sizing recommendations - Mixed Reality | Microsoft Docs.

What is the "Fx Functions" in Azure applications Insights? How can you add one?

Recently, I've been working with application insights and building up my queries and understanding. One of the features that I would expect is to define functions outside of the scope of a particular kusto script/query with the intention that the function can be reused from other scripts/queries.
When I started working with it, I had noticed a menu item under the sources that was labeled fx functions and had assumed that this is where I could eventually add my functions. Initially, I saw no UI path to create one and I thought this was due to authorization policies. As I'm now much more comfortable with the Kusto language, I want to break my big scripts into smaller ones but I can't.
I've checked with a private account, where I'm full owner, if I could add one but there no UI path as well. I spoke with our Azure configurators and he as an owner can't find a UI path as well. This doesn't seem to be a result of limited authorization. I've google this and I can't find anything. I've the documentation and there is not mention.
Anyone knows what this is and if it represents a custom functions library how can it be modified? How would you reference it?
Update 1
From an answer provided by #ivan-yang, it seems that I missed this when trying out with my personal account. Apparently, you can save a script as
A query
Private
Shared
A function
When saving as a function, the system creates a reference in the shared queries but with a different icon.
Update:
Correction, I can update the function. When a function and a shared query exist with the same name, then there is a problem. Once I renamed the shared query to something else, I could overwrite the function.
In the application insights -> Logs, in the editor field, you can write a query, then click save -> in the popup window, provide a name like f1, then save as Function. Then you can see the the new function f1 in the "fx Functions":
And as per my test, if you define a custom function and save it, there is no chance to modify it.
Regarding how to reference it, you can use the function like requests / traces, like using union / filter etc.

Flutter Search Delegate Architecture (code structure best practices)

I am relative new to flutter. I was wondering the proper approach in order to implement an AppBar search by using the Search Delegate in Flutter. I read various articles on how to do that. However, with dummy data (used in examples) and just no real world scenarios (code structure) there is no hustle.
My use case consists of
AppBar (home widget - where the search button exists)
One tab (other widget - having a service call to DB at init)
Another tab (other widget -having a service call to DB at init)
My issue is that I want the search to take place at the results lets say of the first tab. So somehow, I have to pass the values return from the service up to my Home widget and then to search Delegate .
I do not know which is the proper way to do that.
InheritedModel/ InheritedWidget ?
passing via the constructors from one widget to another (then I will have tight widget connections and I do not want that)
Some other way using services ?
if any other solution ?
I want the solution to be scalable (as much as possible), in order to make adjustments at near future or add new functionality.
Thanks in advance for your time.
Update
I tried the InheritedModel/ InheritedWidget. For some reason, when I tried to access the data from the build method in Delegate I was receiving null object for inherited object. Probably, I was doing something wrong...I will keep trying...
Adding an image in order to clarify the problem with my app structure...
Do you already know this tutorial?
https://www.youtube.com/watch?v=Wm3OiFBZ2xI
I think, it is exactly what you need. My App uses Data from the Cloud Firestore and the search function is implemented like the search function in this tutorial. It works very well.

Combine some CScrollView into one

I have some files and i use OpenDocumentFile() to open and get pFirtView of each file.
Now i have CView/CScrollView(s) for the files.
I need combine all CView/CScrollView(s) to only one CScrollView. Any suggestion? Thanks
The framework doesn't support this. You can probably hack around it by providing some sort of aggregate CView that can host multiple windows and does the layouting, but for your mental health, I suggest avoiding Doc/View for any scenario that is not exactly the way it is intended to be used, and do your window creation/drawing.
Remove the CDocTemplate based creation part in the App class, create a CWnd-derived class to host other windows and set m_pMainWnd to that window. That gets you there 90% of the way (well apart from the actual drawing in the child windows, of course...)

Show a specific process dialog in petrel?

I want to show a specified dialog under simulation category like "Developement Strategy" and do something after its "OK" click. Is there a way to show a native petrel process window?
I can see some class and interfaces in "Slb.Ocean.Petrel.UI" like DialogBuilder , DialogPage, IDialogPageFactory, IDialogPage...but I can't use them, even I don't know if they supply my required objects.
I think you want to create a Workstep (Slb.Ocean.Petrel.Workflow). The Ocean wizard lets offers a quick start. It creates optionally a process wrapper for you, which is the item showing up in the process tree.
Once you got familiar with the concepts, you can evolve the simplistic initial implementation by using the WorkflowEditorUIFactory. Check the namespace documentation in the Ocean documentation for more details.
IProcessDiagram offers different Add methods for your custom Process to enable custom positioning in the tree node sequence.
You can programmatically show a particular process dialog using DialogBuilder.ShowSettings(object) and passing the Process instance. This is typically used by a plug-in to launch its own process dialog, but it's possible to obtain a reference to the instance of a native Process by name using FindProcess(string). This is, of course, a very fragile approach:
Process p = PetrelSystem.ProcessDiagram.FindProcess("Development strategy");
PetrelSystem.DialogBuilder.ShowSettings(p);
It would need a lot of error handling, not just to guard against changes to the process name, but also to handle the case where an exclusive process dialog is already open.
However, this will still only launch the dialog. There is no way to know if/when the user clicks the OK button. Petrel processes are typically stand-alone pieces of functionality, and any kind of chaining is generally supported by creating workflows.

Resources