Blender에서 작업하여 Collada로 export한 결과물을 Godot engine에서 import하여 사용해야할 경우, Bone과 Animation을 하지 않은 경우는 크게 문제가 되지 않으나, Bone을 심어서 Animation 작업을 한 경우에는 제대로 동작하지 않는 경우가 있다.(예를 들면 뼈와 살이 분리되서 움직임)

이러한 경우, Blender에서 Bone 작업시 배치를 다 하고 나서, Bone을 전부 다 선택하고 나서 상속(Set Parent to, Ctrl + P key)를 누른 후, With Automatic Weights를 선택한 다음, Animation 작업을 시작한다.

그리고, Pose 작업을 하고 나서 Key 삽입시(Insert Keyframe, I key)에 LocRotScale을 선택하여 준다.

이렇게 작업을 마친 후에 Blender에서 기본으로 제공하는 Collada를 이용하던, Better export dae를 이용하여 export하던 결과물은 godot engine에서 제대로 동작을 한다.

그리고 godot engine의 버그로 추정되는 것이 하나 있는데, 심은 bone 중 하나가 IDE에서는 보이질 않으나(맨마지막 bone으로 추정됨), 작업하는데는 문제가 없다.(사실 Inspector에서는 정상적으로 존재하는 것으로 나옴. View에서만 안보임)

extends Spatial

var camera_distance = 2

func _ready():
	set_process(true)

	$Spatial/Spatial/Camera.translation = camera_distance * Vector3(0, 5, 5)
	$Spatial/Spatial/Camera.rotation_degrees = Vector3(-35, 0, 0)
	
func _process(delta):
	# Left & Right Rotation
	if Input.is_key_pressed(KEY_Q):
		$Spatial.rotate_y(5 * delta)
	elif Input.is_key_pressed(KEY_E):
		$Spatial.rotate_y(-5 * delta)

	# Up & Down Rotation
	if Input.is_key_pressed(KEY_W):
		$Spatial/Spatial.rotate_x(5 * delta)
	elif Input.is_key_pressed(KEY_S):
		$Spatial/Spatial.rotate_x(-5 * delta)

	# Zoomin & Zoomout
	if Input.is_key_pressed(KEY_EQUAL):
		$Spatial.set_scale($Spatial.get_scale() - Vector3(0.8, 0.8, 0.8) * delta)
	elif Input.is_key_pressed(KEY_MINUS):
		$Spatial.set_scale($Spatial.get_scale() + Vector3(0.8, 0.8, 0.8) * delta)

 

<참고>
http://www.bitoutsidethebox.com/godot-tutorial-5-2-axis-gimbal-camera-for-3d-games/

extends Node
...
signal my_signal


func _ready():
    connect("my_signal", self, "signal_handler")
    ...
    var otherNode = get_node("someNode")
    otherNode.connect("my_signal", self, "signal_handler")

func SomeFunc():
    ...
    # causes self.signal_handler() to be called
    emit_signal("my_signal")
    ...

func signal_handler():
    ...

 

[참고] https://godotengine.org/qa/3218/how-to-create-a-custom-signal-in-gdscript

Scene 편집 도구를 이용해도 되지만, GD Script만으로 코딩을 하고 싶을 경우(?)에는 아래 예제를 참고하여 작성하면 된다.

extends Node

func _ready():
	
	var timer = Timer.new()
	add_child(timer)

	timer.connect("timeout", self, "_on_timeout")

	timer.set_wait_time(10)
	timer.start()
	
func _on_timeout():
	
	print("Time out!")

 

[참고] http://docs.godotengine.org/en/3.0/classes/class_timer.html

RigidBody2D에서 총알(Bullet)을 발사하여 벽(Block)에 충돌하였을 경우, 충돌한 객체의 정보를 얻어내기 위해서는 func _ready() 안에 다음 code를 추가한다.

func _ready():
    set_contact_monitor(true)
    set_max_contacts_reported(5) # 0보다 큰 정수를 지정해주면 된다.

그다음 편집기에서 signals에서 함수를 연결하면 되지만, 직접 Gdscript에서 code를 추가하여보자. 그렇기 위해선 _ready() 함수 루틴에 다음과 같이 signal을 연결하는 code를 추가한다.

func _ready():
    set_contact_monitor(true)
    set_max_contacts_reported(5)
    connect("body_entered", self, "collision_detected")

그리고 collision_detected() 함수를 작성한다.

func collision_detected(obj):
    print(self.get_name(), " is colliding with ", obj.get_name())

더 자세한 정보를 얻고 싶을때는 get_colliding_bodies()를 이용하면 된다.

 

<참고>
 https://www.reddit.com/r/godot/comments/3ofhwj/how_can_i_use_body_enter_function/

일반적인 resource들은 load() 혹은 preload()를 이용하여 불러올 수 있다.

예)

var res1 = load("res://sample1.png")

var res2 = preload("res://sample2.png")

 

scene을 불러올 때는 PackedScene.instance()를 이용하면 된다.

예)

var bullet = preload("res://bullet.tscn").instance()

add_child(bullet)

인스턴스(혹은 노드)를 생성할 때 관리를 위해서 그룹화를 하는 경우가 생기는데, 그러한 경우 그룹 안에 몇개의 인스턴스가 생성되어 있는지 확인하고자 할 경우 다음과 같이 하면 된다.

 

get_tree().get_nodes_in_group("그룹명").size()

 

보다 자세한 것은 SceneTree.get_nodes_in_group을 참조하면 된다.

+ Recent posts