티스토리 뷰
고도 게임 엔진에서 하나의 프로젝트는 하나의 폴더를 생성하는 것으로 시작한다. 해당 폴더가 프로젝트의 루트 폴더가 되어서 씬이나 자원, 스크립트 경로를 지정할 때 "res://"는 프로젝트의 루트 폴더를 의미한다. 물론 하위 폴더를 가질 수 있다. 루트 폴더에 고도 프로젝트 파일(project.godot)이 한 개 존재하고 한 개 이상의 씬 파일과 스크립트 파일, 그리고 여러 가지 에셋(이미지, 폰트, 3D 모델 등등) 파일로 프로젝트 파일 시스템을 구성한다.
■ 고도 프로젝트 파일(project.godot)
프로젝트의 이름, 시작 씬, 입력 설정 정보 등의 프로젝트의 주요 설정이 담기는 파일.
config_version=4
[application]
config/name="Global Illumination"
run/main_scene="res://test.tscn"
config/icon="res://icon.png"
[display]
window/dpi/allow_hidpi=true
window/stretch/mode="2d"
window/stretch/aspect="expand"
[input]
■ 고도 씬 파일(*.tscn)
고도의 구성 정보를 담는 씬 파일로 크게 4가지 요소인 ext_resource, sub_resource, node, connection로 이루어진다.
[gd_scene load_steps=58 format=2]
[ext_resource path="res://default_env.tres" type="Environment" id=1]
[ext_resource path="res://camera_controller.gd" type="Script" id=2]
[ext_resource path="res://split_screen.shader" type="Shader" id=3]
[ext_resource path="res://icon.png" type="Texture" id=4]
[ext_resource path="res://player.gd" type="Script" id=5]
[sub_resource type="ShaderMaterial" id=1]
shader = ExtResource( 3 )
shader_param/viewport_size = null
shader_param/split_active = null
shader_param/player1_position = null
shader_param/player2_position = null
shader_param/split_line_thickness = null
shader_param/split_line_color = null
[sub_resource type="CapsuleMesh" id=2]
;......
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource( 2 )
[node name="Trail" type="Particles2D" parent="."]
z_index = -1
amount = 10
speed_scale = 2.0
local_coords = false
process_material = SubResource( 7 )
texture = ExtResource( 2 )
[connection signal="body_entered" from="." to="." method="_on_Player_body_entered"]
대괄호로 시작하는 각 영역에서 ext_resource, sub_resource는 외부 및 내부 자원을 기술하고 node는 부모를 지정하는 방식으로 하나의 씬(Scene)을 구성하는 계층적인 노드를 기술한다. connection은 다양한 이벤트를 선언한다. 이벤트를 처리하는 로직은 고도 스크립트에서 기술한다.
■ 고도 리소스 파일(*.tres)
고도의 씬 파일의 확장으로 리소스 정보를 담는다.
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1]
ground_bottom_color = Color( 0.839216, 0.917647, 0.980392, 1 )
ground_horizon_color = Color( 0.839216, 0.917647, 0.980392, 1 )
[resource]
background_mode = 2
background_sky = SubResource( 1 )
ambient_light_color = Color( 0.560784, 0.560784, 0.560784, 1 )
ambient_light_sky_contribution = 0.3
■ 고도 스크립트(GDScript, *.gd)
고도 게임의 지능 역할을 수행하는 스크립트 파일.
extends Camera
const MOUSE_SENSITIVITY = 0.002
const MOVE_SPEED = 1.5
var rot = Vector3()
var velocity = Vector3()
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _input(event):
# Mouse look (only if the mouse is captured).
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
고도 스크립트는 들여 쓰기, 주요 키워드가 겹치는 점, 세미콜론을 사용하지 않는 등 파이썬과 유사한 특성을 갖는다. 다음은 고도 스크립트의 문법을 EBNF로 표현한 것인데 실제 엔진에서는 기술한 EBNF를 파서를 통해 직접 사용하는 방식이 아니라서 약간의 차이가 있을 수 있다고 한다. 아무튼 기본적인 문법을 파악하기에는 유용한 정보이다.
program = [ inheritance NEWLINE ] [ className ] { topLevelDecl } ;
inheritance = "extends" ( IDENTIFIER | STRING ) { "." IDENTIFIER } ;
className = "class_name" IDENTIFIER [ "," STRING ] NEWLINE ;
topLevelDecl
= classVarDecl
| constDecl
| signalDecl
| enumDecl
| methodDecl
| constructorDecl
| innerClass
| "tool"
;
classVarDecl = [ "onready" ] [ export ] "var" IDENTIFIER [ ":" typeHint ]
[ "=" expression ] [ setget ] NEWLINE ;
setget = "setget" [ IDENTIFIER ] [ "," IDENTIFIER] ;
export = "export" [ "(" [ BUILTINTYPE | IDENTIFIER { "," literal } ] ")" ] ;
typeHint = BUILTINTYPE | IDENTIFIER ;
constDecl = "const" IDENTIFIER [ ":" typeHint ] "=" expression NEWLINE ;
signalDecl = "signal" IDENTIFIER [ signalParList ] NEWLINE ;
signalParList = "(" [ IDENTIFIER { "," IDENTIFIER } ] ")" ;
enumDecl = "enum" [ IDENTIFIER ] "{" [ IDENTIFIER [ "=" INTEGER ]
{ "," IDENTIFIER [ "=" INTEGER ] } [ "," ] ] "}" NEWLINE ;
methodDecl = [ rpc ] [ "static" ] "func" IDENTIFIER "(" [ parList ] ")"
[ "->" typeHint] ":" stmtOrSuite ;
parList = parameter { "," parameter } ;
parameter = [ "var" ] IDENTIFIER [ ":" typeHint ] [ "=" expression ] ;
rpc = "remote" | "master" | "puppet"
| "remotesync" | "mastersync" | "puppetsync";
constructorDecl = "func" IDENTIFIER "(" [ parList ] ")"
[ "." "(" [ argList ] ")" ] ":" stmtOrSuite ;
argList = expression { "," expression } ;
innerClass = "class" IDENTIFIER [ inheritance ] ":" NEWLINE
INDENT [ inheritance NEWLINE ] topLevelDecl { topLevelDecl } DEDENT ;
stmtOrSuite = stmt | NEWLINE INDENT suite DEDENT ;
suite = stmt { stmt };
stmt
= varDeclStmt
| ifStmt
| forStmt
| whileStmt
| matchStmt
| flowStmt
| assignmentStmt
| exprStmt
| assertStmt
| yieldStmt
| preloadStmt
| "breakpoint" stmtEnd
| "pass" stmtEnd
;
stmtEnd = NEWLINE | ";" ;
ifStmt = "if" expression ":" stmtOrSuite { "elif" expression ":" stmtOrSuite }
[ "else" ":" stmtOrSuite ] ;
whileStmt = "while" expression ":" stmtOrSuite;
forStmt = "for" IDENTIFIER "in" expression ":" stmtOrSuite ;
matchStmt = "match" expression ":" NEWLINE INDENT matchBlock DEDENT;
matchBlock = patternList ":" stmtOrSuite { patternList ":" stmtOrSuite };
patternList = pattern { "," pattern } ;
pattern = literal | BUILTINTYPE | CONSTANT | "_" | bindingPattern
| arrayPattern | dictPattern ;
bindingPattern = "var" IDENTIFIER ;
arrayPattern = "[" [ pattern { "," pattern } [ ".." ] ] "]" ;
dictPattern = "{" [ keyValuePattern ] { "," keyValuePattern } [ ".." ] "}" ;
keyValuePattern = STRING [ ":" pattern ] ;
flowStmt
= "continue" stmtEnd
| "break" stmtEnd
| "return" [ expression ] stmtEnd
;
assignmentStmt = subscription ( "=" | "+=" | "-=" | "*=" | "/="
| "%=" | "&=" | "|=" | "^=" ) expression stmtEnd;
varDeclStmt = "var" IDENTIFIER [ "=" expression ] stmtEnd;
assertStmt = "assert" "(" expression [ "," STRING ] ")" stmtEnd ;
yieldStmt = "yield" "(" [ expression "," expression ] ")" ;
preloadStmt = "preload" "(" CONSTANT ")" ;
(* 아래 목록에서 뒤에 있는 것이 우선순위가 높다. *)
exprStmt = expression stmtEnd ;
expression = cast [ "[" expression "]" ] ;
cast = ternaryExpr [ "as" typeHint ];
ternaryExpr = logicOr [ "if" logicOr "else" logicOr ] ;
logicOr = logicAnd { ( "or" | "||" ) logicAnd } ;
logicAnd = logicNot { ( "and" | "&&" ) logicNot };
logicNot = ( "!" | "not" ) logicNot | in;
in = comparison { "in" comparison };
comparison = bitOr { ( "<" | ">" | "<=" | ">=" | "==" | "!=" ) bitOr } ;
bitOr = bitXor { "|" bitXor } ;
bitXor = bitAnd { "^" bitAnd } ;
bitAnd = bitShift { "&" bitShift } ;
bitShift = minus { ( "<<" | ">>" ) minus } ;
minus = plus { "-" plus } ;
plus = factor { "+" factor } ;
factor = sign { ( "*" | "/" | "%" ) sign } ;
sign = ( "-" | "+" ) sign | bitNot ;
bitNot = "~" bitNot | is ;
is = call [ "is" ( IDENTIFIER | BUILTINTYPE ) ] ;
call
= (attribute [ "(" [ argList ] ")" ])
| "." IDENTIFIER "(" [ argList ] ")"
| "$" ( STRING | IDENTIFIER { '/' IDENTIFIER } );
attribute = subscription { "." IDENTIFIER } ;
subscription = primary [ "[" expression "]" ] ;
primary = "true" | "false" | "null" | "self" | literal | arrayDecl
| dictDecl | "(" expression ")" ;
literal = STRING | NUMBER | IDENTIFIER | BUILTINTYPE
| "PI" | "TAU" | "NAN" | "INF" ;
arrayDecl = "[" [ expression { "," expression } "," ] "]" ;
dictDecl = "{" [ keyValue { "," keyValue } "," ] "}" ;
keyValue
= expression ":" expression
| IDENTIFIER "=" expression
;
대문자로 기술된 요소들은 더 이상 확장되지 않는 터미널 요소로 예를 들면 IDENTIFIER는 아이디를 의미하는데 변수 이름, 클래스 이름 등에 적용된다. 고도 스크립트에서는 영문자와 숫자, 밑줄(_)을 아이디로 사용할 수 있고 숫자가 맨 앞에 올 수는 없다. 대소문자를 가리므로 AAA와 aaa는 서로 다른 아이디로 취급된다.
■ C# Script(*.cs)
고도 3.0부터 추가된 기능으로 C# .Net으로 작성한 스크립트 파일을 지칭한다. C# 8.0 스펙을 지원한다.
using Godot;
using real_t = System.Single;
[Tool]
public class PlayerSprite : Sprite
{
private static Texture _stand = ResourceLoader.Load<Texture>("res://assets/player/textures/stand.png");
private static Texture _jump = ResourceLoader.Load<Texture>("res://assets/player/textures/jump.png");
private static Texture _run = ResourceLoader.Load<Texture>("res://assets/player/textures/run.png");
private const int FRAMERATE = 15;
닷넷 프레임워크의 오픈 소스 환경인 mono 환경에서 사용할 수 있다.
■ 플러그인 환경 파일(plugin.cfg)
GDScript로 제작하는 플러그인의 환경 및 스크립트를 설정한다.
[plugin]
name="Heart Plugin Demo"
description="Adds a new Heart node in 2D"
author="Juan Linietsky"
version="1.0"
script="heart_plugin.gd"
플러그인은 addons 폴더 아래 플러그인 이름의 폴더에 plugin.cfg를 비롯한 연관 파일들이 위치하게 된다.
■ 고도 셰이딩 파일(*.shader)
고도의 셰이딩 기능을 지시하는 고도 셰이딩 언어(Godot Shading Language)로 작성한 스크립트. GLSL ES 3.0과 유사하지만 고도만의 기능이 들어가 있다. 그래픽 카드에 대한 직접적인 처리를 지원한다.
shader_type canvas_item;
render_mode unshaded;
uniform vec2 viewport_size;
uniform sampler2D viewport1 : hint_albedo;
uniform sampler2D viewport2 : hint_albedo;
uniform bool split_active;
uniform vec2 player1_position;
uniform vec2 player2_position;
uniform float split_line_thickness;
uniform vec4 split_line_color;
float distanceToLine(vec2 p1, vec2 p2, vec2 point) {
float a = p1.y - p2.y;
float b = p2.x - p1.x;
return abs(a * point.x + b * point.y + p1.x * p2.y - p2.x * p1.y) / sqrt(a * a + b * b);
}
■ 비주얼 스크립트 파일(*.vs)
텍스트 코딩 방식이 아닌 GUI로 스크립트를 작성할 수 있도록 한 것으로 파일은 이진 파일이므로 고도 편집기에서만 열 수 있다.
'게임개발과 무료게임' 카테고리의 다른 글
고도 스크립트 타입과 변수 선언 - 고도 배우기, Godot (0) | 2022.03.04 |
---|---|
고도 스크립트 개요, 예약어와 연산자 - 고도 배우기, Godot (0) | 2022.02.25 |
입력 맵과 고도 스크립트의 연결 - 고도 배우기, Godot (0) | 2022.02.21 |
고도 게임의 완성, 게임 내보내기 - 고도 배우기, Godot (0) | 2020.06.25 |
고도로 만드는 첫 게임 - 고도 배우기, Godot (0) | 2020.06.05 |