Godot: GDScript ํŠน์„ฑ ์‹œ์Šคํ…œ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2018๋…„ 10์›” 18์ผ  ยท  93์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: godotengine/godot

(ํŽธ์ง‘ํ•˜๋‹ค:
์ถ”๊ฐ€ XY ๋ฌธ์ œ ๋ฌธ์ œ๋ฅผ ์ตœ์†Œํ™”ํ•˜๋ ค๋ฉด:
์—ฌ๊ธฐ์—์„œ ํ•ด๊ฒฐ๋œ ๋ฌธ์ œ๋Š” Godot์˜ Node-Scene ์‹œ์Šคํ…œ / ์Šคํฌ๋ฆฝํŒ… ์–ธ์–ด๊ฐ€ 1) ๋ฃจํŠธ ๋…ธ๋“œ์˜ ๊ธฐ๋Šฅ์— ๊ณ ์œ ํ•˜๊ณ  2) ๊ต์ฒด ๋ฐ/๋˜๋Š” ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ทธ๋ฃนํ™”๋œ ๊ตฌํ˜„ ์ƒ์„ฑ์„ ์•„์ง ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ •์  ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋Š” ์Šคํฌ๋ฆฝํŠธ ๋˜๋Š” ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์žˆ๋Š” ํ•˜์œ„ ๋…ธ๋“œ๊ฐ€ ํ›„์ž ๋น„ํŠธ์— ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์ด๊ฒƒ์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Godot๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฃจํŠธ ๋…ธ๋“œ์— ์ €์žฅ๋œ ์”ฌ์˜ ์ „์ฒด ๋™์ž‘์— ๋Œ€ํ•œ ๋กœ์ง์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•˜๋Š” ๋ฐ˜๋ฉด ํ•˜์œ„ ๋…ธ๋“œ์—์„œ ๊ณ„์‚ฐ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ํฌ๊ฒŒ ๋ฒ—์–ด๋‚œ ํ•˜์œ„ ์ž‘์—…์„ ๊ทธ๋“ค์—๊ฒŒ ์œ„์ž„ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด KinematicBody2D๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ AnimationPlayer์— ์œ„์ž„ํ•ฉ๋‹ˆ๋‹ค.

๋™์ž‘์„ ๊ตฌ๋™ํ•˜๊ธฐ ์œ„ํ•ด "๊ตฌ์„ฑ์š”์†Œ" ์ž์‹ ๋…ธ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋” ์–‡์€ ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์€ ์ƒ๋Œ€์ ์œผ๋กœ ์•ฝํ•œ ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ๋™์ž‘์„ ์ž์‹ ๋…ธ๋“œ์— ์œ„์ž„ํ•˜๋Š” ๊ฑฐ์˜ ๋น„์–ด ์žˆ๋Š” ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์€ ์ด ํŒจ๋Ÿฌ๋‹ค์ž„์— ๋ฐ˜๋Œ€๋ฉ๋‹ˆ๋‹ค. ์ž์‹ ๋…ธ๋“œ๋Š” ์ž์ฒด์ ์œผ๋กœ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž๊ธ‰์ž์กฑ ๊ฐœ์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ๋ฃจํŠธ ๋…ธ๋“œ์˜ ๋™์ž‘ ํ™•์žฅ์ด ๋ฉ๋‹ˆ๋‹ค. ๋งค์šฐ ํˆฌ๋ฐ•ํ•˜๊ณ  ๋ฃจํŠธ ๋…ธ๋“œ์˜ ๋ชจ๋“  ๋…ผ๋ฆฌ๋ฅผ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์—ฌ ์„ค๊ณ„๋ฅผ ๋‹จ์ˆœํ™”/๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋…ผ๋ฆฌ๋ฅผ ๊ตฌ์„ฑ ๊ฐ€๋Šฅํ•œ ๋‹ค๋ฅธ ์ฒญํฌ๋กœ ๋‚˜๋ˆŒ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ์˜ ์ฃผ์ œ๋Š” GDScript์— ๊ด€ํ•œ ๊ฒƒ๋ณด๋‹ค ์œ„์˜ ๋ฌธ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ GDScript ํŠน์„ฑ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•˜๊ณ  ์ง์ ‘์ ์ธ ์ ‘๊ทผ ๋ฐฉ์‹์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค.
)

์ •๋ณด๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ํŠน์„ฑ์€ ๋ณธ์งˆ์ ์œผ๋กœ ๋‘ ๊ฐœ์˜ ํด๋ž˜์Šค๋ฅผ ํ•˜๋‚˜๋กœ ํ˜ผํ•ฉํ•˜๋Š” ๋ฐฉ๋ฒ•(๊ฑฐ์˜ ๋ณต์‚ฌ/๋ถ™์—ฌ๋„ฃ๊ธฐ ๋ฉ”์ปค๋‹ˆ์ฆ˜)์ž…๋‹ˆ๋‹ค. ๋ง ๊ทธ๋Œ€๋กœ ํŒŒ์ผ์˜ ํ…์ŠคํŠธ๋ฅผ ๋ณต์‚ฌ/๋ถ™์—ฌ๋„ฃ๊ธฐ ํ•˜๋Š” ๋Œ€์‹  ํ‚ค์›Œ๋“œ ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ํŒŒ์ผ์„ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. (ํŽธ์ง‘: ํŠธ๋ฆญ์€ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๋งŒ ์ƒ์†ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์—ฌ๋Ÿฌ ํŠน์„ฑ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค)

๋‚˜๋Š” ์–ด๋–ค GDScript ํŒŒ์ผ๋„ ๋‹ค๋ฅธ GDScript ํŒŒ์ผ์— ๋Œ€ํ•œ ํŠน์„ฑ์œผ๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ์ƒ์ƒํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ, ํŠน์„ฑํ™”๋œ ์œ ํ˜•์ด ๋ณ‘ํ•ฉ๋œ ์Šคํฌ๋ฆฝํŠธ์— ์˜ํ•ด ์ƒ์†๋œ ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜๋Š” ํ•œ, ์ฆ‰ Sprite ํ™•์žฅ GDScript๋Š” ๋ฆฌ์†Œ์Šค GDScript๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํŠน์„ฑ์ด์ง€๋งŒ Node2D GDScript๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ์œ ์‚ฌํ•œ ๊ตฌ๋ฌธ์„ ์ƒ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# move_right_trait.gd
extends Node2D
class_name MoveRightTrait # not necessary, but just for clarity
func move_right():
    position.x += 1

# my_sprite.gd
extends Sprite
is MoveRightTrait # maybe add a 'use' or 'trait' keyword for this instead?
is "res://move_right_trait.gd" # alternative if class_name isn't used
func _physics_process():
    move_right() # MoveRightTrait's content has been merged into this script
    if MoveRightTrait in self:
        print("I have a MoveRightTrait")

์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. "^trait \์žฌ๋กœ๋“œ ํ”„๋กœ์„ธ์Šค). ํŠน์„ฑ ์ค‘์ฒฉ์„ ์ง€์›ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ๋” ๋งŽ์€ ํŠน์„ฑ ์‚ฝ์ž…์ด ์ˆ˜ํ–‰๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ๋ฐ˜๋ณต ํ›„์— ์ƒ์„ฑ๋œ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ์ง€์†์ ์œผ๋กœ ์žฌ๊ฒ€์‚ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  2. ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ •์ƒ์ ์œผ๋กœ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜์ง€๋งŒ ๊ตฌ๋ฌธ ๋ถ„์„๊ธฐ๊ฐ€ ํ‚ค์›Œ๋“œ๋ฅผ ์ธ์‹ํ•˜๊ณ  ์ฐธ์กฐ๋œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋กœ๋“œํ•˜๊ณ  ํ•ด๋‹น ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ ํ•œ ๋‹ค์Œ ํ•ด๋‹น ClassNode์˜ ๋‚ด์šฉ์„ ํ˜„์žฌ ์Šคํฌ๋ฆฝํŠธ์˜ ์ƒ์„ฑ๋œ ClassNode์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค(ํ•œ ์Šคํฌ๋ฆฝํŠธ์˜ ๊ตฌ๋ฌธ ๋ถ„์„๋œ ๊ฒฐ๊ณผ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์ทจํ•˜๊ณ  ์ถ”๊ฐ€ ๋‹ค๋ฅธ ์Šคํฌ๋ฆฝํŠธ์˜ ๊ตฌ๋ฌธ ๋ถ„์„ ๊ฒฐ๊ณผ๋กœ). ์ด๊ฒƒ์€ ์ž๋™์œผ๋กœ ํŠน์„ฑ ์œ ํ˜•์˜ ์ค‘์ฒฉ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด์— ์‚ฌ๋žŒ๋“ค์€ ํŠน์„ฑ GDScript์— ์ด๋ฆ„์ด ์žˆ๊ธฐ๋ฅผ ์›ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํ•ด๋‹น GDScript์˜ class_name์ด CreateDialog์— ํ‘œ์‹œ๋˜๋Š” ๊ฒƒ์„ ์›ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ž์ฒด์ ์œผ๋กœ ์ƒ์„ฑ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—). ์ด ๊ฒฝ์šฐ, ์–ด๋–ค ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๊ทธ๊ฒƒ์„ ์ง€์›ํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์€ ์‹ค์ œ๋กœ ์ข‹์€ ์ƒ๊ฐ์ด ์•„๋‹ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠน๋ณ„ํžˆ ํ‘œ์‹œ๋œ ๊ฒƒ๋“ค๋งŒ (์•„๋งˆ๋„ ํŒŒ์ผ ๋งจ ์œ„์— 'ํŠน์„ฑ'์„ ์จ์„œ?). ์–ด์จŒ๋“  ์ƒ๊ฐํ•ด๋ณผ ๋ฌธ์ œ.

์ƒ๊ฐ?

ํŽธ์ง‘: ์•ฝ๊ฐ„์˜ ์ˆ™๊ณ  ๋์— 1) ์Šคํฌ๋ฆฝํŠธ ์„ธ๊ทธ๋จผํŠธ๊ฐ€ ์–ด๋–ค ์Šคํฌ๋ฆฝํŠธ์—์„œ ์™”๋Š”์ง€ (๋” ๋‚˜์€ ์˜ค๋ฅ˜ ๋ณด๊ณ ๋ฅผ ์œ„ํ•ด) 2) ์ดํ›„ ๋ฐœ์ƒํ•œ ์˜ค๋ฅ˜๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜ต์…˜ 2๊ฐ€ ํ›จ์”ฌ ๋” ์ข‹์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํฌํ•จ๋œ ์Šคํฌ๋ฆฝํŠธ๋Š” ๋งˆ์ง€๋ง‰์— ๋ชจ๋“  ๊ฒƒ์„ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ˆœ์„œ๋Œ€๋กœ ๊ตฌ๋ฌธ ๋ถ„์„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ตฌ๋ฌธ ๋ถ„์„ ํ”„๋กœ์„ธ์Šค์— ์ถ”๊ฐ€๋˜๋Š” ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์ด ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.

archived discussion feature proposal gdscript

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@aaronfranke Traits ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ Mixins ์™€ ๋™์ผํ•˜๋ฉฐ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์ด ํฌํ•จ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ธํ„ฐํŽ˜์ด์Šค์™€ ์™„์ „ํžˆ ๋‹ค๋ฅธ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๊ธฐ๋ณธ ๊ตฌํ˜„์„ ์ œ๊ณตํ–ˆ๋‹ค๋ฉด ์‹ค์ œ๋กœ ๋” ์ด์ƒ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์•„๋‹ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Traits/Mixins๋Š” PHP, Ruby, D, Rust, Haxe, Scala ๋ฐ ๊ธฐํƒ€ ์—ฌ๋Ÿฌ ์–ธ์–ด (๋งํฌ๋œ Wiki์— ์ž์„ธํžˆ ์„ค๋ช…๋˜์–ด ์žˆ์Œ)์— ์žˆ์œผ๋ฏ€๋กœ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์— ๋Œ€ํ•œ ๊ด‘๋ฒ”์œ„ํ•œ ๋ ˆํผํ† ๋ฆฌ๋ฅผ ๊ฐ€์ง„ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์ด๋ฏธ ๋„๋ฆฌ ์นœ์ˆ™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค๋ฉด(ํŠนํžˆ ์„ ํƒ์  ์ •์  ํƒ€์ดํ•‘์ด ์˜ค๋Š” ๊ฒฝ์šฐ์—) ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ์‚ฌ์‹ค์ƒ ํ•จ์ˆ˜ ์„œ๋ช…์„ ์ง€์ •ํ•˜๊ณ  ๊ด€๋ จ GDScript ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ํ•จ์ˆ˜ ์„œ๋ช…์„ ๊ตฌํ˜„ํ•˜๋„๋ก ์š”๊ตฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํฌํ•จ๋ฉ๋‹ˆ๋‹ค(ํ•ด๋‹น ์‹œ์ ๊นŒ์ง€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ).

๋ชจ๋“  93 ๋Œ“๊ธ€

extends "res://move_right_trait.gd" ๋Œ€์‹  ์–ด๋–ค ์ด์ ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@MrJustreborn ํ•œ ํด๋ž˜์Šค์— ์—ฌ๋Ÿฌ ํŠน์„ฑ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ ํ•˜๋‚˜์˜ ์Šคํฌ๋ฆฝํŠธ๋งŒ ์ƒ์†ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ดํ•ดํ•œ๋‹ค๋ฉด ์ด๊ฒƒ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ C#์ด " ์ธํ„ฐํŽ˜์ด์Šค "๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ฒƒ์ด์ง€๋งŒ ๋น„์ถ”์ƒ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๊นŒ? ํ”„๋กœ๊ทธ๋ž˜๋จธ์—๊ฒŒ ์นœ์ˆ™ํ•œ ํŠน์„ฑ ๋Œ€์‹  ๊ธฐ๋Šฅ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@aaronfranke Traits ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ Mixins ์™€ ๋™์ผํ•˜๋ฉฐ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์ด ํฌํ•จ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ธํ„ฐํŽ˜์ด์Šค์™€ ์™„์ „ํžˆ ๋‹ค๋ฅธ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๊ธฐ๋ณธ ๊ตฌํ˜„์„ ์ œ๊ณตํ–ˆ๋‹ค๋ฉด ์‹ค์ œ๋กœ ๋” ์ด์ƒ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์•„๋‹ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Traits/Mixins๋Š” PHP, Ruby, D, Rust, Haxe, Scala ๋ฐ ๊ธฐํƒ€ ์—ฌ๋Ÿฌ ์–ธ์–ด (๋งํฌ๋œ Wiki์— ์ž์„ธํžˆ ์„ค๋ช…๋˜์–ด ์žˆ์Œ)์— ์žˆ์œผ๋ฏ€๋กœ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์— ๋Œ€ํ•œ ๊ด‘๋ฒ”์œ„ํ•œ ๋ ˆํผํ† ๋ฆฌ๋ฅผ ๊ฐ€์ง„ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์ด๋ฏธ ๋„๋ฆฌ ์นœ์ˆ™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค๋ฉด(ํŠนํžˆ ์„ ํƒ์  ์ •์  ํƒ€์ดํ•‘์ด ์˜ค๋Š” ๊ฒฝ์šฐ์—) ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ์‚ฌ์‹ค์ƒ ํ•จ์ˆ˜ ์„œ๋ช…์„ ์ง€์ •ํ•˜๊ณ  ๊ด€๋ จ GDScript ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ํ•จ์ˆ˜ ์„œ๋ช…์„ ๊ตฌํ˜„ํ•˜๋„๋ก ์š”๊ตฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํฌํ•จ๋ฉ๋‹ˆ๋‹ค(ํ•ด๋‹น ์‹œ์ ๊นŒ์ง€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ).

includes ์™€ ๊ฐ™์€ ํ‚ค์›Œ๋“œ?

extends Node2D
includes TraitClass

ํŠน์„ฑ, mixin, has ๋“ฑ๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ์ด๋ฆ„๋„ ํ™•์‹คํžˆ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

์ถ”๊ฐ€ ๋ฉ”๋‰ด์—์„œ class_name ์œ ํ˜•์„ ์ œ์™ธํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์ด ์žˆ๋‹ค๋Š” ์•„์ด๋””์–ด๋„ ๋งˆ์Œ์— ๋“ญ๋‹ˆ๋‹ค. ์ž์ฒด์ ์œผ๋กœ ๋…ธ๋“œ๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ์ž‘์€ ์œ ํ˜•์œผ๋กœ ์ธํ•ด ๋งค์šฐ ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ ์ž์ฒด๋กœ ํ•˜๋‚˜์˜ ๊ธฐ๋Šฅ ์ฃผ์ œ์ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

(์‹ค์ˆ˜๋กœ ๋‚ด ๋Œ“๊ธ€์„ ์‚ญ์ œํ–ˆ์Šต๋‹ˆ๋‹ค, ์›์Šค! ๋˜ํ•œ "์—ฌ๋Ÿฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋‹จ์ผํ™”๋ฉ๋‹ˆ๋‹ค." )

์ด๊ฒƒ์ด VisualScript์—์„œ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

๋˜ํ•œ ํŠน์„ฑ์ด ๊ตฌํ˜„๋œ ๊ฒฝ์šฐ ํŠน์„ฑ์— ๋Œ€ํ•œ ์ธ์ŠคํŽ™ํ„ฐ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ์ด ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ํŠน์„ฑ์— ๋Œ€ํ•œ ์ผ๋ถ€ ์‚ฌ์šฉ ์‚ฌ๋ก€์—๋Š” ํŠน์„ฑ๋งŒ ์žˆ๊ณ  ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์—†๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ์ƒํ•ฉ๋‹ˆ๋‹ค(์ ์–ด๋„ ํŠน์„ฑ ํŒŒ์ผ์„ ํฌํ•จํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ ์™ธ์—๋Š” ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์—†์Œ). ํ•˜์ง€๋งŒ ๊ณฐ๊ณฐ์ด ์ƒ๊ฐํ•ด๋ณด๋ฉด ํŠธ๋ ˆ์ดํŠธ ํŒŒ์ผ์ด ํฌํ•จ๋œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ๋ณด๋‹ค ๊ทธ๋Ÿฐ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ ๋“ค์ธ ๋…ธ๋ ฅ์ด ๊ทธ๋งŒํ•œ ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

@LikeLakers2

์ด๊ฒƒ์ด VisualScript์—์„œ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

๋‚ด๊ฐ€ ์ œ์•ˆํ•œ ๋ฐฉ์‹์œผ๋กœ ์ˆ˜ํ–‰๋˜๋ฉด VisualScript์—์„œ๋Š” ์ „ํ˜€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. GDScript ์ „์šฉ. VisualScript์— ๋Œ€ํ•ด ๊ตฌํ˜„๋œ ํŠน์„ฑ ์‹œ์Šคํ…œ์€ VisualScript๊ฐ€ ๊ตฌ๋ฌธ ๋ถ„์„๋œ ์–ธ์–ด๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์™„์ „ํžˆ ๋‹ค๋ฅด๊ฒŒ ์„ค๊ณ„๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ€๋Šฅ์„ฑ์„ ์ „ํ˜€ ๋ฐฐ์ œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(๋‹ค๋ฅด๊ฒŒ ๊ตฌํ˜„ํ•ด์•ผ ํ•จ). ๋˜ํ•œ VisualScript ์ƒ์† ์ง€์›์„ ๋จผ์ € ๊ณ ๋ คํ•ด์•ผ ํ• ๊นŒ์š”? ใ…‹ ใ…‹ ใ…‹

๋˜ํ•œ ํŠน์„ฑ์ด ๊ตฌํ˜„๋œ ๊ฒฝ์šฐ ํŠน์„ฑ์— ๋Œ€ํ•œ ์ธ์ŠคํŽ™ํ„ฐ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ์ด ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋ณ„ ์˜๋ฏธ๊ฐ€ ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํŠน์„ฑ์€ ํŠน์„ฑ, ์ƒ์ˆ˜, ์‹ ํ˜ธ ๋ฐ ํŠน์„ฑ์— ์˜ํ•ด ์ •์˜๋œ ๋ฉ”์„œ๋“œ๋ฅผ ์ „๋‹ฌํ•˜์—ฌ GDScript์— ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

ํŠน์„ฑ์— ๋Œ€ํ•œ ์ผ๋ถ€ ์‚ฌ์šฉ ์‚ฌ๋ก€์—๋Š” ํŠน์„ฑ๋งŒ ์žˆ๊ณ  ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์—†๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ์ƒํ•ฉ๋‹ˆ๋‹ค(์ ์–ด๋„ ํŠน์„ฑ ํŒŒ์ผ์„ ํฌํ•จํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ ์™ธ์—๋Š” ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์—†์Œ).

๋‹ค๋ฅธ ์–ธ์–ด๋กœ ํ‘œ์‹œ๋˜๋Š” ํŠน์„ฑ์€ ๋‹จ๋…์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์ง€๋งŒ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋‹ค๋ฅธ ์Šคํฌ๋ฆฝํŠธ์— ํฌํ•จ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค .

๊ทธ๋Ÿฌํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋“ค์ธ ๋…ธ๋ ฅ์ด ๊ทธ๋งŒํ•œ ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

์–ด๋–ค ์‹์œผ๋กœ๋“  Inspector ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ GDScript ๋‹จ๋…์œผ๋กœ๋Š” ๊ทธ๋‹ค์ง€ ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ํŠน์„ฑ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•˜๋ ค๋ฉด ์Šคํฌ๋ฆฝํŠธ ๋ฆฌ์†Œ์Šค์˜ source_code ์†์„ฑ์˜ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ํŽธ์ง‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์Šคํฌ๋ฆฝํŠธ ์ž์ฒด์˜ ์†์„ฑ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์–ด๋Š ์ชฝ์ด๋“  ...

  1. ํŽธ์ง‘๊ธฐ๋Š” ์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด(์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฌ์šด) GDScript ํŒŒ์ผ์— ๋Œ€ํ•œ ์†Œ์Šค ์ฝ”๋“œ์˜ ์ ์ ˆํ•œ ํŽธ์ง‘์„ ๊ตฌ์ฒด์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฐ€๋ฅด์ณ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜๋Š”...
  2. ๋ชจ๋“  ์Šคํฌ๋ฆฝํŠธ๋Š” GDScriptLanguage๊ฐ€ ํŠน์„ฑ์„ ์ถ”๊ฐ€ ๋ฐ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•œ ์ž์ฒด ๋‚ด๋ถ€ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก ํŠน์„ฑ์„ ์ง€์›ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(๊ทธ๋Ÿฌ๋‚˜ ๋ชจ๋“  ์–ธ์–ด๊ฐ€ ํŠน์„ฑ์„ ์ง€์›ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฏ€๋กœ ํŠน์„ฑ์ด ๋ชจ๋“  ๊ฒฝ์šฐ์— ์˜๋ฏธ๊ฐ€ ์—†์Œ).

๊ทธ๋Ÿฌํ•œ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•œ ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ด๊ฒƒ์ด ์ง€๊ธˆ ํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ์ผ๋ถ€ ์ž‘์—…์„ ํ›จ์”ฌ ๋” ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๊ฑฐ์˜ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๋ณต์žกํ•œ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค GDscript๋ฅผ ๋‹จ์ˆœํ•œ ์–ธ์–ด๋กœ ์œ ์ง€ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ์ด ์‚ฌ๋žŒ์ด ๋ฌธ์ œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ๋˜ Child-Nodes-As-Script-Dependencies ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€๋งŒ MultiScript๊ฐ€ ๋‹จ์ผ ์–ธ์–ด๋กœ ์ œํ•œ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋™์ผํ•œ ์ข…๋ฅ˜์˜ ์ˆ˜ํ•˜๋ฌผ ๊ณผ ํ•จ๊ป˜ ์ œ๊ณต๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. GDScript ๋ชจ๋“ˆ์€ ํŠน์„ฑ์ด ์„œ๋กœ ๋ฐ ๊ธฐ๋ณธ ์Šคํฌ๋ฆฝํŠธ์™€ ์–ด๋–ป๊ฒŒ ๊ด€๋ จ๋˜๋Š”์ง€์— ๋Œ€ํ•œ ๋…ผ๋ฆฌ๋ฅผ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋‹ค๋ฅธ ์–ธ์–ด ๊ฐ„์˜ ์ฐจ์ด์ ์„ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์€ ํ›จ์”ฌ ๋” ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์ค‘ ๊ฐ€์ ธ์˜ค๊ธฐ/๋‹ค์ค‘ ์ƒ์†์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์Šคํฌ๋ฆฝํŠธ ์ข…์†์„ฑ์„ ์ž์‹ ๋…ธ๋“œ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ฝ”๋“œ๋ฅผ ๋งŽ์ด ๋ฐ˜๋ณตํ•˜์ง€ ์•Š๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์ด๋ฉฐ ์ด๋Š” ํ™•์‹คํžˆ ๋ฌธ์ œ๋ฅผ ์ข‹์€ ๋ฐฉ์‹์œผ๋กœ ํ•ด๊ฒฐํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@groud @Zireael07 ๋‚ด ๋ง์€, ๋” ๊ธ‰์ง„์ ์ธ ๊ต์ฐจ ์–ธ์–ด ์ ‘๊ทผ ๋ฐฉ์‹์€ 1) ScriptStack์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ˆ„์ ๋œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋‹จ์ผ ์Šคํฌ๋ฆฝํŠธ ํ‘œํ˜„์œผ๋กœ ๋ณ‘ํ•ฉํ•˜๋„๋ก Object๋ฅผ ์™„์ „ํžˆ ์žฌ์„ค๊ณ„ํ•˜๊ณ , 2) MultiScript๋ฅผ ๋‹ค์‹œ ๋„์ž…ํ•˜๊ณ  ์ž๋™์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํŽธ์ง‘๊ธฐ ์ง€์›์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฉ€ํ‹ฐ์Šคํฌ๋ฆฝํŠธ์— ์Šคํฌ๋ฆฝํŠธ ์ถ”๊ฐ€(๋˜๋Š” ๋‹จ์ˆœ์„ฑ์„ ์œ„ํ•ด ๋ชจ๋“  ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ฉ€ํ‹ฐ์Šคํฌ๋ฆฝํŠธ๋กœ ์™„์ „ํžˆ ๋งŒ๋“œ๋Š” ๊ฒƒ, ์ด ๊ฒฝ์šฐ MultiScript์˜ ๊ตฌํ˜„์€ ๋ณธ์งˆ์ ์œผ๋กœ ScriptStack์ด ๋จ), ๋˜๋Š” 3) ๋ณ‘ํ•ฉํ•  ์ˆ˜ ์žˆ๋Š” Object ์œ ํ˜•์— ๋Œ€ํ•œ ์ผ์ข…์˜ ๊ต์ฐจ ์–ธ์–ด ํŠน์„ฑ ์‹œ์Šคํ…œ ๊ตฌํ˜„ ์ฐธ์กฐ ํ™•์žฅ ์Šคํฌ๋ฆฝํŠธ๋Š” ํŠน์„ฑ์œผ๋กœ, ์ผ๋ฐ˜์ ์ธ ์Šคํฌ๋ฆฝํŠธ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋‚ด์šฉ์„ ํ†ตํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ชจ๋“  ์˜ต์…˜์€ ์—”์ง„์— ํ›จ์”ฌ ๋” ์นจ์Šต์ ์ž…๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ๋” ๊ฐ„๋‹จํ•ด์ง‘๋‹ˆ๋‹ค.

๋‚˜๋Š” ํŠน์„ฑ์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š๋Š”๋‹ค. ์šฐ๋ฆฌ์—๊ฒŒ ๊ฐ€์žฅ ํ•„์š”ํ•œ ๊ฒƒ์€ ๋น ๋ฅธ ์—”์ง„ ๋ฆด๋ฆฌ์Šค ์ฃผ๊ธฐ์ž…๋‹ˆ๋‹ค. ๋‚ด ๋ง์€ ๋Œ€๋ถ€๋ถ„์˜ IDE์—์„œ ํ”Œ๋Ÿฌ๊ทธ์ธ ์Šคํƒ€์ผ๊ณผ ๊ฐ™์ด ์ƒˆ dll ์ •๋„ ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์—”์ง„์ด ์ž๋™์œผ๋กœ ํ†ตํ•ฉ๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ƒˆ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ์—”์ง„์„ ๋ณด๋‹ค ์œ ์—ฐํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด websocket์ด ์ž‘๋™ํ•˜๋Š” ๋ฐ ์ •๋ง ์ ˆ์‹คํžˆ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. 3.1์ด ๋ฆด๋ฆฌ์Šค๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆด ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. 3.1์€ ํ˜„์žฌ ๋„ˆ๋ฌด ๋งŽ์€ ๋ฒ„๊ทธ๋กœ ์ธํ•ด ๊นจ์กŒ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์ด ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ƒˆ ํด๋ž˜์Šค๋Š” ์ž„์˜์˜ .dll ๋˜๋Š” ์ผ๋ถ€ ๊ฒฝ๋กœ์˜ .so์—์„œ GDScript์— ์ž๋™ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด C++์—์„œ ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ๋…ธ๋ ฅ์„ ๊ธฐ์šธ์˜€๋Š”์ง€ ๋ชจ๋ฅด์ง€๋งŒ ์ด๊ฒƒ์ด ๋„ˆ๋ฌด ์–ด๋ ต์ง€ ์•Š๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค ๐Ÿ˜

@fian46 ๊ธ€์Ž„์š”, ๋ˆ„๊ตฐ๊ฐ€ ์›น ์†Œ์ผ“์„ ๋‹ค์šด๋กœ๋“œ ๊ฐ€๋Šฅํ•œ GDNative ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ๊ตฌํ˜„ํ–ˆ๋‹ค๋ฉด ์˜ˆ, ๋‹น์‹ ์ด ์„ค๋ช…ํ•œ ๊ฒƒ์€ ์›Œํฌํ”Œ๋กœ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€์‹  ๊ทธ๋“ค์€ ๋ฐ”๋‹๋ผ ์—”์ง„์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ†ตํ•ฉ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๊ทธ๋Ÿฐ ์‹์œผ๋กœ ๊ธฐ๋Šฅ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ๋ง‰์„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ์—†์œผ๋ฏ€๋กœ ๊ท€ํ•˜์˜ ์š”์ ์€ ์ด ๋ฌธ์ œ์˜ ์ฃผ์ œ์™€ ์ „ํ˜€ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค.

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. GDNative๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค ๐Ÿ˜‚๐Ÿ˜‚๐Ÿ˜‚. ํŠน์„ฑ์€ ํ›Œ๋ฅญํ•˜์ง€๋งŒ ๊ฐ€์งœ ํŠน์„ฑ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ  ์ธ์Šคํ„ด์Šคํ™”ํ•˜๊ณ  ๋‚˜์ค‘์— ๊ธฐ๋ณธ ์Šคํฌ๋ฆฝํŠธ์ฒ˜๋Ÿผ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ๋” ์‰ฝ์Šต๋‹ˆ๊นŒ?

Godot ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ด๋ฆ„ ์—†๋Š” ํด๋ž˜์Šค๋ผ๋ฉด, "my_sprite.gd"์— "move_right_trait.gd"๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?
๋ฌธ์ œ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค๋ฉด ์ œ ๋ฌด์ง€์— ๋Œ€ํ•ด ์‚ฌ๊ณผ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

Rust ๋˜๋Š” (์ธํ„ฐํŽ˜์ด์Šค) C++์™€ ๊ฐ™์€ ๋ณด๋‹ค ๊ฐ•๋ ฅํ•œ ํ˜•์‹์˜ ์–ธ์–ด์—์„œ ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋”ํ‚น ํ˜•์‹์˜ ์–ธ์–ด์—์„œ๋Š” ์•ฝ๊ฐ„ ๋ถˆํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ์œ ํ˜• ๊ฐ„์— ๊ท ์ผํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. GDScript๊ฐ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์ด๋‚˜ ํŠธ๋ ˆ์ดํŠธ ์‹œ์Šคํ…œ์ด ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ๋„์›€์ด ๋˜๋Š”์ง€์— ๋Œ€ํ•œ ์ •ํ™•ํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ํ™•์‹ ์ด ์„œ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ preload("Some-other-behavior.gd")๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ณ€์ˆ˜์— ์ €์žฅํ•˜์—ฌ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋™์ผํ•œ ํšจ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์—†์Šต๋‹ˆ๊นŒ?

@fian46 @DriNeo ๋„ค, ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋กœ๋“œํ•˜๊ณ  ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋ฏธ ํ•ด๊ฒฐ๋˜์ง€๋งŒ ๋ฌธ์ œ๋Š” ๊ทธ ์ด์ƒ์œผ๋กœ ํ™•์žฅ๋ฉ๋‹ˆ๋‹ค.

@TheYokai

๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋ฉด ์œ ํ˜• ๊ฐ„์— ๊ท ์ผํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” ๋‹น์‹ ์ด ์˜ณ์•˜๋˜ ๊ท ์ผํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋‹ฌ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋• ํƒ€์ดํ•‘์ด ์ž˜ ํ•ด๊ฒฐ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ด€๋ จ ๊ตฌํ˜„์˜ ๊ทธ๋ฃน์„ ํšจ์œจ์ ์œผ๋กœ ๊ตฌ์„ฑ(๊ฒฐํ•ฉ/๊ต์ฒด)ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.


3.1์—์„œ๋Š” ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฐธ์กฐ ์Šคํฌ๋ฆฝํŠธ(๋˜๋Š” ์‹ค์ œ๋กœ ๋ชจ๋“  ์œ ํ˜•)์—์„œ ์ •์  ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•œ ๋‹ค์Œ ํ•ด๋‹น ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋กœ ์‚ฌ์šฉํ•˜์—ฌ GDScript์—์„œ ํ•ด๋‹น ํ•จ์ˆ˜์— ์ „์—ญ์ ์œผ๋กœ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

extends Reference
class_name Game
static func print_text(p_text):
    print(p_text)
# can even add inner classes for sub-namespaces

extends Node
func _ready():
    Game.print_text("Hello World!")

๊ทธ๋Ÿฌ๋‚˜ ๋น„์ •์  ์ฝ˜ํ…์ธ , ํŠนํžˆ ๋…ธ๋“œ๋ณ„ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ์ฝ˜ํ…์ธ ์˜ ๊ฒฝ์šฐ ๋…ผ๋ฆฌ๋ฅผ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์ด ๋ฒˆ๊ฑฐ๋กญ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, KinematicBody2D๊ฐ€ ์žˆ๊ณ  "์ ํ”„" ๋™์ž‘๊ณผ "์‹คํ–‰" ๋™์ž‘์„ ๊ฐ–๊ณ  ์‹ถ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ฉ๋‹ˆ๊นŒ? ์ด๋Ÿฌํ•œ ๊ฐ ๋™์ž‘์€ KinematicBody2D์˜ ์ž…๋ ฅ ์ฒ˜๋ฆฌ ๋ฐ move_and_slide ๊ธฐ๋Šฅ์— ์•ก์„ธ์Šคํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด์ƒ์ ์œผ๋กœ๋Š” ๊ฐ ๋™์ž‘์˜ ๊ตฌํ˜„์„ ๋…๋ฆฝ์ ์œผ๋กœ ๊ต์ฒดํ•˜๊ณ  ๊ฐ ๋™์ž‘์— ๋Œ€ํ•œ ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ ์Šคํฌ๋ฆฝํŠธ์— ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋‚ด๊ฐ€ ์ต์ˆ™ํ•œ ๋ชจ๋“  ์›Œํฌํ”Œ๋กœ๊ฐ€ ์ตœ์ ์ด ์•„๋‹™๋‹ˆ๋‹ค.

  1. ๋ชจ๋“  ๊ตฌํ˜„์„ ๋™์ผํ•œ ์Šคํฌ๋ฆฝํŠธ์— ์œ ์ง€ํ•˜๊ณ  ์‚ฌ์šฉ ์ค‘์ธ ๊ธฐ๋Šฅ๋งŒ ๋ฐ”๊พธ๋ฉด...

    1. "๋™์ž‘"์„ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ์„ ์„ธํŠธ๋กœ ๊ต์ฒดํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ตฌํ˜„ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํšจ๊ณผ์ ์œผ๋กœ ๊ทธ๋ฃนํ™”ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

    2. ๋ชจ๋“  ๋™์ž‘(X * Y)์— ๋Œ€ํ•œ ๋ชจ๋“  ๊ธฐ๋Šฅ์€ ๋‹จ์ผ ์Šคํฌ๋ฆฝํŠธ์— ์žˆ์œผ๋ฏ€๋กœ ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ๋ถ€ํ’€๋ ค์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  2. ์ „์ฒด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Š” ๋ชจ๋“  ๋™์ž‘ ์กฐํ•ฉ ๊ณผ ํ•ด๋‹น ๋™์ž‘์„ ์‚ฌ์šฉํ•˜๋Š” ๋…ผ๋ฆฌ์— ๋Œ€ํ•ด ์ƒˆ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  3. ์ž์‹ ๋…ธ๋“œ๋ฅผ ์Šคํฌ๋ฆฝํŠธ ์ข…์†์„ฑ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋ถ€๋ชจ๋ฅผ ์žก๊ณ  ์ƒ๋Œ€์ ์œผ๋กœ ๋งํ•ด์„œ ์ผ์ข…์˜ ๋ถ€์ž์—ฐ์Šค๋Ÿฌ์šด move_and_slide ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ด์ƒํ•œ "๊ตฌ์„ฑ ์š”์†Œ" Node2D ๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

    • ๋ถ€๋ชจ๊ฐ€ ํ•ด๋‹น ๋ฐฉ๋ฒ•์„ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ ํ•ด๋‹น ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋…ผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ™•์ธ์„ ํ•˜๋ฉด ์ž๋™์œผ๋กœ ์‹คํŒจํ•˜๊ณ  ๊ฒŒ์ž„์— ์ž ์žฌ์ ์ธ ๋ฒ„๊ทธ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋„๊ตฌ ์Šคํฌ๋ฆฝํŠธ๋กœ ์ „ํ™˜ํ•˜์—ฌ ํŽธ์ง‘๊ธฐ์—์„œ ์‹œ๊ฐ์ ์œผ๋กœ ์•Œ๋ ค์ฃผ๋„๋ก ๋…ธ๋“œ์— ๊ตฌ์„ฑ ๊ฒฝ๊ณ ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

    • ๋˜ํ•œ ๋…ธ๋“œ๋Š” Node2D์—์„œ ํŒŒ์ƒ๋˜๊ณ  ํ•ต์‹ฌ์€ KinematicBody2D ๋ถ€๋ชจ์˜ ๋™์ž‘์„ ๊ตฌ๋™ํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์˜๋„ ํ•œ ๋…ธ๋“œ ์ž‘์—…์— ๋Œ€ํ•œ ์ ์ ˆํ•œ ์ฝ”๋“œ ์™„์„ฑ์„ ์–ป์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ์˜ต์…˜ 3์ด ํ˜„์žฌ ๊ฐ€์žฅ ํšจ๊ณผ์ ์ธ ์›Œํฌํ”Œ๋กœ์ด๋ฉฐ 3.1์—์„œ GDScript์— ๋Œ€ํ•œ ํŽธ๋ฆฌํ•œ ์ •์  ์ž…๋ ฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ๋Œ€๋ถ€๋ถ„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Œ์„ ์ธ์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋” ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Godot์˜ ๋…ธ๋“œ-์”ฌ ์‹œ์Šคํ…œ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์ž์‹ ์˜ ๋ฐ€ํ๋œ ์‹œ์Šคํ…œ์—์„œ ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋…ธ๋“œ ๋˜๋Š” ์žฅ๋ฉด์„ ์ƒ์„ฑํ•˜๋Š” ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์žฅ๋ฉด ๋‚ด์—์„œ ํ•ด๋‹น ๋…ธ๋“œ/์žฅ๋ฉด์„ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๊ณ  ์ƒ์œ„ ์žฅ๋ฉด์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ณ„์‚ฐํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: Area2D ๋ฐ CollisionShape2D ๊ด€๊ณ„์˜ ๊ฒฝ์šฐ).

๊ทธ๋Ÿฌ๋‚˜ ๋ฐ”๋‹๋ผ ์—”์ง„์˜ ์‚ฌ์šฉ ๋ฐ ์ผ๋ฐ˜์ ์ธ ๋ชจ๋ฒ” ์‚ฌ๋ก€ ๊ถŒ์žฅ ์‚ฌํ•ญ์€ ์žฅ๋ฉด์˜ ๋™์ž‘ ์„ ๋ฃจํŠธ ๋…ธ๋“œ ๋ฐ/๋˜๋Š” ํ•ด๋‹น ์Šคํฌ๋ฆฝํŠธ์— ๊ณ ์ •๋œ ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๋ฃจํŠธ์—๊ฒŒ ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ๋ ค์ฃผ๋Š” "๋™์ž‘ ๊ตฌ์„ฑ ์š”์†Œ" ๋…ธ๋“œ๋Š” ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค(์žˆ์„ ๋•Œ ๋งค์šฐ ํˆฌ๋ฐ•ํ•˜๊ฒŒ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค). AnimationPlayer/Tween ๋…ธ๋“œ๋Š” ๋‚ด๊ฐ€ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ๋…ผ์Ÿ์˜ ์—ฌ์ง€๊ฐ€ ์žˆ๋Š” ์˜ˆ์™ธ์ด์ง€๋งŒ ํ•ด๋‹น ์ž‘์—…์กฐ์ฐจ๋„ ๋ฃจํŠธ์— ์˜ํ•ด ์ง€์‹œ๋ฉ๋‹ˆ๋‹ค(์ด๋Š” ์ผ์‹œ์ ์œผ๋กœ ์ œ์–ด๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์œ„์ž„ํ•ฉ๋‹ˆ๋‹ค). (ํŽธ์ง‘: ์ด ๊ฒฝ์šฐ์—๋„ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋ฐ ํŠธ์œ„๋‹ ์€ KinematicBody2D์˜ ์ž‘์—…์ด ์•„๋‹ˆ๋ฏ€ ๋กœ ์ด๋Ÿฌํ•œ ์ž‘์—…์„ ์œ„์ž„ํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹ฌ๋ฆฌ๊ธฐ ๋ฐ ์ ํ”„์™€ ๊ฐ™์€ ์›€์ง์ž„ ์€ ์ฑ…์ž„์ž…๋‹ˆ๋‹ค) ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ๊ฐ„๋‹จํ•˜๊ณ  ์ž์—ฐ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ๋…ธ๋“œ ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ์—„๊ฒฉํ•˜๊ฒŒ ๋ฐ์ดํ„ฐ ์—…/๋™์ž‘ ๋‹ค์šด์œผ๋กœ ์œ ์ง€ํ•˜๊ณ  ์ฝ”๋“œ๋ฅผ ์ž์ฒด ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ๋กœ ๋” ๊ฒฉ๋ฆฌํ•˜๋„๋ก ์œ ์ง€ํ•˜๋ฏ€๋กœ ์ฝ”๋“œ๋ฅผ ๊ตฌ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ํŠน์„ฑ ๊ตฌํ˜„.

์–ด, ์ž์‹ ์„ '์ธํ„ฐํŽ˜์ด์Šค/ํŠน์„ฑ ๊ตฌํ˜„'์œผ๋กœ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ๋„ * is * ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ด๋Š” ๋ฌด์–ธ๊ฐ€์˜ ๊ธฐ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

@OvermindDL1 ์ œ ๋ง์€ ๊ทธ๋Ÿฐ ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋Š” ์˜ˆ๋ฅผ ๋“ค์—ˆ์ง€๋งŒ ์ƒ์†๊ณผ ํŠน์„ฑ ์‚ฌ์šฉ์„ ๊ตฌ๋ถ„ํ•˜๊ณ  ์‹ถ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€์‹  in ๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—์„œ XY ๋ฌธ์ œ์— ๋น ์ง„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์ด ์ฃผ์ œ๋ฅผ ์–ด๋–ค ์‹์œผ๋กœ๋“  ๋‹ค๋ฃจ์—ˆ๊ณ  ์ œ์•ˆ์„œ๋ฅผ ์ œ์ถœํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋˜ 2๊ฐœ์˜ ๋‹ค๋ฅธ ๋ฌธ์ œ(#23052, #15996)์—์„œ ๋ฐฉ๊ธˆ ๋‚˜์™”์ง€๋งŒ ๋ชจ๋“  ์ปจํ…์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•˜์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค.

@groud ์ด ์†”๋ฃจ์…˜์€ #19486์— ๋Œ€ํ•ด ์ œ๊ธฐ๋œ ๋ฌธ์ œ ์ค‘ ํ•˜๋‚˜๋ฅผ ํ•ด๊ฒฐํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@willnationsdev ์ข‹์€ ์•„์ด๋””์–ด, ๊ธฐ๋Œ€๋ฉ๋‹ˆ๋‹ค!

๋‚ด ์ œํ•œ๋œ ์„ค๋ช…์—์„œ ์ด ํŠน์„ฑ ์‹œ์Šคํ…œ์ด ๋‹ฌ์„ฑํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒƒ์€ ์ด ๋น„๋””์˜ค์— ํ‘œ์‹œ๋œ ์›Œํฌํ”Œ๋กœ์™€ ์œ ์‚ฌํ•œ ๊ฒƒ์„ ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. https://www.youtube.com/watch?v=raQ3iHhE_Kk
(์‚ฌ์šฉ๋œ ๊ธฐ๋Šฅ์ด ์•„๋‹ˆ๋ผ ํ‘œ์‹œ๋œ _workflow_์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์Œ์„ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค.)

๋น„๋””์˜ค์—์„œ๋Š” ์žฅ์ ๊ณผ ๋‹จ์ ์ด ์žˆ๋Š” ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ์›Œํฌํ”Œ๋กœ์™€ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.

์ ์–ด๋„ ๋‚ด๊ฐ€ ์•„๋Š” ํ•œ ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ์›Œํฌํ”Œ๋กœ๋Š” ์ƒ์†์ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹ ๋•Œ๋ฌธ์— ํ˜„์žฌ GDScript์—์„œ๋Š” ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

@AfterRebelion ๊ทธ๊ฐ€ ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๋ชจ๋“ˆ์„ฑ, ํŽธ์ง‘ ๊ฐ€๋Šฅ์„ฑ, ๋””๋ฒ„๊ทธ ๊ฐ€๋Šฅ์„ฑ(๋ฐ ํ•ด๋‹น ์†์„ฑ์˜ ๊ด€๋ จ ์„ธ๋ถ€ ์ •๋ณด)์„ ๋ถ„๋ฆฌํ•˜๋Š” ๋น„๋””์˜ค์˜ ์ฒ˜์Œ ๋ช‡ ๋ถ„ ์€ ์‹ค์ œ๋กœ ์ด ๊ธฐ๋Šฅ์„ ์ถ”๊ตฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ ์–ด๋„ ๋‚ด๊ฐ€ ์•„๋Š” ํ•œ ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ์›Œํฌํ”Œ๋กœ๋Š” ์ƒ์†์ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹ ๋•Œ๋ฌธ์— ํ˜„์žฌ GDScript์—์„œ๋Š” ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Godot๋Š” ๋…ธ๋“œ ๊ณ„์ธต ๊ตฌ์กฐ์™€ ๋””์ž์ธ ์”ฌ๊ณผ ๊ด€๋ จํ•˜์—ฌ ์‹ค์ œ๋กœ ์ด๊ฒƒ์„ ์•„์ฃผ ์ž˜ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ถ€๋ถ„์€ ์‚ฌ์‹ค์ด ์•„๋‹™๋‹ˆ๋‹ค. ์žฅ๋ฉด์€ ๋ณธ์งˆ์ ์œผ๋กœ ๋ชจ๋“ˆ์‹์ด๋ฉฐ ์ฝ”๋“œ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๊ณ  ํŽธ์ง‘๊ธฐ์—์„œ ์ง์ ‘ ์†์„ฑ์„ ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ(์‹ฌ์ง€์–ด ์• ๋‹ˆ๋ฉ”์ด์…˜์œผ๋กœ ๋งŒ๋“ค๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค) ์žฅ๋ฉด์ด ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๊ฒƒ์„ ๊ฒฉ๋ฆฌ๋œ ์ƒํƒœ์—์„œ ํ…Œ์ŠคํŠธ/๋””๋ฒ„๊น…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์–ด๋ ค์›€์€ ๋…ผ๋ฆฌ๊ฐ€ ๋ฃจํŠธ ๋…ธ๋“œ์˜ ์ƒ์†๋œ ๊ธฐ๋Šฅ์— ์˜์กดํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ฐ˜์ ์œผ๋กœ ์ž์‹ ๋…ธ๋“œ์— ์•„์›ƒ์†Œ์‹ฑ๋˜๋Š” ๋…ผ๋ฆฌ๋ฅผ ๋ฃจํŠธ ๋…ธ๋“œ์—์„œ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ, ์ž‘๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ๋ถ€๋ชจ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋™์•ˆ ์ž๋…€๊ฐ€ ์ž์‹ ์˜ ์ผ์— ์‹ ๊ฒฝ์„ ์“ฐ๊ฒŒ ํ•˜๊ธฐ๋ณด๋‹ค ๋ถ€๋ชจ์—๊ฒŒ ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋Š”์ง€ ๋งํ•˜๊ธฐ ์‹œ์ž‘ํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

GameObject์—๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์‹ค์ œ ์ƒ์†์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— Unity์—์„œ๋Š” ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Unreal์—์„œ๋Š” Actor์— ๋Œ€ํ•ด ์œ ์‚ฌํ•œ ๋…ธ๋“œ/์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ ๋‚ด๋ถ€ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์•ฝ๊ฐ„(?) ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž, ์—ฌ๊ธฐ์„œ ์ž ์‹œ Devil 's Advocate๋ฅผ ํ”Œ๋ ˆ์ดํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. Unreal์—์„œ ์ด๋Ÿฌํ•œ ์‹œ์Šคํ…œ์„ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์„ ๋ณด๋ƒˆ๊ณ  ์ด๋Š” ์ €์—๊ฒŒ ์ด์— ๋Œ€ํ•œ ์ƒˆ๋กœ์šด ๊ด€์ ์„ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์ข‹์€ ์ƒ๊ฐ์ผ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค / ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ํฅ๋ถ„ํ–ˆ์Šต๋‹ˆ๋‹ค:

ํŠน์„ฑ ์‹œ์Šคํ…œ์„ ๋„์ž…ํ•˜๋ฉด ์œ ์ง€ ๊ด€๋ฆฌ๋ฅผ ๋” ์–ด๋ ต๊ฒŒ ๋งŒ๋“œ๋Š” ์–ธ์–ด์ธ GDScript์— ๋ณต์žก์„ฑ ๊ณ„์ธต์ด ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.

๊ฒŒ๋‹ค๊ฐ€, ํŠน์„ฑ์œผ๋กœ์„œ์˜ ํŠน์„ฑ์€ ๋ณ€์ˆ˜, ์ƒ์ˆ˜, ์‹ ํ˜ธ, ๋ฉ”์„œ๋“œ, ์‹ฌ์ง€์–ด ํ•˜์œ„ ํด๋ž˜์Šค ๊ฐ€ ์‹ค์ œ๋กœ ์–ด๋””์—์„œ ์™”๋Š”์ง€ ๋ถ„๋ฆฌํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋…ธ๋“œ์˜ ์Šคํฌ๋ฆฝํŠธ์— ๊ฐ‘์ž๊ธฐ 12๊ฐœ์˜ ๋‹ค๋ฅธ ํŠน์„ฑ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๋ชจ๋“  ๊ฒƒ์ด ์–ด๋””์—์„œ ์˜ค๋Š”์ง€ ๋ฐ˜๋“œ์‹œ ์•Œ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋ฌด์–ธ๊ฐ€์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ๋ณด์ด๋ฉด ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ์‚ฌ๋ฌผ์ด ์–ด๋””์— ์žˆ๋Š”์ง€ ์•Œ๊ธฐ ์œ„ํ•ด 12๊ฐœ์˜ ๋‹ค๋ฅธ ํŒŒ์ผ์„ ์‚ดํŽด๋ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์–ด์ง„ ๋ฌธ์ œ๋Š” ์ฝ”๋“œ ๊ธฐ๋ฐ˜์—์„œ ํ‰๊ท  2~3๊ฐœ์˜ ๋‹ค๋ฅธ ์œ„์น˜๋ฅผ ์„ ํƒํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Š” ์‹ค์ œ๋กœ ์–ธ์–ด๋กœ์„œ์˜ GDScript ์˜ ๋””๋ฒ„๊น… ๊ฐ€๋Šฅ์„ฑ์„ ์ €ํ•˜์‹œํ‚ต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์œ„์น˜ ์ค‘ ํ•˜๋‚˜๋ผ๋„ ์ฐพ๊ธฐ ์–ด๋ ค์šด ์ด์œ ๋Š” ๊ทธ๋“ค์ด ํ•˜๋‚˜์˜ ์Šคํฌ๋ฆฝํŠธ์— ์žˆ๋‹ค๊ณ  ๋งํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๋‹ค๋ฅธ ๊ณณ์— ์žˆ์œผ๋ฉฐ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์ด ๋ฐ์ดํ„ฐ/๋…ผ๋ฆฌ๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ๋ช…ํ™•ํ•˜๊ฒŒ ๋‚˜ํƒ€๋‚ด์ง€ ์•Š์œผ๋ฉด 2 ๋˜๋Š” 3์ž…๋‹ˆ๋‹ค. ๋‹จ๊ณ„๋Š” ์ž„์˜์˜ ํฌ๊ณ  ์ŠคํŠธ๋ ˆ์Šค๊ฐ€ ๋งŽ์€ ๋‹จ๊ณ„ ์„ธํŠธ๋กœ ๊ณฑํ•ด์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ์˜ ๊ทœ๋ชจ์™€ ๋ฒ”์œ„๊ฐ€ ์ฆ๊ฐ€ํ•˜๋ฉด ์ด๋Ÿฌํ•œ ๋ถ€์ •์ ์ธ ์˜ํ–ฅ์ด ๋”์šฑ ํ™•๋Œ€๋˜๊ณ  ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ค์šด ํ’ˆ์งˆ์ด ๋ฉ๋‹ˆ๋‹ค.


๊ทธ๋Ÿฌ๋‚˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์šฐ๋ฆฌ๋Š” ์ž์‹ "์ปดํฌ๋„ŒํŠธ ๋กœ์ง" ๋…ธ๋“œ๊ฐ€ ์”ฌ ๋ฃจํŠธ์— ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ์„ ์›ํ•˜์ง€ ์•Š์ง€๋งŒ, ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ƒ์†์ด๋‚˜ ์ „์ฒด ์Šคํฌ๋ฆฝํŠธ ๋ณ€๊ฒฝ์— ์˜์กดํ•  ์ˆ˜๋„ ์—†์Šต๋‹ˆ๋‹ค.

์ด ์ƒํ™ฉ ์—์„œ ๋น„ ECS ์—”์ง„์€ ๋ฌด์—‡์„ ํ• ๊นŒ์š”? ๊ตฌ์„ฑ์ด ์—ฌ์ „ํžˆ ๋‹ต์ด์ง€๋งŒ ์ด ๊ฒฝ์šฐ ์ „์ฒด ๋…ธ๋“œ๋Š” ์†Œ์œ ๊ถŒ ๊ณ„์ธต ๊ตฌ์กฐ์˜ ์—ญํ•™์„ ํ™•์žฅ/๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ค ๋•Œ ๋น„ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๋‹ค. ๋Œ€์‹ , ๊ตฌ์ฒด์ ์ธ ํ–‰๋™ ๊ตฌํ˜„์„ ์ถ”์ƒํ™”ํ•˜๋Š” ๋น„๋…ธ๋“œ ๊ตฌํ˜„ ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด ๊ฐ์ฒด๋Š” ๋ชจ๋‘ ์—ฌ์ „ํžˆ ๋ฃจํŠธ ๋…ธ๋“œ๊ฐ€ ์†Œ์œ ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ Reference ์Šคํฌ๋ฆฝํŠธ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# root.gd
extends KinematicBody2D

export(Script) var jump_impl_script = null setget set_jump_impl_script
var jump_impl
func set_jump_impl_script(p_script):
    jump_impl = p_script.new() if p_script else null

export(Script) var move_impl_script = null setget set_move_impl_script
var move_impl
func set_move_impl_script(p_script):
    move_impl = p_script.new() if p_script else null

func _physics_process():
    # use logic involving these...
    move_impl.move(...)
    jump_impl.jump(...)

๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ์ƒˆ๋กœ์šด Resource ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•ด ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํŠน์ • ์œ ํ˜•์„ ํŒŒ์ƒํ•˜๋Š” ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์—ด๊ฑฐํ˜•์œผ๋กœ Inspector์—์„œ ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ–ˆ๋‹ค๋ฉด ์ •๋ง ์ข‹์•˜์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ง€๊ธˆ ํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ๋ฆฌ์†Œ์Šค ์Šคํฌ๋ฆฝํŠธ ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ์ˆ˜์ •ํ•œ ๋‹ค์Œ ๊ตฌํ˜„ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋ฆฌ์†Œ์Šค๋ฅผ ํ™•์žฅํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค(๋‹ค๋ฅธ ์ด์œ  ์—†์ด). ๊ทธ๋Ÿฌ๋‚˜ ๊ตฌํ˜„ ์ž์ฒด์— Inspector์—์„œ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋ฆฌ์†Œ์Šค๋ฅผ ํ™•์žฅํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. :-)

์ด์ œ ์ด๋ฅผ ๋” ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์Šค๋‹ˆํŽซ ์‹œ์Šคํ…œ์ด๋‚˜ ๋งคํฌ๋กœ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ์žฌ์‚ฌ์šฉ๋˜๋Š” ์„ ์–ธ์  ์ฝ”๋“œ ์„น์…˜์„ ๋” ์‰ฝ๊ฒŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์–ด์จŒ๋“ , ๋„ค, ์ €๋Š” ํŠน์„ฑ ์‹œ์Šคํ…œ๊ณผ ๋ฌธ์ œ ํ•ด๊ฒฐ์— ๋Œ€ํ•œ ๋” ๋‚˜์€ ์ ‘๊ทผ ๋ฐฉ์‹์—์„œ ๋ˆˆ์— ๋„๋Š” ๋ฌธ์ œ๋ฅผ ์‹๋ณ„ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. XY ๋ฌธ์ œ ๋ฌธ์ œ๋งŒ ๋งŒ์„ธ! /์—์Šค

ํŽธ์ง‘ํ•˜๋‹ค:

๋”ฐ๋ผ์„œ ์œ„ ์˜ˆ์ œ์˜ ์›Œํฌํ”Œ๋กœ์—๋Š” ๊ตฌํ˜„ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์„ค์ •ํ•œ ๋‹ค์Œ ๋Ÿฐํƒ€์ž„์— ์Šคํฌ๋ฆฝํŠธ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ž‘์„ ์ •์˜ํ•˜๋Š” ์ž‘์—…์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ตฌํ˜„ ์ž์ฒด์— Inspector์—์„œ ์ •์ ์œผ๋กœ ์„ค์ •ํ•˜๋ ค๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? ๋‹ค์Œ์€ ๋Œ€์‹  ๋ฆฌ์†Œ์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ๋ฒ„์ „์ž…๋‹ˆ๋‹ค.

# root.gd
extends KinematicBody2D

# if you use a Resource script AND had a way of specifying that the assigned Resource 
# must extend that script, then the editor would automatically assign an instance of 
# that resource script to the var. No separate instancing or setter necessary.

export(Resource) var jump_impl = null # set jump duration, max height, tween easing via Inspector
export(Resource) var move_impl = null # similarly customize movement from Inspector

# can then create different Resources as different implementations. Because they are resources,
# one can edit them even outside of a scene!
func _physics_process():
    move_impl.move(...)
    jump_impl.jump(...)

๊ด€๋ จ: #22660

@AfterRebelion

์‚ฌ์šฉ๋œ ๊ธฐ๋Šฅ์ด ์•„๋‹ˆ๋ผ ํ‘œ์‹œ๋œ ์›Œํฌํ”Œ๋กœ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์Œ์„ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค.

์•„์ด๋Ÿฌ๋‹ˆํ•˜๊ฒŒ๋„ ๋‹น์‹ ์ด ์ด๊ฒƒ์„ ๋ช…ํ™•ํžˆ ํ•˜๊ณ  ๋‚ด๊ฐ€ ์ตœ์ ์˜ ์›Œํฌํ”Œ๋กœ์— ๋™์˜ํ•œ ๋‹ค์Œ ๋Œ“๊ธ€์˜ ๋’ท๋ถ€๋ถ„์— ๋™์˜ํ•˜์ง€ ์•Š์€ ๋‹ค์Œ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ•ด๋‹น ๋น„๋””์˜ค์—์„œ "์‚ฌ์šฉ๋œ ๊ธฐ๋Šฅ"์ด ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์ด์ƒ์ ์ธ ๋ฐฉ๋ฒ•์ธ์ง€ ๋งํ•จ์œผ๋กœ์จ ํ›„์† ์กฐ์น˜๋ฅผ ์ทจํ•ฉ๋‹ˆ๋‹ค. ์–ด์จŒ๋“  Godot์˜ ์ด ๋ฌธ์ œ. ใ…‹.

# root.gd
extends KinematicBody2D

export(Script) var jump_impl_script = null setget set_jump_impl_script
var jump_impl
func set_jump_impl_script(p_script):
jump_impl = p_script.new() if p_script else null
...

์™€, ์ˆ˜์ถœ์ด ์ด๋ ‡๊ฒŒ ๊ฐ•๋ ฅํ•œ์ง€ ๋ชฐ๋ž์Šต๋‹ˆ๋‹ค. ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ ๋ฐ ๊ธฐํƒ€ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์™€๋งŒ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‚˜์˜ ์ด์ „ ์˜๊ฒฌ์„ ๋ฌดํšจ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
๋ง์”€ํ•˜์‹  ๋Œ€๋กœ ๊ตฌํ˜„์„ ๋” ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์–ด๋–ค ์ข…๋ฅ˜์˜ ๋งคํฌ๋กœ๊ฐ€ ๊ตฌํ˜„๋œ๋‹ค๋ฉด MultiScript ์—†์ด๋„ ํ•ด๋‹น ์›Œํฌํ”Œ๋กœ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ฏธ๋ฆฌ ์„ ์–ธํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— Unity๋งŒํผ ๋‹ค์žฌ๋‹ค๋Šฅํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ์—ฌ์ „ํžˆ ์ข‹์€ ์˜ต์…˜์ž…๋‹ˆ๋‹ค.

@AfterRebelion

๋ง์”€ํ•˜์‹  ๋Œ€๋กœ ๊ตฌํ˜„์„ ๋” ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์–ด๋–ค ์ข…๋ฅ˜์˜ ๋งคํฌ๋กœ๊ฐ€ ๊ตฌํ˜„๋œ๋‹ค๋ฉด MultiScript ์—†์ด๋„ ํ•ด๋‹น ์›Œํฌํ”Œ๋กœ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ธ€์Ž„์š”, ๊ฐ™์€ ๋Œ“๊ธ€์—์„œ ์–ธ๊ธ‰ํ•œ Resource ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ๋ฐฉ์‹๊ณผ #22660์˜ ๋” ๋‚˜์€ ํŽธ์ง‘๊ธฐ ์ง€์›์„ ๊ฒฐํ•ฉํ•˜๋ฉด Unity๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•œ ํ’ˆ์งˆ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ฏธ๋ฆฌ ์„ ์–ธํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— Unity๋งŒํผ ๋‹ค์žฌ๋‹ค๋Šฅํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ์—ฌ์ „ํžˆ ์ข‹์€ ์˜ต์…˜์ž…๋‹ˆ๋‹ค.

๊ธ€์Ž„, ๊ทธ๋“ค์ด 3.2์—์„œ ๋ฐฐ์—ด ์œ ํ˜• ํžŒํŠธ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ™•์žฅํ•˜๊ณ  ์ž์‹ ์˜ ๊ฒƒ์„ ํšจ๊ณผ์ ์œผ๋กœ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š” ํŒŒ์ผ ๊ฒฝ๋กœ์— ๋Œ€ํ•ด ๋‚ด๋ณด๋‚ธ ๋ฐฐ์—ด์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ EditorInspectorPlugin ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ๋ฆฌ์†Œ์Šค ๋˜๋Š” ๋…ธ๋“œ์— ๋Œ€ํ•œ Inspector์— ์‚ฌ์šฉ์ž ์ •์˜ ์ฝ˜ํ…์ธ ๋ฅผ ์ถ”๊ฐ€ํ•จ์œผ๋กœ์จ 3.1์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ†ตํ•ด ์ˆ˜ํ–‰ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด ๋ง์€, "Unity"์™€ ๊ฐ™์€ ์‹œ์Šคํ…œ์„ ์›ํ–ˆ๋‹ค๋ฉด ์‹ค์ œ๋กœ ๋ฃจํŠธ์— ์ˆ˜ํ–‰ํ•  ์ž‘์—…์„ ์•Œ๋ ค์ฃผ๋Š” ํ•˜์œ„ ๋…ธ๋“œ๊ฐ€ ์žˆ๊ณ  ์ˆ˜๋™์œผ๋กœ ์„ ์–ธํ•˜๊ฑฐ๋‚˜ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ  ์ด๋ฆ„์„ ์ฐธ์กฐํ•˜์—ฌ ๊ฐ€์ ธ์˜ค๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋ฃจํŠธ ๋…ธ๋“œ์˜ ์Šคํฌ๋ฆฝํŠธ์—์„œ. Resource ๋ฉ”์„œ๋“œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํ›จ์”ฌ ๋” ํšจ๊ณผ์ ์ด๋ฉฐ ๋” ๊นจ๋—ํ•œ ์ฝ”๋“œ๋ฒ ์ด์Šค๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

ํŠน์„ฑ ์‹œ์Šคํ…œ์€ GDScript ์ฝ”๋“œ์˜ ์‚ฌ์šฉ์„ฑ์— ๊ณผ๋„ํ•œ ๋ถ€๋‹ด์„ ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์ œ๊ฐ€ ์„ค๋ช…ํ•œ ์ด์œ ์— ๋”ฐ๋ผ ์ด ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ถ”๊ฐ€์˜ ํ•จ์ •์€ ๊ทธ๋Ÿฌํ•œ ์‹œ์Šคํ…œ์—์„œ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๋น„๊ต์  ๋นˆ์•ฝํ•œ ์ด์ ๋ณด๋‹ค ํ›จ์”ฌ ํฝ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋™์ผํ•œ ์ด์ ์€ ๋” ๋ช…ํ™•ํ•˜๊ณ  ์œ ์šฉํ•˜๊ฒŒ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธ€์Ž„์š”, ์ œ๊ฐ€ ์—†๋Š” ๋™์•ˆ ์ด ํ† ๋ก ์„ ๋†“์ณค์Šต๋‹ˆ๋‹ค. ์•„์ง ๋ชจ๋“  ๊ฒƒ์„ ์ฝ์ง€๋Š” ์•Š์•˜์ง€๋งŒ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด GDScript์— ํŠน์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋Š” ์•„์ด๋””์–ด๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋Š” ํŒŒ์ƒ ์œ ํ˜•์— ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ฒจ๋ถ€ํ•˜๋Š” ๊ฐ€์งœ ๋‹ค์ค‘ ์ƒ์†๋ณด๋‹ค ํ›จ์”ฌ ๋” ์šฐ์•„ํ•˜๊ณ  ๋ช…ํ™•ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ํ•  ์ผ์€ ํŠน์ • ํŠธ๋ ˆ์ž‡ ํŒŒ์ผ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด์ง€๋งŒ ์–ด๋–ค ํด๋ž˜์Šค ํŒŒ์ผ๋„ ํŠธ๋ ˆ์ž‡์ด ๋˜๋„๋ก ํ—ˆ์šฉํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋„ˆ๋ฌด ๋‚˜์˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š๋Š”๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์—ฌ๋Ÿฌ ๋…ธ๋“œ ์œ ํ˜•์—์„œ ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š” ์ฃผ์š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์ œ์•ˆ์— ์—ด๋ ค ์žˆ์Šต๋‹ˆ๋‹ค.

@vnen ๋งˆ์ง€๋ง‰ ํ•ญ๋ชฉ์ธ ์†”๋ฃจ์…˜์€ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์„น์…˜์„ ๋ฆฌ์†Œ์Šค ์Šคํฌ๋ฆฝํŠธ์— ์•„์›ƒ์†Œ์‹ฑํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  • ๋…ธ๋“œ์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์ธ ๊ฒƒ์ฒ˜๋Ÿผ ์—ฌ์ „ํžˆ ๋…ธ์ถœ๋˜๊ณ  ์†์„ฑ์ด ์ธ์ŠคํŽ™ํ„ฐ์—์„œ ํŽธ์ง‘๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๊ทธ๋“ค์€ ๋ฐ์ดํ„ฐ์™€ ๋…ผ๋ฆฌ๊ฐ€ ์–ด๋””์—์„œ ์™”๋Š”์ง€์— ๋Œ€ํ•œ ๋ช…ํ™•ํ•œ ํ”์ ์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋งŽ์€ ํŠน์„ฑ์ด ํ•˜๋‚˜์˜ ์Šคํฌ๋ฆฝํŠธ์— ํฌํ•จ๋˜๋ฉด ์‰ฝ๊ฒŒ ์†์ƒ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๊ทธ๋“ค์€ ์–ธ์–ด๋กœ์„œ์˜ GDScript์— ๊ณผ๋„ํ•œ ๋ณต์žก์„ฑ์„ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์กด์žฌํ•œ๋‹ค๋ฉด ๊ณต์œ  ํ’ˆ์งˆ(์†์„ฑ, ์ƒ์ˆ˜, ์‹ ํ˜ธ)์ด ๊ธฐ๋ณธ ์Šคํฌ๋ฆฝํŠธ์— ๋ณ‘ํ•ฉ๋˜๋Š” ๋ฐฉ์‹์„ ํ•ด๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(๋˜๋Š” ๋ณ‘ํ•ฉ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž๊ฐ€ ์ข…์†์„ฑ ์ถฉ๋Œ์„ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๊ฐ•์ œ).

  • ๋ฆฌ์†Œ์Šค ์Šคํฌ๋ฆฝํŠธ๋Š” Inspector์—์„œ ํ• ๋‹น ๋ฐ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋” ์ข‹์Šต๋‹ˆ๋‹ค. ๋””์ž์ด๋„ˆ, ์ž‘๊ฐ€ ๋“ฑ์€ ํŽธ์ง‘๊ธฐ์—์„œ ์ง์ ‘ ๊ตฌํ˜„ ๊ฐœ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@willnationsdev (๋ชจ๋“  ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋ฆฌ์†Œ์Šค์ด๊ธฐ ๋•Œ๋ฌธ์— "๋ฆฌ์†Œ์Šค ์Šคํฌ๋ฆฝํŠธ"๋ผ๋Š” ์ด๋ฆ„์ด ์ด์ƒํ•˜๊ฒŒ ๋“ค๋ฆด์ง€๋ผ๋„) ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด ์†”๋ฃจ์…˜์˜ ์ฃผ์š” ๋ฌธ์ œ๋Š” ์‚ฌ๋žŒ๋“ค์ด ์ƒ์† ์ ‘๊ทผ ๋ฐฉ์‹์œผ๋กœ ๊ธฐ๋Œ€ํ•˜๋Š” ๊ฒƒ์„ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚ด๋ณด๋‚ธ ๋ณ€์ˆ˜์™€ ์‹ ํ˜ธ๋ฅผ ์žฅ๋ฉด์˜ ๋ฃจํŠธ ๋…ธ๋“œ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค(ํŠนํžˆ ์žฅ๋ฉด์„ ๋‹ค๋ฅธ ๊ณณ์—์„œ ์ธ์Šคํ„ด์Šคํ™”ํ•  ๋•Œ). ํ•˜์œ„ ๋ฆฌ์†Œ์Šค์—์„œ ๋‚ด๋ณด๋‚ธ ๋ณ€์ˆ˜๋ฅผ ๊ณ„์† ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์‹ค์šฉ์„ฑ์ด ๋–จ์–ด์ง‘๋‹ˆ๋‹ค(ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ๋Š” ์†์„ฑ์„ ํ•œ ๋ˆˆ์— ์•Œ ์ˆ˜ ์—†์Œ).

๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ๋Š” ์ƒ์šฉ๊ตฌ ์ฝ”๋“œ๋ฅผ ๋งŽ์ด ๋ฐ˜๋ณตํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— ๋ฆฌ์†Œ์Šค ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹ค์ œ๋กœ ์„ค์ •๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์žฅ์ ์€ ์•„๋ฌด๊ฒƒ๋„ ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ด๋ฏธ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์ด ๋ฌธ์„œํ™”๋˜์–ด์•ผ ํ•˜๊ณ  ํ˜„์žฌ "ํŒŒ์ƒ ๋…ธ๋“œ์— ์Šคํฌ๋ฆฝํŠธ ์ฒจ๋ถ€" ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ์†”๋ฃจ์…˜์ด ์–ผ๋งˆ๋‚˜ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ์ง€ ๋ณด๊ธฐ ์œ„ํ•ด ์†”๋ฃจ์…˜์— ๋Œ€ํ•ด ์–ธ๊ธ‰ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@vnen

๊ทธ๋Ÿฌ๋‚˜ ๋œ ์‹ค์šฉ์ ์ด ๋ฉ๋‹ˆ๋‹ค(ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ๋Š” ์†์„ฑ์„ ํ•œ ๋ˆˆ์— ์•Œ ์ˆ˜ ์—†์Œ).

์—ฌ๊ธฐ์„œ ๋ฌด์Šจ ๋ง์ธ์ง€ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ํŠนํžˆ #22660๊ณผ ๊ฐ™์€ ํ•ญ๋ชฉ์ด ๋ณ‘ํ•ฉ๋œ ๊ฒฝ์šฐ ์–ด๋–ค ์†์„ฑ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ๋ช…ํ™•์„ฑ์ด ์ƒ๋‹นํžˆ ๋ถ€์กฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ์žฅ๋ฉด์„ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๊ณ  ํŽธ์ง‘ ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ์‹ถ์œผ๋ฏ€๋กœ ํ•ด๋‹น ์žฅ๋ฉด์˜ ๋ฃจํŠธ ๋…ธ๋“œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  2. ๋Œ€๋ณธ์„ ๋ณด๋‹ˆ...

    • export(MoveImpl) var move_impl = FourWayMoveImpl.new()

    • use FourWayMoveTrait

  3. ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์—ด๊ธฐ ์œ„ํ•œ ์‹๋ณ„์ž(์‹ค์ œ๋กœ 3.1.1 ๊ธฐ๋Šฅ์ด์–ด์•ผ ํ•จ!)๋ฅผ ํด๋ฆญ ์ถ”์ ํ•˜๋Š” ์ˆ˜๋‹จ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด ์—ฐ๊ฒฐ๋œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์—ด๊ณ  ํ•ด๋‹น ์†์„ฑ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋ญ”๊ฐ€๋ฅผ ๋†“์น˜๊ณ  ์žˆ์ง€ ์•Š๋Š” ํ•œ, ๋‚˜์—๊ฒŒ ๊ฐ™์€ ์ˆ˜์˜ ๋‹จ๊ณ„์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ, ์–ด๋–ค ์†์„ฑ์ด ํŽธ์ง‘ ๊ฐ€๋Šฅํ•œ์ง€ ์‹ค์ œ๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ›จ์”ฌ ๋” ๋ช…ํ™•ํ•ด์ง‘๋‹ˆ๋‹ค. ๊ตฌํ˜„์— ๊ณ ์œ ํ•œ ์†์„ฑ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ตฌํ˜„๊ณผ ๊ด€๋ จ๋˜์–ด ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์ด ๊ตฌํ˜„ ์ธ์Šคํ„ด์Šค, ์ฆ‰ move_impl.<property> .

๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ๋Š” ์ƒ์šฉ๊ตฌ ์ฝ”๋“œ๋ฅผ ๋งŽ์ด ๋ฐ˜๋ณตํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— ๋ฆฌ์†Œ์Šค ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹ค์ œ๋กœ ์„ค์ •๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ดˆ๊ธฐํ™”๊ฐ€ ํฌํ•จ๋œ ๋‚ด๋ณด๋‚ด๊ธฐ์˜ ์ด์ ์ด ์ถ”๊ฐ€๋œ ๋ง์˜ ๋น„์šฉ๋ณด๋‹ค ๋” ํฌ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

("๊ณ ์œ„๊ธ‰ ํŒ€์›", HLT, ๋””์ž์ด๋„ˆ, ์ž‘๊ฐ€, ์•„ํ‹ฐ์ŠคํŠธ ๋“ฑ)

  • ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์—ด์ง€ ์•Š๊ณ  Inspector์—์„œ ์ง์ ‘ ๊ฐ’์„ ํ• ๋‹นํ•˜๊ณ  ๋ณ€๊ฒฝํ•  ์˜ฌ๋ฐ”๋ฅธ ์ค„์„ ์ฐพ์€ ๋‹ค์Œ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ด๋ฏธ ์–ธ๊ธ‰ํ–ˆ์ง€๋งŒ...).

  • ๋‚ด๋ณด๋‚ธ ์ฝ˜ํ…์ธ ์— ๊ธฐ๋ณธ ์œ ํ˜• ์š”๊ตฌ ์‚ฌํ•ญ์ด ์žˆ์Œ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด Inspector๋Š” ํ—ˆ์šฉ ๊ฐ€๋Šฅํ•œ ๊ตฌํ˜„์˜ ์—ด๊ฑฐ๋œ ๋ชฉ๋ก์„ ์ž๋™์œผ๋กœ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ HLT๋Š” ํ•ด๋‹น ์œ ํ˜•์˜ ํŒŒ์ƒ๋ฌผ๋งŒ ์•ˆ์ „ํ•˜๊ฒŒ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ฃผ์œ„์— ๋– ๋Œ์•„๋‹ค๋‹ˆ๋Š” ๋ชจ๋“  ๋‹ค๋ฅธ ํŠน์„ฑ ์Šคํฌ๋ฆฝํŠธ์˜ ๊ฒฐ๊ณผ๋ฅผ ์•Œ์•„์•ผ ํ•˜๋Š” ๋Œ€์•ˆ์—์„œ ๊ทธ๋“ค์„ ๊ฒฉ๋ฆฌํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ use ํ‚ค์›Œ๋“œ๋ฅผ ๋ณธ ๊ฒƒ์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ๋ช…๋ช…๋œ ํŠน์„ฑ ํŒŒ์ผ๊ณผ ๋ช…๋ช…๋˜์ง€ ์•Š์€ ํŠน์„ฑ ํŒŒ์ผ ์กฐํšŒ๋ฅผ ์ง€์›ํ•˜๋„๋ก GDScript์˜ ์ž๋™ ์™„์„ฑ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ๊ตฌํ˜„ ๊ตฌ์„ฑ์„ *.tres ํŒŒ์ผ๋กœ ์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ HLT๋Š” FileSystem ๋„ํฌ์—์„œ ๋Œ์–ด๋‹ค ๋†“๊ฑฐ๋‚˜ Inspector์—์„œ ๊ณ ์œ ํ•œ ๊ถŒํ•œ์„ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠน์„ฑ์œผ๋กœ ๋™์ผํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ์žฌ์ •์˜ํ•˜๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ์ƒ์„ฑ์ž๋ฅผ ์ œ๊ณตํ•˜๋Š” ํŒŒ์ƒ ํŠน์„ฑ์„ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋ช…๋ นํ˜•์œผ๋กœ ์ฝ”๋”ฉ๋œ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ๋Œ€์‹  ํ•ด๋‹น ํŠน์„ฑ์„ "์‚ฌ์ „ ๊ตฌ์„ฑ"์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    1. ์„ ์–ธ์ ์ด๊ธฐ๋ณด๋‹ค๋Š” ๋ช…๋ น์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ์•ฝํ•ฉ๋‹ˆ๋‹ค.
    2. ์ƒ์„ฑ์ž๊ฐ€ ์Šคํฌ๋ฆฝํŠธ์—์„œ ๋ช…์‹œ์ ์œผ๋กœ ์ •์˜๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋” ์•ฝํ•ฉ๋‹ˆ๋‹ค.
    3. ํŠธ๋ ˆ์ดํŠธ์— ์ด๋ฆ„์ด ์ง€์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž ๋Š” ๊ธฐ๋ณธ ๊ธฐ๋ณธ ํŠธ๋ ˆ์ดํŠธ ๋Œ€์‹  ์ ์ ˆํžˆ ์‚ฌ์šฉ ํ•˜๊ธฐ ์œ„ํ•ด ํŠธ๋ ˆ์ดํŠธ์˜ ์œ„์น˜๋ฅผ โ€‹โ€‹์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํŠธ๋ ˆ์ดํŠธ์˜ ์ด๋ฆ„์ด ์ง€์ •๋˜๋ฉด ์ „์—ญ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๊ฐ€ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋ง‰ํž™๋‹ˆ๋‹ค.
    4. $ use MoveTrait use FourWayMoveTrait ๋ผ๊ณ  ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๊ธฐ๋ณธ MoveTrait ์™€๋„ ํ˜ธํ™˜๋œ๋‹ค๋Š” ์ง€์†์ ์ธ ํ‘œ์‹œ๊ฐ€ ๋” ์ด์ƒ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ FourWayMoveTrait ๊ฐ€ ๊นจ์ง€์ง€ ์•Š๊ณ  ๋‹ค๋ฅธ MoveTrait ๋กœ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€์— ๋Œ€ํ•œ HLT ํ˜ผ๋™์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
    5. HLT๊ฐ€ ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ์ƒˆ๋กœ์šด ํŠน์„ฑ ๊ตฌํ˜„์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ ๊ธฐ๋ณธ ํŠน์„ฑ์—์„œ ์„ค์ •ํ•  ์ˆ˜/ํ•„์š”ํ•œ ๋ชจ๋“  ์†์„ฑ์„ ๋ฐ˜๋“œ์‹œ ์•Œ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ธ์ŠคํŽ™ํ„ฐ์—์„œ ์ƒ์„ฑ๋œ ๋ฆฌ์†Œ์Šค์™€ ๊ด€๋ จ๋œ ๋ฌธ์ œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.
  • ๊ฐ™์€ ์œ ํ˜•์˜ ๋ฆฌ์†Œ์Šค๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ์žˆ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค(์ด์œ ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ). ํŠน์„ฑ์€ ์ด๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์ง€๋งŒ ๋Œ€์‹  ๊ตฌ๋ฌธ ๋ถ„์„ ์ถฉ๋Œ์„ ์œ ๋ฐœํ•ฉ๋‹ˆ๋‹ค.

  • 2D/3D ๋ทฐํฌํŠธ๋ฅผ ๋ฒ—์–ด๋‚˜์ง€ ์•Š๊ณ ๋„ ๊ตฌ์„ฑ ๋ฐ/๋˜๋Š” ๊ฐœ๋ณ„ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ HLT์— ํ›จ์”ฌ ๋” ํŽธ์•ˆํ•ฉ๋‹ˆ๋‹ค(์ฝ”๋“œ ๋ฅผ ๋ด์•ผ ํ•  ๋•Œ ์™„์ „ํžˆ ์งœ์ฆ์ด ๋‚˜๋Š” ์‚ฌ๋žŒ์„ ๋งŽ์ด ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค).

๊ทธ ๋ชจ๋“  ๋ง๊ณผ ํ•จ๊ป˜, ๋‚˜๋Š” ์ƒ์šฉ๊ตฌ๊ฐ€ ์งœ์ฆ๋‚œ๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋งคํฌ๋กœ ๋˜๋Š” ์Šค๋‹ˆํŽซ ์‹œ์Šคํ…œ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๋‹จ์ˆœํ™”ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์Šค๋‹ˆํŽซ ์‹œ์Šคํ…œ์€ GDScript ๋‹จ๋…์ด ์•„๋‹ˆ๋ผ ScriptEditor์—์„œ ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ์–ธ์–ด๋ฅผ ์ง€์›ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ข‹์€ ์•„์ด๋””์–ด์ž…๋‹ˆ๋‹ค.

์— ๋Œ€ํ•œ:

๊ทธ๋Ÿฌ๋‚˜ ๋œ ์‹ค์šฉ์ ์ด ๋ฉ๋‹ˆ๋‹ค(ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ๋Š” ์†์„ฑ์„ ํ•œ ๋ˆˆ์— ์•Œ ์ˆ˜ ์—†์Œ).

๋‚˜๋Š” ์ธ์ŠคํŽ™ํ„ฐ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์„œ "HLT"๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ง€ ์•Š๋Š” ์‚ฌ๋žŒ๋“ค. ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ ๋‚ด๋ณด๋‚ธ ์†์„ฑ์„ ์Šคํฌ๋ฆฝํŠธ์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฆฌ์†Œ์Šค ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ณ€์ˆ˜๋ฅผ ๋ฆฌ์†Œ์Šค ์ž์ฒด๋กœ๋งŒ ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ•˜์œ„ ๋ฆฌ์†Œ์Šค๋ฅผ ํŽธ์ง‘ํ•˜์ง€ ์•Š๋Š” ํ•œ ์ธ์ŠคํŽ™ํ„ฐ์— ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋‹น์‹ ์˜ ์ฃผ์žฅ์„ ์ดํ•ดํ•˜์ง€๋งŒ ๊ทธ๊ฒƒ์€ ์›๋ž˜์˜ ๋ฌธ์ œ๋ฅผ ๋„˜์–ด์„œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค: ์ฝ”๋“œ ๋ฐ˜๋ณต์„ ํ”ผํ•˜์‹ญ์‹œ์˜ค(์ƒ์† ์—†์ด). ํŠน์„ฑ์€ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋ฅผ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งŽ์€ ๊ฒฝ์šฐ ์žฌ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ๊ตฌํ˜„์ด ํ•˜๋‚˜๋ฟ์ด๋ฉฐ ์ด๋ฅผ ์ธ์ŠคํŽ™ํ„ฐ์— ๋…ธ์ถœํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์ฝ”๋“œ์—์„œ ์ง์ ‘ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ๋‚ด๋ณด๋‚ด๊ธฐ ์—†์ด ๋ฆฌ์†Œ์Šค ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ๊ณตํ†ต ๊ตฌํ˜„์—์„œ ๋‚ด๋ณด๋‚ธ ๋ณ€์ˆ˜์™€ ์‹ ํ˜ธ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์‚ฌ๋žŒ๋“ค์ด ์‹œ๋„ํ•˜๋Š” ์ฃผ๋œ ์ด์œ  ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ์ƒ์†์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰, ์‚ฌ๋žŒ๋“ค์€ ํ˜„์žฌ ๊ธฐ๋Šฅ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‚ด๋ณด๋‚ธ ์†์„ฑ(์ผ๋ฐ˜์ ์œผ๋กœ ํ•ด๋‹น ๊ธฐ๋Šฅ๊ณผ ๊ด€๋ จ๋จ) ๋ฐ ์‹ ํ˜ธ(๊ทธ๋Ÿฌ๋ฉด UI์™€ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Œ)์— ๋Œ€ํ•ด ์ผ๋ฐ˜ ์Šคํฌ๋ฆฝํŠธ์—์„œ ์ƒ์†์„ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ํ•ด๊ฒฐํ•˜๊ธฐ ์–ด๋ ค์šด ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. GDScript๋งŒ์œผ๋กœ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์ง€๋งŒ ๋‹ค์‹œ ํ•œ ๋ฒˆ ์ƒ์šฉ๊ตฌ ์ฝ”๋“œ๋ฅผ ๋ณต์‚ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์™ธ๋ถ€ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋งˆ์น˜ ๋ฉ”์ธ ์Šคํฌ๋ฆฝํŠธ ์ž์ฒด์— ์ง์ ‘ ์ž‘์„ฑ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ์ž‘๋™ํ•˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐœ์ƒํ•ด์•ผ ํ•˜๋Š” ์ „ํ›„ ๊ด€๊ณ„๋ฅผ ์ƒ์ƒํ•  ์ˆ˜ ์žˆ์„ ๋ฟ์ž…๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์„ ์ด๋ฃจ๊ธฐ ์œ„ํ•ด ํ•˜๋Š˜๊ณผ ๋•…์ด ์›€์ง์—ฌ์•ผ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๋ฉด ์žˆ์œผ๋ฉด ์ข‹์„ ํ…๋ฐ. ์—‘์Šค)

@vnen ์ง€๊ธˆ ๋ฌด์Šจ ๋ง์”€ ํ•˜์‹œ๋Š”์ง€ ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ธ€์Ž„, ์ด๋ฒˆ ํ˜ธ์—๋Š” ์•„์ง ์ƒ๋ช…์ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์Œ์— ๊ธฐํšŒ๊ฐ€ ์žˆ์„ ๋•Œ ๋‹ค์‹œ ์—ด๊ฒ ์Šต๋‹ˆ๋‹ค.

์žฌ๊ฐœ๋ด‰ ์†Œ์‹์€ ์—†๋‚˜์š”? ์ด์ œ GodotCon 2019๊ฐ€ ๋ฐœํ‘œ๋˜๊ณ  Godot Sprint๊ฐ€ ํ•˜๋‚˜์˜ ์ผ์ด๋ฏ€๋กœ, ์•„๋งˆ๋„ ์ด๊ฒƒ์€ ์ด์•ผ๊ธฐํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@AfterRebelion ๋‚˜๋Š” ๋Œ์•„์™€์„œ ๊ทธ๊ฒƒ์„ ๋‹ค์‹œ ์—ฌ๋Š” ๊ฒƒ์„ ์žŠ์—ˆ์Šต๋‹ˆ๋‹ค. ์ƒ๊ธฐ์‹œ์ผœ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. XD

@willnationsdev EditorInspectorPlugin ์— ๊ด€ํ•ด ์ฝ์€ ๋‚ด์šฉ์ด ๋งˆ์Œ์— ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค! ๋น ๋ฅธ ์งˆ๋ฌธ, ์ด๊ฒƒ์€ ๋ฐ์ดํ„ฐ ์œ ํ˜•์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž ์ •์˜ ๊ฒ€์‚ฌ๊ธฐ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค... ์˜ˆ๋ฅผ ๋“ค์–ด... ๊ฒ€์‚ฌ๊ธฐ์— ๋ฒ„ํŠผ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
(์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ์ง€ ๊ฝค ์˜ค๋ž˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ธ์ŠคํŽ™ํ„ฐ์˜ ๋ฒ„ํŠผ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋””๋ฒ„๊น… ๋ชฉ์ ์œผ๋กœ ์ด๋ฒคํŠธ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)

@xDGameStudios ๋„ค , ๊ทธ ์™ธ์—๋„ ํ›จ์”ฌ ๋” ๋งŽ์€ ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ •์˜ ์ปจํŠธ๋กค์€ ์ƒ๋‹จ, ํ•˜๋‹จ, ์†์„ฑ ์œ„ ๋˜๋Š” ๋ฒ”์ฃผ ์•„๋ž˜์—์„œ Inspector์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@willnationsdev ๊ฐœ์ธ์ ์œผ๋กœ ์—ฐ๋ฝ๋“œ๋ ค๋„ ๋˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ๋„ค์š”!! ํ•˜์ง€๋งŒ EditorInspectorPlugin(์ผ๋ถ€ ์ƒ˜ํ”Œ ์ฝ”๋“œ์™€ ๊ฐ™์€)์— ๋Œ€ํ•ด ๋” ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ง€์ • ๋ฆฌ์†Œ์Šค ์œ ํ˜•(์˜ˆ: MyResource)์— ์†์„ฑ ๋‚ด๋ณด๋‚ด๊ธฐ "์ด๋ฆ„"์ด ์žˆ๊ณ  "์ด๋ฆ„"์„ ์ธ์‡„ํ•˜๋Š” ๊ฒ€์‚ฌ๊ธฐ ๋ฒ„ํŠผ์ด ์žˆ๋Š” ์ค„์— ์žˆ๋Š” ๊ฒƒ ๋ณ€์ˆ˜๋ฅผ ๋ˆ„๋ฅด๋ฉด (ํŽธ์ง‘๊ธฐ์—์„œ ๋˜๋Š” ๋””๋ฒ„๊น… ์ค‘)! ์ด ๋ฌธ์ œ์—์„œ ๋ฌธ์„œํ™”๋Š” ์‹œ๊ฐ„์ด ๋งŽ์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค... ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ฉด ๋ฌธ์„œ๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค! :D ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

๋‚˜๋Š” ๋˜ํ•œ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๋” ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์—‘์Šค)

๊ทธ๋ ‡๋‹ค๋ฉด ์ด๊ฒƒ์€ ์ •์  ํ•จ์ˆ˜๋ฅผ ํฌํ•จํ•˜๋Š” ์„œ๋ธŒํด๋ž˜์Šค๊ฐ€ ์žˆ๋Š” ์ž๋™ ๋กœ๋“œ ์Šคํฌ๋ฆฝํŠธ์™€ ๋™์ผํ•œ๊ฐ€์š”?

์˜ˆ๋ฅผ ๋“ค์–ด ๊ท€ํ•˜์˜ ์‚ฌ๋ก€๋Š” Traits.MoveRightTrait.move_right() ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

๋˜๋Š” ๋” ๊ฐ„๋‹จํ•˜๊ฒŒ ์„œ๋กœ ๋‹ค๋ฅธ ํŠน์„ฑ ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์„œ๋กœ ๋‹ค๋ฅธ ์ž๋™ ๋กœ๋“œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Movement.move_right()

์•„๋‹ˆ์š”, ํŠน์„ฑ์€ ํ•œ ์Šคํฌ๋ฆฝํŠธ์˜ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๋‹ค๋ฅธ ์Šคํฌ๋ฆฝํŠธ์— ๋ณต์‚ฌํ•˜์—ฌ ๋ถ™์—ฌ๋„ฃ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์–ธ์–ด๋ณ„ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค(ํŒŒ์ผ ๋ณ‘ํ•ฉ๊ณผ ์œ ์‚ฌ). ๋”ฐ๋ผ์„œ move_right() ๊ฐ€ ์žˆ๋Š” ํŠน์„ฑ์ด ์žˆ๊ณ  ๋‘ ๋ฒˆ์งธ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ํ•ด๋‹น ํŠน์„ฑ์„ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์„ ์–ธํ•˜๋ฉด ์ •์ ์ด ์•„๋‹ˆ๊ณ  ์•ก์„ธ์Šคํ•˜๋”๋ผ๋„ move_right() ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค์˜ ๋‹ค๋ฅธ ์œ„์น˜์— ์žˆ๋Š” ์†์„ฑ. ์†์„ฑ์ด ๋‘ ๋ฒˆ์งธ ์Šคํฌ๋ฆฝํŠธ์— ์—†์œผ๋ฉด ๊ตฌ๋ฌธ ๋ถ„์„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋‹ค์ค‘ ์ƒ์†์„ ๊ฐ€์งˆ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ค‘๋ณต ์ฝ”๋“œ(์ž‘์€ ๊ธฐ๋Šฅ, ์˜ˆ๋ฅผ ๋“ค์–ด ํ˜ธ ๋งŒ๋“ค๊ธฐ) ๋˜๋Š” ๋ถˆํ•„์š”ํ•œ ๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๊ต‰์žฅํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ •ํ™•ํžˆ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง„ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋‹ค๋ฅธ ๋…ธ๋“œ ์œ ํ˜•์—์„œ ์‚ฌ์šฉํ•˜๋„๋ก ๋งŒ๋“ค์–ด์•ผ ํ•˜๋ฏ€๋กœ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ•œ ์ค„์˜ ์ฝ”๋“œ์— ๋Œ€ํ•ด ์„œ๋กœ ๋‹ค๋ฅธ extend ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ํ˜„์žฌ ์‹œ์Šคํ…œ์œผ๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์•„๋Š” ์‚ฌ๋žŒ์ด ์žˆ์œผ๋ฉด ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค.

extends Node ๊ฐ€ ์žˆ๋Š” ์Šคํฌ๋ฆฝํŠธ์— ๋Œ€ํ•œ ๊ธฐ๋Šฅ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์†Œ์Šค ํŒŒ์ผ์„ ๋ณต์ œํ•˜๊ณ  ์ ์ ˆํ•œ extend ๋กœ ๋ฐ”๊พธ์ง€ ์•Š๊ณ ๋„ ๋™์ผํ•œ ๋™์ž‘์„ ๋‹ค๋ฅธ ๋…ธ๋“œ ์œ ํ˜•์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด์— ๋Œ€ํ•œ ์ง„์ „์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์•ž์—์„œ ๋งํ–ˆ๋“ฏ์ด ๊ณ„์† ์ฝ”๋“œ๋ฅผ ๋ณต์ œํ•˜๊ฑฐ๋‚˜ ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด 3.1์—์„œ ๋๋‚˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ์•„๋งˆ๋„ 3.2๋ฅผ ๋ชฉํ‘œ๋กœ ํ•  ๊ฒƒ์ž…๋‹ˆ๊นŒ?

์˜ค, ๋‚˜๋Š” ์ด๊ฒƒ์— ๋Œ€ํ•ด ์ „ํ˜€ ์ž‘์—…ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค, ๋‚˜๋Š” ์ด๊ฒƒ๋ณด๋‹ค ํ™•์žฅ ๋ฉ”์†Œ๋“œ ๊ตฌํ˜„์— ๋” ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ์™€ ํ•จ๊ป˜ ์ตœ๊ณ ์˜ ๊ตฌ๋ฌธ/๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ํ•ด๊ฒฐํ•˜๊ณ  ์‹ถ๊ธฐ ๋•Œ๋ฌธ์— ๋‘˜ ๋‹ค์— ๋Œ€ํ•ด vnen๊ณผ ์ด์•ผ๊ธฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํŽธ์ง‘: ๋‹ค๋ฅธ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ํŠน์„ฑ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ๊ท ์—ด์„ ์ผ์œผํ‚ค๊ณ  ์‹ถ๋‹ค๋ฉด ๋›ฐ์–ด๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž์™€ ํ˜‘๋ ฅํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

"ํ™•์žฅ ๋ฐฉ๋ฒ• ๊ตฌํ˜„"?

@Zireael07 #15586
๊ทธ๊ฒƒ์€ ์‚ฌ๋žŒ๋“ค์ด ์—”์ง„ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์ƒˆ๋กœ์šด "๋‚ด์žฅ๋œ" ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ๋ฌธ์— ๋Œ€ํ•œ ๋‚ด ํ•ด์„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

static Array func sum(p_self: Array):
    if not len(p_self):
        return 0
    var value = p_self[0]
    for i in range(1, len(p_self)):
        value += p_self[i]
    return value

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‹ค๋ฅธ ๊ณณ์—์„œ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

var arr = [1, 2, 3]
print(arr.sum()) # prints 6

์ง€์†์ ์œผ๋กœ ๋กœ๋“œ๋˜๋Š” ํ™•์žฅ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋น„๋ฐ€๋ฆฌ์— ํ˜ธ์ถœํ•˜๊ณ  Array ํด๋ž˜์Šค์— ๋ฐ”์ธ๋”ฉ๋œ ๋™์ผํ•œ ์ด๋ฆ„์˜ ์ •์  ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

์ด์— ๋Œ€ํ•ด @vnen ๋ฐ @jahd2602 ์™€ ๋ช‡ ๊ฐ€์ง€ ์ด์•ผ๊ธฐ๋ฅผ ๋‚˜๋ˆด์Šต๋‹ˆ๋‹ค. ๋งˆ์Œ์— ๋– ์˜ค๋ฅด๋Š” ํ•œ ๊ฐ€์ง€๋Š” ๋‹คํ˜•์„ฑ์— ๋Œ€ํ•œ Jai์˜ ์†”๋ฃจ์…˜์ธ ์†์„ฑ์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๊ฐ€์ ธ์˜ค๊ธฐ์ž…๋‹ˆ๋‹ค.

์ด ๋ฐฉ๋ฒ•์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

class A:
    var a_prop: String = "Hello"
    func foo():
        print("A's a_prop: ", a_prop)
    func bar():
        print("A's bar()")

class B:
    using var a: A = A.new()
    var a_prop: String = "World" # Overriding A's a_prop

    func bar():  # Overriding A's bar()
        print("B's bar()")

func main():
    var b: B = B.new()
    b.foo() # output: "A's a_prop: World"
    b.bar() # output: "B's bar()"

์š”์ ์€ using ํ‚ค์›Œ๋“œ๊ฐ€ ์†์„ฑ์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ๊ฐ€์ ธ์˜ค๋ฏ€๋กœ b.foo() ๋Š” ์‹ค์ œ๋กœ b.a.foo() ์— ๋Œ€ํ•œ ๊ตฌ๋ฌธ์  ์„คํƒ•์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋‹ค์Œ b is A == true ๋ฐ ํ•ด๋‹น B๊ฐ€ A๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ์ž…๋ ฅ๋œ ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋˜ํ•œ ํŠน์„ฑ์œผ๋กœ ์„ ์–ธํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๊ณตํ†ต ํ’ˆ์งˆ ์ด๋ฆ„์ด ์—†๋Š” ๋ชจ๋“  ํ•ญ๋ชฉ์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

ํ•œ ๊ฐ€์ง€ ๋ฌธ์ œ๋Š” ์ด๊ฒƒ์ด ํ˜„์žฌ ์ƒ์† ์‹œ์Šคํ…œ๊ณผ ์ž˜ ๋งž์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. A์™€ B๊ฐ€ ๋ชจ๋‘ Node2D์ด๊ณ  A: func baz(): print(self.position) ์—์„œ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒฝ์šฐ b.baz() ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์–ด๋–ค ์œ„์น˜๊ฐ€ ์ธ์‡„๋ฉ๋‹ˆ๊นŒ?
ํ•œ ๊ฐ€์ง€ ํ•ด๊ฒฐ์ฑ…์€ ํ˜ธ์ถœ์ž๊ฐ€ self ๋ฅผ ๊ฒฐ์ •ํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. b.foo()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด b๋ฅผ self๋กœ ์‚ฌ์šฉํ•˜์—ฌ foo()๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  bafoo()๋Š” foo()๋ฅผ self๋กœ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

Python( x.f(y) ์€ f(x,y) ์— ๋Œ€ํ•œ ์„คํƒ•)๊ณผ ๊ฐ™์€ ๋…๋ฆฝํ˜• ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ๊ตฌํ˜„ํ•˜๊ธฐ๊ฐ€ ์ •๋ง ์‰ฌ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ ๋‹ค๋ฅธ ๊ด€๋ จ ์—†๋Š” ์•„์ด๋””์–ด:

๋…๋ฆฝํ˜• ๊ธฐ๋Šฅ, JavaScript ์Šคํƒ€์ผ์—๋งŒ ์ค‘์ ์„ ๋‘ก๋‹ˆ๋‹ค.

์ •์  ํ•จ์ˆ˜์— ๋Œ€ํ•ด x.f(y) == f(x,y) ๊ทœ์น™์„ ์ฑ„ํƒํ•˜๋ฉด ๋‹ค์Œ์„ ๋งค์šฐ ์‰ฝ๊ฒŒ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

class Jumper:
    static func jump(_self: KinematicBody2D):
        # jump implementation

class Runner:
    static func run(_self: KinematicBody2D, direction: Vector2):
        # run implementation

class Character:
    extends KinematicBody2D
    func run = Runner.run       # Example syntax
    func jump = Jumper.jump

func main():
    var character = Character.new()
    character.jump()
    character.run(Vector2(1,0))

์ด๊ฒƒ์€ ์‹ค์ œ๋กœ ๋ฉ”์„œ๋“œ์—๋งŒ ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ธฐ ๋•Œ๋ฌธ์— ํด๋ž˜์Šค ์‹œ์Šคํ…œ์— ์ตœ์†Œํ•œ์˜ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์ด ์ •๋ง๋กœ ์œ ์—ฐํ•˜๊ธฐ๋ฅผ ์›ํ•œ๋‹ค๋ฉด ์šฐ๋ฆฌ๋Š” ์™„์ „ํ•œ JavaScript๋กœ ์ „ํ™˜ํ•˜๊ณ  ํ•จ์ˆ˜ ์ •์˜๊ฐ€ ํ• ๋‹น ๊ฐ€๋Šฅํ•˜๊ณ  ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•œ ๊ฐ’์„ ํ—ˆ์šฉํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@jabcross ์ข‹์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ผ์ข…์˜ ์„ ํƒ์  ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๊ฐœ๋…์ด ๋งˆ์Œ์— ๋“ค๊ณ  ๊ธฐ๋Šฅ ์•„์ด๋””์–ด๊ฐ€ ํฅ๋ฏธ๋กญ์Šต๋‹ˆ๋‹ค.

ํ•˜๋‚˜์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์™€ ๊ด€๋ จํ•˜์—ฌ ๋‹จ์ˆœํžˆ using A ๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ์„ ์–ธ์  ์‚ฌํ•ญ์ด ๊ด€๋ จ ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ์ด์œ ๊ฐ€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์ค‘ ์ƒ์†์œผ๋กœ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•ด์•ผ ํ•˜๋Š”์ง€๋„ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ์˜ต์…˜ A๋Š” ๋‘ ์Šคํฌ๋ฆฝํŠธ ๋ชจ๋‘ ๋™์ผํ•œ ์œ ํ˜•์„ ์ƒ์†ํ•˜๋„๋ก ๊ฐ•์ œํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ ํŠน๋ณ„ํ•œ ๋ณ‘ํ•ฉ ์—†์ด ๋‘˜ ๋‹ค ๋™์ผํ•œ ํด๋ž˜์Šค์˜ ๋งจ ์œ„์—์„œ ํ™•์žฅ๋ฉ๋‹ˆ๋‹ค.

์˜ต์…˜ B, ํŠน์„ฑ ํด๋ž˜์Šค๋ฅผ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•œ ์ถ”๊ฐ€ GDScript ํ‚ค์›Œ๋“œ ๋ฐ ํžŒํŠธ๋ฅผ ์›ํ•˜๋Š” ํด๋ž˜์Šค. ๊ฐ™์€ ์ƒ๊ฐ์ด์ง€๋งŒ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ๋ณด์ด๋ ค๋ฉด ์ถ”๊ฐ€ ๋‹จ๊ณ„๋งŒ ์žˆ์„ ๋ฟ์ž…๋‹ˆ๋‹ค.

A.gd ์ƒ๋‹จ:

extends Trait as Node2D
is Trait as Node2D
is Trait extends B
extends B as Trait

์˜ค, ๋‚˜๋Š” ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๊ฐ€์ ธ์˜ค๊ธฐ์˜ ๊ฐœ๋…์„ ์ •๋ง ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ํŠน์„ฑ ๋ฌธ์ œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์—”์ง„ ์œ ํ˜•์— ์ฝ˜ํ…์ธ ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•œ ์ž ์žฌ์ ์œผ๋กœ "ํ™•์žฅ ๋ฐฉ๋ฒ•" ๊ฐœ๋…๋„ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

class_name ArrayExt
static func sum(_self: Array) -> int:
    var sum: int = 0
    for a_value in _self:
        sum += a_value
    return sum

using ArrayExt
func _ready():
    var a = [1, 2, 3]
    print(a.sum())

@jabcross ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋žŒ๋ฐ”๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๊ฐ์ฒด๊ฐ€ ํ˜ธ์ถœ ์—ฐ์‚ฐ์ž๋ฅผ ๊ตฌํ˜„ํ•˜๋„๋ก ํ—ˆ์šฉํ–ˆ๋‹ค๋ฉด(ํ˜ธํ™˜ ๊ฐ€๋Šฅํ•œ ๊ฐ’์— ๋Œ€ํ•ด callable ์œ ํ˜•์„ ๊ฐ€์ง) GDScript ์ฝ”๋“œ์— ๋ณด๋‹ค ๊ธฐ๋Šฅ ์ง€ํ–ฅ์ ์ธ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค( ์ข‹์€ ์•„์ด๋””์–ด๊ฐ€ ๋  ๊ฒƒ ๊ฐ™์•„์š”.) ๋ฌผ๋ก  ๊ทธ ์‹œ์ ์—์„œ @vnen ์˜ #18698 ์˜์—ญ์— ๋” ๋งŽ์ด ๋“ค์–ด๊ฐ€๊ธด ํ–ˆ์ง€๋งŒ...

์šฐ๋ฆฌ๋Š” GDScript๊ฐ€ ์—ฌ์ „ํžˆ ๋™์  ์–ธ์–ด์ด๋ฉฐ ์ด๋Ÿฌํ•œ ์ œ์•ˆ ์ค‘ ์ผ๋ถ€๋Š” ํ˜ธ์ถœ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ๋Ÿฐํƒ€์ž„ ๊ฒ€์‚ฌ๊ฐ€ ํ•„์š”ํ•˜๊ณ  ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ์ถ”๊ฐ€๋œ๋‹ค๋Š” ์ ์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์‚ฌ๋žŒ๋“ค์—๊ฒŒ๋„ ๋ชจ๋“  ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ํ™•์ธํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์†์„ฑ ์กฐํšŒ๋„ ๊ฐ€๋Šฅ). ์ด๊ฒƒ์ด ํ™•์žฅ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์€ ์ƒ๊ฐ์ธ์ง€ ํ™•์‹ ํ•  ์ˆ˜ ์—†๋Š” ์ด์œ ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค(ํŠนํžˆ ๋ณธ์งˆ์ ์œผ๋กœ ๊ตฌ๋ฌธ ์„คํƒ•์ด๊ธฐ ๋•Œ๋ฌธ์—).

๋‚˜๋Š” ํŠน์„ฑ์ด ํด๋ž˜์Šค๊ฐ€ ์•„๋‹ˆ๋ผ ๊ณ ์œ ํ•œ ํŠน์„ฑ์ธ ์ˆœ์ˆ˜ ํŠน์„ฑ ์‹œ์Šคํ…œ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ปดํŒŒ์ผ ์‹œ๊ฐ„์— ์™„์ „ํžˆ ํ•ด๊ฒฐ๋  ์ˆ˜ ์žˆ๊ณ  ์ด๋ฆ„ ์ถฉ๋Œ์˜ ๊ฒฝ์šฐ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์ด ์ถ”๊ฐ€์ ์ธ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ ์—†์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค.

@vnen Ahhh, ๋Ÿฐํƒ€์ž„ ๋น„์šฉ์— ๋Œ€ํ•ด ๊นจ๋‹ซ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์ด ๋ชจ๋“  ํ™•์žฅ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์— ์ ์šฉ๋œ๋‹ค๋ฉด ๊ทธ๊ฒƒ๋„ ์ด์ƒ์ ์ด์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์ˆœ์ˆ˜ํ•œ ํŠน์„ฑ ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค์—ˆ๋‹ค๋ฉด ๋‹ค๋ฅธ ์Šคํฌ๋ฆฝํŠธ์—์„œ extends ์™€ using TraitName under extends ๋Œ€์‹  trait TraitName ๋ฅผ ๋งŒ๋“ค ์ƒ๊ฐ์ด์—ˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์„ ์ง์ ‘ ๊ตฌํ˜„ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ์œ„์ž„ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

์šฐ๋ฆฌ๊ฐ€ ์ˆœ์ˆ˜ํ•œ ํŠน์„ฑ ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค์—ˆ๋‹ค๋ฉด ๋‹ค๋ฅธ ์Šคํฌ๋ฆฝํŠธ์—์„œ extends ์™€ using TraitName under extends ๋Œ€์‹  trait TraitName ๋ฅผ ๋งŒ๋“ค ์ƒ๊ฐ์ด์—ˆ์Šต๋‹ˆ๊นŒ?

๊ทธ๊ฒŒ ๋‚ด ์ƒ๊ฐ์ด์•ผ. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์ถฉ๋ถ„ํžˆ ๊ฐ„๋‹จํ•˜๊ณ  ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์— ๋Œ€ํ•œ ๊ฑฐ์˜ ๋ชจ๋“  ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ๋‚˜๋Š” ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค๊ฐ€ ํŠน์„ฑ ๋ฉ”์†Œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜๋„๋ก ํ—ˆ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค(์ปดํŒŒ์ผ ํƒ€์ž„์— ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ). ํŠน์„ฑ์€ ๋‹ค๋ฅธ ํŠน์„ฑ์„ ํ™•์žฅํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์„ ์ง์ ‘ ๊ตฌํ˜„ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ์œ„์ž„ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

๋‚˜๋Š” ๊ทธ ์ผ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ์—๊ฒŒ ๊ทธ ์ผ์„ ๋งก๊ธฐ๋Š” ๊ฒƒ์„ ๊บผ๋ คํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์–ด์จŒ๋“  ์‹œ๊ฐ„์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฏธ๋ฆฌ ๋””์ž์ธ์— ๋™์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์„ธ๋ถ€ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ์ƒ๋‹นํžˆ ์œ ์—ฐํ•˜์ง€๋งŒ 1) ๋Ÿฐํƒ€์ž„ ๊ฒ€์‚ฌ์—์„œ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•„์•ผ ํ•˜๊ณ (GDScript๋Š” ์ปดํŒŒ์ผ์—์„œ ์•Œ์•„๋‚ผ ์ˆ˜ ์—†๋Š” ํ•ญ๋ชฉ์— ์ ํ•ฉํ•˜๋‹ค๊ณ  ๋ฏฟ์–ด์•ผ ํ•จ), 2) ๋น„๊ต์  ๊ฐ„๋‹จํ•ด์•ผ ํ•˜๋ฉฐ, 3) ์ปดํŒŒ์ผ ์‹œ๊ฐ„.

@vnen ์ด ์•„์ด๋””์–ด๋ฅผ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ํŠธ๋ ˆ์ž‡์ด ํฌํ•จ๋œ ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์ž๋™ ์™„์„ฑ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋˜๋Š” ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ธ์ง€ ์–ด๋–ป๊ฒŒ ์ƒ์ƒํ•˜๋Š”์ง€ ๊ถ๊ธˆํ•˜์‹ญ๋‹ˆ๊นŒ?

ํŠธ๋ ˆ์ž‡์ด ํฌํ•จ๋œ ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์ž๋™ ์™„์„ฑ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋˜๋Š” ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ธ์ง€ ์–ด๋–ป๊ฒŒ ์ƒ์ƒํ•˜๋Š”์ง€ ๊ถ๊ธˆํ•˜์‹ญ๋‹ˆ๊นŒ?

๋‚ด ๊ด€์ ์—์„œ ํŠน์„ฑ์€ ๋ณธ์งˆ์ ์œผ๋กœ "๊ฐ€์ ธ์˜ค๊ธฐ"์ž…๋‹ˆ๋‹ค. ๊ตฌ์„ฑ์›์„ ์œ„ํ•œ ์™„๋ฃŒ๊ฐ€ ์ž‘๋™ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด ์™„๋ฃŒ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ์ด ๊ฐ„๋‹จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@vnen ๊ธฐ๋ณธ์ ์œผ๋กœ trait ํ”Œ๋ž˜๊ทธ๊ฐ€ ์„ค์ •๋œ ClassNode๋กœ ๊ตฌ๋ฌธ ๋ถ„์„ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ using ๋ฌธ์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋ชจ๋“  ์†์„ฑ/๋ฉ”์†Œ๋“œ/์‹ ํ˜ธ/์ƒ์ˆ˜/ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ํ˜„์žฌ ์Šคํฌ๋ฆฝํŠธ์— ๋ณ‘ํ•ฉํ•˜๋ ค๊ณ  ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.

  1. ๋ฉ”์„œ๋“œ๊ฐ€ ์ถฉ๋Œํ•˜๋ฉด ์ƒ์†๋œ ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํ˜„์žฌ ์Šคํฌ๋ฆฝํŠธ์˜ ๊ตฌํ˜„์ด ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

    • ๊ทธ๋Ÿฌ๋‚˜ ๊ธฐ๋ณธ ํด๋ž˜์Šค์— ์ด๋ฏธ "๋ณ‘ํ•ฉ๋œ" ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

  2. ์†์„ฑ, ์‹œ๊ทธ๋„, ์ƒ์ˆ˜๊ฐ€ ๊ฒน์น  ๊ฒฝ์šฐ ๊ฐ™์€ ํƒ€์ž…/์‹œ๊ทธ๋‹ˆ์ฒ˜์ธ์ง€ ํ™•์ธํ•˜์„ธ์š”. ๋ถˆ์ผ์น˜๊ฐ€ ์—†์œผ๋ฉด ์†์„ฑ/์‹ ํ˜ธ/์ƒ์ˆ˜์˜ "๋ณ‘ํ•ฉ"์œผ๋กœ ๊ฐ„์ฃผํ•˜์‹ญ์‹œ์˜ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์‚ฌ์šฉ์ž์—๊ฒŒ ์œ ํ˜•/์„œ๋ช… ์ถฉ๋Œ(๋ถ„์„ ์˜ค๋ฅ˜)์„ ์•Œ๋ฆฝ๋‹ˆ๋‹ค.

๋‚˜์œ ์ƒ๊ฐ? ์•„๋‹ˆ๋ฉด ๋น„๋ฉ”์„œ๋“œ ์ถฉ๋Œ์„ ์™„์ „ํžˆ ๊ธˆ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ์„œ๋ธŒํด๋ž˜์Šค๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๋Ÿฌํ•œ ๊ฐˆ๋“ฑ์„ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๋Š” ๋Š๋‚Œ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@willnationsdev "๋‹ค์ด์•„๋ชฌ๋“œ ๋ฌธ์ œ"(์ผ๋ช… "์ฃฝ์Œ์˜ ๋‹ค์ด์•„๋ชฌ๋“œ"๋ผ๊ณ ๋„ ํ•จ)์ฒ˜๋Ÿผ ๋“ค๋ฆฌ๋Š”๋ฐ, ์ด๋ฏธ ์—ฌ๋Ÿฌ ์ธ๊ธฐ ์žˆ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์— ์ ์šฉ๋œ ๋‹ค์–‘ํ•œ ์†”๋ฃจ์…˜๊ณผ ํ•จ๊ป˜ ์ž˜ ๋ฌธ์„œํ™”๋œ ๋ชจํ˜ธ์„ฑ์ž…๋‹ˆ๋‹ค.

์ƒ๊ฐ๋‚˜๋Š” ๊ฒƒ:
@vnen ํŠน์„ฑ์ด ๋‹ค๋ฅธ ํŠน์„ฑ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@jahd2602 ๊ทธ๋Š” ์ด๋ฏธ ๊ทธ๊ฒƒ์„ ๊ฐ€๋Šฅ์„ฑ์œผ๋กœ ์ œ์•ˆํ–ˆ์Šต๋‹ˆ๋‹ค .

ํŠน์„ฑ์€ ๋‹ค๋ฅธ ํŠน์„ฑ์„ ํ™•์žฅํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

@jahd2602 Perl/Python ์†”๋ฃจ์…˜์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์—ฌ ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฐ ํด๋ž˜์Šค์˜ ์ฝ˜ํ…์ธ ๋ฅผ ํฌํ•จํ•˜๋Š” ๋ ˆ์ด์–ด์˜ "์Šคํƒ"์„ ํ˜•์„ฑํ•˜์—ฌ ๋งˆ์ง€๋ง‰์œผ๋กœ ์‚ฌ์šฉ๋œ ํŠน์„ฑ์˜ ์ถฉ๋Œ์ด ๋‹ค๋ฅธ ๋ฒ„์ „ ์œ„์— ๋†“์ด๊ณ  ๋ฎ์–ด์“ฐ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ์ด ์‹œ๋‚˜๋ฆฌ์˜ค์— ๋Œ€ํ•œ ๊ฝค ์ข‹์€ ์†”๋ฃจ์…˜์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. ๋‹น์‹ ์ด๋‚˜ @vnen ์—๊ฒŒ ๋‹ค๋ฅธ ์ƒ๊ฐ์ด ์—†๋‹ค๋ฉด. ์†”๋ฃจ์…˜ jahd์˜ ์—ฐ๊ฒฐ๋œ ๊ฐœ์š”์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

๋ช‡ ๊ฐ€์ง€ ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ฒซ์งธ: using ๋ฌธ์„ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์ง€์›ํ•ด์•ผ ํ•˜๋‚˜์š”?

using ๋ฌธ์—๋Š” ์ƒ์ˆ˜ ๊ฐ’ GDScript๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

using preload("res://my_trait.gd") # a preloaded expression
using ScriptClass.MyTrait # a const resource
using Autoload.MyTrait # a const resource
using MyTrait # a regular script class

์œ„์˜ ๋ชจ๋“  ๊ฒƒ์„ ์ƒ๊ฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋‘˜์งธ: ํŠน์„ฑ ๋ฐ/๋˜๋Š” ๊ทธ ์ด๋ฆ„์„ ์ •์˜ํ•˜๋Š” ๋ฐ ํ—ˆ์šฉ๋˜๋Š” ๊ตฌ๋ฌธ์€ ๋ฌด์—‡์ด์–ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๋ˆ„๊ตฐ๊ฐ€๋Š” ๋ฐ˜๋“œ์‹œ ์ž์‹ ์˜ ํŠน์„ฑ์— ๋Œ€ํ•ด ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์–ดํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ trait TraitName ์š”๊ตฌ ์‚ฌํ•ญ์„ ์ ์šฉํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. trait ๊ฐ€ ์ค„์— ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋„๊ตฌ ์Šคํฌ๋ฆฝํŠธ๋ผ๋ฉด ๋‹น์—ฐํžˆ ๋งจ ์œ„์— ๋„๊ตฌ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ํŠน์„ฑ์ด๋ฉด ๋‹ค์Œ ์ค„์— ํŠน์„ฑ์ธ์ง€ ์—ฌ๋ถ€๋ฅผ ์ •์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒ์ ์œผ๋กœ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ๊ฐ™์€ ์ค„์— ์žˆ๋Š” ํŠน์„ฑ ์„ ์–ธ ๋‹ค์Œ์— ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค ์ด๋ฆ„์„ ๋ช…์‹œํ•˜๋„๋ก ํ—ˆ์šฉํ•˜๊ณ , ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๊ฒฝ์šฐ class_name ๋„ ์‚ฌ์šฉํ•˜๋„๋ก ํ—ˆ์šฉํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ํŠน์„ฑ ์ด๋ฆ„์„ ์ƒ๋žตํ•˜๋ฉด class_name <name> ๊ฐ€ ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‹ค๋ฅธ ์œ ํ˜•์„ ํ™•์žฅํ•  ๋•Œ ํŠน์„ฑ ์„ ์–ธ ๋’ค์— extends ๋ฅผ ์‚ฝ์ž…ํ•˜๊ฑฐ๋‚˜ ํŠน์„ฑ ์„ ์–ธ ๋’ค์— ์ž์ฒด ํ–‰์— ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค์Œ ๊ฐ ํ•ญ๋ชฉ์ด ์œ ํšจํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค.

# Global name from trait keyword.
trait MyTrait extends BaseTrait

# Global name from class_name keyword, but is still a trait and also happens to be a tool script.
tool
trait
extends BaseTrait
class_name MyTrait

# A trait with no global name associated with it. Does not extend anything.
trait

์…‹์งธ: ์ž๋™ ์™„์„ฑ ๋ชฉ์  ๋ฐ/๋˜๋Š” ์˜๋„/์š”๊ตฌ ์‚ฌํ•ญ ์„ ์–ธ์„ ์œ„ํ•ด ํŠธ๋ ˆ์ž‡์ด ํ™•์žฅํ•ด์•ผ ํ•˜๋Š” ๊ธฐ๋ณธ ์œ ํ˜•์„ ์ •์˜ํ•˜๋„๋ก ํ—ˆ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

์šฐ๋ฆฌ๋Š” ์ด๋ฏธ ํŠน์„ฑ์ด ๋‹ค๋ฅธ ํŠน์„ฑ์˜ ์ƒ์†์„ ์ง€์›ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๋…ผ์˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ TraitA๋ฅผ extend Node ๋กœ ํ—ˆ์šฉํ•˜๊ณ  TraitA ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋…ธ๋“œ ์ž๋™ ์™„์„ฑ์„ ์–ป๋„๋ก ํ—ˆ์šฉํ•ด์•ผ ํ•˜์ง€๋งŒ ํ˜„์žฌ ํด๋ž˜์Šค๊ฐ€ Node๋ฅผ ํ™•์žฅํ•˜์ง€ ์•Š์„ ๋•Œ using TraitA ๋ฌธ์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ๊ตฌ๋ฌธ ๋ถ„์„ ์˜ค๋ฅ˜๋„ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋˜๋Š” ํŒŒ์ƒ ์œ ํ˜• ์ค‘ ํ•˜๋‚˜?

๋„ค ๋ฒˆ์งธ: ํŠธ๋ ˆ์ž‡์ด ๋‹ค๋ฅธ ํŠธ๋ ˆ์ž‡์„ ํ™•์žฅํ•˜๋„๋ก ํ•˜๋Š” ๋Œ€์‹  ํด๋ž˜์Šค ํ™•์žฅ์„ ์œ„ํ•ด ์˜ˆ์•ฝ๋œ extends ๋ช…๋ น๋ฌธ์„ ์œ ์ง€ํ•˜๊ณ  ํŠธ๋ ˆ์ž‡์ด ์ด ๋ช…๋ น๋ฌธ์„ ์ „ํ˜€ ํ•„์š”๋กœ ํ•˜์ง€ ์•Š๊ฒŒ ํ•˜๊ณ  ๊ธฐ๋ณธ ํŠธ๋ ˆ์ž‡์„ ํ™•์žฅํ•˜๋Š” ๋Œ€์‹  ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ํŠน์„ฑ์„ ํ•˜์œ„ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ํ†ตํ•ด ๊ณ ์œ  ํ•œ using ๋ช…๋ น๋ฌธ์„ ๊ฐ–๋„๋ก ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

# base_trait.gd
trait
func my_method():
    print("Hello")

# derived_trait.gd
trait
using preload("base_trait.gd")
func my_method():
   print("World") # overrides previous method, will only print "World".

๋ฌผ๋ก  ์—ฌ๊ธฐ์˜ ์ด์ ์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ํฌํ•จํ•˜๋Š” C++ ํฌํ•จ ํŒŒ์ผ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ์—ฌ๋Ÿฌ using ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹จ์ผ ํŠน์„ฑ ์ด๋ฆ„์œผ๋กœ ์—ฌ๋Ÿฌ ํŠน์„ฑ์„ ์ผ๊ด„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹ค์„ฏ์งธ: ํŠน์„ฑ์ด ์žˆ๊ณ  ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด using ๋˜๋Š” extends ๊ฐ€ ์žˆ๊ณ  ๊ณ ์œ ํ•œ ํŠน์„ฑ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ํ•จ์ˆ˜ ๋‚ด์—์„œ ํ˜ธ์ถœํ•  ๋•Œ ์ˆ˜ํ–‰ํ•  ์ž‘์—… .<method_name> ๊ธฐ๋ณธ ๊ตฌํ˜„์„ ์‹คํ–‰ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์ด๋Ÿฌํ•œ ํ˜ธ์ถœ์€ ํ•ญ์ƒ ํด๋ž˜์Šค ์ƒ์† ์ปจํ…์ŠคํŠธ ๋‚ด์—์„œ ์‹คํ–‰๋˜๊ณ  ํŠน์„ฑ ๊ณ„์ธต ๊ตฌ์กฐ๊ฐ€ ์—ฌ๊ธฐ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๊นŒ?

cc @vnen

์ฒซ์งธ: using ๋ฌธ์„ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์ง€์›ํ•ด์•ผ ํ•˜๋‚˜์š”?

using ๋ฌธ์—๋Š” ์ƒ์ˆ˜ ๊ฐ’ GDScript๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

using preload("res://my_trait.gd") # a preloaded expression
using ScriptClass.MyTrait # a const resource
using Autoload.MyTrait # a const resource
using MyTrait # a regular script class

๋‚˜๋Š” ๊ทธ ๋ชจ๋“  ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฒฝ๋กœ์˜ ๊ฒฝ์šฐ ๋ฌธ์ž์—ด์„ ์ง์ ‘ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. using "res://my_trait.gd"

๋‘˜์งธ: ํŠน์„ฑ ๋ฐ/๋˜๋Š” ๊ทธ ์ด๋ฆ„์„ ์ •์˜ํ•˜๋Š” ๋ฐ ํ—ˆ์šฉ๋˜๋Š” ๊ตฌ๋ฌธ์€ ๋ฌด์—‡์ด์–ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๋ˆ„๊ตฐ๊ฐ€๋Š” ์ž์‹ ์˜ ํŠน์„ฑ์— ๋Œ€ํ•ด ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์–ดํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ trait TraitName ์š”๊ตฌ ์‚ฌํ•ญ์„ ์ ์šฉํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. trait ๊ฐ€ ์ค„์— ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋„๊ตฌ ์Šคํฌ๋ฆฝํŠธ๋ผ๋ฉด ๋‹น์—ฐํžˆ ๋งจ ์œ„์— ๋„๊ตฌ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ํŠน์„ฑ์ด๋ฉด ๋‹ค์Œ ์ค„์— ํŠน์„ฑ์ธ์ง€ ์—ฌ๋ถ€๋ฅผ ์ •์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒ์ ์œผ๋กœ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ๊ฐ™์€ ์ค„์— ์žˆ๋Š” ํŠน์„ฑ ์„ ์–ธ ๋‹ค์Œ์— ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค ์ด๋ฆ„์„ ๋ช…์‹œํ•˜๋„๋ก ํ—ˆ์šฉํ•˜๊ณ , ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๊ฒฝ์šฐ class_name ๋„ ์‚ฌ์šฉํ•˜๋„๋ก ํ—ˆ์šฉํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ํŠน์„ฑ ์ด๋ฆ„์„ ์ƒ๋žตํ•˜๋ฉด class_name <name> ๊ฐ€ ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‹ค๋ฅธ ์œ ํ˜•์„ ํ™•์žฅํ•  ๋•Œ ํŠน์„ฑ ์„ ์–ธ ๋’ค์— extends ๋ฅผ ์‚ฝ์ž…ํ•˜๊ฑฐ๋‚˜ ํŠน์„ฑ ์„ ์–ธ ๋’ค์— ์ž์ฒด ํ–‰์— ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค์Œ ๊ฐ ํ•ญ๋ชฉ์ด ์œ ํšจํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค.

# Global name from trait keyword.
trait MyTrait extends BaseTrait

# Global name from class_name keyword, but is still a trait and also happens to be a tool script.
tool
trait
extends BaseTrait
class_name MyTrait

# A trait with no global name associated with it. Does not extend anything.
trait

ํŠธ๋ ˆ์ดํŠธ์˜ tool ๋Š” ์ง์ ‘ ์‹คํ–‰๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ฌด๋Ÿฐ ์ฐจ์ด๊ฐ€ ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ํŠน์„ฑ์ด ๋ฐ˜๋“œ์‹œ ๊ธ€๋กœ๋ฒŒ ์ด๋ฆ„์„ ๊ฐ€์งˆ ํ•„์š”๋Š” ์—†๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. trait tool ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์˜ ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์ฃผ์„ ์ œ์™ธ). ํ‚ค์›Œ๋“œ ๋‹ค์Œ์— ํŠน์„ฑ ์ด๋ฆ„์ด ์„ ํƒ์ ์œผ๋กœ ์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ํด๋ž˜์Šค๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— class_name ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์…‹์งธ: ์ž๋™ ์™„์„ฑ ๋ชฉ์  ๋ฐ/๋˜๋Š” ์˜๋„/์š”๊ตฌ ์‚ฌํ•ญ ์„ ์–ธ์„ ์œ„ํ•ด ํŠธ๋ ˆ์ž‡์ด ํ™•์žฅํ•ด์•ผ ํ•˜๋Š” ๊ธฐ๋ณธ ์œ ํ˜•์„ ์ •์˜ํ•˜๋„๋ก ํ—ˆ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

์†”์งํžˆ ํŽธ์ง‘์ž๋ฅผ ์œ„ํ•ด ์–ธ์–ด์— ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ์ข‹์•„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ ์ฃผ์„์ด ์œ ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด์ œ ํŠน์ • ์œ ํ˜•(๋ฐ ํŒŒ์ƒ ์ƒํ’ˆ)์—๋งŒ ํŠน์„ฑ์„ ์ ์šฉํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค, ์ €๋Š” ์ด๊ฒƒ์ด ์ •์  ๊ฒ€์‚ฌ๋ฅผ ์œ„ํ•ด ๋” ๋‚ซ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค: ์ด๊ฒƒ์€ ํŠธ๋ ˆ์ž‡์ด ํด๋ž˜์Šค์˜ ํ•ญ๋ชฉ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๋ฐ˜๋ฉด ์ปดํŒŒ์ผ์€ ์‹ค์ œ๋กœ ์˜ฌ๋ฐ”๋ฅธ ์œ ํ˜• ๋ฐ ๊ธฐํƒ€ ํ•ญ๋ชฉ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋„ค ๋ฒˆ์งธ: ํŠธ๋ ˆ์ž‡์ด ๋‹ค๋ฅธ ํŠธ๋ ˆ์ž‡์„ ํ™•์žฅํ•˜๋„๋ก ํ•˜๋Š” ๋Œ€์‹  ํด๋ž˜์Šค ํ™•์žฅ์„ ์œ„ํ•ด ์˜ˆ์•ฝ๋œ extends ๋ช…๋ น๋ฌธ์„ ์œ ์ง€ํ•˜๊ณ  ํŠธ๋ ˆ์ž‡์ด ์ด ๋ช…๋ น๋ฌธ์„ ์ „ํ˜€ ํ•„์š”๋กœ ํ•˜์ง€ ์•Š๊ฒŒ ํ•˜๊ณ  ๊ธฐ๋ณธ ํŠธ๋ ˆ์ž‡์„ ํ™•์žฅํ•˜๋Š” ๋Œ€์‹  ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ํŠน์„ฑ์ด _๊ทธ_ ํŠน์„ฑ์„ ํ•˜์œ„ ๊ฐ€์ ธ์˜ค๊ธฐํ•˜๋Š” ์ž์ฒด using ๋ฌธ์„ ๊ฐ–๋„๋ก ํ•˜๋ ค๋ฉด?

๊ธ€์Ž„์š”, ๊ทธ๊ฒƒ์€ ๋Œ€๋ถ€๋ถ„ ์˜๋ฏธ๋ก ์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ํŠน์„ฑ์ด ๋‹ค๋ฅธ ํŠน์„ฑ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์–ธ๊ธ‰ํ–ˆ์„ ๋•Œ extends ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ฃผ์š” ์ฐจ์ด์ ์€ extends ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•˜๋‚˜๋งŒ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๊ณ  using ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค๋ฅธ ๋งŽ์€ ํŠน์„ฑ์„ ํ•˜๋‚˜์— ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” using ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ์ฃผ๊ธฐ๊ฐ€ ์—†๋‹ค๋ฉด ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‹ค์„ฏ ๋ฒˆ์งธ: ํŠน์„ฑ์ด ์žˆ๊ณ  ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด using ๋˜๋Š” extends ๊ฐ€ ์žˆ๊ณ  ๊ณ ์œ ํ•œ ํŠน์„ฑ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ํ•จ์ˆ˜ ๋‚ด์—์„œ ํ˜ธ์ถœํ•  ๋•Œ ์ˆ˜ํ–‰ํ•  ์ž‘์—… .<method_name> ๊ธฐ๋ณธ ๊ตฌํ˜„์„ ์‹คํ–‰ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์ด๋Ÿฌํ•œ ํ˜ธ์ถœ์€ ํ•ญ์ƒ ํด๋ž˜์Šค ์ƒ์† ์ปจํ…์ŠคํŠธ ๋‚ด์—์„œ ์‹คํ–‰๋˜๊ณ  ํŠน์„ฑ ๊ณ„์ธต ๊ตฌ์กฐ๊ฐ€ ์—ฌ๊ธฐ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๊นŒ?

์–ด๋ ค์šด ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ํŠน์„ฑ์ด ํด๋ž˜์Šค ์ƒ์†์„ ๋‹ค๋ฃจ๋Š” ๋น„์ฆˆ๋‹ˆ์Šค๊ฐ€ ์—†๋‹ค๊ณ  ๊ฐ€์ •ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์  ํ‘œ๊ธฐ๋ฒ•์€ ๋ถ€๋ชจ ํŠน์„ฑ์— ๋Œ€ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์žˆ๋Š” ๊ฒฝ์šฐ). ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ํŠน์„ฑ์€ ์ž์‹ ์ด ์†ํ•œ ํด๋ž˜์Šค๋ฅผ ์ธ์‹ํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

OTOH, ํŠน์„ฑ์€ ๊ฑฐ์˜ "ํฌํ•จ"๊ณผ ๊ฐ™์œผ๋ฏ€๋กœ ํด๋ž˜์Šค์— ๊ทธ๋Œ€๋กœ ์ ์šฉ๋˜๋ฏ€๋กœ ๋ถ€๋ชจ ๊ตฌํ˜„์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์†”์งํžˆ ๊ทธ ๋ฐฉ๋ฒ•์ด ๋ถ€๋ชจ ํŠธ๋ ˆ์ž‡์—์„œ ๋ฐœ๊ฒฌ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋‚˜๋Š” ๋‹จ์ˆœํžˆ ์  ํ‘œ๊ธฐ๋ฒ•์„ ๊ธˆ์ง€ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํด๋ž˜์Šค์— ํ•˜๋‚˜ ์ด์ƒ์˜ ๋‹ค๋ฅธ ํŠน์„ฑ์ด ์žˆ์–ด์•ผ ํ•˜๋Š” ํŠน์„ฑ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ์˜ˆ๋ฅผ ๋“ค์–ด Jumper , Upgradable , ๊ทธ๋ฆฌ๊ณ  KinematicBody2D ๋ฅผ ์ƒ์†ํ•˜๋Š” ํด๋ž˜์Šค๊ฐ€ ๋ชจ๋‘ ํ•„์š”ํ•œ DoubleJumper $ ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, Rust๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด์™€ ๊ฐ™์€ ์œ ํ˜• ์„œ๋ช…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. KinematicBody2D: Jumper, Upgradable ์™€ ๊ฐ™์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ : ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์œ ํ˜•์— ์ฃผ์„์„ ๋‹ฌ๊ธฐ ๋•Œ๋ฌธ์— KinematicBody2D & Jumper & Upgradable ๋˜๋Š” ๊ธฐํƒ€๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹คํ˜•์„ฑ ๋ฌธ์ œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠน์„ฑ ๊ตฌํ˜„์ด ํด๋ž˜์Šค๋งˆ๋‹ค ๋‹ค๋ฅด์ง€๋งŒ ๋™์ผํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋…ธ์ถœํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?

์˜ˆ๋ฅผ ๋“ค์–ด, Enemy ์™€ Player ๋ชจ๋‘์—์„œ ์‚ฌ์šฉํ•˜๋Š” Jumper ํŠธ๋ ˆ์ž‡์— kill() ๋ฉ”์†Œ๋“œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋™์ผํ•œ Jumper ์œ ํ˜• ์‹œ๊ทธ๋‹ˆ์ฒ˜์™€ ํ˜ธํ™˜๋˜๋„๋ก ์œ ์ง€ํ•˜๋ฉด์„œ ๊ฐ ๊ฒฝ์šฐ์— ๋Œ€ํ•ด ์„œ๋กœ ๋‹ค๋ฅธ ๊ตฌํ˜„์„ ์›ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•?

๋‹คํ˜•์„ฑ์˜ ๊ฒฝ์šฐ kill() ๊ฐ€ ์žˆ๋Š” ํŠน์„ฑ์„ ํฌํ•จํ•˜๋Š” ๋ณ„๋„์˜ ํŠน์„ฑ์„ ๋งŒ๋“  ๋‹ค์Œ ๋ฉ”์„œ๋“œ์˜ ๊ณ ์œ ํ•œ ํŠน์ • ๋ฒ„์ „์„ ๊ตฌํ˜„ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด์ „์— ํฌํ•จ๋œ ํŠธ๋ ˆ์ดํŠธ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜๋Š” ํŠธ๋ ˆ์ดํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ์œ ํ˜• ํžŒํŠธ์— ํŠน์„ฑ ์š”๊ตฌ ์‚ฌํ•ญ์ด ํฌํ•จ๋˜๋„๋ก ํ•  ๊ณ„ํš์€ (์•„์ง) ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ์šฐ๋ฆฌ๊ฐ€ ํ•˜๊ณ  ์‹ถ์€ ์ผ์ž…๋‹ˆ๊นŒ?

๋ณ„๋„์˜ ํŠน์„ฑ์„ ์ƒ์„ฑ

์ผํšŒ์„ฑ ํŠน์„ฑ ํŒŒ์ผ์„ ๋งŽ์ด ์ƒ์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? ์ค‘์ฒฉ๋œ ํŠน์„ฑ ์„ ์–ธ( class ํ‚ค์›Œ๋“œ์™€ ์œ ์‚ฌ)์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋” ํŽธ๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค์—์„œ ์ง์ ‘ ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ•๋ ฅํ•œ ์œ ํ˜• ์„œ๋ช… ์‹œ์Šคํ…œ(๋ถ€์šธ ๊ตฌ์„ฑ ๋ฐ ์„ ํƒ ์‚ฌํ•ญ/null์ด ์•„๋‹Œ ๊ฒฝ์šฐ)์— ์ •๋ง ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ํŠน์„ฑ์ด ๋”ฑ ๋“ค์–ด๋งž์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋…ผ์˜๋˜์—ˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ๊ธฐ๋Šฅ์˜ ํŠน์„ฑ ํŠน์ • ๋ฒ„์ „์„ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

trait A
func m():
  print("A")

trait B
func m():
  print("B")

class C
using A
using B

func c():
  A.m()
  B.m()
  m()

A , B , B ๋ฅผ ์ธ์‡„ํ•ฉ๋‹ˆ๋‹ค.


๋˜ํ•œ "๋Ÿฐํƒ€์ž„ ๋น„์šฉ ์—†์Œ"์— ๋Œ€ํ•ด ์™„์ „ํžˆ ํ™•์‹ ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๋ณด๋‚ด๊ธฐ ์ „์— ์ •์˜๋œ ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค์™€ ํ•จ๊ป˜ ๋™์ ์œผ๋กœ ๋กœ๋“œ๋œ ์Šคํฌ๋ฆฝํŠธ(๋‚ด๋ณด๋‚ด๊ธฐ ์ค‘์—๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ)๋ฅผ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๊นŒ? ๋‚ด๊ฐ€ ๋ญ”๊ฐ€ ์˜คํ•ดํ•˜๊ณ  ์žˆ๋Š” ๊ฑธ๊นŒ? ์•„๋‹ˆ๋ฉด ๊ทธ ๊ฒฝ์šฐ๊ฐ€ "๋Ÿฐํƒ€์ž„"์œผ๋กœ ๊ฐ„์ฃผ๋˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

๋…ผ์˜๋˜์—ˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ๊ธฐ๋Šฅ์˜ ํŠน์„ฑ ํŠน์ • ๋ฒ„์ „์„ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๋ฏธ ์ด๊ฒƒ์„ ๊ณ ๋ คํ•˜๊ณ  ์žˆ์—ˆ์ง€๋งŒ ํด๋ž˜์Šค๊ฐ€ ์ถฉ๋Œํ•˜๋Š” ํŠน์„ฑ(์ฆ‰, ๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•˜๋Š” ํŠน์„ฑ)์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ํ™•์‹ ์ด ์—†์Šต๋‹ˆ๋‹ค. using ๋ฌธ์˜ ์ˆœ์„œ๋Š” ์ฐจ์ด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ "๋Ÿฐํƒ€์ž„ ๋น„์šฉ ์—†์Œ"์— ๋Œ€ํ•ด ์™„์ „ํžˆ ํ™•์‹ ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๋ณด๋‚ด๊ธฐ ์ „์— ์ •์˜๋œ ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค์™€ ํ•จ๊ป˜ ๋™์ ์œผ๋กœ ๋กœ๋“œ๋œ ์Šคํฌ๋ฆฝํŠธ(๋‚ด๋ณด๋‚ด๊ธฐ ์ค‘์—๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ)๋ฅผ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๊นŒ? ๋‚ด๊ฐ€ ๋ญ”๊ฐ€ ์˜คํ•ดํ•˜๊ณ  ์žˆ๋Š” ๊ฑธ๊นŒ? ์•„๋‹ˆ๋ฉด ๊ทธ ๊ฒฝ์šฐ๊ฐ€ "๋Ÿฐํƒ€์ž„"์œผ๋กœ ๊ฐ„์ฃผ๋˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

์ˆ˜์ถœํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ์€ ๋กœ๋”ฉ ์‹œ์— ์ผ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ๋กœ๋”ฉ ์‹œ๊ฐ„์— ํ™•์‹คํžˆ ์˜ํ–ฅ์„ ๋ฏธ์น  ๊ฒƒ์ด์ง€๋งŒ(๋งค์šฐ ์ค‘์š”ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ) ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰๋  ๋•Œ๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด์ƒ์ ์œผ๋กœ๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋‚ด๋ณด๋‚ผ ๋•Œ ์ปดํŒŒ์ผํ•ด์•ผ ํ•˜์ง€๋งŒ ์ด๋Š” ๋˜ ๋‹ค๋ฅธ ๋…ผ์˜์ž…๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ๋ถ„, ์•ˆ๋…•ํ•˜์„ธ์š”.

์ €๋Š” Godot๋ฅผ ์ฒ˜์Œ ์ ‘ํ–ˆ๊ณ  ์ง€๋‚œ ๋ฉฐ์น  ๋™์•ˆ ์ต์ˆ™ํ•ด์กŒ์Šต๋‹ˆ๋‹ค. ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ ์‚ฌ์šฉํ•  ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค๋ฅผ ์ฐพ์œผ๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๋ฉด์„œ ํŒจํ„ด์„ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ํ•ญ์ƒ ๋‹ค๋ฅธ ์žฅ๋ฉด์—์„œ ์ธ์Šคํ„ด์‹ฑ๋˜๋„๋ก ์˜๋„๋œ ํ•˜์œ„ ์žฅ๋ฉด์˜ ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์™ธ๋ถ€์—์„œ ์„ค์ •ํ•˜๋ ค๋Š” ๋ชจ๋“  ์†์„ฑ์„ ๋‚ด๋ณด๋‚ด๋„๋ก ๋งŒ๋“ค ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ํ•œ ๋‚˜๋จธ์ง€ ์žฅ๋ฉด์—๋Š” ์ธ์Šคํ„ด์Šค๋œ ๋ถ„๊ธฐ์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ์— ๋Œ€ํ•œ ์ง€์‹์ด ํ•„์š”ํ•˜์ง€ ์•Š๊ฒŒ ํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ๋ฃจํŠธ ๋…ธ๋“œ๊ฐ€ ์†์„ฑ์„ "๋‚ด๋ณด๋‚ด๊ธฐ"ํ•œ ๋‹ค์Œ ๊ฐ’์„ _ready์˜ ์ ์ ˆํ•œ ์ž์‹์— ๋ณต์‚ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ž์‹ Timer๊ฐ€ ์žˆ๋Š” Bomb ๋…ธ๋“œ๋ฅผ ์ƒ์ƒํ•ด ๋ณด์‹ญ์‹œ์˜ค. ํ•˜์œ„ ์žฅ๋ฉด์˜ ๋ฃจํŠธ Bomb ๋…ธ๋“œ๋Š” "detonation_time"์„ ๋‚ด๋ณด๋‚ธ ๋‹ค์Œ _ready์—์„œ $Timer.wait_time = detonation_time ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๊ฒƒ์„ ์ธ์Šคํ„ด์Šคํ™”ํ•  ๋•Œ๋งˆ๋‹ค ์•„์ด๋“ค์„ ํŽธ์ง‘ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ  ํƒ€์ด๋จธ๋กœ ๋“œ๋ฆด๋‹ค์šดํ•  ํ•„์š” ์—†์ด Godot์˜ UI์—์„œ ๋ฉ‹์ง€๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ
1) ๊ทธ๊ฒƒ์€ ๋งค์šฐ ๊ธฐ๊ณ„์  ๋ณ€ํ˜•์ด๋ฏ€๋กœ ์‹œ์Šคํ…œ์—์„œ ์œ ์‚ฌํ•œ ๊ฒƒ์„ ์ง€์›ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
2) ์ž์‹ ๋…ธ๋“œ์—์„œ ์ง์ ‘ ์ ์ ˆํ•œ ๊ฐ’์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์•ฝ๊ฐ„์˜ ๋น„ํšจ์œจ์„ฑ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ณ„์†ํ•˜๊ธฐ ์ „์— ์ด๊ฒƒ์€ ์ผ์ข…์˜ "๋น„๊ณต๊ฐœ" ์ƒ์†(C++ ์šฉ์–ด๋กœ)์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋…ผ์˜ ์ค‘์ธ ๋‚ด์šฉ๊ณผ ๊ด€๋ จ์ด ์—†์–ด ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ €๋Š” ์ƒ์†๊ณผ ๊ฐ™์€ ์—”์ง€๋‹ˆ์–ด๋ง ๋Œ€์‹  Scene ์š”์†Œ๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ ๋™์ž‘์„ ๊ตฌ์ถ•ํ•˜๋Š” Godot์˜ ์‹œ์Šคํ…œ์„ ์‹ค์ œ๋กœ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ "๊ธฐ์žฌ๋œ" ๊ด€๊ณ„๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๊ณ  ์ •์ ์ž…๋‹ˆ๋‹ค. OTOH, ์žฅ๋ฉด ๊ตฌ์กฐ๋Š” ๋™์ ์ด๋ฉฐ ๋Ÿฐํƒ€์ž„์— ๋ณ€๊ฒฝํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒŒ์ž„ ๋กœ์ง์€ ๊ฐœ๋ฐœํ•˜๋Š” ๋™์•ˆ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Godot์˜ ๋””์ž์ธ์ด ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์•„์ฃผ ์ž˜ ๋งž๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ž์‹ ๋…ธ๋“œ๊ฐ€ ๋ฃจํŠธ ๋…ธ๋“œ์˜ ๋™์ž‘ ํ™•์žฅ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์ด ์‚ฌ์‹ค์ด์ง€๋งŒ ๊ทธ๋ ‡๋‹ค๊ณ  ํ•ด์„œ ์ž๊ธ‰์ž์กฑ์ด ๋ถ€์กฑํ•œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค(IMO). ํƒ€์ด๋จธ๋Š” ์‹œ๊ฐ„์— ์ต์ˆ™ํ•ด์ง€๋Š” ๊ฒƒ๊ณผ ์ƒ๊ด€์—†์ด ์™„๋ฒฝํ•˜๊ฒŒ ๋…๋ฆฝ์ ์ด๋ฉฐ ๋™์ž‘์„ ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ˆŸ๊ฐ€๋ฝ์œผ๋กœ ์ˆ˜ํ”„๋ฅผ ๋จน๋“  ์•„์ด์Šคํฌ๋ฆผ์„ ๋จน๋“  ์†์„ ๋ป—๋Š” ์—ญํ• ์„ ํ•˜๋ฉด์„œ๋„ ์ œ ๊ธฐ๋Šฅ์„ ์ œ๋Œ€๋กœ ๋ฐœํœ˜ํ•œ๋‹ค. ๋‚˜๋Š” ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ž์‹ ๋…ธ๋“œ์˜ ๋™์ž‘์„ ์กฐ์ •ํ•˜๋Š” ๊ฑฐ์žฅ์œผ๋กœ ๊ฐ„์ฃผํ•˜๋ฏ€๋กœ ์„œ๋กœ์— ๋Œ€ํ•ด ์ง์ ‘ ์•Œ ํ•„์š”๊ฐ€ ์—†์œผ๋ฉฐ ๋”ฐ๋ผ์„œ ๋…๋ฆฝ์ ์œผ๋กœ ์œ ์ง€๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒ์œ„/๋ฃจํŠธ ๋…ธ๋“œ๋Š” ์ฑ…์ž„์„ ์œ„์ž„ํ•˜์ง€๋งŒ ์ง์ ‘์ ์ธ ์ž‘์—…์„ ๋งŽ์ด ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๋Š” ๋ฐ์Šคํฌ ๋ฐ”์ธ๋”ฉ๋œ ๊ด€๋ฆฌ์ž์ž…๋‹ˆ๋‹ค. ์–‡๊ธฐ ๋•Œ๋ฌธ์— ์•ฝ๊ฐ„ ๋‹ค๋ฅธ ๋™์ž‘์„ ์œ„ํ•ด ์ƒˆ ๊ฒƒ์„ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋ฃจํŠธ ๋…ธ๋“œ๋Š” ์ „์ฒด ์ธ์Šคํ„ด์Šค ๋ถ„๊ธฐ์˜ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ์ธํ„ฐํŽ˜์ด์Šค ์—ญํ• ๋„ ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ธ์Šคํ„ด์Šค์—์„œ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ์†์„ฑ์€ ์†์„ฑ์˜ ์ตœ์ข… ์†Œ์œ ์ž๊ฐ€ ์ผ๋ถ€ ์ž์‹ ๋…ธ๋“œ์ธ ๊ฒฝ์šฐ์—๋„ ๋ถ„๊ธฐ์˜ ๋ฃจํŠธ ๋…ธ๋“œ์—์„œ "์„ค์ • ๊ฐ€๋Šฅ"ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ œ๊ฐ€ ๋†“์น˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ์—†๋‹ค๋ฉด, ์ด๊ฒƒ์€ Godot์˜ ํ˜„์žฌ ๋ฒ„์ „์—์„œ ์ˆ˜๋™์œผ๋กœ ์ •๋ ฌ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋™์  ์‹œ์Šคํ…œ์˜ ์ด์ ๊ณผ ๋” ์‰ฌ์šด ์Šคํฌ๋ฆฝํŒ…์„ ๊ฒฐํ•ฉํ•˜๊ธฐ ์œ„ํ•ด ์ด๊ฒƒ์ด ์–ด๋–ป๊ฒŒ๋“  ์ž๋™ํ™”๋  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์ƒ๊ฐํ•˜๊ณ  ์žˆ๋Š” ํ•œ ๊ฐ€์ง€๋Š” Node.js์˜ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” "๋™์  ์ƒ์†" ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌํ•œ ์Šคํฌ๋ฆฝํŠธ์—๋Š” ์†์„ฑ/๋ฉ”์„œ๋“œ์˜ ๋‘ ๊ฐ€์ง€ ์†Œ์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜๋Š” ํ™•์žฅํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ์˜ ์†Œ์Šค์ด๊ณ  ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ์žฅ๋ฉด ๊ตฌ์กฐ ๋‚ด์˜ ์ž์‹์—์„œ "๋ฒ„๋ธ”์—…๋œ" ์†Œ์Šค์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Bomb์— ๋Œ€ํ•œ ๋‚ด ์˜ˆ์ œ๋Š” bomb.gd ์Šคํฌ๋ฆฝํŠธ์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜ ์„น์…˜ ๋‚ด์—์„œ export lifted var $Timer.wait_time [= value?] as detonation_time ์™€ ๊ฐ™์ด ๋ฉ๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ _ready ์ฝœ๋ฐฑ์—์„œ $Timer.wait_time = detonation_time ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  Bomb ๋…ธ๋“œ์˜ ๋ถ€๋ชจ๋กœ๋ถ€ํ„ฐ $Bomb.detonation_time = 5 ๋ฅผ ํ—ˆ์šฉํ•˜์—ฌ $Timer.wait_time = 5 ๊ฐ€ ์„ค์ •๋˜๋„๋ก ํ•˜๋Š” getter/setter๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

MoveRightTrait๊ฐ€ ์žˆ๋Š” OP์˜ ์˜ˆ์—์„œ๋Š” mysprite.gd๊ฐ€ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ์— MoveRightTrait๊ฐ€ ์ž์‹ ๋…ธ๋“œ๋กœ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ mysprite.gd์— lifted func $MoveRightTrait.move_right [as move_right] ์™€ ๊ฐ™์€ ํ•ญ๋ชฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค(์ด๋ฆ„์ด ๊ฐ™์„ ๋•Œ 'as'๋Š” ์„ ํƒ ์‚ฌํ•ญ์ผ ์ˆ˜ ์žˆ์Œ). ์ด์ œ mysprite.gd์—์„œ ์ƒ์„ฑ๋œ ์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์— ๋Œ€ํ•ด move_right๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ž๋™์œผ๋กœ ์ ์ ˆํ•œ ์ž์‹ ๋…ธ๋“œ์— ์œ„์ž„๋ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์‹ ํ˜ธ๊ฐ€ ๋ฒ„๋ธ”๋ง๋˜์–ด ๋ฃจํŠธ์—์„œ ์ž์‹ ๋…ธ๋“œ์— ์—ฐ๊ฒฐ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋งˆ๋„ ์ „์ฒด ๋…ธ๋“œ๋Š” func, signal ๋˜๋Š” var ์—†์ด lifted $MoveRightTrait [as MvR] ๋กœ ๋ฒ„๋ธ”๋ง๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ MoveRightTrait์˜ ๋ชจ๋“  ๋ฉ”์„œ๋“œ์™€ ์†์„ฑ์€ mysprite.move_right๋กœ mysprite์—์„œ ์ง์ ‘ ์•ก์„ธ์Šคํ•˜๊ฑฐ๋‚˜ 'as MvR'์ด ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ mysprite.MvR.move_right๋ฅผ ํ†ตํ•ด ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ธ์Šคํ„ด์Šค ๋ธŒ๋žœ์น˜์˜ ๋ฃจํŠธ์— ์žˆ๋Š” ์”ฌ ๊ตฌ์กฐ์— ๋Œ€ํ•œ ์ธํ„ฐํŽ˜์ด์Šค ์ƒ์„ฑ์„ ๋‹จ์ˆœํ™”ํ•˜๊ณ , ๊ทธ๋“ค์˜ "๋ธ”๋ž™๋ฐ•์Šค" ํŠน์„ฑ์„ ์ฆ๊ฐ€์‹œํ‚ค๊ณ  Godot์˜ ๋‹ค์ด๋‚ด๋ฏนํ•œ ์”ฌ ์‹œ์Šคํ…œ์˜ ํž˜๊ณผ ํ•จ๊ป˜ ์Šคํฌ๋ฆฝํŒ… ํŽธ์˜์„ฑ์„ ์–ป๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ํ•˜๋‚˜์˜ ์•„์ด๋””์–ด์ž…๋‹ˆ๋‹ค. ๋ฌผ๋ก  ๊ณ ๋ คํ•ด์•ผ ํ•  ์ธก๋ฉด ์„ธ๋ถ€ ์‚ฌํ•ญ์ด ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ธฐ๋ณธ ํด๋ž˜์Šค์™€ ๋‹ฌ๋ฆฌ ์ž์‹ ๋…ธ๋“œ๋Š” ๋Ÿฐํƒ€์ž„์— ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ์˜ค๋ฅ˜์˜ ๊ฒฝ์šฐ ํ˜ธ์ถœ/์•ก์„ธ์Šคํ•˜๋Š” ๊ฒฝ์šฐ ๋ฒ„๋ธ”๋ง/๋ฆฌํ”„ํŠธ๋œ ํ•จ์ˆ˜ ๋ฐ ์†์„ฑ์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ์˜ฌ๋ฐ”๋ฅธ NodePath๊ฐ€ ์žˆ๋Š” ๋…ธ๋“œ๊ฐ€ ๋‹ค์‹œ ์ถ”๊ฐ€๋˜๋ฉด ํ•ด์ œ๋œ ์†์„ฑ์ด ๋‹ค์‹œ ์ž‘๋™ํ•˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๊นŒ? [YES, IMO] ๋˜ํ•œ Node์—์„œ ํŒŒ์ƒ๋˜์ง€ ์•Š์€ ํด๋ž˜์Šค์—์„œ 'lifted'๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” ๋ฒ„๋ธ”/๋ฆฌํ”„ํŠธํ•  ์ž์‹์ด ์ ˆ๋Œ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ๋…ธ๋“œ์— ๋™์ผํ•œ ์ด๋ฆ„์˜ ์†์„ฑ/๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์ค‘๋ณต๋œ "as {name}" ๋˜๋Š” "lifted $Timer1 lifted $Timer2"๋กœ ์ด๋ฆ„ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋Š” ์ด๋Ÿฌํ•œ ๋…ผ๋ฆฌ์  ๋ฌธ์ œ๋ฅผ ์ด์ƒ์ ์œผ๋กœ ๊ฐ์ง€ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด ์šฐ๋ฆฌ๊ฐ€ ์ „๋‹ฌ ํ•จ์ˆ˜์™€ ์ดˆ๊ธฐํ™”๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋˜๋Š” ๋‹จ์ง€ ๊ตฌ๋ฌธ์ƒ์˜ ์„คํƒ•์ผ์ง€๋ผ๋„ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์„ ๋งŽ์ด ์ค„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฐœ๋…์ ์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ์ด ๊ทธ๋ฆฌ ์–ด๋ ต์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์–ด์จŒ๋“  ์—ฌ๊ธฐ๊นŒ์ง€ ์ฝ์œผ์…จ๋‹ค๋ฉด ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

๋‚˜๋Š” ๋ชจ๋“  ๊ณณ์—์„œ "๋“ค์–ด ์˜ฌ๋ฆฐ"์„ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ ๊ทธ๊ฒƒ์€ ๋‹จ์ง€ ์˜ˆ์‹œ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.
using var $Timer.wait_time as detonation_time ๋˜๋Š” using $Timer ์™€ ๊ฐ™์€ ๊ฒƒ๋„ ๋ถ„๋ช…ํžˆ ์ข‹์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ๊ฒฝ์šฐ๋“  ์ž์‹ ๋…ธ๋“œ์—์„œ ํŽธ๋ฆฌํ•˜๊ฒŒ ์˜์‚ฌ ์ƒ์†์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ธ์Šคํ„ด์Šคํ™”ํ•  ๋ถ„๊ธฐ์˜ ๋ฃจํŠธ์—์„œ ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ผ๊ด€๋œ ๋‹จ์ผ ์•ก์„ธ์Šค ์ง€์ ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ธฐ๋Šฅ ๋ถ€๋ถ„์— ๋Œ€ํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์€ ๋…ธ๋“œ ๋˜๋Š” ํ•ด๋‹น ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜์—ฌ ๋” ํฐ ๊ตฌ์„ฑ ์š”์†Œ์— ์ž์‹์œผ๋กœ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์„ ๋ณด๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ๋…ธ๋“œ์—์„œ ์ƒ์†๋œ ์Šคํฌ๋ฆฝํŠธ์˜ "ํ™•์žฅ" ํ‚ค์›Œ๋“œ๊ฐ€ "is-a" ๊ด€๊ณ„๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐ˜๋ฉด ์Šคํฌ๋ฆฝํŠธ์—์„œ "์‚ฌ์šฉ" ๋˜๋Š” "๋ฆฌํ”„ํŠธ" ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ "๋ฒ„๋ธ”์—…"ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž์† ๋…ธ๋“œ์˜ ๋ฉค๋ฒ„๋Š” ๋‹จ์ผ ์ƒ์†์ด์ง€๋งŒ ๋‹ค์ค‘ "์ธํ„ฐํŽ˜์ด์Šค"(์˜ˆ: Java)๊ฐ€ ์žˆ๋Š” ์–ธ์–ด์— ์กด์žฌํ•˜๋Š” "๊ตฌํ˜„"[ํ—ค์ด, ๊ฐ€๋Šฅํ•œ ํ‚ค์›Œ๋“œ]๊ณผ ์œ ์‚ฌํ•œ ๊ฒƒ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฌด์ œํ•œ ๋‹ค์ค‘ ์ƒ์†(์˜ˆ: C++)์—์„œ ๊ธฐ๋ณธ ํด๋ž˜์Šค๋Š” [์ •์  ์ž‘์„ฑ] ํŠธ๋ฆฌ๋ฅผ ํ˜•์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋น„์œ ํ•˜์ž๋ฉด ์ €๋Š” Godot์˜ ๊ธฐ์กด ๋…ธ๋“œ ํŠธ๋ฆฌ ์œ„์— ํŽธ๋ฆฌํ•œ ๊ตฌ๋ฌธ๊ณผ ์ƒ์šฉ๊ตฌ ์ œ๊ฑฐ๋ฅผ ๋ ˆ์ด์–ด๋งํ•˜๋Š” ๊ฒƒ์„ ์ œ์•ˆํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ํƒ๊ตฌํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค๊ณ  ํŒ๋‹จ๋˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋””์ž์ธ ๊ณต๊ฐ„ ์ธก๋ฉด์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
1) "์‚ฌ์šฉ"์—์„œ ์ง๊ณ„ ์ž๋…€๋งŒ ํ—ˆ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. IOW using $Timer ๋Š” ์•„๋‹ˆ์ง€๋งŒ using $Bomb/Timer'? This would be simpler but would force us to write boilerplate in some cases. I say that a full NodePath ROOTED in the Node to which the script is attached should be legal [but NO references to parents/siblings allowed]. 2) Should there be an option that find_node์˜ the "using"-ed node instead of following a written in NodePath? For example using "Timer" with a string for the pattern would be slower but the forwarding architecture would continue to work if a referenced node's position in the sub-tree changes at run time. This could be used selectively for child nodes that we expect to move around beneath the root. Of course syntax would have to be worked out especially when using a particular member (eg. using var "Timer".wait_time as detonation_time is icky). 3) Should there be a way query for certain functionality [equivalent to asking if an interface is implemented or a child node is present]? Perhaps "using" entire nodes with aliases should allow testing the alias to be a query. So MoveRightTrait ์‚ฌ์šฉ DirectionalMover in a script would result in node.DirectionalMover returning the child MoveRightTrait. This is logical because node.DirectionalMover.move_right() calls the method on the child MoveRightTrait. Other nodes without that statement would return null. So the statement node.DirectionalMover:`๊ฐ€ ๊ด€๋ก€์— ๋”ฐ๋ผ ๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ๊ฐ€ ๋œ๋‹ค๋ฉด.
4) ์ƒํƒœ ํŒจํ„ด์€ "using"-ed ๋…ธ๋“œ๋ฅผ "using" ๋ฌธ์—์„œ ์ฐธ์กฐ๋œ ๊ฒƒ๊ณผ ๋™์ผํ•œ ์ธํ„ฐํŽ˜์ด์Šค[๋• ํƒ€์ดํ•‘] ๋ฐ ๋™์ผํ•œ NodePath๋ฅผ ๊ฐ–์ง€๋งŒ ๋ณ€ํ˜• ๋™์ž‘์„ ๊ฐ–๋Š” ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ๊ต์ฒดํ•˜์—ฌ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์žฅ๋ฉด ํŠธ๋ฆฌ๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ด๊ฒƒ์€ ๊ฑฐ์˜ ๋ฌด๋ฃŒ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹œ์Šคํ…œ์€ ์ƒ์œ„๋ฅผ ํ†ตํ•ด ์—ฐ๊ฒฐ๋œ ์‹ ํ˜ธ๋ฅผ ์ถ”์ ํ•˜๊ณ  ๊ต์ฒด๋œ ํ•˜์œ„์—์„œ ์—ฐ๊ฒฐ์„ ๋ณต์›ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ €๋Š” ์ง€๊ธˆ ํ•œ๋™์•ˆ GDScript๋กœ ์ž‘์—…ํ•ด ์™”์œผ๋ฉฐ ์–ด๋–ค ์ข…๋ฅ˜์˜ ํŠน์„ฑ/๋ฏน์Šค์ธ ๋ฐ ํ”„๋ก์‹œ/์œ„์ž„ ๊ธฐ๋Šฅ์ด ์ ˆ์‹คํžˆ ํ•„์š”ํ•˜๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์†์„ฑ์„ ์—ฐ๊ฒฐํ•˜๊ฑฐ๋‚˜ ์žฅ๋ฉด์˜ ๋ฃจํŠธ์— ์žˆ๋Š” ์ž์‹ ๋ฉ”์„œ๋“œ๋ฅผ ๋…ธ์ถœํ•˜๊ธฐ ์œ„ํ•ด ์ด ๋ชจ๋“  ์ƒ์šฉ๊ตฌ๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์ƒ๋‹นํžˆ ์„ฑ๊ฐ€์‹  ์ผ์ž…๋‹ˆ๋‹ค.

๋˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋งŒ ํŠธ๋ฆฌ ์ˆ˜์ค€์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค(๊ฐ ์ƒˆ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋ชจ๋“  ๋…ธ๋“œ ๊ฒฝ๋กœ๋ฅผ ๊นจ๋œจ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ์ƒ๋‹นํžˆ ๋นจ๋ฆฌ ๋ณต์žกํ•ด์ง‘๋‹ˆ๋‹ค). ํ•œ ๋…ธ๋“œ์—์„œ ์—ฌ๋Ÿฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ๋ฉ”ํƒ€/๋ฉ€ํ‹ฐ ์Šคํฌ๋ฆฝํŠธ์™€ ๊ฐ™์€ ๋” ๋‚˜์€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ด€์šฉ์  ์ธ ์†”๋ฃจ์…˜์ด ์žˆ์œผ๋ฉด ๊ณต์œ ํ•˜์‹ญ์‹œ์˜ค ...

C++(GDNative)๋ฅผ ๋ฏน์Šค์— ๋„ฃ์œผ๋ฉด _ready ๋ฐ _init ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒํ™ฉ์ด ๋”์šฑ ์•…ํ™”๋ฉ๋‹ˆ๋‹ค(์ฝ๊ธฐ: ๊ธฐ๋ณธ๊ฐ’์„ ์‚ฌ์šฉํ•œ ์ดˆ๊ธฐํ™”๊ฐ€ ๋ฐ˜์ฏค ์ž‘๋™ํ•˜๊ฑฐ๋‚˜ ์ „ํ˜€ ์ž‘๋™ํ•˜์ง€ ์•Š์Œ).

์ด๊ฒƒ์ด ๋‚ด๊ฐ€ GDScript์—์„œ ํ•ด๊ฒฐํ•ด์•ผ ํ•˜๋Š” ์ฃผ์š” ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ์ „์ฒด ์ƒ์† ๊ตฌ์กฐ๋ฅผ ๊ตฌ์„ฑํ•˜์ง€ ์•Š๊ณ  ๋…ธ๋“œ ๊ฐ„์— ๊ธฐ๋Šฅ์„ ๊ณต์œ ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ”Œ๋ ˆ์ด์–ด์™€ ์ƒ์  ์ฃผ์ธ์—๊ฒŒ๋Š” ์ธ๋ฒคํ† ๋ฆฌ๊ฐ€ ์žˆ๊ณ , ํ”Œ๋ ˆ์ด์–ด+์•„์ดํ…œ+์ ์—๊ฒŒ๋Š” ํ†ต๊ณ„๊ฐ€ ์žˆ๊ณ , ํ”Œ๋ ˆ์ด์–ด์™€ ์ ์—๊ฒŒ๋Š” ์žฅ๋น„ ์•„์ดํ…œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋‚˜๋Š” ์ด๋Ÿฌํ•œ ๊ณต์œ  '๊ตฌ์„ฑ ์š”์†Œ'๋ฅผ ์ด๋ฅผ ํ•„์š”๋กœ ํ•˜๋Š” '์—”ํ‹ฐํ‹ฐ'์— ๋กœ๋“œ๋œ ํด๋ž˜์Šค ๋˜๋Š” ๋…ธ๋“œ๋กœ ๊ตฌํ˜„ํ•˜์ง€๋งŒ ์ง€์ €๋ถ„ํ•˜๊ณ (๋…ธ๋“œ์— ๋Œ€ํ•œ ๋งŽ์€ ๊ฒ€์ƒ‰์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์˜ค๋ฆฌ ํƒ€์ดํ•‘์„ ๊ฑฐ์˜ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋“ฑ) ๋Œ€์ฒด ์ ‘๊ทผ ๋ฐฉ์‹์—๋Š” ์ž์ฒด ๋‹จ์ ์ด ์žˆ์œผ๋ฏ€๋กœ ๋” ๋‚˜์€ ๋ฐฉ๋ฒ•์„ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ํŠน์„ฑ/๋ฏน์Šค์ธ์€ ๋‚ด ์ƒ๋ช…์„ ์ ˆ๋Œ€์ ์œผ๋กœ ๊ตฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฒฐ๋ก ์€ ์ƒ์†์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๊ฐ์ฒด ๊ฐ„์— ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ œ ์ƒ๊ฐ์— ์ด๊ฒƒ์€ ํ˜„์žฌ Godot์—์„œ ๊น”๋”ํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ํ•„์š”ํ•˜์ง€๋งŒ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ Rust ํŠน์„ฑ(https://doc.rust-lang.org/1.8.0/book/traits.html)์„ ์ดํ•ดํ•˜๋Š” ๋ฐฉ์‹์€ ๊ทธ๋“ค์ด Haskell ์œ ํ˜• ํด๋ž˜์Šค์™€ ๊ฐ™๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์œ ํ˜•์— ๋Œ€ํ•ด ์ •์˜ํ•ด์•ผ ํ•˜๋Š” ์ผ๋ถ€ ๋งค๊ฐœ๋ณ€์ˆ˜ํ™”๋œ ํ•จ์ˆ˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค ํŠน์„ฑ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ํŠน์„ฑ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ชจ๋“  ์œ ํ˜•์— ๋Œ€ํ•ด ์ •์˜๋œ ์ผ๋ถ€ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. Rust ํŠน์„ฑ์ด ์—ฌ๊ธฐ์— ์ œ์•ˆ๋œ ๊ฒƒ๊ณผ ๋‹ค๋ฅธ๊ฐ€์š”?

์—ฌ๊ธฐ์—์„œ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ๋…ผ์˜๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ํ•ญ๋ชฉ์€ ์•„๋งˆ๋„ ๋„๋งค๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—์„œ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ๋…ผ์˜๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ํ•ญ๋ชฉ์€ ์•„๋งˆ๋„ ๋„๋งค๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

_๋‚˜๋Š” ์ œ์•ˆ์˜ "์ด๋™"์ด ๋ฌด์˜๋ฏธํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๊ด€์‹ฌ์„ ํ‘œ๋ช…ํ•˜๋ฉด godot-proposals๋ฅผ ๋‹ซ๊ณ  ๋‹ค์‹œ ์—ด๋„๋ก ์š”์ฒญํ•˜๊ณ  ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋‹ค๋ฅธ ์ œ์•ˆ์„ ์‹ค์ œ๋กœ ๊ตฌํ˜„ํ•˜๋„๋ก ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์–ด์จŒ๋“ ..._

๋‚˜๋Š” 1๋…„ ์ „์— ์ด ๋ฌธ์ œ๋ฅผ ์šฐ์—ฐํžˆ ๋งŒ๋‚ฌ์ง€๋งŒ ์ด์ œ์„œ์•ผ ํŠน์„ฑ ์‹œ์Šคํ…œ์˜ ์ž ์žฌ์ ์ธ ์œ ์šฉ์„ฑ์„ ์ดํ•ดํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๋ฌธ์ œ๋ฅผ ๋” ์ž˜ ์ดํ•ดํ•˜๋„๋ก ์˜๊ฐ์„ ์ฃผ๊ธฐ ์œ„ํ•ด ํ˜„์žฌ ์ž‘์—… ํ๋ฆ„์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค(๊ทธ๋ฆฌ๊ณ  ์•„๋งˆ๋„ ํŠน์„ฑ ์‹œ์Šคํ…œ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋‚˜์€ ๋Œ€์•ˆ์„ ์ œ์•ˆํ•  ์ˆ˜ ์žˆ์Œ).

1. ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉ๋œ ๊ฐ ๋…ธ๋“œ ์œ ํ˜•์— ๋Œ€ํ•œ ๊ตฌ์„ฑ ์š”์†Œ ํ…œํ”Œ๋ฆฟ์„ ์ƒ์„ฑํ•˜๋Š” ๋„๊ตฌ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

@willnationsdev https://github.com/godotengine/godot/issues/23101#issuecomment -431468744

์ด์ œ ์ด๋ฅผ ๋” ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์Šค๋‹ˆํŽซ ์‹œ์Šคํ…œ์ด๋‚˜ ๋งคํฌ๋กœ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ์žฌ์‚ฌ์šฉ๋˜๋Š” ์„ ์–ธ์  ์ฝ”๋“œ ์„น์…˜์„ ๋” ์‰ฝ๊ฒŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹น์‹ ์˜ ๋ฐœ์ž์ทจ๋ฅผ ๋”ฐ๋ผ ๊ฑท๋Š”๋‹ค... ๐Ÿ˜‚

tool
extends EditorScript

const TYPES = [
    'Node',
    'Node2D',
]
const TYPES_PATH = 'types'
const TYPE_BASENAME_TEMPLATE = 'component_%s.gd'

const TEMPLATE = \
"""class_name Component{TYPE} extends {TYPE}

signal host_assigned(node)

export(bool) var enabled = true

export(NodePath) var host_path
var host

func _ready():
    ComponentCommon.init(self, host_path)"""

func _run():
    _update_scripts()


func _update_scripts():

    var base_dir = get_script().resource_path.get_base_dir()
    var dest = base_dir.plus_file(TYPES_PATH)

    for type in TYPES:
        var filename = TYPE_BASENAME_TEMPLATE % [type.to_lower()]
        var code = TEMPLATE.format({"TYPE" : type})
        var path = dest.plus_file(filename)

        print_debug("Writing component code for: " + path)

        var file = File.new()
        file.open(path, File.WRITE)
        file.store_line(code)
        file.close()

2. ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ํ˜ธ์ŠคํŠธ๋กœ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋ฐ ์žฌ์‚ฌ์šฉํ•  ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค(์˜ˆ: ๋ฃจํŠธ).

class_name ComponentCommon

static func init(p_component, p_host_path = NodePath()):

    assert(p_component is Node)

    # Try to assign
    if not p_host_path.is_empty():
        p_component.host = p_component.get_node(p_host_path)

    elif is_instance_valid(p_component.owner):
        p_component.host = p_component.owner

    elif is_instance_valid(p_component.get_parent()):
        p_component.host = p_component.get_parent()

    # Check
    if not is_instance_valid(p_component.host):
        push_warning(p_component.name.capitalize() + ": couldn't find a host, disabling.")
        p_component.enabled = false
    else:
        p_component.emit_signal('host_assigned')

์ฒซ ๋ฒˆ์งธ ์Šคํฌ๋ฆฝํŠธ๋กœ ์ƒ์„ฑ๋œ ๊ตฌ์„ฑ ์š”์†Œ(ํŠน์„ฑ)๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

class_name ComponentNode2D extends Node2D

signal host_assigned(node)

export(bool) var enabled = true

export(NodePath) var host_path
var host

func _ready():
    ComponentCommon.init(self, host_path)

(์„ ํƒ ์‚ฌํ•ญ) 3. ๊ตฌ์„ฑ ์š”์†Œ ํ™•์žฅ(ํŠน์„ฑ)

@vnen https://github.com/godotengine/godot/issues/23101#issuecomment -471816901

๊ทธ๊ฒŒ ๋‚ด ์ƒ๊ฐ์ด์•ผ. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์ถฉ๋ถ„ํžˆ ๊ฐ„๋‹จํ•˜๊ณ  ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์— ๋Œ€ํ•œ ๊ฑฐ์˜ ๋ชจ๋“  ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ๋‚˜๋Š” ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค๊ฐ€ ํŠน์„ฑ ๋ฉ”์†Œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜๋„๋ก ํ—ˆ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค(์ปดํŒŒ์ผ ํƒ€์ž„์— ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ). ํŠน์„ฑ์€ ๋‹ค๋ฅธ ํŠน์„ฑ์„ ํ™•์žฅํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹น์‹ ์˜ ๋ฐœ์ž์ทจ๋ฅผ ๋”ฐ๋ผ ๊ฑท๋Š”๋‹ค... ๐Ÿ˜‚

class_name ComponentMotion2D extends ComponentNode2D

const MAX_SPEED = 100.0

var linear_velocity = Vector2()
var collision

export(Script) var impl
...

์‹ค์ œ๋กœ ๋‚ด๋ณด๋‚ธ Script ๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋‹น ํŠน์ • ํ˜ธ์ŠคํŠธ/๋ฃจํŠธ ๋…ธ๋“œ ์œ ํ˜•์˜ ๋™์ž‘์„ ๊ตฌ๋™ํ•˜๊ธฐ ์œ„ํ•ด ์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ComponentMotion2D ์—๋Š” ์ฃผ๋กœ ๋‘ ๊ฐœ์˜ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • motion_kinematic_body_2d.gd
  • motion_rigid_body_2d.gd

๊ทธ๋ž˜์„œ ์•„์ด๋“ค์€ ์—ฌ์ „ํžˆ โ€‹โ€‹์—ฌ๊ธฐ์„œ host / root ํ–‰๋™์„ ํ•ฉ๋‹ˆ๋‹ค. host ์šฉ์–ด๋Š” ๋‚ด๊ฐ€ ์ƒํƒœ ๋จธ์‹ ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€์ ธ์˜จ ๊ฒƒ์ด๋ฉฐ, ์ƒํƒœ๊ฐ€ ๋…ธ๋“œ imo๋กœ ๋” ์ž˜ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํŠน์„ฑ์ด ์™„๋ฒฝํ•˜๊ฒŒ ์ ํ•ฉํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค.

๊ตฌ์„ฑ ์š”์†Œ ์ž์ฒด๋Š” onready ๋ฉค๋ฒ„๋กœ ๋งŒ๋“ค์–ด ๋ฃจํŠธ์— "ํ•˜๋“œ์™€์ด์–ด๋ง"๋˜์–ด ์ƒ์šฉ๊ตฌ ์ฝ”๋“œ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์ค„์ž…๋‹ˆ๋‹ค(์‹ค์ œ๋กœ ์ด๋“ค์„ object.motion ๋กœ ์ฐธ์กฐํ•ด์•ผ ํ•˜๋Š” ๋น„์šฉ ๋ถ€๋‹ด).

extends KinematicBody2D

onready var motion = $motion # ComponentMotion2D

์ด๊ฒƒ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ C#์—๋Š” ํด๋ž˜์Šค ์œ ํ˜•์˜ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜๋Š” ํ™•์žฅ ๋ฉ”์„œ๋“œ ๋ผ๋Š” ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ํ•จ์ˆ˜๋Š” ์ •์ ์ด์–ด์•ผ ํ•˜๋ฉฐ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํ•„์ˆ˜์ด๋ฉฐ self ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ •์˜๋กœ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

ํ™•์žฅ์ž.gd

# any script that uses this method must be an instance of `Node2D`
static func distance(self source: Node2D, target: Node2D):
    return source.global_position.distance_to(target.global_position)

# any script that uses this method must be an instance of `Rigidbody2D`
# a `Sprite` instance cannot use this method
static func distance(self source: Rigidbody2D, target: Node2D):
    return source.global_position.distance_to(target.global_position)

๊ทธ๋Ÿฐ ๋‹ค์Œ distance ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

ํ”Œ๋ ˆ์ด์–ด.gd

func _ready() -> void:
    print(self.distance($Enemy))
    print($BulletPoint.distance($Enemy))

๋‚˜๋Š” ๊ทธ๊ฒƒ์— ์ต์ˆ™ํ•˜์ง€๋งŒ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ๋„์›€์ด๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ—คํ—ค ๊ทธ๋ž˜๋„ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

@TheColorRed ํ™•์žฅ ๋ฐฉ๋ฒ•์€ ์ด๋ฏธ ์ œ์•ˆ๋˜์—ˆ์ง€๋งŒ ๋™์  ์–ธ์–ด์—์„œ๋Š” ์‹คํ˜„ ๊ฐ€๋Šฅํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋˜ํ•œ ๊ทธ๋“ค์ด ์ฒ˜์Œ์— ์ด ํ† ๋ก ์„ ์‹œ์ž‘ํ•œ ๊ทผ๋ณธ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


๋˜ ๋‹ค๋ฅธ ์ฐธ๊ณ  ์‚ฌํ•ญ์œผ๋กœ, GDScript์— ๋Œ€ํ•œ ๋งŽ์€ ์ œ์•ˆ์„ GIP๋กœ ์—ด ๊ฒƒ์ž…๋‹ˆ๋‹ค( @willnationsdev ๊ฐ€ ์ƒ๊ด€ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ํฌํ•จ๋จ).

๋‚˜๋Š” ์—ฌ์ „ํžˆ ํŠน์„ฑ์ด OO ์–ธ์–ด์—์„œ ์ˆ˜ํ‰์œผ๋กœ ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ํ•ฉ๋ฆฌ์ ์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค(๋‹ค์ค‘ ์ƒ์† ์—†์ด, ํ•˜์ง€๋งŒ ๊ทธ๋ ‡๊ฒŒ ๊ฐ€๊ณ  ์‹ถ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค).

๋™์  ์–ธ์–ด์—์„œ๋Š” ์‹คํ˜„ ๊ฐ€๋Šฅํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

GDS๋Š” ๋™์ ์ž…๋‹ˆ๊นŒ? ํ™•์žฅ ๋ฉ”์†Œ๋“œ๋Š” ์œ ํ˜•์ด ์ง€์ •๋œ ์ธ์Šคํ„ด์Šค๋กœ๋งŒ ์ œํ•œ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋‹ค๋ฅธ ์–ธ์–ด์—์„œ์™€ ์ •ํ™•ํžˆ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ ์ค‘ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ์„ ์ •์  ๋ฉ”์†Œ๋“œ(ํ•จ์ˆ˜) ํ˜ธ์ถœ๋กœ ๋Œ€์ฒดํ•˜๋Š” ๊ตฌ๋ฌธ ์„คํƒ•๋ฟ์ž…๋‹ˆ๋‹ค. ์†”์งํžˆ ๋งํ•ด์„œ, ์ €๋Š” ํ”„๋กœํ† ํƒ€์ž… ala JS ๋˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ํด๋ž˜์Šค ๋˜๋Š” ์‹ฌ์ง€์–ด ์ธ์Šคํ„ด์Šค์— ์—ฐ๊ฒฐํ•˜๋Š” ๋‹ค๋ฅธ ๋™์  ๋ฐฉ๋ฒ•๋ณด๋‹ค ๋จผ์ € ํฌ์ฃผ(ext. ๋ฉ”์†Œ๋“œ)๋ฅผ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ๋ฌด์—‡์„ ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜๋“ ์ง€ ์ด๋ฆ„์„ "ํฌ์ฃผ"๋กœ ์ง€์ •ํ•˜์ง€ ์•Š๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

GDS๋Š” ๋™์ ์ž…๋‹ˆ๊นŒ?

์ด ๋งฅ๋ฝ์—์„œ "๋™์ "์— ๋Œ€ํ•œ ๋งŽ์€ ์ •์˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ถ„๋ช…ํžˆ ํ•˜์ž๋ฉด, ๋ณ€์ˆ˜ ์œ ํ˜•์€ ์ปดํŒŒ์ผ ์‹œ๊ฐ„์— ์•Œ๋ ค์ง€์ง€ ์•Š์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋Ÿฐํƒ€์ž„์— ๋ฉ”์„œ๋“œ ํ™•์žฅ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ๋“  ์„ฑ๋Šฅ์ด ์ €ํ•˜๋จ).

ํ™•์žฅ ๋ฉ”์„œ๋“œ๋Š” ์œ ํ˜•์ด ์ง€์ •๋œ ์ธ์Šคํ„ด์Šค๋กœ๋งŒ ์ œํ•œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์ž‘์—…์„ ์‹œ์ž‘ํ•˜๋ฉด GDScript๋ฅผ ์œ ํ˜•๋งŒ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ๋‚ด๊ฐ€ ์—ฌ๊ธฐ์—์„œ ํ•˜์ง€ ๋ง์•„์•ผ ํ•  ์™„์ „ํžˆ ๋‹ค๋ฅธ ๋…ผ์˜์ž…๋‹ˆ๋‹ค.

์š”์ ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์Šคํฌ๋ฆฝํŠธ์— ์œ ํ˜•์„ ์ถ”๊ฐ€ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž‘์—…์ด ์‹œ์ž‘๋˜๊ฑฐ๋‚˜ ์ค‘์ง€๋˜์–ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿด ๋•Œ๋ฉด ๊ฑฐ์˜ ํ•ญ์ƒ ํ˜ผ๋ž€์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ, ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์–ด์จŒ๋“  ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋™์ผํ•œ ์ฝ”๋“œ๋ฅผ ์—ฌ๋Ÿฌ ์œ ํ˜•์— ์ฒจ๋ถ€ํ•˜๋ ค๊ณ  ํ•˜๋Š” ๋ฐ˜๋ฉด ํ™•์žฅ ๋ฉ”์„œ๋“œ๋Š” ํ•œ ์œ ํ˜•์—๋งŒ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

์†”์งํžˆ ๋งํ•ด์„œ, ์ €๋Š” ํ”„๋กœํ† ํƒ€์ž… ala JS ๋˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ํด๋ž˜์Šค ๋˜๋Š” ์‹ฌ์ง€์–ด ์ธ์Šคํ„ด์Šค์— ์—ฐ๊ฒฐํ•˜๋Š” ๋‹ค๋ฅธ ๋™์  ๋ฐฉ๋ฒ•๋ณด๋‹ค ๋จผ์ € ํฌ์ฃผ(ext. ๋ฉ”์†Œ๋“œ)๋ฅผ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

์•„๋ฌด๋„ (๋Ÿฐํƒ€์ž„์—) ๋ฉ”์„œ๋“œ๋ฅผ ๋™์ ์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์„ (์•„์ง) ์ œ์•ˆํ•˜์ง€ ์•Š์•˜์œผ๋ฉฐ ๋‚˜๋„ ์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŠน์„ฑ์€ ์ปดํŒŒ์ผ ์‹œ ์ •์ ์œผ๋กœ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

์›๋ž˜ Hax์™€ ๋ฏน์Šค์ธ ๋งคํฌ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด ์–ธ๊ธ‰ํ–ˆ์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๊ฐ€ ํƒ€์‚ฌ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ตœ๊ทผ์— ์ด๊ฒƒ์ด ํ•„์š”ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž๊ฐ€ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋™์ผํ•œ ๋ถ€๋ชจ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์—†๋Š” ์ผ๋ถ€ ๊ฐœ์ฒด๊ฐ€ ์žˆ์ง€๋งŒ ์œ ์‚ฌํ•œ API ๊ทธ๋ฃน์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋™์ผํ•œ ๋ถ€๋ชจ๋กœ๋ถ€ํ„ฐ ์ƒ์†ํ•  ์ˆ˜ ์—†์ง€๋งŒ ์œ ์‚ฌํ•œ API ์„ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ผ๋ถ€ ํด๋ž˜์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
์ฐฝ๊ณ : ์žฌ์ •, ์‚ญ์ œ, MouseInteraction + ๊ธฐํƒ€
์ฐจ๋Ÿ‰: ์žฌ์ •, ์‚ญ์ œ, MouseInteraction + ๊ธฐํƒ€
VehicleTerminal: ์žฌ์ •, ์‚ญ์ œ, MouseInteraction + ๊ธฐํƒ€

์žฌ์ •์˜ ๊ฒฝ์šฐ get_finances_component()๊ฐ€ ๊ฒŒ์ž„ ๊ฐœ์ฒด์— ๋Œ€ํ•ด ์ „ํ˜€ ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ถฉ๋ถ„ํ•œ API์ด๋ฏ€๋กœ ์ตœ์†Œํ•œ์˜ ์ƒ์šฉ๊ตฌ ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์‚ฌ๋žŒ:
MouseInteraction ๋ฐ Deection ๊ฒŒ์ž„ ๊ฐœ์ฒด์— ๋Œ€ํ•ด ์•Œ์•„์•ผ ํ•˜๋ฏ€๋กœ ๋ณต์‚ฌํ•˜์—ฌ ๋ถ™์—ฌ๋„ฃ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด์ƒํ•œ ์œ„์ž„์„ ํ•˜์ง€ ์•Š๋Š” ํ•œ ์ผ๋ถ€ ๊ตฌ์„ฑ์€ ์—ฌ๊ธฐ์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Warehouse:
  func delete():
      get_delete_component().delete(self);

๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์ด ์ƒ์†๋œ ํด๋ž˜์Šค๋ผ๋ฉด ํ•„์š”ํ•  ๊ฒฝ์šฐ ์‚ญ์ œ ์ฝ”๋“œ์˜ ์ผ๋ถ€๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์‚ญ์ œ ์ž‘๋™ ๋ฐฉ์‹์„ ์žฌ์ •์˜ํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.

๋งˆ์šฐ์Šค ์ƒํ˜ธ ์ž‘์šฉ ๋ฐ ์„ ํƒ ๊ฒŒ์ž„ ๊ฐœ์ฒด์— ๋Œ€ํ•ด ์•Œ์•„์•ผ ํ•˜๋ฏ€๋กœ ๋ณต์‚ฌํ•˜์—ฌ ๋ถ™์—ฌ๋„ฃ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด์ƒํ•œ ์œ„์ž„์„ ํ•˜์ง€ ์•Š๋Š” ํ•œ ์ผ๋ถ€ ๊ตฌ์„ฑ์€ ์—ฌ๊ธฐ์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ onready ๋…ธ๋“œ๋ฅผ ํ†ตํ•ด ๊ตฌ์„ฑ ์š”์†Œ์— ์•ก์„ธ์Šคํ•ฉ๋‹ˆ๋‹ค. ๋น„์Šทํ•œ ์ผ์„ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

# character.gd

var input = $input # input component

func _set(property, value):
    if property == "focused": # override
        input.enabled = value
    return true

๊ทธ๋ž˜์„œ ์ด๊ฑฐ:

character.input.enabled = true

๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฉ๋‹ˆ๋‹ค.

character.focused = true

@Calinou๊ฐ€ ์นœ์ ˆํ•˜๊ฒŒ ๋‚ด ๋ฌธ์ œ๋ฅผ ์ง€์ ํ–ˆ๋“ฏ์ด https://github.com/godotengine/godot-proposals/issues/758 ์€ ์ด๊ฒƒ๊ณผ ๋ฐ€์ ‘ํ•˜๊ฒŒ ๊ด€๋ จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฃน์— ํŠน์„ฑ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ œ์•ˆ์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ? ์ด๋กœ ์ธํ•ด ์Šคํฌ๋ฆฝํŠธ ๋ฐ ๊ธฐํƒ€ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ํฌ๊ฒŒ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ณต์œ  ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ๋ฅผ ํด๋ž˜์Šค์— ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ’์„ ๋‚ด๋ณด๋‚ธ ๊ฒฝ์šฐ ์ด๋Ÿฌํ•œ ๊ฐ’์ด ์ธ์ŠคํŽ™ํ„ฐ์— ํ‘œ์‹œ๋˜๊ณ  ๋ฉ”์„œ๋“œ์™€ ์†์„ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  ์ฝ”๋“œ ์™„์„ฑ์œผ๋กœ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Godot ์—”์ง„์— ๋Œ€ํ•œ ๊ธฐ๋Šฅ ๋ฐ ๊ฐœ์„  ์ œ์•ˆ์€ ํ˜„์žฌ ์ „์šฉ Godot ๊ฐœ์„  ์ œ์•ˆ(GIP) ( godotengine/godot-proposals ) ์ด์Šˆ ํŠธ๋ž˜์ปค์—์„œ ๋…ผ์˜๋˜๊ณ  ๊ฒ€ํ† ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. GIP ์ถ”์ ๊ธฐ์—๋Š” ์ œ์•ˆ์„œ์— ๋ชจ๋“  ๊ด€๋ จ ์ •๋ณด๊ฐ€ ํฌํ•จ๋˜์–ด ์ƒ์‚ฐ์ ์ธ ํ† ๋ก ์„ ์‹œ์ž‘ํ•˜๊ณ  ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ์—”์ง„ ์ œ์•ˆ์„œ์˜ ์œ ํšจ์„ฑ์„ ํ‰๊ฐ€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋„๋ก ์„ค๊ณ„๋œ ์ƒ์„ธํ•œ ๋ฌธ์ œ ํ…œํ”Œ๋ฆฟ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ( godotengine/godot ) ์ถ”์ ๊ธฐ๋Š” ์ด์ œ ์ „์ ์œผ๋กœ ๋ฒ„๊ทธ ๋ณด๊ณ ์„œ ๋ฐ ๋Œ์–ด์˜ค๊ธฐ ์š”์ฒญ ์ „์šฉ์ด๋ฏ€๋กœ ๊ธฐ์—ฌ์ž๊ฐ€ ๋ฒ„๊ทธ ์ˆ˜์ • ์ž‘์—…์— ๋” ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด์ œ ์ฃผ์š” ์ด์Šˆ ํŠธ๋ž˜์ปค์—์„œ ์ด์ „ ๊ธฐ๋Šฅ ์ œ์•ˆ์„ ๋ชจ๋‘ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ธฐ๋Šฅ ์ œ์•ˆ์— ๊ด€์‹ฌ์ด ์žˆ๋‹ค๋ฉด ์ฃผ์–ด์ง„ ๋ฌธ์ œ ํ…œํ”Œ๋ฆฟ ์— ๋”ฐ๋ผ GIP ํŠธ๋ž˜์ปค์—์„œ ์ƒˆ ์ œ์•ˆ์„ ์—ฌ์‹ญ์‹œ์˜ค (์ด๋ฏธ ์กด์žฌํ•˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธํ•œ ํ›„). ๊ด€๋ จ ํ† ๋ก ์ด ํฌํ•จ๋œ ๊ฒฝ์šฐ ์ด ๋‹ซํžŒ ๋ฌธ์ œ๋ฅผ ์ฐธ์กฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์ƒˆ ์ œ์•ˆ์—์„œ ์š”์•ฝํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค). ๋ฏธ๋ฆฌ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

์ฐธ๊ณ : ์ด๊ฒƒ์€ ์ธ๊ธฐ ์žˆ๋Š” ์ œ์•ˆ์ž…๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ ์ด๋ฅผ Godot ์ œ์•ˆ์œผ๋กœ ์˜ฎ๊ธฐ๋ฉด ํ† ๋ก ๋„ ์š”์•ฝํ•ด ๋ณด์„ธ์š”.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰