Adding advanced tween module for tweening objects and fixed some bukket error
This commit is contained in:
parent
f8bde6f4e8
commit
921af23d66
10 changed files with 529 additions and 91 deletions
|
|
@ -7,6 +7,15 @@
|
|||
"Quad": {
|
||||
"$path": "src"
|
||||
}
|
||||
},
|
||||
"StarterGui": {
|
||||
"$className": "StarterGui",
|
||||
"QuadTesting": {
|
||||
"$className": "ScreenGui",
|
||||
"testScript": {
|
||||
"$path": "testScript.client.lua"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
67
readme.lua
Normal file
67
readme.lua
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
-- 이렇게 모듈을 부를 수 있다, 뒤에 if 가 붇은것은 자동완성이 뜨도록 하기 위해서 사용된다
|
||||
---@module "src/init.lua"
|
||||
local quad = require(game.ReplicatedStorage:WaitForChild "Quad");
|
||||
local render = quad.init();
|
||||
-- init 함수를 이용해 여러 스크립트가 이 모듈을 호출해도 완전히 별계의
|
||||
-- 환경에서 실행될 수 있도록 만든다, init 를 호출하면 완전히 새로운 store 와 style
|
||||
-- 등을 가진 모듈을 새로 생성한다
|
||||
|
||||
-- 하위 모듈을 이렇게 부른다
|
||||
local class = render.class;
|
||||
local mount = render.mount;
|
||||
local store = render.store;
|
||||
|
||||
-- 오브젝트를 이렇게 불러온다
|
||||
local frame = class "Frame"; -- 이렇게 원하는 오브젝트를 불러올 수 있다
|
||||
local text = class "TextLabel";
|
||||
text.TextSize = 17; -- 이렇게 오브젝트의 기본값도 정할 수 있다
|
||||
text.Size = UDim2.new(1,0,0,30);
|
||||
local titleText = class "TextLabel";
|
||||
-- 당연 이렇게 똑같은 className 을 가진 오브젝트를 여러번 import 도 된다
|
||||
-- 다른 임포트에서 설정한 기본값은 여기에 적용되지 않는다
|
||||
|
||||
local gui = script.Parent;
|
||||
local app = mount(gui,frame "testFrame" { -- mount 로 트리를 마운트한다, 이후 app 에서 unmount 호출가능
|
||||
Size = UDim2.fromOffset(120,60);
|
||||
Position = UDim2.fromScale(0.5,0.5);
|
||||
AnchorPoint = Vector2.new(0.5,0.5);
|
||||
text "texts" { -- 이렇게 단순히 child 개체를 만들 수 있다
|
||||
Text = "We can make ui like this";
|
||||
};
|
||||
text "texts" {
|
||||
Position = UDim2.fromOffset(0,30);
|
||||
Text = "qweiufnwlqef";
|
||||
};
|
||||
titleText { -- 아이디를 명명하지 않아도 오브젝트를 바로 만들 수 있다
|
||||
Text = "test";
|
||||
};
|
||||
});
|
||||
|
||||
print(store.getObject("texts"));
|
||||
-- getObject 를 호출하면 해당 id 로 명명된 오브젝트중
|
||||
-- 가장 처음으로 생성된 객체를 반환한다
|
||||
store.getObjects("texts"):each(function(index,this)
|
||||
this.Text = "이렇게 모든 택스트를 한꺼번에 바꿀 수도 있습니다";
|
||||
end);
|
||||
-- getObjects 를 이용하면 해당 id 로 명명된 오브젝트가 담긴 array 를 가져온다
|
||||
-- for 을 돌릴 수 있지만 each 를 이용해 async 된 작업을 수행할 수 있다
|
||||
store.getObjects("texts"):eachSync(function(index,this)
|
||||
this.Text = "또한, 기본적으로 Aync 를 이용하기 때문에 순차적인 실행이 필요한 경우 Sync 를 붇여야합니다";
|
||||
end);
|
||||
-- sync 를 하면 일반 스크립트를 실행하는것 처럼 순차적으로 실행되도록 만들 수도 있다
|
||||
-- 이 때 순서는 먼저 생생된 순서이다, 항상 같음을 유지한다는 보장이 없으므로 순서가 중요한경우
|
||||
-- 직접 for 을 이용해 순서 검증을 한 뒤 task 를 수행해야한다
|
||||
|
||||
-- 이렇게 어떤 오브젝트를 가지고 task 수행하는 thread 를 만들 수 있다
|
||||
do local this = store.getObject("testFrame");
|
||||
spawn(function ()
|
||||
local flip = false;
|
||||
while wait(0.5) do
|
||||
flip = not flip;
|
||||
this.BackgroundTransparency = flip and 1 or 0;
|
||||
end
|
||||
end);
|
||||
end
|
||||
|
||||
app.unmount(); -- 트리의 객체들을 모두 파기한다, 플러그인에서 unload 같은곳에 쓰는 함수
|
||||
return app;
|
||||
|
|
@ -13,11 +13,14 @@ local module = {};
|
|||
|
||||
function module.init(shared)
|
||||
local new = {};
|
||||
local bind = shared.event.bind;
|
||||
local addObject = shared.store.addObject;
|
||||
local storeNew = shared.store.new;
|
||||
local mount = shared.mount;
|
||||
local getHolder = shared.mount.getHolder;
|
||||
local event = shared.event; ---@module "src.event"
|
||||
local bind = event.bind;
|
||||
local store = shared.store; ---@module "src.store"
|
||||
local addObject = store.addObject;
|
||||
local storeNew = store.new;
|
||||
local mount = shared.mount; ---@module "src.mount"
|
||||
local getHolder = mount.getHolder;
|
||||
local advancedTween = shared.advancedTween; ---@module "src.libs.AdvancedTween"
|
||||
|
||||
-- make object that from instance, class and more
|
||||
function new.make(ClassName,...) -- render object
|
||||
|
|
@ -89,15 +92,26 @@ function module.init(shared)
|
|||
end
|
||||
end
|
||||
local tween = value.tvalue;
|
||||
local from = value.fvalue;
|
||||
|
||||
-- adding event function
|
||||
local function regFn(newValue,store)
|
||||
if from then
|
||||
newValue = from[newValue];
|
||||
end
|
||||
if with then
|
||||
newValue = with(newValue,item,store);
|
||||
end
|
||||
item[index] = newValue;
|
||||
if tween then
|
||||
if not advancedTween then
|
||||
return wran "module 'AdvancedTween' needs to be loaded for tween properties but it is not founded on 'src.libs'. you should adding that to src.libs directory";
|
||||
end
|
||||
advancedTween.RunTween(item,tween,{[index] = newValue});
|
||||
else
|
||||
item[index] = newValue;
|
||||
end
|
||||
end
|
||||
value.register(regFn);
|
||||
value:register(regFn);
|
||||
|
||||
-- this is using hacky of roblox instance
|
||||
-- this is will keep reference from week table until
|
||||
|
|
@ -208,7 +222,7 @@ function module.init(shared)
|
|||
if child then
|
||||
for _,v in pairs(child) do
|
||||
if v then
|
||||
((type(v) == table and rawget(v,"__object") or v).Parent = object;
|
||||
((type(v) == "table") and rawget(v,"__object") or v).Parent = object;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
10
src/init.lua
10
src/init.lua
|
|
@ -24,15 +24,17 @@ frame{
|
|||
]]
|
||||
|
||||
local require = require(script.require);
|
||||
local event = require("event"); ---@module "src.event"
|
||||
local store = require("store"); ---@module "src.store"
|
||||
local event = require "event"; ---@module "src.event"
|
||||
local store = require "store"; ---@module "src.store"
|
||||
--local style = require("style");
|
||||
local class = require("class"); ---@module "src.class"
|
||||
local mount = require("mount"); ---@module "src.mount"
|
||||
local class = require "class"; ---@module "src.class"
|
||||
local mount = require "mount"; ---@module "src.mount"
|
||||
local _,advancedTween = pcall(require,"src.libs.AdvancedTween"); ---@module "src.libs.AdvancedTween"
|
||||
|
||||
function module.init()
|
||||
local this = {items = {}};
|
||||
|
||||
this.advancedTween = type(advancedTween) == "table" and advancedTween;
|
||||
this.event = event.init(this);
|
||||
this.store = store.init(this);
|
||||
--this.style = style.init(this);
|
||||
|
|
|
|||
23
src/libs/AdvancedTween/BezierCurves.lua
Normal file
23
src/libs/AdvancedTween/BezierCurves.lua
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
local module = {}
|
||||
|
||||
function Lerp(Alpha,Point1,Point2)
|
||||
return Point1 + ( (Point2 - Point1) * Alpha )
|
||||
end
|
||||
|
||||
function module.Bezier(Alpha,...)
|
||||
local New = {}
|
||||
local Len = #{...}
|
||||
|
||||
for i = 1,Len do
|
||||
if i ~= 1 then
|
||||
New[#New+1] = Lerp(Alpha,select(...,i-1),select(...,i))
|
||||
end
|
||||
end
|
||||
|
||||
if Len <= 2 then
|
||||
return New[1]
|
||||
end
|
||||
return module.Bezier(Alpha,unpack(New))
|
||||
end
|
||||
|
||||
return module
|
||||
75
src/libs/AdvancedTween/EasingFunctions.lua
Normal file
75
src/libs/AdvancedTween/EasingFunctions.lua
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
local EasingFunctions = {}
|
||||
|
||||
local function reverse(Index)
|
||||
return 1 - Index
|
||||
end
|
||||
|
||||
local Linear = {} do
|
||||
Linear.Run = function(Index)
|
||||
return Index
|
||||
end
|
||||
end
|
||||
EasingFunctions["Linear"] = Linear
|
||||
|
||||
local Circle = {} do
|
||||
Circle.Run = function(Index)
|
||||
return 1-((1-Index)^2)
|
||||
end
|
||||
end
|
||||
EasingFunctions["Circle"] = Circle
|
||||
|
||||
local Exp2 = {} do
|
||||
local MinIndex = -4
|
||||
local MaxIndex = 2
|
||||
local GetIndex = function(Index)
|
||||
return Index * (MaxIndex - MinIndex) + MinIndex
|
||||
end
|
||||
|
||||
local Min = math.exp(MinIndex)
|
||||
local Max = math.exp(MaxIndex) - Min
|
||||
|
||||
Exp2.Reverse = true
|
||||
Exp2.Run = function(Index)
|
||||
-- Index ; max = 1 min = 0
|
||||
return (math.exp(GetIndex(Index)) - Min) / Max
|
||||
end
|
||||
end
|
||||
EasingFunctions["Exp2"] = Exp2
|
||||
|
||||
local Exp4 = {} do
|
||||
local MinIndex = -4
|
||||
local MaxIndex = 4
|
||||
local GetIndex = function(Index)
|
||||
return Index * (MaxIndex - MinIndex) + MinIndex
|
||||
end
|
||||
|
||||
local Min = math.exp(MinIndex)
|
||||
local Max = math.exp(MaxIndex) - Min
|
||||
|
||||
Exp4.Reverse = true
|
||||
Exp4.Run = function(Index)
|
||||
-- Index ; max = 1 min = 0
|
||||
return (math.exp(GetIndex(Index)) - Min) / Max
|
||||
end
|
||||
end
|
||||
EasingFunctions["Exp4"] = Exp4
|
||||
|
||||
local Exp2Max4 = {} do
|
||||
local MinIndex = -2
|
||||
local MaxIndex = 4
|
||||
local GetIndex = function(Index)
|
||||
return Index * (MaxIndex - MinIndex) + MinIndex
|
||||
end
|
||||
|
||||
local Min = math.exp(MinIndex)
|
||||
local Max = math.exp(MaxIndex) - Min
|
||||
|
||||
Exp2Max4.Reverse = true
|
||||
Exp2Max4.Run = function(Index)
|
||||
-- Index ; max = 1 min = 0
|
||||
return (math.exp(GetIndex(Index)) - Min) / Max
|
||||
end
|
||||
end
|
||||
EasingFunctions["Exp2Max4"] = Exp2Max4
|
||||
|
||||
return EasingFunctions
|
||||
23
src/libs/AdvancedTween/Stepped.lua
Normal file
23
src/libs/AdvancedTween/Stepped.lua
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
local IsRoblox = version and version() or nil
|
||||
|
||||
-- 로블록스 이외의 다른 lua 플렛폼을 위한 바인드 스탭,
|
||||
-- 여기에다 프레임 앞에 실행되는 이벤트를 핸들링해서 StepFunction 을
|
||||
-- 연동해주면 됨,
|
||||
|
||||
-- 이 함수는 한 프레임마다 트윈들을 가져와서 실행시켜줌, (만약 트윈 효과가 하나도 없으면 그냥 건너뜀)
|
||||
|
||||
local module = {}
|
||||
function module.BindStep(StepFunction)
|
||||
if IsRoblox then
|
||||
local RunService = game:GetService("RunService")
|
||||
if RunService:IsStudio() and (not RunService:IsRunning()) and RunService:IsEdit() then
|
||||
RunService.Heartbeat:Connect(StepFunction)
|
||||
else
|
||||
RunService.Stepped:Connect(StepFunction)
|
||||
end
|
||||
else
|
||||
-- do something here
|
||||
end
|
||||
end
|
||||
|
||||
return module
|
||||
280
src/libs/AdvancedTween/init.lua
Normal file
280
src/libs/AdvancedTween/init.lua
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
local module = {}
|
||||
|
||||
------------------------------------
|
||||
-- 기본함수, 필요 모듈 가져오기
|
||||
------------------------------------
|
||||
local type = typeof or type
|
||||
local clock = os.clock
|
||||
local tonumber = tonumber
|
||||
|
||||
local script = script
|
||||
local EasingFunctions = require(script and script.EasingFunctions or "EasingFunctions")
|
||||
local Stepped = require(script and script.Stepped or "Stepped")
|
||||
|
||||
local BindedFunctions = {} -- 애니메이션을 위해 프레임에 연결된 함수들
|
||||
|
||||
module.PlayIndex = setmetatable({},{__mode = "k"}) -- 애니메이션 실행 스택 저장하기
|
||||
-- PlayIndex[Item][Property] = 0 or nil <= 트윈중이지 않은 속성
|
||||
-- PlayIndex[Item][Property] = 1... <= 트윈중인 속성
|
||||
|
||||
------------------------------------
|
||||
-- Easing 스타일
|
||||
------------------------------------
|
||||
module.EasingFunctions = {
|
||||
--// for Autocomplete
|
||||
Linear = EasingFunctions.Linear; --// 직선
|
||||
Circle = EasingFunctions.Circle; --// 사분원
|
||||
Exp2 = EasingFunctions.Exp2; --// 덜 가파른 지수 그래프
|
||||
Exp4 = EasingFunctions.Exp4; --// 더 가파른 지수 그래프
|
||||
Exp2Max4 = EasingFunctions.Exp2Max4; --// 적당히 가파른 지수 그래프
|
||||
}
|
||||
for i,v in pairs(EasingFunctions) do
|
||||
module.EasingFunctions[i] = v
|
||||
end
|
||||
|
||||
module.EasingDirection = {
|
||||
Out = "Out"; -- 반전된 방향
|
||||
In = "In" ; -- 기본방향
|
||||
}
|
||||
|
||||
------------------------------------
|
||||
-- Lerp 함수
|
||||
------------------------------------
|
||||
-- 이중 선형, Alpha 를 받아서 값을 구해옴
|
||||
function Lerp(start,goal,alpha)
|
||||
return start + ((goal - start) * alpha)
|
||||
end
|
||||
|
||||
-- 기본적으로 로블록스에 있는 클래스중, + - * / 과 같은 연산자 처리 메타 인덱스가 있는것들
|
||||
local DefaultItems = {
|
||||
["Vector2"] = true;
|
||||
["Vector3"] = true;
|
||||
["CFrame" ] = true;
|
||||
["number" ] = true;
|
||||
}
|
||||
|
||||
-- 예전 값,목표 값,알파를 주고 각각 해당하는 속성에 입력해줌
|
||||
-- 기본적으로 모든 속성값 적용은 여기에서 이루워짐
|
||||
function LerpProperties(Item,Old,New,Alpha)
|
||||
for Property,OldValue in pairs(Old) do
|
||||
local NewValue = New[Property]
|
||||
if NewValue ~= nil then
|
||||
local Type = type(OldValue)
|
||||
if DefaultItems[Type] then
|
||||
Item[Property] = Lerp(OldValue,NewValue,Alpha)
|
||||
elseif Type == "UDim2" then
|
||||
Item[Property] = UDim2.new(
|
||||
Lerp(OldValue.X.Scale ,NewValue.X.Scale ,Alpha),
|
||||
Lerp(OldValue.X.Offset,NewValue.X.Offset,Alpha),
|
||||
Lerp(OldValue.Y.Scale ,NewValue.Y.Scale ,Alpha),
|
||||
Lerp(OldValue.Y.Offset,NewValue.Y.Offset,Alpha)
|
||||
)
|
||||
elseif Type == "UDim" then
|
||||
Item[Property] = UDim.new(
|
||||
Lerp(OldValue.Scale ,NewValue.Scale ),
|
||||
Lerp(OldValue.Offset,NewValue.Offset)
|
||||
)
|
||||
elseif Type == "Color3" then
|
||||
Item[Property] = Color3.fromRGB(
|
||||
Lerp(OldValue.r*255,NewValue.r*255),
|
||||
Lerp(OldValue.g*255,NewValue.g*255),
|
||||
Lerp(OldValue.b*255,NewValue.b*255)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------
|
||||
-- 모듈 함수 지정
|
||||
------------------------------------
|
||||
-- 트윈 메서드 지정, 트윈을 만들게 됨
|
||||
-- Item : 트윈할 인스턴트
|
||||
-- Data : 트윈 정보들 (태이블)
|
||||
--Data.Time (in seconds, you can use 0.5 .. etc)
|
||||
--Data.Easing (function)
|
||||
--Data.Direction ("Out" , "In")
|
||||
--Data.CallBack 콜백 함수들(태이블), 예시 :
|
||||
--Data.CallBack[0.5] = function() end 다음과 같이 쓰면 인덱스가 정확히 0.5 가 되는 순간(시간이 아니라 이징 함수에 의해 나온 값이 같아지는 순간)
|
||||
--해당 함수가 실행됨
|
||||
--Properties : 트윈할 속성과 목표값 예시 :
|
||||
--Data.Properties.Position = UDim2.new(1,0,1,0) 처럼 하면 Position 속성의 목표를 1,0,1,0 으로 지정
|
||||
function module.RunTween(Item,Data,Properties,Ended)
|
||||
-- 시간 저장
|
||||
local Time = Data.Time or 1
|
||||
local EndTime = clock() + Time
|
||||
|
||||
-- 플레이 인덱스 저장
|
||||
local ThisPlayIndex = module.PlayIndex[Item] or {}
|
||||
module.PlayIndex[Item] = ThisPlayIndex
|
||||
|
||||
-- 예전의 트윈을 덮어쓰고 현재 값을 저장함
|
||||
local NowAnimationIndex = {}
|
||||
local LastProperties = {}
|
||||
for Property,_ in pairs(Properties) do
|
||||
LastProperties[Property] = Item[Property]
|
||||
ThisPlayIndex[Property] = ThisPlayIndex[Property] ~= nil and ThisPlayIndex[Property] + 1 or 1
|
||||
NowAnimationIndex[Property] = ThisPlayIndex[Property]
|
||||
end
|
||||
|
||||
-- 이징 효과 가져오기
|
||||
local Direction = Data.Direction or "Out"
|
||||
local Easing do
|
||||
local Data_Easing = Data.Easing or EasingFunctions.Exp2
|
||||
local Data_EasingType = type(Data_Easing)
|
||||
Easing = (Data_EasingType == "function" and Data_Easing) or (Data_EasingType == "table" and Data_Easing.Run)
|
||||
if Data_EasingType == "table" and Data_Easing.Reverse then
|
||||
Direction = Direction == "Out" and "In" or "Out"
|
||||
end
|
||||
end
|
||||
|
||||
-- 중간중간 실행되는 함수 확인
|
||||
local CallBack = Data.CallBack
|
||||
if CallBack then
|
||||
for FncIndex,Fnc in pairs(CallBack) do
|
||||
if type(Fnc) ~= "function" or type(tonumber(FncIndex)) ~= "number" then
|
||||
CallBack[FncIndex] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
-- 스탭핑
|
||||
local Step
|
||||
Step = function()
|
||||
-- 아에 멈추게 되는 경우
|
||||
if module.PlayIndex[Item] == nil then
|
||||
table.remove(BindedFunctions,table.find(BindedFunctions,Step))
|
||||
return
|
||||
end
|
||||
|
||||
local Now = clock()
|
||||
local Index = 1 - (EndTime - Now) / Time
|
||||
|
||||
-- 속성 Lerp 수행
|
||||
if Direction == "Out" then
|
||||
LerpProperties(
|
||||
Item,
|
||||
LastProperties,
|
||||
Properties,
|
||||
Easing(Index)
|
||||
)
|
||||
else
|
||||
LerpProperties(
|
||||
Item,
|
||||
LastProperties,
|
||||
Properties,
|
||||
1 - Easing(1 - Index)
|
||||
)
|
||||
end
|
||||
|
||||
-- 다른 트윈이 속성을 바꾸고 있다면(이후 트윈이) 그 속성을 건들지 않도록 없엠
|
||||
local StopByOther = true
|
||||
for Property,Index in pairs(NowAnimationIndex) do
|
||||
if Index ~= ThisPlayIndex[Property] then
|
||||
LastProperties[Property] = nil
|
||||
Properties[Property] = nil
|
||||
NowAnimationIndex[Property] = nil
|
||||
else
|
||||
StopByOther = false
|
||||
end
|
||||
end
|
||||
|
||||
-- 만약 다른 트윈이 지금 트윈하고 있는 속성을 모두 먹은경우 현재 트윈을 삭제함
|
||||
if StopByOther then
|
||||
table.remove(BindedFunctions,table.find(BindedFunctions,Step))
|
||||
return
|
||||
end
|
||||
|
||||
-- 끝남
|
||||
if Now >= EndTime then
|
||||
for Property,_ in pairs(Properties) do
|
||||
ThisPlayIndex[Property] = 0
|
||||
end
|
||||
|
||||
local PlayIndexLen = 0
|
||||
for _,_ in pairs(ThisPlayIndex) do
|
||||
PlayIndexLen = PlayIndexLen + 1
|
||||
end
|
||||
if PlayIndexLen == 0 then
|
||||
ThisPlayIndex = nil
|
||||
end
|
||||
|
||||
table.remove(BindedFunctions,table.find(BindedFunctions,Step))
|
||||
Index = 1
|
||||
if Ended then
|
||||
Ended()
|
||||
end
|
||||
end
|
||||
|
||||
-- 중간 중간 함수 배정된것 실행
|
||||
if CallBack then
|
||||
for FncIndex,Fnc in pairs(CallBack) do
|
||||
if tonumber(FncIndex) <= Index then
|
||||
Fnc()
|
||||
CallBack[FncIndex] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 스캐줄에 등록
|
||||
table.insert(BindedFunctions,Step)
|
||||
end
|
||||
|
||||
-- 여러개의 개체를 트윈시킴
|
||||
function module.RunTweens(Items,Data,Properties,Ended)
|
||||
local First = true
|
||||
for _,Item in pairs(Items) do
|
||||
module.RunTween(Item,Data,Properties,First and Ended)
|
||||
First = false
|
||||
end
|
||||
end
|
||||
|
||||
-- 트윈 멈추기
|
||||
function module.StopTween(Item)
|
||||
module.PlayIndex[Item] = nil
|
||||
end
|
||||
|
||||
-- 해당 개체가 트윈중인지 반환
|
||||
function module.IsTweening(Item)
|
||||
if module.PlayIndex[Item] == nil then
|
||||
return false
|
||||
end
|
||||
|
||||
for Property,Index in pairs(module.PlayIndex[Item]) do
|
||||
if Index ~= 0 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- 해당 개체의 해당 프로퍼티가 트윈중인지 반환
|
||||
function module.IsPropertyTweening(Item,PropertyName)
|
||||
if module.PlayIndex[Item] == nil then
|
||||
return false
|
||||
end
|
||||
|
||||
if module.PlayIndex[Item][PropertyName] == nil then
|
||||
return false
|
||||
end
|
||||
|
||||
return module.PlayIndex[Item][PropertyName] ~= 0
|
||||
end
|
||||
|
||||
------------------------------------
|
||||
-- 프레임 연결
|
||||
------------------------------------
|
||||
-- 1 프레임마다 실행되도록 해야되는 함수
|
||||
-- ./Stepped.lua 에서 연결점 편집 가능
|
||||
-- roblox 는 이미 연결되어 있음
|
||||
function module.Stepped()
|
||||
if not BindedFunctions[1] then
|
||||
return;
|
||||
end
|
||||
for _,Function in ipairs(BindedFunctions) do
|
||||
Function()
|
||||
end
|
||||
end
|
||||
Stepped.BindStep(module.Stepped)
|
||||
|
||||
return module
|
||||
|
|
@ -84,6 +84,25 @@ function module.init(shared)
|
|||
end
|
||||
end
|
||||
|
||||
local registerMt = {
|
||||
register = function (s,efunc)
|
||||
insert(s.event,efunc);
|
||||
end;
|
||||
with = function (s,efunc)
|
||||
return setmetatable({wfunc = efunc},{__index = s});
|
||||
end;
|
||||
default = function (s,value)
|
||||
return setmetatable({dvalue = value},{__index = s});
|
||||
end;
|
||||
tween = function (s,value)
|
||||
return setmetatable({tvalue = value},{__index = s});
|
||||
end;
|
||||
from = function (s,value)
|
||||
return setmetatable({fvalue = value},{__index = s});
|
||||
end;
|
||||
};
|
||||
registerMt.__index = registerMt;
|
||||
|
||||
-- bindable store object
|
||||
local store = {};
|
||||
function store:__index(key)
|
||||
|
|
@ -103,23 +122,12 @@ function module.init(shared)
|
|||
if not register then
|
||||
local event = setmetatable({},week);
|
||||
self.__evt[key] = event;
|
||||
register = {
|
||||
register = function (efunc)
|
||||
insert(event,efunc);
|
||||
end;
|
||||
with = function (s,efunc)
|
||||
return setmetatable({wfunc = efunc},{__index = s});
|
||||
end;
|
||||
default = function (s,value)
|
||||
return setmetatable({dvalue = value},{__index = s});
|
||||
end;
|
||||
tween = function (s,value)
|
||||
return setmetatable({tvalue = value},{__index = s});
|
||||
end;
|
||||
register = setmetatable({
|
||||
event = event;
|
||||
key = key;
|
||||
store = self;
|
||||
t = "reg";
|
||||
};
|
||||
},registerMt);
|
||||
self.__reg[key] = register;
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,67 +1,4 @@
|
|||
-- 이렇게 모듈을 부를 수 있다, 뒤에 if 가 붇은것은 자동완성이 뜨도록 하기 위해서 사용된다
|
||||
---@module "src/init.lua"
|
||||
local quad = require(game.ReplicatedStorage:WaitForChild "Quad");
|
||||
local render = quad.init();
|
||||
-- init 함수를 이용해 여러 스크립트가 이 모듈을 호출해도 완전히 별계의
|
||||
-- 환경에서 실행될 수 있도록 만든다, init 를 호출하면 완전히 새로운 store 와 style
|
||||
-- 등을 가진 모듈을 새로 생성한다
|
||||
local Quad = require(game.ReplicatedStorage:WaitForChild "Quad"); ---@module "src"
|
||||
local _ = Quad.init(); local class,mount,store,event,advancedTween = _.class,_.mount,_.store,_.event,_.advancedTween;
|
||||
|
||||
-- 하위 모듈을 이렇게 부른다
|
||||
local class = render.class;
|
||||
local mount = render.mount;
|
||||
local store = render.store;
|
||||
|
||||
-- 오브젝트를 이렇게 불러온다
|
||||
local frame = class "Frame"; -- 이렇게 원하는 오브젝트를 불러올 수 있다
|
||||
local text = class "TextLabel";
|
||||
text.TextSize = 17; -- 이렇게 오브젝트의 기본값도 정할 수 있다
|
||||
text.Size = UDim2.new(1,0,0,30);
|
||||
local titleText = class "TextLabel";
|
||||
-- 당연 이렇게 똑같은 className 을 가진 오브젝트를 여러번 import 도 된다
|
||||
-- 다른 임포트에서 설정한 기본값은 여기에 적용되지 않는다
|
||||
|
||||
local gui = script.Parent;
|
||||
local app = mount(gui,frame "testFrame" { -- mount 로 트리를 마운트한다, 이후 app 에서 unmount 호출가능
|
||||
Size = UDim2.fromOffset(120,60);
|
||||
Position = UDim2.fromScale(0.5,0.5);
|
||||
AnchorPoint = Vector2.new(0.5,0.5);
|
||||
text "texts" { -- 이렇게 단순히 child 개체를 만들 수 있다
|
||||
Text = "We can make ui like this";
|
||||
};
|
||||
text "texts" {
|
||||
Position = UDim2.fromOffset(0,30);
|
||||
Text = "qweiufnwlqef";
|
||||
};
|
||||
titleText { -- 아이디를 명명하지 않아도 오브젝트를 바로 만들 수 있다
|
||||
Text = "test";
|
||||
};
|
||||
});
|
||||
|
||||
print(store.getObject("texts"));
|
||||
-- getObject 를 호출하면 해당 id 로 명명된 오브젝트중
|
||||
-- 가장 처음으로 생성된 객체를 반환한다
|
||||
store.getObjects("texts"):each(function(index,this)
|
||||
this.Text = "이렇게 모든 택스트를 한꺼번에 바꿀 수도 있습니다";
|
||||
end);
|
||||
-- getObjects 를 이용하면 해당 id 로 명명된 오브젝트가 담긴 array 를 가져온다
|
||||
-- for 을 돌릴 수 있지만 each 를 이용해 async 된 작업을 수행할 수 있다
|
||||
store.getObjects("texts"):eachSync(function(index,this)
|
||||
this.Text = "또한, 기본적으로 Aync 를 이용하기 때문에 순차적인 실행이 필요한 경우 Sync 를 붇여야합니다";
|
||||
end);
|
||||
-- sync 를 하면 일반 스크립트를 실행하는것 처럼 순차적으로 실행되도록 만들 수도 있다
|
||||
-- 이 때 순서는 먼저 생생된 순서이다, 항상 같음을 유지한다는 보장이 없으므로 순서가 중요한경우
|
||||
-- 직접 for 을 이용해 순서 검증을 한 뒤 task 를 수행해야한다
|
||||
|
||||
-- 이렇게 어떤 오브젝트를 가지고 task 수행하는 thread 를 만들 수 있다
|
||||
do local this = store.getObject("testFrame");
|
||||
spawn(function ()
|
||||
local flip = false;
|
||||
while wait(0.5) do
|
||||
flip = not flip;
|
||||
this.BackgroundTransparency = flip and 1 or 0;
|
||||
end
|
||||
end);
|
||||
end
|
||||
|
||||
app.unmount(); -- 트리의 객체들을 모두 파기한다, 플러그인에서 unload 같은곳에 쓰는 함수
|
||||
return app;
|
||||
Loading…
Reference in a new issue