更新
This commit is contained in:
parent
678c6035a9
commit
11ddf9fe1f
Binary file not shown.
BIN
excel/anim.xlsx
BIN
excel/anim.xlsx
Binary file not shown.
Binary file not shown.
BIN
excel/enemy.xlsx
BIN
excel/enemy.xlsx
Binary file not shown.
BIN
excel/level.xlsx
BIN
excel/level.xlsx
Binary file not shown.
@ -1,3 +1,4 @@
|
||||
[
|
||||
{"id":20000,"type":1,"icon":1,"behaviourName":"SwordWave","upgradeCost":[30000,5,10],"upgradeValue":[10,200],"recycle":[30000,100]}
|
||||
{"id":20000,"type":1,"icon":1,"behaviourName":"Attack","upgradeCost":[30000,5,0],"upgradeValue":[10,0],"recycle":[30000,0]},
|
||||
{"id":20001,"type":1,"icon":1,"behaviourName":"SwordWave","upgradeCost":[30000,5,10],"upgradeValue":[10,200],"recycle":[30000,100]}
|
||||
]
|
@ -1,3 +1,4 @@
|
||||
[
|
||||
{"id":1,"name":"SwordWave","rbxId":"133335766636767","priority":"Action"}
|
||||
{"id":1,"name":"SwordWave","rbxId":"133335766636767","priority":"Action"},
|
||||
{"id":2,"name":"Attack","rbxId":"17283773476","priority":"Action"}
|
||||
]
|
@ -14,7 +14,7 @@
|
||||
{"id":13,"type":1,"effectAttribute":"shadowDef","battleValue":[1,10],"iconId":13},
|
||||
{"id":14,"type":2,"effectAttribute":"attackRate","battleValue":[1,10],"iconId":14},
|
||||
{"id":15,"type":2,"effectAttribute":"hpRate","battleValue":[1,10],"iconId":15},
|
||||
{"id":16,"type":2,"effectAttribute":"atkSpeed","battleValue":[1,10],"iconId":16},
|
||||
{"id":16,"type":1,"effectAttribute":"atkSpeed","battleValue":[1,10],"iconId":16},
|
||||
{"id":20,"type":2,"effectAttribute":"critRate","battleValue":[1,10],"iconId":17},
|
||||
{"id":21,"type":2,"effectAttribute":"critDamageRate","battleValue":[1,10],"iconId":18},
|
||||
{"id":22,"type":2,"effectAttribute":"atkSpeedRate","battleValue":[1,10],"iconId":19},
|
||||
|
@ -1,5 +1,5 @@
|
||||
[
|
||||
{"id":1,"type":1,"name":1,"attack":83,"hp":400,"walkSpeed":10,"attackSpeed":1,"model":"Thief"},
|
||||
{"id":2,"type":1,"name":2,"attack":30,"hp":300,"walkSpeed":10,"attackSpeed":1,"model":"Thief"},
|
||||
{"id":1000,"type":2,"name":1000,"attack":240,"hp":2000,"walkSpeed":20,"attackSpeed":1,"model":"Thief"}
|
||||
{"id":1,"type":1,"name":1,"attack":83,"hp":400,"walkSpeed":8,"attackSpeed":1,"model":"Thief"},
|
||||
{"id":2,"type":1,"name":2,"attack":30,"hp":300,"walkSpeed":8,"attackSpeed":1,"model":"Thief"},
|
||||
{"id":1000,"type":2,"name":1000,"attack":240,"hp":2000,"walkSpeed":4,"attackSpeed":1,"model":"Thief"}
|
||||
]
|
@ -1,52 +1,52 @@
|
||||
[
|
||||
{"id":1,"type":1,"timeLimit":null,"atkBonus":500,"hpBonus":500,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":2,"type":1,"timeLimit":null,"atkBonus":520,"hpBonus":520,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":3,"type":1,"timeLimit":null,"atkBonus":540,"hpBonus":540,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":4,"type":1,"timeLimit":null,"atkBonus":560,"hpBonus":560,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":1,"type":1,"timeLimit":null,"atkBonus":500,"hpBonus":500,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":2,"type":1,"timeLimit":null,"atkBonus":520,"hpBonus":520,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":3,"type":1,"timeLimit":null,"atkBonus":540,"hpBonus":540,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":4,"type":1,"timeLimit":null,"atkBonus":560,"hpBonus":560,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":5,"type":2,"timeLimit":60,"atkBonus":1050,"hpBonus":1050,"wave":[[10,1000,1]]},
|
||||
{"id":6,"type":1,"timeLimit":null,"atkBonus":600,"hpBonus":600,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":7,"type":1,"timeLimit":null,"atkBonus":620,"hpBonus":620,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":8,"type":1,"timeLimit":null,"atkBonus":640,"hpBonus":640,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":9,"type":1,"timeLimit":null,"atkBonus":660,"hpBonus":660,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":6,"type":1,"timeLimit":null,"atkBonus":600,"hpBonus":600,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":7,"type":1,"timeLimit":null,"atkBonus":620,"hpBonus":620,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":8,"type":1,"timeLimit":null,"atkBonus":640,"hpBonus":640,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":9,"type":1,"timeLimit":null,"atkBonus":660,"hpBonus":660,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":10,"type":2,"timeLimit":60,"atkBonus":1100,"hpBonus":1100,"wave":[[10,1000,1]]},
|
||||
{"id":11,"type":1,"timeLimit":null,"atkBonus":700,"hpBonus":700,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":12,"type":1,"timeLimit":null,"atkBonus":720,"hpBonus":720,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":13,"type":1,"timeLimit":null,"atkBonus":740,"hpBonus":740,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":14,"type":1,"timeLimit":null,"atkBonus":760,"hpBonus":760,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":11,"type":1,"timeLimit":null,"atkBonus":700,"hpBonus":700,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":12,"type":1,"timeLimit":null,"atkBonus":720,"hpBonus":720,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":13,"type":1,"timeLimit":null,"atkBonus":740,"hpBonus":740,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":14,"type":1,"timeLimit":null,"atkBonus":760,"hpBonus":760,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":15,"type":2,"timeLimit":60,"atkBonus":1150,"hpBonus":1150,"wave":[[10,1000,1]]},
|
||||
{"id":16,"type":1,"timeLimit":null,"atkBonus":800,"hpBonus":800,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":17,"type":1,"timeLimit":null,"atkBonus":820,"hpBonus":820,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":18,"type":1,"timeLimit":null,"atkBonus":840,"hpBonus":840,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":19,"type":1,"timeLimit":null,"atkBonus":860,"hpBonus":860,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":16,"type":1,"timeLimit":null,"atkBonus":800,"hpBonus":800,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":17,"type":1,"timeLimit":null,"atkBonus":820,"hpBonus":820,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":18,"type":1,"timeLimit":null,"atkBonus":840,"hpBonus":840,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":19,"type":1,"timeLimit":null,"atkBonus":860,"hpBonus":860,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":20,"type":2,"timeLimit":60,"atkBonus":1250,"hpBonus":1250,"wave":[[10,1000,1]]},
|
||||
{"id":21,"type":1,"timeLimit":null,"atkBonus":900,"hpBonus":900,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":22,"type":1,"timeLimit":null,"atkBonus":920,"hpBonus":920,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":23,"type":1,"timeLimit":null,"atkBonus":940,"hpBonus":940,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":24,"type":1,"timeLimit":null,"atkBonus":960,"hpBonus":960,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":21,"type":1,"timeLimit":null,"atkBonus":900,"hpBonus":900,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":22,"type":1,"timeLimit":null,"atkBonus":920,"hpBonus":920,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":23,"type":1,"timeLimit":null,"atkBonus":940,"hpBonus":940,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":24,"type":1,"timeLimit":null,"atkBonus":960,"hpBonus":960,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":25,"type":2,"timeLimit":60,"atkBonus":1350,"hpBonus":1350,"wave":[[10,1000,1]]},
|
||||
{"id":26,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":27,"type":1,"timeLimit":null,"atkBonus":1020,"hpBonus":1020,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":28,"type":1,"timeLimit":null,"atkBonus":1040,"hpBonus":1040,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":29,"type":1,"timeLimit":null,"atkBonus":1060,"hpBonus":1060,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":26,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":27,"type":1,"timeLimit":null,"atkBonus":1020,"hpBonus":1020,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":28,"type":1,"timeLimit":null,"atkBonus":1040,"hpBonus":1040,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":29,"type":1,"timeLimit":null,"atkBonus":1060,"hpBonus":1060,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":30,"type":2,"timeLimit":60,"atkBonus":1500,"hpBonus":1500,"wave":[[10,1000,1]]},
|
||||
{"id":31,"type":1,"timeLimit":null,"atkBonus":1100,"hpBonus":1100,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":32,"type":1,"timeLimit":null,"atkBonus":1120,"hpBonus":1120,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":33,"type":1,"timeLimit":null,"atkBonus":1140,"hpBonus":1140,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":34,"type":1,"timeLimit":null,"atkBonus":1160,"hpBonus":1160,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":31,"type":1,"timeLimit":null,"atkBonus":1100,"hpBonus":1100,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":32,"type":1,"timeLimit":null,"atkBonus":1120,"hpBonus":1120,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":33,"type":1,"timeLimit":null,"atkBonus":1140,"hpBonus":1140,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":34,"type":1,"timeLimit":null,"atkBonus":1160,"hpBonus":1160,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":35,"type":2,"timeLimit":60,"atkBonus":2000,"hpBonus":2000,"wave":[[10,1000,1]]},
|
||||
{"id":36,"type":1,"timeLimit":null,"atkBonus":1200,"hpBonus":1200,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":37,"type":1,"timeLimit":null,"atkBonus":1220,"hpBonus":1220,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":38,"type":1,"timeLimit":null,"atkBonus":1240,"hpBonus":1240,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":39,"type":1,"timeLimit":null,"atkBonus":1260,"hpBonus":1260,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":36,"type":1,"timeLimit":null,"atkBonus":1200,"hpBonus":1200,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":37,"type":1,"timeLimit":null,"atkBonus":1220,"hpBonus":1220,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":38,"type":1,"timeLimit":null,"atkBonus":1240,"hpBonus":1240,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":39,"type":1,"timeLimit":null,"atkBonus":1260,"hpBonus":1260,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":40,"type":2,"timeLimit":60,"atkBonus":2500,"hpBonus":2500,"wave":[[10,1000,1]]},
|
||||
{"id":41,"type":1,"timeLimit":null,"atkBonus":1300,"hpBonus":1300,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":42,"type":1,"timeLimit":null,"atkBonus":1320,"hpBonus":1320,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":43,"type":1,"timeLimit":null,"atkBonus":1340,"hpBonus":1340,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":44,"type":1,"timeLimit":null,"atkBonus":1360,"hpBonus":1360,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":41,"type":1,"timeLimit":null,"atkBonus":1300,"hpBonus":1300,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":42,"type":1,"timeLimit":null,"atkBonus":1320,"hpBonus":1320,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":43,"type":1,"timeLimit":null,"atkBonus":1340,"hpBonus":1340,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":44,"type":1,"timeLimit":null,"atkBonus":1360,"hpBonus":1360,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":45,"type":2,"timeLimit":60,"atkBonus":3000,"hpBonus":3000,"wave":[[10,1000,1]]},
|
||||
{"id":46,"type":1,"timeLimit":null,"atkBonus":1400,"hpBonus":1400,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":47,"type":1,"timeLimit":null,"atkBonus":1420,"hpBonus":1420,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":48,"type":1,"timeLimit":null,"atkBonus":1440,"hpBonus":1440,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":49,"type":1,"timeLimit":null,"atkBonus":1460,"hpBonus":1460,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":46,"type":1,"timeLimit":null,"atkBonus":1400,"hpBonus":1400,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":47,"type":1,"timeLimit":null,"atkBonus":1420,"hpBonus":1420,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":48,"type":1,"timeLimit":null,"atkBonus":1440,"hpBonus":1440,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":49,"type":1,"timeLimit":null,"atkBonus":1460,"hpBonus":1460,"wave":[[10,1,1,50,1,1]]},
|
||||
{"id":50,"type":2,"timeLimit":60,"atkBonus":3500,"hpBonus":3500,"wave":[[10,1000,1]]}
|
||||
]
|
48
src/ReplicatedStorage/Modules/BehavioursClient/Attack.luau
Normal file
48
src/ReplicatedStorage/Modules/BehavioursClient/Attack.luau
Normal file
@ -0,0 +1,48 @@
|
||||
-- 剑气
|
||||
|
||||
--> Services
|
||||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||
|
||||
--> Dependencies
|
||||
local BehaviourClient = require(ReplicatedStorage.Base.BehaviourClient)
|
||||
|
||||
--> Variables
|
||||
local PrefabFolder = ReplicatedStorage:WaitForChild("Prefabs")
|
||||
-- local Prefab_Attack = PrefabFolder:WaitForChild("Projectiles"):WaitForChild("Attack")
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local Attack = {}
|
||||
Attack.__index = Attack
|
||||
setmetatable(Attack, {__index = BehaviourClient})
|
||||
|
||||
function Attack:Init(CasterPlayer: Player, CastInfo: table, DelayTime: number, CastState: boolean)
|
||||
local self = BehaviourClient:Init(CasterPlayer, CastInfo, DelayTime, CastState)
|
||||
setmetatable(self, Attack)
|
||||
|
||||
-- 加载动画
|
||||
self:LoadAnimationByName("Attack")
|
||||
return self
|
||||
end
|
||||
|
||||
function Attack:Show(CasterPlayer: Player, CastInfo: table, DelayTime: number, CastState: boolean)
|
||||
self.EffectDispatcher:ShowAnimation(self.Player, DelayTime, self:GetAnimationByName("Attack"))
|
||||
end
|
||||
|
||||
function Attack:Destroy()
|
||||
if self.ShowTask then
|
||||
task.cancel(self.ShowTask)
|
||||
self.ShowTask = nil
|
||||
end
|
||||
if self.Tween then
|
||||
self.Tween:Cancel()
|
||||
self.Tween = nil
|
||||
end
|
||||
if self.Projectile then
|
||||
self.Projectile:Destroy()
|
||||
self.Projectile = nil
|
||||
end
|
||||
BehaviourClient.Destroy(self)
|
||||
end
|
||||
|
||||
return Attack
|
@ -12,6 +12,16 @@ local RE_CleanPlayerPerformance = ReplicatedStorage:FindFirstChild("Events"):Fin
|
||||
--> Dependencies
|
||||
local TypeList = require(ServerStorage.Base.TypeList)
|
||||
local Communicate = require(ServerStorage.Modules.Tools.Communicate)
|
||||
local Utils = require(ReplicatedStorage.Tools.Utils)
|
||||
|
||||
--> Json
|
||||
local JsonAttributes = require(ReplicatedStorage.Json.Attributes)
|
||||
|
||||
--> 临时维护一个属性数据表,用于记录属性类型
|
||||
local AttributesNameData = {}
|
||||
for _, Attribute in JsonAttributes do
|
||||
AttributesNameData[Attribute.effectAttribute] = Utils:DeepCopyTable(Attribute)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -54,7 +64,6 @@ end
|
||||
|
||||
-- 检查行为前先清理之前遗留的引用数据
|
||||
function Behaviour:CheckClean()
|
||||
|
||||
if self.Mobs then
|
||||
for _, Mob in self.Mobs do
|
||||
self.Mobs[Mob] = nil
|
||||
@ -69,6 +78,21 @@ function Behaviour:CheckClean()
|
||||
end
|
||||
end
|
||||
|
||||
function Behaviour:GetAttributeValue(AttributeName: string)
|
||||
local AttributeValue = self.Character.Instance:FindFirstChild("Attributes"):GetAttribute(AttributeName)
|
||||
if not AttributeValue then return nil end
|
||||
-- 处理对应的值
|
||||
local AttributeData = AttributesNameData[AttributeName]
|
||||
if not AttributeData then return nil end
|
||||
|
||||
local typeValue = AttributeData.type
|
||||
if typeValue == 1 then
|
||||
return AttributeValue
|
||||
elseif typeValue == 2 then
|
||||
return AttributeValue / 100
|
||||
end
|
||||
end
|
||||
|
||||
-- 启动冷却时间清除计时
|
||||
function Behaviour:StartCooldownTask()
|
||||
self.Cooldown = self.OrgCooldown
|
||||
|
121
src/ServerStorage/Modules/Behaviours/Attack.luau
Normal file
121
src/ServerStorage/Modules/Behaviours/Attack.luau
Normal file
@ -0,0 +1,121 @@
|
||||
-- 移动行为
|
||||
|
||||
--> Services
|
||||
local ServerStorage = game:GetService("ServerStorage")
|
||||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||
|
||||
--> Dependencies
|
||||
local TypeList = require(ServerStorage.Base.TypeList)
|
||||
local Behaviour = require(ServerStorage.Base.Behaviour)
|
||||
local MobsProxy = require(ServerStorage.Proxy.MobsProxy)
|
||||
local DamageProxy = require(ServerStorage.Proxy.DamageProxy)
|
||||
local Utils = require(ReplicatedStorage.Tools.Utils)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local Attack = {}
|
||||
Attack.__index = Attack
|
||||
setmetatable(Attack, {__index = Behaviour})
|
||||
|
||||
local CAST_DISTANCE = 8
|
||||
local COOLDOWN = 1
|
||||
local ATTRIBUTE_LIST = {
|
||||
{Name = "attack", ElementType = DamageProxy.ElementType.NONE},
|
||||
{Name = "fireAtk", ElementType = DamageProxy.ElementType.FIRE},
|
||||
{Name = "iceAtk", ElementType = DamageProxy.ElementType.ICE},
|
||||
{Name = "lightAtk", ElementType = DamageProxy.ElementType.LIGHT},
|
||||
{Name = "shadowAtk", ElementType = DamageProxy.ElementType.SHADOW},
|
||||
|
||||
}
|
||||
|
||||
function Attack:Init(PlayerAI, Character: TypeList.Character, Player: Player)
|
||||
local self = Behaviour:Init(PlayerAI, Character, script.Name)
|
||||
self.Player = Player
|
||||
self.Mobs = nil
|
||||
setmetatable(self, Attack)
|
||||
self.OrgCooldown = COOLDOWN
|
||||
-- self:StartCooldownTask()
|
||||
|
||||
-- 客户端表现
|
||||
self:SendPerformanceEvent("Init", self.Player, script.Name, true, {})
|
||||
return self
|
||||
end
|
||||
|
||||
function Attack:Check(CheckInfo: table)
|
||||
if Behaviour.CheckStat(self) then return -1, self.CheckData end
|
||||
self:CheckClean()
|
||||
|
||||
self.Mobs = MobsProxy:GetPlayerMobs(self.Player)
|
||||
if not self.Mobs then return end
|
||||
|
||||
|
||||
local closestMob, minDistance = nil, CAST_DISTANCE
|
||||
for _, Mob in self.Mobs do
|
||||
if Mob.Instance and Mob.Instance.PrimaryPart then
|
||||
local dist = (Mob.Instance.PrimaryPart.Position - self.Character.Instance.PrimaryPart.Position).Magnitude
|
||||
if dist < minDistance then
|
||||
minDistance = dist
|
||||
closestMob = Mob
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.CheckData = {}
|
||||
if closestMob then
|
||||
self.CheckData["ClosestCharacter"] = closestMob
|
||||
return 50, self.CheckData
|
||||
end
|
||||
|
||||
-- 返回优先级,执行数据
|
||||
return -1, self.CheckData
|
||||
end
|
||||
|
||||
function Attack:Execute()
|
||||
self.ExeTask = task.spawn(function ()
|
||||
self:ChangeExecutingState(true)
|
||||
-- cd放前面之后发送事件才能正常记录cd
|
||||
-- self:StartCooldownTask()
|
||||
|
||||
-- 停止移动
|
||||
self.Character.Humanoid:MoveTo(self.Character.Root.Position)
|
||||
-- 朝向目标
|
||||
local HumanoidRootPart = self.Character.Root
|
||||
local TargetPosition = self.CheckData["ClosestCharacter"].Instance.PrimaryPart.Position
|
||||
|
||||
if HumanoidRootPart then
|
||||
HumanoidRootPart.CFrame = CFrame.lookAt(HumanoidRootPart.Position, TargetPosition)
|
||||
end
|
||||
|
||||
local atkSpeed = self:GetAttributeValue("atkSpeed")
|
||||
if not atkSpeed then warn("atkSpeed not found") return end
|
||||
|
||||
-- 表现部分
|
||||
self:SendPerformanceEvent("Show", self.Player, self.ScriptName, true, {
|
||||
{ UniqueId = self.PlayerAI:GetBehaviourUniqueId() }
|
||||
})
|
||||
-- 攻击前摇
|
||||
task.wait(atkSpeed)
|
||||
|
||||
-- TODO: 之后这里可以提前做暴击判定
|
||||
|
||||
-- 伤害逻辑计算部分
|
||||
local damageData = {}
|
||||
for _, attribute in ATTRIBUTE_LIST do
|
||||
local attributeValue = self:GetAttributeValue(attribute.Name)
|
||||
if attributeValue then
|
||||
table.insert(damageData, {
|
||||
Damage = attributeValue,
|
||||
Type = DamageProxy.DamageType.NORMAL,
|
||||
Tag = DamageProxy.DamageTag.NORMAL,
|
||||
ElementType = attribute.ElementType,
|
||||
})
|
||||
end
|
||||
end
|
||||
DamageProxy:TakeDamage(self.Character, self.CheckData["ClosestCharacter"], damageData)
|
||||
|
||||
-- task.wait(atkSpeed / 2)
|
||||
self:ChangeExecutingState(false)
|
||||
end)
|
||||
end
|
||||
|
||||
return Attack
|
@ -14,6 +14,8 @@ local Move = {}
|
||||
Move.__index = Move
|
||||
setmetatable(Move, {__index = Behaviour})
|
||||
|
||||
local ATTACK_DISTANCE = 8
|
||||
|
||||
function Move:Init(PlayerAI, Character: TypeList.Character, Player: Player)
|
||||
local self = Behaviour:Init(PlayerAI, Character, script.Name)
|
||||
self.Player = Player
|
||||
@ -41,8 +43,11 @@ function Move:Check(CheckInfo: table)
|
||||
|
||||
self.CheckData = {}
|
||||
if closestMob then
|
||||
self.CheckData["ClosestCharacter"] = closestMob
|
||||
return 10, self.CheckData
|
||||
local distance = (closestMob.Instance.PrimaryPart.Position - self.Character.Instance.PrimaryPart.Position).Magnitude
|
||||
if distance > ATTACK_DISTANCE then
|
||||
self.CheckData["ClosestCharacter"] = closestMob
|
||||
return 10, self.CheckData
|
||||
end
|
||||
end
|
||||
|
||||
-- 返回优先级,执行数据
|
||||
@ -50,10 +55,22 @@ function Move:Check(CheckInfo: table)
|
||||
end
|
||||
|
||||
function Move:Execute()
|
||||
if self.ExeTask then task.cancel(self.ExeTask) end
|
||||
self.ExeTask = task.spawn(function ()
|
||||
self:ChangeExecutingState(true)
|
||||
self.Character.Humanoid:MoveTo(self.CheckData["ClosestCharacter"].Instance:GetPivot().Position)
|
||||
task.wait(0.5)
|
||||
|
||||
-- 新移动朝向
|
||||
local TargetCharacter = self.CheckData["ClosestCharacter"].Instance
|
||||
local TargetPosition = TargetCharacter:GetPivot().Position
|
||||
local CharacterPosition = self.Character.Instance:GetPivot().Position
|
||||
local Direction = (TargetPosition - CharacterPosition).Unit
|
||||
local MoveToPosition = TargetPosition - (Direction * ATTACK_DISTANCE)
|
||||
|
||||
self.Character.Humanoid:MoveTo(MoveToPosition)
|
||||
|
||||
-- 旧内容
|
||||
-- self.Character.Humanoid:MoveTo(self.CheckData["ClosestCharacter"].Instance:GetPivot().Position)
|
||||
task.wait(0.2)
|
||||
self:ChangeExecutingState(false)
|
||||
end)
|
||||
end
|
||||
|
@ -86,7 +86,6 @@ local function LoadData(Player: Player): (boolean, any)
|
||||
|
||||
if Success and Response then
|
||||
print(("DataManager: User %s's data loaded into the game."):format(Player.Name))
|
||||
print(Response)
|
||||
else
|
||||
print(("DataManager: User %s had no data to load from."):format(Player.Name))
|
||||
end
|
||||
|
@ -67,9 +67,7 @@ task.defer(function()
|
||||
local Enemy = Mob.Humanoid
|
||||
|
||||
-- Simulation
|
||||
if Mob.Root.Anchored then
|
||||
Mob.Root.Anchored = false
|
||||
end
|
||||
if Mob.Root.Anchored then Mob.Root.Anchored = false end
|
||||
if not Mob.Root:GetNetworkOwner() then
|
||||
Mob.Root:SetNetworkOwner(Player)
|
||||
task.wait(0.05) -- Give physics more time so it doesn't appear as choppy
|
||||
@ -78,9 +76,12 @@ task.defer(function()
|
||||
-- Tracking
|
||||
if Player and Enemy and PlayerRole then
|
||||
if PlayerRole.Stats.Died then return end
|
||||
if distance > 5 then
|
||||
if distance > 8 then
|
||||
Enemy:SetAttribute("AttackState", "Idle")
|
||||
Enemy:MoveTo(Player.Character:GetPivot().Position, Player.Character.PrimaryPart)
|
||||
else
|
||||
Enemy:SetAttribute("AttackState", "Hit")
|
||||
Mob.Root.Anchored = true
|
||||
Mob.ExecutingState = true
|
||||
-- 停止移动
|
||||
Enemy:MoveTo(MobInstance:GetPivot().Position)
|
||||
@ -92,7 +93,7 @@ task.defer(function()
|
||||
if not Player then return end
|
||||
if PlayerRole.Stats.Died then return end
|
||||
|
||||
if AI:GetModelDistance(MobInstance, Player.Character) <= 5 then
|
||||
if AI:GetModelDistance(MobInstance, Player.Character) <= 8 then
|
||||
-- 调用伤害模块
|
||||
DamageProxy:TakeDamage(Mob, Mob.PlayerRole, {
|
||||
{
|
||||
@ -104,6 +105,7 @@ task.defer(function()
|
||||
})
|
||||
end
|
||||
Mob.ExecutingState = false
|
||||
Enemy:SetAttribute("AttackState", "Idle")
|
||||
end
|
||||
end
|
||||
else
|
||||
|
@ -99,7 +99,10 @@ function MobsProxy:CreateMob(Player: Player, MobId: number, AtkBonus: number?, H
|
||||
AI:StartTracking(Mob)
|
||||
-- 关卡系数
|
||||
if AtkBonus then Mob:ChangeAttributeValue("attack", math.floor(Mob.Config.attack * (AtkBonus / 1000))) end
|
||||
if HpBonus then Mob:ChangeAttributeValue("hp", math.floor(Mob.Config.hp * (HpBonus / 1000))) end
|
||||
if HpBonus then
|
||||
Mob:ChangeAttributeValue("hp", math.floor(Mob.Config.hp * (HpBonus / 1000)))
|
||||
Mob:ChangeAttributeValue("maxhp", math.floor(Mob.Config.maxhp * (HpBonus / 1000)))
|
||||
end
|
||||
MobsProxy.pData[Player.UserId][Mob.Instance] = Mob
|
||||
return Mob
|
||||
end
|
||||
|
@ -65,6 +65,7 @@ function PlayerRole.new(Player: Player, CharacterId: number)
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
function PlayerRole:Died()
|
||||
self:ChangeState("Died", true)
|
||||
self.Humanoid.WalkSpeed = 0
|
||||
@ -119,7 +120,6 @@ function PlayerFightProxy:UpdatePlayerFightData(Player: Player)
|
||||
local AbilityProxy = require(ServerStorage.Proxy.AbilityProxy)
|
||||
local GemProxy = require(ServerStorage.Proxy.GemProxy)
|
||||
|
||||
|
||||
local AttributesData = {}
|
||||
|
||||
-- 计算角色基础属性值 + 装备属性值 + 宝石属性值,赋值属性
|
||||
@ -178,8 +178,9 @@ function PlayerFightProxy:UpdatePlayerFightData(Player: Player)
|
||||
for _, behaviourName in behaviourNameList do
|
||||
playerAI:AddBehaviour(behaviourName)
|
||||
end
|
||||
-- playerAI:AddBehaviour("Move")
|
||||
playerAI:AddBehaviour("SwordWave")
|
||||
playerAI:AddBehaviour("Move")
|
||||
-- playerAI:AddBehaviour("SwordWave")
|
||||
playerAI:AddBehaviour("Attack")
|
||||
|
||||
|
||||
-- 给前端发送技能信息
|
||||
|
@ -5,7 +5,7 @@ local RunService = game:GetService("RunService")
|
||||
local player = Players.LocalPlayer
|
||||
local camera = workspace.CurrentCamera
|
||||
|
||||
local CAMERA_DISTANCE = 20
|
||||
local CAMERA_DISTANCE = 30
|
||||
local CAMERA_HEIGHT = 40
|
||||
local CAMERA_ANGLE = math.rad(-45)
|
||||
local SCREEN_OFFSET = 5
|
||||
|
159
src/StarterPlayerScripts/ClientMain/MobAnim.luau
Normal file
159
src/StarterPlayerScripts/ClientMain/MobAnim.luau
Normal file
@ -0,0 +1,159 @@
|
||||
--[[
|
||||
Evercyan @ March 2023
|
||||
MobClient
|
||||
|
||||
Unlike MobLib which handles server-sided code, and most of it in general, we run
|
||||
some code on the client for things such as custom health overlays & overwriting humanoid state types.
|
||||
|
||||
If you want to edit mob code to add new behavior or edit existing behavior, you likely want to refer
|
||||
to the server-sided code under ServerStorage.
|
||||
]]
|
||||
|
||||
--> Services
|
||||
local CollectionService = game:GetService("CollectionService")
|
||||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||
local Players = game:GetService("Players")
|
||||
|
||||
--> Player
|
||||
local Player = Players.LocalPlayer
|
||||
|
||||
--> Dependencies
|
||||
local Tween = require(ReplicatedStorage.Modules.Tween)
|
||||
local Maid = require(ReplicatedStorage.Modules.Maid)
|
||||
|
||||
--> Variables
|
||||
local Mobs = {}
|
||||
|
||||
-- Folder
|
||||
local ClientMainPrefabs = Player.PlayerScripts.ClientMainPrefabs
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- WaitForChild keeps yielding, even if the Instance is removed.
|
||||
-- Using this for safe yielding with StreamingEnabled!
|
||||
local function safeWait(Item: Instance, Name: string): Instance?
|
||||
if not Item then
|
||||
return
|
||||
elseif Item:FindFirstChild(Name) then
|
||||
return Item:FindFirstChild(Name)
|
||||
end
|
||||
|
||||
local ItemAdded = Instance.new("BindableEvent")
|
||||
local Maid = Maid.new()
|
||||
|
||||
Maid:Add(Item.ChildAdded:Connect(function(Child)
|
||||
if Child.Name == Name then
|
||||
ItemAdded:Fire(Child)
|
||||
ItemAdded:Destroy()
|
||||
Maid:Destroy()
|
||||
end
|
||||
end))
|
||||
Maid:Add(Item.Destroying:Connect(function()
|
||||
ItemAdded:Fire()
|
||||
ItemAdded:Destroy()
|
||||
Maid:Destroy()
|
||||
end))
|
||||
|
||||
return ItemAdded.Event:Wait()
|
||||
end
|
||||
|
||||
-- Creates an "AnimationTrack" instance which is stored on the client for playing
|
||||
local function LoadAnimationTrack(MobInstance: Model, Name: string, Priority: string) : AnimationTrack?
|
||||
local Humanoid = MobInstance:FindFirstChild("Humanoid") :: Humanoid
|
||||
local Animator = Humanoid and Humanoid:FindFirstChild("Animator") :: Animator
|
||||
if not Animator then return nil end
|
||||
|
||||
local Animation
|
||||
Animation = ClientMainPrefabs.MobClient.DefaultAnimations[Name]
|
||||
|
||||
local AnimationTrack = Animator:LoadAnimation(Animation)
|
||||
AnimationTrack.Priority = Enum.AnimationPriority[Priority or "Core"]
|
||||
|
||||
return AnimationTrack
|
||||
end
|
||||
|
||||
local function PerMob(MobInstance: Model)
|
||||
if Mobs[MobInstance] then return end
|
||||
|
||||
local Humanoid = safeWait(MobInstance, "Humanoid") :: Humanoid
|
||||
local Root = safeWait(MobInstance, "HumanoidRootPart") :: BasePart
|
||||
if not Humanoid or not Root then return end
|
||||
|
||||
local Maid = Maid.new()
|
||||
|
||||
-- Set humanoid states (helps prevent falling down & useless calculations - you're unlikely to have an enemy climbing without pathfinding)
|
||||
for _, EnumName in {"FallingDown", "Seated", "Flying", "Swimming", "Climbing"} do
|
||||
local HumanoidStateType = Enum.HumanoidStateType[EnumName]
|
||||
Humanoid:SetStateEnabled(HumanoidStateType, false)
|
||||
if Humanoid:GetState() == HumanoidStateType then
|
||||
Humanoid:ChangeState(Enum.HumanoidStateType.Running)
|
||||
end
|
||||
end
|
||||
|
||||
-- Animations / Behavior ---------------------------------------------------
|
||||
|
||||
local AnimationTracks = {
|
||||
Running = LoadAnimationTrack(MobInstance, "Running", "Core"),
|
||||
Jumping = LoadAnimationTrack(MobInstance, "Jumping", "Movement"),
|
||||
Hit = LoadAnimationTrack(MobInstance, "Hit", "Action")
|
||||
}
|
||||
|
||||
Maid:Add(Humanoid.Running:Connect(function(Speed)
|
||||
if Speed > 0.01 then
|
||||
local Percent = Speed/Humanoid.WalkSpeed
|
||||
if not AnimationTracks.Running.IsPlaying then
|
||||
AnimationTracks.Running:Play()
|
||||
end
|
||||
AnimationTracks.Running:AdjustSpeed(Percent)
|
||||
else
|
||||
AnimationTracks.Running:Stop()
|
||||
end
|
||||
end))
|
||||
|
||||
Maid:Add(Humanoid.Jumping:Connect(function()
|
||||
AnimationTracks.Jumping.TimePosition = 0
|
||||
if not AnimationTracks.Jumping.IsPlaying then
|
||||
AnimationTracks.Jumping:Play()
|
||||
end
|
||||
end))
|
||||
|
||||
-- Maid:Add(Humanoid.Died:Once(function()
|
||||
-- Root:ApplyImpulse(-Root.CFrame.LookVector * Root.AssemblyMass*50) -- Ragdoll Impulse
|
||||
-- end))
|
||||
|
||||
Maid:Add(Root:GetPropertyChangedSignal("Anchored"):Connect(function()
|
||||
if Root.Anchored then
|
||||
AnimationTracks.Running:Stop()
|
||||
end
|
||||
end))
|
||||
|
||||
-- TODO: 攻击动画之后要做延迟处理和攻速处理
|
||||
Maid:Add(Humanoid:GetAttributeChangedSignal("AttackState"):Connect(function()
|
||||
if Humanoid:GetAttribute("AttackState") == "Hit" then
|
||||
if AnimationTracks.Hit.IsPlaying then
|
||||
AnimationTracks.Hit.TimePosition = 0
|
||||
else
|
||||
AnimationTracks.Hit:Play()
|
||||
end
|
||||
else
|
||||
AnimationTracks.Hit:Stop()
|
||||
end
|
||||
end))
|
||||
|
||||
local Mob = {}
|
||||
Mob.Instance = MobInstance
|
||||
Mob.AnimationTracks = AnimationTracks
|
||||
Mobs[MobInstance] = Mob
|
||||
|
||||
Maid:Add(MobInstance.Destroying:Connect(function()
|
||||
Mobs[MobInstance] = nil
|
||||
Maid:Destroy()
|
||||
end))
|
||||
end
|
||||
|
||||
CollectionService:GetInstanceAddedSignal("Mob"):Connect(PerMob)
|
||||
for _, MobInstance in CollectionService:GetTagged("Mob") do
|
||||
task.spawn(PerMob, MobInstance)
|
||||
end
|
||||
|
||||
return {}
|
@ -35,8 +35,8 @@ end
|
||||
|
||||
function DamageBoard:CreateNormalDamageBoard(DamageDetail: table)
|
||||
local DamageInitPos = DamageDetail.DamagePosition
|
||||
local BiasPos = Vector3.new(0, 4, 0)
|
||||
local MultPos = Vector3.new(0, 1.5, 0)
|
||||
local BiasPos = Vector3.new(0, 6, 0)
|
||||
local MultPos = Vector3.new(0, 1, 0)
|
||||
|
||||
-- 根据元素类型排序
|
||||
local DamageInfos = DamageDetail["DamageInfos"]
|
||||
|
@ -56,7 +56,6 @@ RE_PerformanceEvent.OnClientEvent:Connect(function(ServerTime: number, CastTag:
|
||||
|
||||
local delayTime = ServerTime - tick()
|
||||
if CastTag == "Init" then
|
||||
-- print("Init", BehaviourName)
|
||||
-- 暂时就新增一个表,不调用初始化,因为服务端不是多个new做的,而是多次调用
|
||||
if not PerformanceClient.pData[UserId][BehaviourName] then
|
||||
PerformanceClient.pData[UserId][BehaviourName] = {}
|
||||
|
@ -2,30 +2,57 @@ local UserInputService = game:GetService("UserInputService")
|
||||
|
||||
local PlayerControl = {}
|
||||
|
||||
-- 监听按键按下
|
||||
function PlayerControl.ListenMoveKeyDown(onKeyDown)
|
||||
UserInputService.InputBegan:Connect(function(input, gameProcessed)
|
||||
if gameProcessed then return end
|
||||
if input.UserInputType == Enum.UserInputType.Keyboard then
|
||||
local key = input.KeyCode
|
||||
if key == Enum.KeyCode.W or key == Enum.KeyCode.A or key == Enum.KeyCode.S or key == Enum.KeyCode.D then
|
||||
onKeyDown(key)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
-- 添加按键状态跟踪
|
||||
local pressedKeys = {}
|
||||
|
||||
-- 监听按键松开
|
||||
function PlayerControl.ListenMoveKeyUp(onKeyUp)
|
||||
UserInputService.InputEnded:Connect(function(input, gameProcessed)
|
||||
if gameProcessed then return end
|
||||
if input.UserInputType == Enum.UserInputType.Keyboard then
|
||||
local key = input.KeyCode
|
||||
if key == Enum.KeyCode.W or key == Enum.KeyCode.A or key == Enum.KeyCode.S or key == Enum.KeyCode.D then
|
||||
onKeyUp(key)
|
||||
pressedKeys[key] = nil -- 移除当前按键状态
|
||||
|
||||
-- 检查是否还有其他移动按键在按下
|
||||
local hasOtherKeysPressed = false
|
||||
for k, v in pairs(pressedKeys) do
|
||||
if k == Enum.KeyCode.W or k == Enum.KeyCode.A or k == Enum.KeyCode.S or k == Enum.KeyCode.D then
|
||||
hasOtherKeysPressed = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- 只有当没有其他移动按键按下时才调用onKeyUp
|
||||
if not hasOtherKeysPressed then
|
||||
onKeyUp(key)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- 添加按键按下监听
|
||||
function PlayerControl.ListenMoveKeyDown(onKeyDown)
|
||||
UserInputService.InputBegan:Connect(function(input, gameProcessed)
|
||||
if gameProcessed then return end
|
||||
if input.UserInputType == Enum.UserInputType.Keyboard then
|
||||
local key = input.KeyCode
|
||||
if key == Enum.KeyCode.W or key == Enum.KeyCode.A or key == Enum.KeyCode.S or key == Enum.KeyCode.D then
|
||||
pressedKeys[key] = true
|
||||
onKeyDown(key)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- 添加获取当前按下按键的函数
|
||||
function PlayerControl.GetPressedKeys()
|
||||
return pressedKeys
|
||||
end
|
||||
|
||||
-- 添加检查特定按键是否按下的函数
|
||||
function PlayerControl.IsKeyPressed(keyCode)
|
||||
return pressedKeys[keyCode] == true
|
||||
end
|
||||
|
||||
return PlayerControl
|
@ -128,6 +128,14 @@ function UIManager:IsOpened(WindowName: string)
|
||||
return UIManager.Instances[WindowName] ~= nil
|
||||
end
|
||||
|
||||
function UIManager:SetData(WindowName: string, Data: table)
|
||||
if not UIManager.Instances[WindowName] then
|
||||
warn("UIManager:SetData() 窗口不存在:" .. WindowName)
|
||||
return
|
||||
end
|
||||
UIManager.Instances[WindowName]:SetData(Data)
|
||||
end
|
||||
|
||||
-- 获取当前窗口堆栈信息(用于调试)
|
||||
function UIManager:GetWindowStackInfo()
|
||||
local info = {}
|
||||
|
@ -62,14 +62,16 @@ function MainWindow:OnOpenWindow()
|
||||
table.insert(self.Connections, chaCon)
|
||||
table.insert(self.Connections, attributeUpgradeCon)
|
||||
|
||||
local playerDataFolder = Utils:WaitPlayerDataFolder(LocalPlayer)
|
||||
local StatsFolder = playerDataFolder:WaitForChild("PlayerInfo"):WaitForChild("Stats")
|
||||
local levelCon = StatsFolder.level.Changed:Connect(function(newValue)
|
||||
-- TODO: 暂时用主关卡数显示,我记得之前这里主要是记录的,Challenge中才是正在挑战的内容
|
||||
-- TODO: 之后LevelProxy也应该挪到ReplicatedStorage下,之前可能是因为觉得Challenge是临时的内容所以放在workspace下,但是逻辑做的不统一
|
||||
local playerDataFolder = game.Workspace:WaitForChild("Level"):WaitForChild(LocalPlayer.UserId)
|
||||
local StatsFolder = playerDataFolder:WaitForChild("Progress")
|
||||
local levelCon = StatsFolder.Main.Changed:Connect(function(newValue)
|
||||
self:SetShowLevel(newValue)
|
||||
end)
|
||||
|
||||
-- 初始值设置
|
||||
self:SetShowLevel(StatsFolder.level.Value)
|
||||
self:SetShowLevel(StatsFolder.Main.Value)
|
||||
table.insert(self.Connections, levelCon)
|
||||
end
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user