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