0 votes

What is the best way to instance a node in multiplayer for everyone to see it.
if I instance a new node in a player node the only one who can see it is the network_master, but other players cannot.

Godot version Godot 3.3.2
in Engine by (108 points)

1 Answer

0 votes
Best answer

Hi!
I use a factory-programming-pattern for that.
https://en.wikipedia.org/wiki/Factory_method_pattern

This is a centralized object for creating any type of object.
I integrate this as a "submodul" in my NetworkManager.
Whenever i want to create something i call:
app.NetworkManager.NetworkFactory.create("something",parent_node)

Where app is a autoloaded singleton as base for all global calls.
and all components like NetworkManager register to this app-object.

# this is my custom component system ... ignore this
extends NetworkModul
class_name NetworkFactory

#---- COMPONENT
func _init():
    app.register_component( self, "NetworkFactory", ["NetworkManager"] )
var NetworkManager:NetworkManager
#---- COMPONENT END


var instance_count = 0

var instances:Array
var instance_cache = {}
var instance_preload = {}

var instance_path = {
    "player": "res://gameobjects/player/Character.tscn",
    "steam": "res://gameobjects/fx/steam/Steam.tscn",
    "cable": "res://gameobjects/consumables/cable/Cable.tscn",
    "FlowPipe": "res://gameobjects/FlowNodes/FlowPipeline/Pipe/Pipe.tscn"
}

#------------------------ actually create things
func __make( what ):
    var a
    if instance_cache.has(what):
        #use allready loaded from cache
        a = instance_cache[what].instance()
    else:
        #load instance
        var o = load(instance_path[what])
        instance_cache[what] = o
        a = o.instance()

    instances.append(a)
    return a

#------------------------ get rid of things
func dispose( inst ):
    rpc("net_free", inst.get_path() )

#------------------------ actually get rid of things
remotesync func net_free( instPath ):
    print_debug("network-factory: free instance "+instPath)
    var inst = get_node( instPath )
    inst.queue_free()
    instances.erase( inst )

#------------------------ the function to call when creating something
func create( what, parent, name=null, on_ready=null ):
    print_debug("network-factory: create instance of "+what+" in "+parent.get_path())
    assert( instance_path.has(what), "NetworkFactory has no instance path of \""+what+"\"")
    var a = __make( what )

    if not name:
        name = "instance_"+str(instance_count)
        instance_count += 1
    a.name = name

    if on_ready:
        a.connect("ready",on_ready, "call_func", [], CONNECT_ONESHOT)

    parent.add_child(a)
    rpc("net_create", what, parent.get_path(), name )
    return a

#------------------------ gets called on the other clients
remote func net_create( what, parentPath, name ):
    var parent = get_node(parentPath)
    var a = __make( what )
    var icount = int(name)
    if icount > instance_count:
        instance_count = icount
    a.name = name
    parent.add_child(a)
by (4,088 points)
selected by
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.