Godot에서init(args)를 쓰면 장면을 실례화할 때 곤란해요.

개시하다


이 글은 고독 엔진으로 장면을 실례화할 때 제대로 진행되지 않는 내용을 일본어로 공유한다.내용은 3.2.3.stable.official의 버전을 확인했다.
개요는 아래와 같다.
  • _init(args)라고 적힌 장면은 실례화할 때 초기화할 수 없고 확장된 함수를 호출할 수 없습니다
  • 원본, _init(args)장류new시 사용
  • 장면 초기화의 소박한 해결 방안
  • _init(args)라고 적힌 장면은 실례화할 때 초기화할 수 없고 확장된 함수를 호출할 수 없습니다


    Godot에서 장면은 재활용할 수 있는 자원으로 실례화를 통해 편리하게 사용할 수 있다.
    그러나 특정한 매개 변수_init(args)가 정의한 스크립트가 있는 장면에서는 실례화할 때 초기 값을 제시할 수 없고 이 실례는 계승 노드에 추가된 함수를 호출할 수 없다.
    Scene.gd
    # Scene.tscn のルートノードにアタッチしてあるスクリプト。
    # ルートノードはSpriteとした
    extends Sprite
    
    # 独自の関数を定義する
    func change_stats():
    	print("change_stats")
    
    func _init(s:String):
    	print("hello from _init" + str)
    
    Main.gd
    const Child_Scene = preload("res://Scene.tscn")
    func instance_scene():
    	var s_instance = Child_Scene.instance() # 引数に何かを与えるとエラーになる
    	print(s_instance.get_class()) # -> Sprite
    	s_instance.change_stats() #  Invalid call. Nonexistent function 'change_stats' in base 'Sprite'.
    	add_child(s_instance)
    
    위의 예는 print일 뿐이지만 이 행위는 아래의 일에 대응할 수 없다.
  • 장면에서 초기값을 설정하고 싶을 때
  • 장면에서 노드를 확장한 함수를 사용하고 싶을 때
  • _init(args)는 반을 업데이트할 때만


    조사 결과 파라미터_init()가 없는 상황에서 확장된 함수를 정확하게 호칭할 수 있었다.
    Scene.gd
    extends Sprite
    func _init():
    	print("hello from _init")
    
    func print_some(s): # 関数を拡張
    	print("some " + s)
    
    Main.gd
    const ChildScene = preload("res://Scene.tscn")
    ChildScene.instance() # -> hello from _init
    ChildScene.instance().print_some("hoge") # 拡張された関数も呼べる
    
    다만, 물론 이 예는 초기값을 교부할 수 없다.
    원래 파라미터가 있는 _init(args)는 스크립트에서 반new까지 사용할 수 있습니다.
    Scene.gd
    extends Sprite
    func _init(s):
    	print("hello " + s)
    
    func print_some(s): # 関数を拡張
    	print("some " + s)
    
    Main.gd
    const SceneClass = preload("res://Scene.gd") # シーンではなく、スクリプトをロード
    SceneClass.new("uho") # -> hello uho
    SceneClass.new("uho").print_some("hoge") # 拡張された関数も呼べる
    
    또는 class_name를 사용하여 엔진에 등록하면 탑재할 필요가 없습니다.
    Scene.gd
    extends Sprite
    class_name ExtendSprite # クラスをエンジンに登録する
    func _init(s):
    	print("hello " + s)
    	
    func print_some(s): # 関数を拡張
    	print("some " + s)
    
    Main.gd
    ExtendSprite.new("uho") # -> hello uho
    ExtendSprite.new("uho").print_some("hoge") # 拡張された関数も呼べる
    
    반을 초기화하는 방법과 장면을 초기화하는 방법은 현재 Godot에서는 다른 것 같습니다.

    장면 초기화 방법의 순박한 해결


    지금까지_init(args)는 장면을 잘 초기화하지 못했고 이 방법을 보면 반을 초기화할 수 밖에 없었다.그렇다면 어떻게 장면의 초기화를 진행합니까?
    순박한 방법이지만 초기화용 함수를 만들어 실례화한 뒤 바로 불러내는 방법이 있다.
    다음 스크립트를 루트 노드에 첨부하여 Scene.tscn를 만듭니다.
    Scene.gd
    func initialize( pos: Vector2 ): # 初期化するための関数
    	set_position(pos)
    	return self # selfを返すとメソッドチェーンで一行で書けるので良い
    
    이렇게 실례 코드Scene.tscn를 사용할 수 있다.
    Main.gd
    const Scene = preload("res://Scene.tscn")
    
    func some_function():
    	var pos = Vector2.new(0, 0)
    	var s = Scene.instance().initialize(pos) # instance()の後に呼び出す
            add_child(s) # _readyが呼ばれる
    

    참고 자료

  • instance 및 new
  • 장면을 실례화할 때 초기 값을 매개 변수로 하는 방법 (영문 문장)
  • 끝말


    학급new()에 따른 것이냐, 장면instance()에 따른 것이냐에 따라 조금만 디자인해도 혼란스러울 것 같다.무슨 의도가 있었어?자세한 사연이 있으면 즐거울 거예요.

    좋은 웹페이지 즐겨찾기