Movement script

mail@pastecode.io avatar
unknown
lua
a year ago
16 kB
3
Indexable
Never
function Tick (deltaTime)

if not EQUIPMENT.owner then return end
nextUpdate = nextUpdate - deltaTime
		
	local forward = 			propMotorcycle:GetWorldRotation () * Vector3.FORWARD
	local velocity = 			LastVelocity.size  
	local direction = 			CoreMath.Clamp (LastVelocity * 100 .. forward, -1, 1)	
	local reverse = 			CoreMath.Clamp (-direction, 0, 1)
	local is_forward = 			CoreMath.Clamp (direction, 0, 1)
	local velocity_normalized = velocity / propMaxSpeed


--reset any parameters that should be zero'd 
local surfaceNormal = Vector3.ZERO



----
--GET VEHICLE INPUTS	
----

	if Input.IsActionHeld(EQUIPMENT.owner, "Steer") then
	Steering_Inputs = Input.GetActionValue(EQUIPMENT.owner, "Steer")
	
		if Steering_Inputs > 0 then
		
			Steering_R_Magnitude = CoreMath.Clamp(Steering_R_Magnitude+deltaTime, 0,1)
			Steering_L_Magnitude = Steering_L_Magnitude-deltaTime
			
				if Steering_L_Magnitude <= 0 then
				Steering_L_Magnitude = 0 
				else
				Steering_L_Magnitude = Steering_L_Magnitude-deltaTime
				end
				
		elseif Steering_Inputs < 0 then
		
			Steering_L_Magnitude = CoreMath.Clamp(Steering_L_Magnitude+deltaTime, 0,1)
			Steering_R_Magnitude = Steering_R_Magnitude-deltaTime
			
				if Steering_R_Magnitude <= 0 then
				Steering_R_Magnitude = 0 
				else
				Steering_R_Magnitude = Steering_R_Magnitude-deltaTime
				end
		end
	
	else
	Steering_Inputs = 0 
	
			Steering_R_Magnitude = Steering_R_Magnitude-deltaTime
			
				if Steering_R_Magnitude <= 0 then
				Steering_R_Magnitude = 0 
				else
				Steering_R_Magnitude = Steering_R_Magnitude-deltaTime
				end
			Steering_L_Magnitude = Steering_L_Magnitude-deltaTime
			
				if Steering_L_Magnitude <= 0 then
				Steering_L_Magnitude = 0 
				else
				Steering_L_Magnitude = Steering_L_Magnitude-deltaTime
				end						
	end

	if Input.IsActionHeld(EQUIPMENT.owner, "Pitch") then
	Pitch = Input.GetActionValue(EQUIPMENT.owner, "Pitch")
	else
	Pitch = 0 
	end
	
	if AccelerationPressed then
	accelerating = 1
	else
	accelerating = 0
	end

	if Input.IsActionHeld(EQUIPMENT.owner, "Air Brake Left") then
	Left_Airbrake = Input.GetActionValue(EQUIPMENT.owner, "Air Brake Left")
	lab_Magnitude = lab_Magnitude+deltaTime
	lab_Magnitude = CoreMath.Clamp(lab_Magnitude, 0, 1)
	
	else
	Left_Airbrake = 0 
	
		if lab_Magnitude <= 0 then
		lab_Magnitude = 0 
		else
		lab_Magnitude = lab_Magnitude-deltaTime
		end
	end
	
	if Input.IsActionHeld(EQUIPMENT.owner, "Air Brake Right") then
	Right_Airbrake = Input.GetActionValue(EQUIPMENT.owner, "Air Brake Right")
	rab_Magnitude = rab_Magnitude+deltaTime
	rab_Magnitude = CoreMath.Clamp(rab_Magnitude, 0, 1)
	
	else
	Right_Airbrake = 0 
	
		if rab_Magnitude <= 0 then
		rab_Magnitude = 0 
		else
		rab_Magnitude = rab_Magnitude-deltaTime
		end
	
	end

	if BrakePressed then
	accelerating = -1
	end

	local accelerating = 		CoreMath.Clamp (INPUT.y, 0, 1)
	local braking = 			CoreMath.Clamp (-INPUT.y, 0, 1)
	local coasting = 			1 - accelerating - braking
	local steering_speed = 		propSteeringSpeedCurve:GetValue (velocity_normalized) * propSteeringSpeedScale
	local steeringDelta_Magnitude = math.abs(Steering_R_Magnitude + -Steering_L_Magnitude)
	
	INPUT = Vector3.New(Steering_Inputs,accelerating,Pitch)
	
	
	
	
	
----	
--HANDLE BOOSTS AND LIMIT THE TOP SPEED IF NOT BOOSTING	
----

	if boostpower > 0 then
	propAccelerationScale = EQUIPMENT:GetCustomProperty("AccelerationScale")*(boostpower*2)
	steeringDeceleration = 1
	
		if playBoostFX == 1 then
		boostSFX:Stop()
	    boostSFX:Play()
	    Events.Broadcast('CameraShakeEvent', 'default', 'RoughDriving', 5, 5)
	    end

		Boost_Duration = Boost_Duration - deltaTime
		playBoostFX = 0 
			
		if Boost_Duration <= 0 then
		boostpower = 0 
		end
	else
	propAccelerationScale = EQUIPMENT:GetCustomProperty("AccelerationScale")
	
		if velocity_normalized >= .8 then 
		propAccelerationScale = 0 
		coasting = 1
		end
	
	end
	
	
	
	
	
	
----		
--SIMULATE THE ENGINE
----

	local torque_speed_acceleration = 	propAccelerationScale 	* accelerating *steeringDeceleration--reduceifsteering
	local torque_speed_braking = 		propBrakePower 			* braking	
	local torque_speed_coasting = 		propDecelerationScale 	* coasting	
	
	local overrev = 					CoreMath.Clamp (CURRENT_TORQUE * (math.floor (CURRENT_TORQUE)), 0, 1)
	local reversing = 					CURRENT_TORQUE * reverse * 1.5							-- Higher value = slower reversing
	local smooth_stop = 				CoreMath.Clamp (0.5 + (2.5 * velocity_normalized), 0, 1)
	
	if Steering_Inputs < 0 then
	left_weight = math.abs(Steering_Inputs)
	else
	left_weight = 0
	end
	
	if Steering_Inputs > 0 then
	right_weight = Steering_Inputs
	else
	right_weight = 0
	end		
	
	CURRENT_TORQUE = 		CURRENT_TORQUE + (
							(torque_speed_acceleration / CURRENT_GEAR_FLOORED)					-- Acceleration
							- torque_speed_braking * smooth_stop								-- Braking
							- (Right_Airbrake*velocity_normalized*CoreMath.Clamp(right_weight, .5, 1) )/10 	--6		-- Right air Braking  
							- (Left_Airbrake*velocity_normalized*CoreMath.Clamp(left_weight, .5, 1))/10							-- Left air Braking
							- torque_speed_coasting * direction * propDecelerationCurve:GetValue (velocity_normalized) -- Decelerating / Coasting
							- overrev * is_forward - reversing 	-- Ensuring the torque doesn't exceed the value of 1.0 and limiting the reversing.
							) * deltaTime

	CURRENT_GEAR = 			CURRENT_TORQUE * CURRENT_TORQUE * propTotalGears + 1			-- Current gear total + current gear travel.
	CURRENT_GEAR_FLOORED = 	CoreMath.Clamp (math.floor (CURRENT_GEAR), 0, propTotalGears)	-- Current gear integer.
	GEAR_TRAVEL = 			(CURRENT_GEAR - CURRENT_GEAR_FLOORED)							-- Normalized gear travel (0.0 - 1.0).
	POWER_OUTPUT = 			CURRENT_TORQUE - (torque_speed_acceleration * (1 - propPowerCurve:GetValue (GEAR_TRAVEL)) * deltaTime) -- Applying the gear power curve.
	
	velocityDirection = POWER_OUTPUT * forward 
	NEW_DIRECTION = 		Vector3.Lerp (NEW_DIRECTION, Vector3.New(velocityDirection.x,velocityDirection.y, 0), deltaTime * 25 )	
	
	SUDO_RPM = 				CoreMath.Lerp (SUDO_RPM, (GEAR_TRAVEL / 3.5 + NEW_DIRECTION.size / 1.25) * is_forward, deltaTime * (5 + 5 * (1)))
							-- The sudo RPM is a smoothed out revving range that is used to provide feedback 
							-- to the player in forms of controlling the engine SFX pitch and the animation.
	
	-- Moving the focus pivot which determines the direction player steers at.
	local newSteeringFocus = 	Vector3.ZERO
	local newWheelSteer = 		Vector3.ZERO
	local questionable_fix =	CoreMath.Clamp ((1 - velocity_normalized * 100) * 100, 0, 100)    -- Reduces the idle drifting 
	
	BRAKE_LOCK = 			CoreMath.Lerp (BRAKE_LOCK, (propBrakeLockUpAmount * velocity_normalized * braking), deltaTime * velocity_normalized * propBrakeLockUpSpeed)
	newSteeringFocus.x = 	10 + questionable_fix * 10
	newSteeringFocus.y = 	propSteeringCurve:GetValue (velocity_normalized) * INPUT.x * propSteeringSensitivity / (1 + BRAKE_LOCK)
	newWheelSteer.y = 		newSteeringFocus.y * propWheelSteeringCurve:GetValue (velocity_normalized) * propWheelSteeringSensitivity * direction
	
	-- Animating the Vehicle.
	local steering_normalized = 	newSteeringFocus.y / propSteeringSensitivity
	local steering_direction = 		CoreMath.Clamp (steering_normalized * 1000, -1, 1)
	local steering_normalized_abs = math.abs (steering_normalized)
	local wobbling = 				math.sin (time () * 10) * 5 * propWobbleCurve:GetValue (velocity_normalized) * propWobbleScale
	local vibrations = 				math.sin (time () * 25) * propPowerCurve:GetValue (velocity_normalized) * propVibrationScale
	local wheel_rotation = 			Vector3.RIGHT * CoreMath.Clamp (velocity, -800, 800) / propWheelRadius * direction
	
	
	
	
	
	
	
	
----	
--Get Surface Normal
----
	local CurrentPlayerPos = propMotorcycle:GetWorldPosition()

	--Offset the raycast startpoint and endpoint, relative to the vehicles current VectorUP. ( subtract 600 units from the Z position )
	local VUP = propMotorcycle:GetWorldRotation() * Vector3.UP	
	
	
	
	--ignore the players roll  and update the offset calculation based on this-- The roll represents the vehicle leaning from side to side when turning and is mostly visual. 
	local Lean_From_Inputs = 
					Rotation.New(
						--get x rotation local to player foward based on inputs
							CoreMath.Lerp (
								propMotorcycle:GetWorldRotation ().x, (propLeanAngle*Steering_Inputs) 				
								+ (propLeanAngle*Steering_Inputs*velocity_normalized) 								
								+ (-20*Left_Airbrake)*lab_Magnitude
								+ ( 20*Right_Airbrake)*rab_Magnitude												
								+ wobbling,
								deltaTime* steering_speed),
								0,0)															
					
												
	local Rotation_From_Steering =  Rotation.New(0,0,Steering_Inputs - (Left_Airbrake*velocity_normalized*lab_Magnitude) + (Right_Airbrake*velocity_normalized*rab_Magnitude))
	
	local VUP = (propMotorcycle:GetWorldRotation()-Lean_From_Inputs) * Vector3.UP

	
	
	local direction = -VUP -- get the opposite direction
	local distance = 600
	local offset = direction * distance -- get the offset vector
	
	local UpOffset = -direction *75
	local Raystart = CurrentPlayerPos + UpOffset
	local targetPos = CurrentPlayerPos + offset -- calculate the target position
	
	--NormalizedUP = (Raystart-targetPos):GetNormalized()
	local Road = World.Raycast(Raystart, targetPos, {shouldDebugRender = true, ignorePlayers = true , debugRenderDuration = 2, debugRenderThickness = 5, debugRenderColor = Color.ORANGE})
	
	if Road then 

		if Road.other.name ~= "Road" then
			
			local RoadAll = World.RaycastAll(Raystart, targetPos, {shouldDebugRender = true, debugRenderDuration = 2, debugRenderThickness = 5, ignorePlayers = true})
			local threshold = 1
			
			for index, HitResult in pairs(RoadAll) do
				if HitResult.other.name == "Road" then
				Road = HitResult
				threshold = threshold - 1
				end
			end
			
			if threshold == 1 then 
			Road = nil
			end
			
		end
	end
	
	
	
----
--use surface normal to align vehicle to surface
----	
	if Road then 
	surfaceNormal = Road:GetImpactNormal()	
	end

	if Road and surfaceNormal then

		local VForward = propMotorcycle:GetWorldRotation()* Vector3.FORWARD
		local VectUP = propMotorcycle:GetWorldRotation()* Vector3.FORWARD
		local VectRight = propMotorcycle:GetWorldRotation()* Vector3.RIGHT
		
		 surfaceQuaternion = Quaternion.New(VUP, surfaceNormal)  --  renamed to surfaceQuaternion from--"surfaceRotation" = Quaternion.New(VUP, surfaceNormal)

	    -- apply the surface rotation to the player's orientation
	    targetOrientation = surfaceQuaternion * Quaternion.New(Vector3.FORWARD, VForward)
	    targetOrientationX = surfaceQuaternion * Quaternion.New(Vector3.RIGHT, VectRight)
	    targetOrientationZ = surfaceQuaternion * Quaternion.New(Vector3.UP, VectUP)
	    

		surfaceRotation = Rotation.New(targetOrientationX.x,targetOrientation:GetRotation().y,targetOrientationZ:GetRotation().z)

	else
	-- lerp back to current gravity vector instead of 0,0,0 if in the air -- TODO
	
		surfaceRotation = Rotation.New(
								CoreMath.Lerp(surfaceRotation.x, 0, deltaTime*10),
								CoreMath.Lerp(surfaceRotation.y, 0, deltaTime*10),
								propMotorcycle:GetWorldRotation().z

								)
								
	end
	


----
--ROTATE THE VEHICLES INPUTS RELATIVE TO VEHICLE DIRECTION
----
	local Motorcycle_Rotation = propMotorcycle:GetRotation()
	--Roll
	local x_Value = 	
			
			(propLeanAngle*Steering_Inputs) 						-- base lean value when steering
		    + (propLeanAngle*Steering_Inputs*velocity_normalized) 	-- add more lean when going faster
			+ (-20*Left_Airbrake)*lab_Magnitude
			+ ( 20*Right_Airbrake)*rab_Magnitude					-- add more lean when airbraking but can still cancel eachother out
			+ wobbling			

	--Pitch			
	local y_Value = 0
	--Yaw
	local z_Value = Steering_Inputs - (Left_Airbrake*velocity_normalized*lab_Magnitude) + (Right_Airbrake*velocity_normalized*rab_Magnitude) --was using this one
	
	local InputVectorSpace = Vector3.New(x_Value, y_Value, z_Value)
	local dir = propMotorcycle:GetWorldTransform():TransformDirection(Vector3.New(InputVectorSpace.x, InputVectorSpace.y, InputVectorSpace.z))	
	
	--draw Current Vehicle Vectors.
 	local CurrentFORWARD = propMotorcycle:GetWorldRotation()*Vector3.FORWARD
 	local CurrentUP = propMotorcycle:GetWorldRotation()*Vector3.UP
 	local CurrentRIGHT = propMotorcycle:GetWorldRotation()*Vector3.RIGHT

	CoreDebug.DrawLine(propMotorcycle:GetWorldPosition(), propMotorcycle:GetWorldRotation()*Vector3.FORWARD*2000+(propMotorcycle:GetWorldPosition()), {duration = .1, thickness = 10, color=Color.GREEN})
	CoreDebug.DrawLine(propMotorcycle:GetWorldPosition(), propMotorcycle:GetWorldRotation()*Vector3.RIGHT*2000+(propMotorcycle:GetWorldPosition()), {duration = .1, thickness = 10 , color=Color.RED})
	CoreDebug.DrawLine(propMotorcycle:GetWorldPosition(), propMotorcycle:GetWorldRotation()*Vector3.UP*2000+(propMotorcycle:GetWorldPosition()), {duration = .1, thickness = 10,color=Color.BLUE})

print(dir)
-------------------------------

----
--ROTATE THE VEHICLE
----

globalRotation = propMotorcycle:GetWorldRotation ()		
	propMotorcycle:SetRotation (


		Rotation.New (
			CoreMath.Lerp (
		--x	
			globalRotation.x, globalRotation.x + dir.x,
			deltaTime), 
		--y
			CoreMath.Lerp ( propMotorcycle:GetWorldRotation ().y,surfaceRotation.y + dir.y, deltaTime*20), 
				
		--z	
			Motorcycle_Rotation.z + dir.z
			)

		)	


-----------------------------------

--	 ALIGNS TO SLOPE + INPUTS				
--[[

		
	propMotorcycle:SetRotation (

		Rotation.New (
			CoreMath.Lerp (
		--x	
			propMotorcycle:GetWorldRotation ().x, (propLeanAngle*Steering_Inputs) 				-- base lean value when steering
		    + (propLeanAngle*Steering_Inputs*velocity_normalized) 								-- add more lean when going faster
			+ (-20*Left_Airbrake)*lab_Magnitude
			+ ( 20*Right_Airbrake)*rab_Magnitude												-- add more lean when airbraking but can still cancel eachother out
			+ wobbling,
			deltaTime * steering_speed), 
		--y
			CoreMath.Lerp ( propMotorcycle:GetWorldRotation ().y,surfaceRotation.y, deltaTime*20), 
				
		--z	
			Motorcycle_Rotation.z + Steering_Inputs - (Left_Airbrake*velocity_normalized*lab_Magnitude) + (Right_Airbrake*velocity_normalized*rab_Magnitude)
			)

		)			
]]

----	
--Move the Vehicle	
----	

	local newForward
	=  propMotorcycle:GetWorldRotation () * Vector3.FORWARD
	POWER_OUTPUT = 			CURRENT_TORQUE - (torque_speed_acceleration * (1 - propPowerCurve:GetValue (GEAR_TRAVEL)) * deltaTime) -- Applying the gear power curve.
	
	velocityDirection = POWER_OUTPUT * newForward
	
	
	if Road then
	local roadPosition = Road:GetImpactPosition()
	local distanceToRoad = (CurrentPlayerPos-roadPosition).size
					

	local distanceNormalized = CoreMath.Clamp(distanceToRoad, 0, 500)/500  -- adjusts the normal road height to target
	local roadDistanceMultiplier = road_gravity_curve:GetValue(distanceNormalized)*10*velocity_normalized
	local roadGravity = 1000*-roadDistanceMultiplier -- road gravity force	

	local GravityUp = (propMotorcycle:GetWorldRotation () * Vector3.UP)*roadGravity -- orient the gravity vector to the players Vector.UP

		LastVelocity = GravityUp + Vector3.New(
									velocityDirection.x*propMaxSpeed, 	
									velocityDirection.y*propMaxSpeed,	
									velocityDirection.z*propMaxSpeed
									)																																				
	propMotorcycle:MoveContinuous(LastVelocity)
	
	else  -- player is in the air -- add gravity for falling later and it will be relative to the current gravity field vector the player is in
	
	LastVelocity = Vector3.New(
					velocityDirection.x*propMaxSpeed, 	
					velocityDirection.y*propMaxSpeed,
					CoreMath.Lerp(LastVelocity.z, -16000, deltaTime/4)					 
					)
	propMotorcycle:MoveContinuous(LastVelocity)
	
	end