티스토리 뷰
기본 사용법은 아는 상태에서 보완 및 보강, 실제 제작이 막히는 문제를 해결하기 위해 정리중
정리된 내용은 초보자용이 아니라 제가 놓친 부분입니다
볼 때마다 정리중
www.youtube.com/watch?v=wX145eoLFSM&list=PL9FzW-m48fn2SlrW0KoLT4n5egNdX-W9a
1편
- Input.is_action_pressed() 보다 Input.get_action_strength() 가 훨씬 나음.
2편
- Vector2.move_toward() 를 사용하면 클램핑 걱정을 안 해도 됨.
v1.move_toward(v2, 이동량) - 지터 (앞뒤로 왔다갔다 시간여행 끊김) & 슬러터 (그냥 뚝뚝 끊김) 고치기:
docs.godotengine.org/en/latest/tutorials/misc/jitter_stutter.html- 뭔가 스무싱하는 API 가 3.1에 생겼다는데 모르겠음
- 그냥 physics_process로 돌리자
3편
- move_and_colide() 의 패러미터에는 delta를 곱해야 함.
move_and_slide() 는 delta를 곱하면 안 됨. - move_and_slide() 의 반환값은 새 속도. 제대로 미끄러지려면 미끄러진 뒤의 속도 벡터를 반영해야 함.
아니면 벽에 부딛혔을 때 덜덜덜 떨릴 것임
velocity = move_and_slide(velocity)
4편
- Node (Node2D 말고)는 아직도 아리송한데 이미지나 노드를 Node의 자식으로 드래그 & 드랍 하면 가운데로 간다는 모양.
x, y 좌표를 처리 못 하는 게 아닐까? - YSort 노드 사용시 transform 위치가 기준이므로 노드의 중심 배치에 주의할 것
"분기로 변경" 이 이상해서 "가지로 변경" 으로 weblate 쪽에 반영. 미리 말해두지만 저는 분명히 그냥 브랜치라고 했었습니다.
5편
- AnimationPlayer에 방향별로 다 집어넣음. 왜? 는 다음편에 AnimationTree 를 쓴다고. (이거 쓸 줄 모르는데 잘된듯)
- onready var 알려줄 거 같았는데 진짜 알려주는데, 그 방식이 재미있음
- 일단 func _ready(): 에서 멤버 설정하는 걸 보여주고
- 더 쉬운 방법(쇼트컷) 이 있다 고 알려줌
- "자식 노드를 스크립트에 접근하기"
6편
- (따로 문서 읽어봄) anim_player 는 NodePath 타입임.
- 그냥 pre-parsed 일 뿐이고, Node.get_node() 에서 쓰면 되는 모양.
- 트리상의 다른 노드를 선택할 때 이걸 export 하면 되는 듯? (에디터에서 이럴 일 많음)
- 인스턴스화된 노드가 아니라 새로 만들 때에는 PackedScene이었던가...
- 뭐가 졸 많은데? 일단 State Machine 만 쓴다고.
- Animation 하나가 State Machine 노드 하나고 상태 전이를 드래그 & 드랍으로 만들 수 있음 (신기하다)
- 실제로는 StateMachine 이 아니라 BlendSpace2D 를 사용함.
- 똑같이 상태 전이 가능하고 대신 입력받은 좌표에 따라 애니메이션을 골라주는 고마운 녀석.
- 원래대로라면 본 기반 애니메이션에서 서로 다른 애니메이션을 섞는 데 썼겠지만 이번에는 혼합 모드를 이산으로 설정해놔서 2D 애니용으로 쓰임.
- 네 꼭지에 각각의 애니메이션 추가. y 좌표 + 가 게임에서는 아래쪽이지만 에디터에서는 위쪽이라는 점만 유의하면 됨
- 코드로 조작은 좀 성가신데...
- animationTree.set("마우스 호버해서 알아낸 속성", input_vector) 랑
animationTree.get("parameters/playback") 을 animationState로 보관해둔 뒤 travel("이름") 호출.
왜 속성으로 안 나와있는지 좀 이해가 안 됨. - 자동 시작이 빠져있으면 게임이 켜져도 애니메이션이 하나도 재생되지 않음. 동영상에서 이거 놓쳤다가 "쟤는 되는데 왜 나는 안 되지" 하고있었음..
- 왼쪽, 오른쪽을 우선하게 하는 데에는 트릭을 사용함. BlendSpace2D의 위, 아래 애니메이션을 1.1, -1.1 위치로 옮김.
- 혼합 모드를 이산(끊긴 점)으로 하지 않으면 지랄발광하므로 주의 (한참 찾았네...)
- 혼합 모드를 이산(끊긴 점)으로 하지 않으면 지랄발광하므로 주의 (한참 찾았네...)
어 근데 AnimationTree 가 이런거면 그냥 AnimationTreePlayer 쓰면 안 되는건가? 합쳐져있는 거처럼 생겼는데?
-> 추가해보니까 Deprecated 라고.
7편
- 스프라이트의 반복 기능. 아무리 반복을 체크하고 reimport 해도 안 됐던 게 리전을 활성화하니 마법같이 됨!
이거 예전부터 못 해서 진짜 애먹었는데...
- 리전은 원래 여러 스프라이트 이미지를 뭉쳐서 하나로 만들어놓은 커다란 아틀라스의 일부분을 표시하기 위한 기능인데, (리전 사용이 체크된 채로) 스프라이트가 "반복"이 체크된 채로 import 되었다면 리전의 의향을 존중해서 반복되어 늘어나주는 모양. :respect_bmcoe:
- 리전은 아래쪽의 텍스처 영역(리전인데 번역이...) 에서도 설정 가능
- 오토타일이라는 게 생겼는데, 비트마스크로 인접하게 배치될 타일을 결정하는 방식. 문서를 읽어봐야할듯
- 한 타일 이미지에 여러 종류의 타일셋을 넣을 수 있는 모양!
- 2.x 의 수동 타일맵 굽기에서 장족의 발전을 이뤘네요 충돌 설정도 되고
- 비트마스크 2x2 모드는 생각하는 그대로 동작하는데, 최소 비트 하나는 있어야 타일을 쓸 수 있음
-> 2 *2 - 1 = 15개 셀 - 3x3 (미니멀) 은 코너에 점이 있으면 코너 두 옆면 중 하나는 비트가 설정이 되어있어야 함.
아무것도 연결 안 된 셀은 가운데에 마스크를 하나 설정해야 함
-> 47개 셀 - 3x3 은 256개 셀
- "ignore" 비트는 Shift + click 이라는데 이게 뭔지는 모르것
- 빨갛게 설정된 비트: 옆에 닿아있는 셀들이 전부 빨개야 함
- 안 설정된 비트: 옆에 닿아있는 셀 중 최소 하나는 빨갛지 않아야 함
- 무시된 비트: 위 규칙 다 무시함
aha
- 한 타일 이미지에 여러 종류의 타일셋을 넣을 수 있는 모양!
8편
- 아직 충돌 상자 넣는 게 되게 불편한데, 사각형을 꽉 채울 생각이라면 번거로워짐
- 그래도 댓글에서 PageUp / PageDown 으로 현재 선택된 타일을 바꿀 수 있다는 걸 확인함
- 이슈
- 타일의 Z Order를 변경하면 트리 순서를 무시하고 글로벌로 반영됨.
- z-order는 Node2D에도 있음. UI가 아닌 2D 노드에 모두 Z 인덱스가 있다는 소리.
- CanvasLayer 및 이것의 CanvasTransforms 와는 다른 것임. z-order를 변경하는 편이 차라리 성능이 더 나음
- 그림자 캐스팅 (Occlusion) 도 있는데 이 튜토리얼에서는 다루지 않는다고.
- 언덕 위에 있는지, 언덕 밑에 있는지에 따라서 충돌 영역 밖의 내용을 가리는 건 어려운듯? 이렇게 할거면 트리 구성을 잘 생각해봐야 할지도.
- YSort 노드 말고 TileMap 에도 YSort 옵션이 있는데 이런다고 해결되지 않음. 검색해봤는데 타일맵이 자기 자식을 정렬한다고. 다수의 타일맵 개체를 쓰는 경우에는 문제가 될 듯. 그게 아니라 타일맵이 하나면...
- 차라리 유효한 해결법은 RPG Maker의 모델을 상정해서 땅, 언덕 위, 물 타일셋 세 개로 나누고 플레이어를 그 셋 중 하나의 자식으로 두는 것도 방법이 아닐까?
9편
- State machine을 간단한 enum 으로 넣기. GDScript 의 enum은 Dictionary의 syntatic sugar 라서 타입 취급이 안 되는 점이 불편 (닫힌 이슈)
- AnimationTree의 Tree Root로 AnimationNodeStateMachine (리소스) 를 만들어 넣었었고 까맣게 잊고 있었음.
- 공격이 끝난 뒤에 내부 State Machine의 enum 변수까지 바꾸기 위해 애니메이션 종료 시그널... 그런 거 아무리 찾아도 안 나옴.
- 심지어 AnimationNodeStateMachinePlayback 에도 그런 건 업1따
- 내부 트리 구성이 바뀔때의 이벤트가 있는데 대체 무슨 필요?
- 가만 생각해보면 엔진 디자인하는 입장에서 보면 애니메이션 트리 자체가 블렌딩이 가능해야 하는데 시그널을 넣는다는 것 자체가 좀 껄끄러운 일이기 함.
- 유효한 해결법은 각 애니메이션의 트랙에 스크립트 트랙을 넣어서 메서드를 호출하는 방법 뿐...
- 공격이 끝난 뒤에 내부 State Machine의 enum 변수까지 바꾸기 위해 애니메이션 종료 시그널... 그런 거 아무리 찾아도 안 나옴.
10편
- YSort 자식으로 YSort가 올 수 있습니다. 같이 소팅됩니다. (충격)
- 이번 영상에서는 시그널을 가르쳐주는데, yield가 있다는 걸 생각해냈습니다.
- 시그널이 있으면? yield가 있다.
- 사실 일반 시그널 연결법부터 가르쳐주는 게 맞긴 합니다.
- 문서를 봤는데 문법이 생각보다 쉽네요.
yield(animatedSprite, "animation_finished")
- 파일 시스템 독에서 코드에 끌어넣으면 바로 그 경로가 코드로... 와...
- get_tree() 로 root SceneTree 를 가져올 수 있는 건 알고 있었는데, 그걸 런타임 트리보기로 이해시키는 건 와 대단해
- 그러면서 인스펙팅 하는 거까지 가르쳐줌. 기회를 놓치지 않는 heartbeast 씨
- 나는 항상 self를 적는데, 그럴 필요가 없음. 만약 가르치게 된다면 둘 다 얘기해놔야지 나중에 질문이 안 들어온다...
- 근데 왜 preload가 아니고 load()를 콜하죠?
11편
오늘은 원래 하던 프로젝트가 손에 없어서 편집기만 열어서 살펴보기만.
- 이펙트는 별도 씬에 만드네요. 이유는 충돌 해제 코드를 짜기가 싫어서인듯. queue_free() 하면 끝나고 나중에 바꿀 수도 있으니까요.
- HitBox, HurtBox 두 개의 충돌상자 전용 씬을 만듭니다. (인-터레스팅-)
- 저는 하위 씬 편집 허용은 가급적이면 피하는 편인데 (원본 씬을 수정하면 어떻게 될 지 모름) 이 분 적극적으로 쓰시네요... 차라리 Area2D는 그대로 두고 CollisionShape2D만 따로 씬 하위에 넣는 게 낫지 않았을까요. 그럼 편집 허용을 할 필요는 없잖아요? 되나? 잘 되네요
- 씬 트리의 쁠러스 옆에 있는 링크 버튼이 인스턴스 씬 추가였습니다. 고걸 몰랏내!
- 검의 히트박스 Area2D를 Point2D 의 자식으로 옮기고, 검 휘두르는 애니메이션에 포함. (Rotation)
- CollisionShape는 알다시피 컴파일 될 때 구워버리니까... 부모를 옮기는 건 맞는데 Area2D를 옮겼어도 괜찮았을 것.
- 놀랍게도 충돌 여부 변경은 CollisionShape2D의 Disabled 프로퍼티를 애니메이션에 추가 (저거 굽는 거 아니었어?)
- 굽는 거 맞는데 동작함.
- https://docs.godotengine.org/en/latest/classes/class_collisionshape2d.html 읽어봐야한다...
- Collision Layer와 Mask 소개.
- 속성에서 이름 지정이 가능한데 자꾸 까먹음. Layer -> 내 충돌상자, Mask -> 내가 검사할 충돌 대상. KinematicBody2D 같은 내장 Physics 엔진 기반 노드들도 영향 받음
개념도
CollisionObject (Area2D) -> CollisionShape2D (Editor only)
CollisionObject -> ShapeOwner (노드가 아님) -> Shape, Shape, Shape, ...
-> ShapeOwner (노드가 아님) -> Shape, Shape, Shape, ...
CollisionShape가 {ShapeOwner -> Shape} 쌍으로 변하는 듯? 그래서 disabled 같은 걸 조작하는 게 먹는 듯. 실제로는 CollisionObject에서 ShapeOwner를 key 삼아 조작해야 함.
충돌의 단위가 ShapeOwner 인 듯?
shape_owner_set_disabled ( int owner_id, bool disabled ) 같은 게 있으니
문서
https://docs.godotengine.org/en/latest/classes/class_collisionshape2d.html f
질답
https://godotengine.org/qa/62180/clarification-about-collisionobject2d
https://www.reddit.com/r/godot/comments/fi3erf/what_are_shape_owners_and_how_do_they_work/
충돌상자 코드로 런타임에 모양이나 크기 같은 거 조작 안 할거면 굳이 알 필요 없을듯.
12편
정리하는 걸 깜빡 잊음.
동영상과는 다르게 다른 영상에서 봤던 StateMachine을 구현... 하느라 정신이 팔렸고 덕분에 정리를 스킵했었음
- GDScript 상의 클래스의 베이스 클래스는 무엇?
- 별도로 명시하지 않으면 기본적으로 Reference 클래스임 (GC가 아니라는 거야 알고있었고)
(이게 제일 궁금했었음) - Object를 상속하는 경우 메모리 관리를 직접 해야 함
- Object -> Reference -> 기타등등
- 별도로 명시하지 않으면 기본적으로 Reference 클래스임 (GC가 아니라는 거야 알고있었고)
13편
박쥐 적과 공격 knockback
- 인스턴스화된 씬에 스크립트를 붙이는 경우, 원본 씬에는 반영되지 않으므로 안심하고 붙여도 될 듯
(스크립트를 상속해서 펼치는 거야 두말할 것도 없고) - 플레이어 히트박스에서 넉백 값을 가져옴. 감지는 적 히트박스(HurtBox)에서.
- 이동하는 방향인 roll_vector를 쓴다는 게 특이점
- 프로퍼티가 개체에 있는지 확인하는 방법
- get() 이 null 인지
- "in" 연산자
- 내 프로젝트에서는 박쥐가 풀잎에 한 번 더 튕기는 현상이 있었는데 Monitoring, Monitored 쪽을 수정해야 하는 모양. 관련 버그도 있음
github.com/godotengine/godot/issues/7644- Area2D는 같은 Layer에 있는 Monitorable도 Monitor 하는 것 같음.
- 어차피 공격을 탐지하는 거니까, Layer는 필요없고 Mask만 있으면 됨 (충격)
www.youtube.com/watch?v=UZu8NwlkXcU
- 풀떼기 없애는 데 자꾸 나는 에러는 충돌 탐지중에 충돌을 비활성해서 나는 문제였던 모양.
godotengine.org/qa/38401/does-cant-change-this-state-while-flushing-queries-error-mean
- 수정은 시그널 연결하는 부분에서 지연(deferred) 체크하고 하는 김에 1회(oneshot)도 체크
14편
- export(float) var
- 스크립트 상속. 씬 상속은 다루지 않았음. 대체 씬 상속은 어떻게 돌아가는걸까...
- Stats 라는 별도의 노드를 만들어서 거기에 체력을 넣음.
- setget
- died 시그널.
- 재사용 가능한 프로퍼티의 has-a 관계화 (노드화) 는 계속 생각중인 건데도 이렇게 간단하게 해버리는 걸 보니 너무 내가 과도했던 게 아닌가 싶기도...
- 소드에 데미지를 주기 위해 소드 히트박스 (PlayerHitbox) 에 export(float) damage 를 함.
- 충돌한 게 area 니까 area.damage 를 빼면 그만이었던 거시다...
15편
15편에서는 스크립트만 떼서 재사용을 하는데, 난 그건 됐고 다른 방안을 살펴봄.
- option 1: 스크립트만 재사용 (하는 김에 connect(), preload 도 가르쳐줌)
영상에 나옴 - option 2: 같은 씬을 만들고 리소스만 갈아치우자
- 여러 삽질을 해봤는데
- class_name Effect를 정의하고 static method에서 인스턴스를 하는 간편 메소드
-> (preload()나 Effect).instance() 를 Effect.gd에서 하는 순간 순환 참조가 되어버림- load()로 바꾸면 되는데 석연찮음
- class_name Effect를 정의하고 static method에서 인스턴스를 하는 간편 메소드
- remove_and_skip() 은 내 자식을 죄다 부모로 옮기고 나를 없애므로 이펙트만 넣으려는 이 상황에는 매우 부적합함
- 스프라이트의 오프셋을 바꿀 수 없는 치명적인 문제가 있음
(SpriteFrame 리소스에는 오프셋이나 트랜스폼, 포지션이 없지롱)
- 여러 삽질을 해봤는데
- option 3: 씬 상속 (해보니 제일 나음)
- (씬 상속 방법은 설명하지 않음)
- 위험요소는 씬 상속이 이해하기 어렵다는 건데,
클래스 상속이 아닌 프로토타입 상속에 가깝다고 보면 될 듯. 이제 이해했으니 맘대로 써도 된당 :> - 스프라이트의 오프셋 문제가 여전히 있긴 한데, 해결 방법은 두 가지
- Effect.tscn 자체가 AnimationSprite 노드이게 만들지 말고 다시 Node2D의 자식으로 만들던가
- 자식으로 삽입할 때 global_position을 대뜸 할당하지 말던가 (바로 아래의 코드)
내 부모에 내 위치 기준으로 새 노드 삽입하기
func add_to_parent_of(target: Node2D):
var parent = target.get_parent()
if parent:
parent.add_child(self)
self.global_position = target.global_position + self.position
else:
self.queue_free()
물론 이렇게 하면 회전이 유지 안 될텐데, transform으로 어떻게 처리해봐야 할 텐데 그 쪽 개념을 잘 몰라서, 아니 헷갈리고 잘 몰라서. 해보니 아래 코드로 고치면 되는데, 이걸 이해하려면 선형대수의 매트릭스 선형 결합 쪽이라 3b1b 영상 하나랑 고도엔진 글 하나를 읽어야 함. (역행렬까지 필요 없었네...)
func add_to_parent_of(target: Node2D):
var parent = target.get_parent()
if parent:
parent.add_child(self)
# 둘 다 됨
# self.global_transform = self.global_transform * target.global_transform
self.transform = target.transform * self.transform
else:
self.queue_free()
씬 상속
Effect.tscn
[gd_scene load_steps=2 format=2]
[ext_resource path="res://Effects/Effect.gd" type="Script" id=1]
[node name="Effect" type="AnimatedSprite"]
script = ExtResource( 1 )
test_var = 3
GrassEffect.tscn
- [node name="GrassEffect"] 는 리소스 Effect.tscn 의 인스턴스임.
- Effect.tscn 은 Effect 인스턴스를 직렬화한 씬 파일 리소스임.
- 즉,
Effect 인스턴스
-> 인스턴스를 직렬화된 Effect.tscn
-> 이걸 인스턴스화한 GrassEffect 인스턴스
-> 이걸 직렬화한 GrassEffect.tscn 리소스
라는 관계가 성립함. - 즉, 씬 상속은 루트 노드가 인스턴스화된 노드인 것과 동일하다는 말.
[gd_scene load_steps=9 format=2]
// 뭐 첫 줄은 그 리소스가 뭔지 아니겠습니까.
// 레퍼런스는 안 찾아봤지만 딱 보면 삘이 온다 아입니까
[ext_resource path="res://Effects/Effect.tscn" type="PackedScene" id=1]
[ext_resource path="res://Effects/GrassEffect.png" type="Texture" id=2]
// ext_resource는 뭐 외부 리소스겠죠
고유 리소스 생략
[node name="GrassEffect" instance=ExtResource( 1 )]
position = Vector2( 8, 8 )
frames = SubResource( 6 )
// 노드는 한참 아래에 적혀있더군요.
// 부모인 Effect.tscn에는 type 속성이 있었지만
// 자식에는 대신 instance가 있습니다.
- Total
- Today
- Yesterday
- 업비트
- Oracle Cloud Infrastructure
- exercism
- 개발기록
- C++ FAQ
- K8s
- pdf.js
- javascript
- Sass
- scss
- ArchLinuxARM
- kotlin당했다
- vuex
- gitea
- 왜 생각이 안 났지
- 오라클 클라우드
- mvu
- Godot Engine
- upbit
- 시스어드민
- ActivityPub
- OStatus
- 오라클 클라우드 인프라
- rust-lang
- 쿠버네티스
- C#
- 마스토돈
- c++
- pleroma
- 토이프로젝트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |