plitri

검색어 '학습/Godot 엔진'로 4개의 글을 찾았습니다.

  1. 2017.08.21 [Godot] 루프에서 wait 함수 사용하기 
  2. 2017.03.11 [Godot] GUI를 카메라에 영향받지 않도록 하기 
  3. 2017.03.11 [Godot] C2의 scale-in 구현 (반응형) 
  4. 2017.03.10 [Godot] Patch9Frame 

[Godot] 루프에서 wait 함수 사용하기

2017.08.21 17:45학습/Godot 엔진

2.x 기준입니다.

wait 함수

OS.delay_msec 등의 함수가 있지만 이건 왠만하면 사용하지 않도록 합시다. 스레드 째로 멈춰버려서 다른 게 아예 실행이 안 될 수 있습니다. (테스트는 안 해봤음)

타이머 노드

고도 엔진에서 대기할 일이 있으면 왠만하면 타이머 노드를 사용한다고 보시면 됩니다. 에디터에서 타이머 노드의 timeout 시그널을 함수에 연결해서 해당 함수로 시간이 경과되었을 때의 처리를 작성할 수는 있는데 이건 함수 실행 도중에 함수의 수행을 일시정지하고 기다렸다 재개하고 싶다- 라는 요구사항에는 안 맞죠.

아무튼 타이머 노드에서 필요한 시그널은 timeout 입니다. 잘 기억해둡시다.

yield

다른 언어처럼 GDScript에서도 yield()(문서: GDScript 기본-코루틴 / @GDScript.yield )를 호출해 함수를 중간에서 멈추고, 나중에 멈춘 지점부터 계속 실행할 수 있습니다. yield() 를 호출하면 함수의 실행 상태를 담은 값(GDFunctionState)을 반환하게 되고, 이걸 resume() 하면 함수가 이어서 마저 실행됩니다.

func myfunc():
    print( yield() ) # yield를 호출하는 순간 반환합니다.

func _ready():
    var y = myfunc() # yield로 반환되었기에 GDFunctionState 값이 y에 할당됩니다.
    print( y.resume("world") )

이걸 잘 활용하면 wait 함수를 직접 짤 수 있으나 아직 좀 번거롭습니다.

yield + signal

yield 함수에는 추가로 인자를 넣을 수 있습니다. yield( 대상 객체, 시그널 이름 ) 으로, 이렇게 호출한 경우 특정 개체의 시그널을 받으면 함수의 수행을 그 자리부터 재개하게 됩니다.

그래서, 유니티에서는 이렇게 하는 코드를

yield return new WaitForSeconds(.1f);

고도에서는 이렇게 합니다 / 2.

yield( timer, "timeout" ) # timer 개체의 timeout 시그널이 발생하면 여기서부터 재개합니다.

유니티에서는 타이머 객체를 필요할 때 생성하는 반면 고도엔진에서는 특정 객체의 시그널이 발생하면 해당 지점으로부터 재개할 수 있도록 바로 설정할 수 있습니다. 그래서… 씬 트리에 삽입되어있는 객체인 Timer 노드를 사용하려면 timeout이 발생할 수 있도록 사전 조작을 필요로 합니다. 타이머가 없다면 만들어 씬 트리에 넣고, 타이머를 시작할 필요가 있죠.

func myfunc():
    var timer = Timer.new()
    self.add_child(timer)

    for i in range(10):
        timer.set_one_shot( true )
        timer.set_wait_time( 1.0 )
        timer.start()
        yield( timer, "timeout" )

    timer.queue_free() # free 처리를 안 해주면 myfunc()이 호출될 때마다 타이머가 쌓일겁니다.
    # 아니면 사전에 timer 노드가 트리에 있고 영속적이라면 문제가 없죠.

기억에 의하면 Timer 노드는 트리에 삽입된 상태여야지 동작하는 것 같던데 이 점은 아쉽더라구요. 노드가 아닌 타이머가 필요하다면 Reference를 상속받는 커스텀 객체 같은 걸 만들어서 yield로 호출되었을 때 별도의 코드 없이 바로 처리되게 만들수도 있을 것 같습니다.

여담인데 yield가 값이 아닌 함수의 상태를 반환하는 바람에 제너레이터 패턴을 손쉽게 만들 수 없습니다. 멤버변수 등으로 우회할 순 있겠지만요.

신고

[Godot] GUI를 카메라에 영향받지 않도록 하기

2017.03.11 14:47학습/Godot 엔진

CanvasLayer 밑에 두래요.

참고

근데 왜일까요... (...) 아, 메뉴얼에 자세한 설명이 있었군요. 어쩌다보니 까먹었지만요. ParallaxBackground 도 CanvasLayer의 자식입니다.

아무튼 저거때문에 일시정지 메뉴의 루트를 바꿔버렸습니다. 잘 되네요. 일단 사용하는 입장에서는 자세히는 몰라도 되지 않을까 싶습니다.

어 그럼 C2의 Parallax Ratio는 어떻게 구현하지...?

ParallaxBackground 아래에 두면 되지 싶은데 확인하긴 번거로우니 나중에 필요할 때 알아보기로 하겠습니다.

신고

[Godot] C2의 scale-in 구현 (반응형)

2017.03.11 12:33학습/Godot 엔진

참고자료


여러 방법이 있겠는데 저는 keep-width와 keep-height를 거꾸로 적용하는 방법으로 갔습니다.

저는 아래 코드를 자동로드(autoload / 싱글톤)에 넣고 구동했습니다. OS.get_window_size()가 모바일에서도 동작하는지는 아직 확인하지 않았습니다.

# https://godotengine.org/qa/9947/responsive-to-fit-multiple-resolutions
# https://sites.google.com/site/dsgodot/code-snippets/viewport-size
extends Node

var min_screen = Vector2(Globals.get("display/width"), Globals.get("display/height"))

func _ready():
	get_tree().connect("screen_resized", self, "_screen_resized");
	_screen_resized()

func _screen_resized():
	var scene_rect = OS.get_window_size()
	# print("DEBUG","Scene resized : " + str(scene_rect) )
	if scene_rect.width > scene_rect.height:
		get_tree().set_screen_stretch( SceneTree.STRETCH_MODE_VIEWPORT, SceneTree.STRETCH_ASPECT_KEEP_HEIGHT, min_screen )
	else:
		get_tree().set_screen_stretch( SceneTree.STRETCH_MODE_VIEWPORT, SceneTree.STRETCH_ASPECT_KEEP_WIDTH, min_screen )
	# print("DEBUG","Scene resized : " + str( get_tree().get_root().get_node("level_player/pause_ui").get_size() ) )

프로젝트 설정은 이렇습니다.

  • width, height 지정
  • stretch_mode - viewport
  • stretch_aspect - keep
  • 씬의 루트 노드는 풀스크린 앵커링된 컨트롤


이제 카메라 세팅하는 법 알아보러 가야...

신고

[Godot] Patch9Frame

2017.03.10 02:29학습/Godot 엔진

128x128, 외곽 둥긂 32px 인 스프라이트로 확인하였습니다.




Region Rect는 스프라이트에서 9 Patch를 지정한 영역을 나타내는 듯 합니다. Width, Height 둘 다 0인 경우 아예 이미지 전체영역을 잡는 것 같습니다. 이미지 전체 기준일 경우 굳이 수정할 필요 없습니다.

Patch Margin은 상하좌우 테두리 영역인 듯 합니다.

Draw Center를 체크 해제하면 가운데가 비게 됩니다.

신고
1