본문 바로가기
로블록스

로블록스에서의 모듈스크립트와 메타테이블 그리고 SetPrimaryPartCFrame 문제

by JK쌤 2023. 1. 7.

메타테이블을 만드는 방식은 여러가지이다. 프로그래밍을 배우는 것이 조금 어려운 점은 똑같이 기능하는 것이라도 표현을 다르게 쓸 수 있다는 것이다. 프로그래머의 편의를 위해서 간략히 쓸 수 있도록 지원을 하는 것인데, 입문자 입장에서는 그게 꽤나 진입장벽을 높이는 것이다. 게다가.. 사실 정확히 같은 기능을 하지 않을 때도 있다는 것이 문제.  

로블록스에서 메타테이블을 만들기 연습을 하다 SetPrimaryPartCFrame이 메타테이블안에서 작동하지 않는 점을 발견했다. 유튜브를 보면서 따라 했는데 2021년 4월에는 분명 작동을 했는데..-뭐 편집으로 작동하는 것처럼 보였을 수도 있지만 그런것 같지는 않았다.- 지금은 작동을 하지 않는다. 데브포럼을 뒤져보니 분명 그런 문제가 있었던 것 같기도 하다.

https://devforum.roblox.com/t/changing-player-position-not-working-in-a-metamethod/934699/2

 

Changing player position not working in a metamethod

There are no weird special limitations like these on metatables. The only thing I can think of is sending tables w/ metatables across server/client boundary, i.e. w/ RemoteEvents. That strips the metatable and just sends the plain table and IIRC is documen

devforum.roblox.com

일단 기록을 남겨둔다. 

작동하지 않은 스크립트.

Script

local Car = require(script.Parent.Car)

local c = Car:new(Model = workspace.CarModel)

c:Drive()

Car

local Engine = require(script.Parent.Engine)
local Wheel = require(script.Parent.Wheel)

local Car={}


Car.__index = Car

function Car.new()
	return setmetatable({
		Model = model,
		Engine = Engine.new(),
		Wheels = {
			Left = Wheel.new(),
			Right = Wheel.new(),
		}
	}, Car)
end

function Car:Drive()
	
	if not self.Wheels.Left.IsFlat and not self.Wheels.Right.IsFlat then
		self.Engine:TurnOn()
		print(self.Model)
		self.Model:SetPrimaryPartCFrame(CFrame.new(10,10,10))
		print("Your car is driving!")
	else
		warn("Your car's tires are flat!")
	end
end

return Car

Engine

local Engine = {}
Engine.__index = Engine

function Engine.new(speed)
	return setmetatable({
		Speed = speed,
		Fuel = 100,
		IsOn = false,
	}, Engine)
end

function Engine:TurnOn()
	self.IsOn = true
	print("Engine is running!")
end

return Engine

Wheel

local Wheel = {}
Wheel.__index = Wheel

function Wheel.new()
	return setmetatable({
		IsFlat = false,
		
	}, Wheel)
end

return Wheel

위와 같이 코드를 작성했을 때 SetPrimaryPartCFrame은 작동하지 않았다. 아래와 같이 메타테이블 만드는 방법을 'Script'와 'Car' 모듈스크립트를 바꾸어 주었더니 정상 작동했다.

Script

local Car = require(script.Parent.Car)

local c = Car:new({Model = workspace.CarModel})

c:Drive()

Car

local Engine = require(script.Parent.Engine)
local Wheel = require(script.Parent.Wheel)

local Car ={
	Model = nil,
	Engine = Engine.new({Speed = 10}),
	Wheel = {
		Left = Wheel.new(),
		Right = Wheel.new(),
	},
	
	new = function(self, o)
		o = o or {}
		setmetatable(o, self)
		self.__index = self
		return o

	end,
	
	Drive = function(self)
		if not self.Wheel.Left.IsFlat and not self.Wheel.Right.IsFlat then
			self.Engine:TurnOn()
			self.Model:SetPrimaryPartCFrame(CFrame.new(10,10,10))
			print("Your car is driving")
		else
			warn("Your car's tires are flat!")
		end
	end,
}

return Car

이제 응용들어가자.