04. 반응하기 — 이벤트
대상 독자: 03. 값이 흐르게 하기를 끝낸 개발자 목표: 버튼을 눌러 원천에 값을 넣고, 카운터를 완결시키기
03장에서는 값을 코드로 직접 :Set 했습니다. 이제 그 자리를 사용자의 클릭으로 바꿉니다.
지금까지의 코드
섹션 제목: “지금까지의 코드”-- (Main.client.luau 계속 — 카드를 화면 가운데 놓는 AnchorPoint/Position은 생략합니다.-- 03장 §2의 count:Set(7)과 §3에서 확인용으로 만든 suffix/both 줄은 지웁니다)const count = q.Source(0)
const countText: q.State<string> = count:Compute(function(c) return `카운트: {c:Get()}`end)
const card = q.Elem "Frame" { Size = UDim2.fromOffset(240, 160), BackgroundColor3 = Color3.fromRGB(35, 35, 42), UICorner = 12,
q.Elem "TextLabel" { Position = UDim2.fromOffset(16, 0), Size = UDim2.new(1, -32, 0, 48), BackgroundTransparency = 1, TextColor3 = Color3.fromRGB(255, 255, 255), TextScaled = true, Text = countText, },}countText 뒤의 : q.State<string>은 왜 붙어 있나요?
--!strict로 쓸 때를 위한 결과 타입 주석입니다. const countText = count:Compute(...)처럼 타입 없이 받으면 Luau의 현재 한계로 그 결과의 타입이 비어 버려, countText를 쓰는 이후 모든 코드의 타입 검사가 조용히 사라집니다 — Text에 숫자를 넣어도 진단이 뜨지 않으니 “strict를 통과했으니 타입이 맞다”고 믿게 되지만, 실제로는 그 지점부터 무검사입니다. 파생 State를 만드는 줄에 결과 타입을 적으면(: q.State<string>) 다시 검사가 살아납니다. 콜백 파라미터에 다는 주석(08·10장)과는 다른 자리입니다 — 이건 바인딩 그 자체입니다. 이 문서의 화면 코드는 기본 모드(--!nonstrict)라 지금 당장 필요하지는 않지만, 이 튜토리얼도 프로퍼티에 꽂는 파생 State에는 대개 이렇게 적어 둡니다(print로 확인만 하는 예제는 생략합니다).
1. 버튼 달기
섹션 제목: “1. 버튼 달기”card의 숫자 키 자리, 라벨 아래에 버튼을 하나 더합니다.
-- … card의 숫자 키 자리, 라벨 바로 아래에 이어집니다 q.Elem "TextButton" { Size = UDim2.new(1, -40, 0, 42), Position = UDim2.new(0, 20, 1, -62), BackgroundColor3 = Color3.fromRGB(0, 162, 255), TextColor3 = Color3.fromRGB(255, 255, 255), Text = "+ 1", TextSize = 16, UICorner = 8,
-- 이벤트도 문자 키 자리에 이름으로 적는다 Activated = function() count:Set(count:Get() + 1) end, },실행하면 버튼을 누를 때마다 위 라벨의 숫자가 하나씩 올라갑니다. 여기까지가 완결된 카운터입니다.
이벤트는 프로퍼티와 같은 자리(문자 키)에 씁니다. 그 이름이 프로퍼티인지 이벤트인지는 엔진 리플렉션이 판정하므로, Activated 같은 이름을 그대로 키로 쓰면 됩니다.
콜백엔 정확히 어떤 인자가 오나요?
콜백은 엔진이 주는 인자만 받습니다 — self도, 인스턴스도 앞에 붙지 않습니다. Activated라면 function(inputObject, clickCount)가 그대로 들어옵니다. 이 예제에서는 인자를 안 쓰니 빈 파라미터로 뒀습니다.
흐름을 다시 보면 이렇습니다.
클릭 → count:Set(n + 1) → :Compute 재계산 → Text 프로퍼티가 갱신버튼 콜백이 손대는 것은 원천 하나뿐입니다. 화면을 직접 고치는 코드는 어디에도 없습니다.
값이 바뀔 때 화면 밖에서 무언가 하는 길 — 로그를 찍거나, 소리를 내거나, 서버로 보내는 일 — 은 08. 관측하기에서 다룹니다. 반대 방향, 즉 엔진이 스스로 바꾼 프로퍼티(입력창의 Text, 스크롤의 CanvasPosition)를 다시 Source로 끌어올리는 것은 06. 다시 위로 올려보내기에서 봅니다.
이해 점검
섹션 제목: “이해 점검”이벤트를 적는 자리
Activated 같은 이벤트는 props의 어느 자리에 적나요?
- 프로퍼티와 같은 문자 키 자리에 이름으로 적습니다 — 프로퍼티인지 이벤트인지는 엔진 리플렉션이 판정합니다
- 자식과 같은 숫자 키 자리에 값으로 놓습니다 — 이름을 붙이면 프로퍼티로 읽힙니다
-
Events = { Activated = fn }처럼 이벤트 전용 문자 키 안에 모아 적습니다
이벤트는 프로퍼티와 같은 자리에 쓰고, 그 이름이 프로퍼티인지 이벤트인지는 엔진 리플렉션이 판정하므로 Activated 같은 이름을 그대로 키로 쓰면 됩니다.
이벤트 콜백이 받는 인자
문자 키 자리에 적은 Activated 콜백은 어떤 인자를 받나요?
- 첫 인자로 그 인스턴스가 오고, 그 뒤에 엔진이 주는 인자가 이어집니다
- 엔진이 주는 인자만 그대로 옵니다 —
Activated라면function(inputObject, clickCount)입니다 - 관측 대상의 핸들이 와서
:Get()으로 값을 꺼내 씁니다
콜백은 엔진이 주는 인자만 받고 self도 인스턴스도 앞에 붙지 않습니다. 이 장의 예제는 그 인자를 쓰지 않아 빈 파라미터로 두었습니다.
더 알고 싶다면
섹션 제목: “더 알고 싶다면”- 레퍼런스:
q.Elem— 문자 키 — 이벤트 값 자리에 올 수 있는 것, 콜백이 아닌 값을 넣었을 때의 에러 - 04. RemoteEvent와 엔진 입력을 상태로 브릿징하기 —
RemoteEvent·UserInputService를Source:Set으로 격리하기
퀴즈 진행 상황
0 / 0 답변한 문제 (0%)
0 정답
퀴즈 완료!
0%
0 / 0 정답
답변함: 0 / 0 (0%)