Advertisement
Guest User

Untitled

a guest
Apr 8th, 2020
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.06 KB | None | 0 0
  1. local framework = _G.ServerFramework or _G.ClientFramework()
  2.  
  3. ----
  4.  
  5. local class = {}
  6. class.__index = class
  7.  
  8. ----
  9.  
  10. local STIFFNESS = 400
  11. local DAMPING = 40
  12. local PERCISION = 0.001
  13.  
  14. local MOVE_TO_PADDING = 2
  15.  
  16. local V3_FLAT = Vector3.new(1, 0, 1)
  17. local V3_ZERO = Vector3.new(0, 0, 0)
  18. local V3_UP = Vector3.new(0, 1, 0)
  19.  
  20. ----
  21.  
  22. local function solveSpring(deltaTime, position, velocity, destination)
  23.     local displacement = position - destination
  24.     local springForce = -STIFFNESS * displacement
  25.     local dampForce = -DAMPING * velocity
  26.  
  27.     local acceleration = springForce + dampForce
  28.     local newVelocity = velocity + acceleration * deltaTime
  29.     local newPosition = position + velocity * deltaTime
  30.    
  31.     if newVelocity.magnitude < PERCISION and (destination - newPosition).magnitude < PERCISION then
  32.         return destination, velocity * 0
  33.     else
  34.         return newPosition, newVelocity
  35.     end
  36. end
  37.  
  38. local function getMass(instance)
  39.     local mass = 0
  40.    
  41.     for _, object in next, instance:GetDescendants() do
  42.         if object:IsA("BasePart") then
  43.             mass = mass + object:GetMass()
  44.         end
  45.     end
  46.    
  47.     return mass
  48. end
  49.  
  50. ----
  51.  
  52. function class.new(instance, controller)
  53.     local self = {}
  54.     self.Controller = controller
  55.     self.Instance = instance
  56.  
  57.     self.RootPart = instance.PrimaryPart
  58.     self.Humanoid = instance:WaitForChild("Humanoid")
  59.    
  60.     self.MoveForce = self.RootPart:WaitForChild("VectorForce")
  61.     self.TurnForce = self.RootPart:WaitForChild("BodyGyro")
  62.     self.HeightForce = self.RootPart:WaitForChild("BodyPosition")  
  63.    
  64.     self.CurrentAcceleration = Vector3.new()
  65.     self.MassCache = getMass(self.Instance)
  66.     self.Brain = {}
  67.  
  68.     return setmetatable(self, class)
  69. end
  70.  
  71. ----
  72.  
  73. function class:Destroy()
  74.     self.Step = function() end
  75.     self.Brain = {}
  76.    
  77.     self.RootPart = nil
  78.     self.Instance = nil
  79.     self.Humanoid = nil
  80.    
  81.     self.MoveForce = nil
  82.     self.TurnForce = nil
  83.     self.HeightForce = nil 
  84. end
  85.  
  86. function class:ResetMass()
  87.     self.MassCache = getMass(self.Instance)
  88. end
  89.  
  90. function class:SyncBrain(newStates)
  91.     for index, value in next, newStates do
  92.         self.Brain[index] = value
  93.     end
  94. end
  95.  
  96. function class:Step(deltaTime)
  97.     -- floor getting, height setting
  98.         -- raycasting is just a lazy library for common raycasting cases
  99.         -- :CharacterGroundCast() just finds the ground info below the character
  100.         -- it's almost always the point directly below the RootPart
  101.     local hipHeight = self.Humanoid.HipHeight + 1
  102.     local ground, groundPos, groundNorm = raycasting:CharacterGroundCast(self.RootPart.CFrame, hipHeight)
  103.     local hipOffset = V3_UP * (hipHeight)
  104.    
  105.     -- handle height popping and falling
  106.     if ground then
  107.         self.RootPart.BodyPosition.MaxForce = V3_UP * 10000000
  108.     else
  109.         self.RootPart.BodyPosition.MaxForce = V3_ZERO
  110.     end
  111.    
  112.     self.RootPart.BodyPosition.Position = groundPos + hipOffset
  113.    
  114.     -- move direction setting
  115.     local currentPosition = self.RootPart.CFrame.p
  116.     local currentVelocity = self.RootPart.Velocity
  117.  
  118.     local moveTargetPosition = nil;
  119.     local moveTargetSpeed = 0
  120.    
  121.     local moveDirection = self.RootPart.CFrame.LookVector
  122.     local moveSpeed = self.Brain.MoveSpeed or 0
  123.    
  124.     -- figure where to go
  125.     if self.Brain.TargetPosition then
  126.         moveTargetPosition = self.Brain.TargetPosition
  127.     end
  128.    
  129.     -- if we've got somewhere to go
  130.     if moveTargetPosition then
  131.         local vectorTo = (moveTargetPosition - currentPosition) * V3_FLAT
  132.         local distance = vectorTo.Magnitude
  133.        
  134.         -- we're close enough to stop now
  135.         if distance <= MOVE_TO_PADDING then
  136.             moveSpeed = moveTargetSpeed
  137.        
  138.         -- set walk direction to target
  139.         else
  140.             moveDirection = vectorTo.unit
  141.         end
  142.        
  143.     -- no where to go
  144.     else
  145.         moveSpeed = 0      
  146.     end
  147.    
  148.     -- thanks luanoid
  149.     currentVelocity, self.CurrentAcceleration = solveSpring(
  150.         deltaTime,
  151.         currentVelocity,
  152.         self.CurrentAcceleration,
  153.         moveDirection * moveSpeed
  154.     )
  155.    
  156.     self.MoveForce.Force = self.MassCache * self.CurrentAcceleration * V3_FLAT
  157.    
  158.     -- move rotation
  159.     if moveSpeed > 0 then
  160.         self.TurnForce.CFrame = CFrame.new(moveDirection * 0, moveDirection)
  161.     end
  162.  
  163.     -- humanoid force state
  164.     self.Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
  165. end
  166.  
  167. ----
  168.  
  169. return class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement