Haha Mech go stomp, any feedback?

Haha, finally made mech have that big stompy feel. Just a little sin and cos to make sway and go up and down really make a difference from my very first attempt.

https://i.imgur.com/dstM2Ma.mp4

I’ve decided to share the module of the procedural animation which tbh is the same mechanism as @iGottic R15 foot planting resource but now is more OOPed and a bit more robust. It’s robustness because this module now uses a for loop to control all the legs in the form of a dictionary so now I can make a mech with 4 or more legs :shock:.

It could be better, more polished, and more robust which is why I didn’t put it in #resources:community-resources for now maybe. Moreover, this could potentially work with any IK method, but for now, it uses my LimbChain module to do it.

Procedural animator class script
-- Procedural Animator Class
-- Dthecoolest
-- November 20, 2020
local RunService = game:GetService("RunService")

local ProceduralAnimatorClass = {}
ProceduralAnimatorClass.__index = ProceduralAnimatorClass

--Module to handle the procedural animation the hip and legs

--remnants from iGottics Code
local CF			=CFrame.new 
local ANGLES		=CFrame.Angles 
local x_and_y = Vector3.new(1, 0, 1)
local TAU = 2*math.pi
local DOWN = 10*Vector3.new(0,-1,0)

--template for legs
local mechLegs = {
	["rightLeg"] = {
		["CurrentCycle"] = 0,
		["LimbChain"] = rightLegChain,
		["HipAttachment"]= rightHipAttachment,
		["FootAttachment"] = rightStepAttachment,
	},

	["leftLeg"] = {
		["CurrentCycle"] = math.pi,
		["LimbChain"] =leftLegChain,
		["HipAttachment"]= leftHipAttachment,
		["FootAttachment"] = leftStepAttachment,
	}
}

function ProceduralAnimatorClass.new(RootPart,Legs,RootMotor)

	local self = setmetatable({}, ProceduralAnimatorClass)

	--Constants
	self.RootPart = RootPart
	self.RaycastParams = nil --manual input it

	if RootMotor then
		self.RootMotor = RootMotor
		self.RootMotorC1Store = RootMotor.C1
		self.WaistCycle = 0 
	end

	self.Legs = Legs

	--Default settings for legs
	self.DefaultStride = 12 -- Changes how far the legs move
	self.CycleSpeed = 4 -- How fast the leg-movement cycle is. Change this to suit your needs!
	self.DefaultStrideOffset = 2
	-- Radius of the circle at CFrame front of the player
	self.DefaultStrideCF = CFrame.new(0, 0, -self.DefaultStride / 2) -- Turn that stride number into a CFrame we can use


	--Variables that will change
	self.MovementDirectionXZ = Vector3.new(1, 0, 1) -- This will be changed
	self.rootvelm = 0

	return self

end

function ProceduralAnimatorClass:MoveLegs(stepCycle)
	--if moving
	if self.rootVelocityMagnitude > 0.1 then
		for i, Leg in pairs(self.Legs) do
			local strideCF = Leg.StrideCF or self.DefaultStrideCF
			local strideOffset = Leg.StrideOffset or self.DefaultStrideOffset
			local raycastParams = self.RaycastParams
			Leg.CurrentCycle = (Leg.CurrentCycle+stepCycle)%360
			local cycle = Leg.CurrentCycle

			local hip			=Leg.HipAttachment.WorldPosition
			--Position of where the lower leg should be, spread out
			local ground		=Leg.FootAttachment.WorldPosition
			local desiredPos	=(CF(ground, ground+self.MovementDirectionXZ)*ANGLES(-cycle, 0, 0)*strideCF).p
			local offset		=(desiredPos-hip)--vector from hip to the circle
			local raycastResult = workspace:Raycast(hip,offset.unit*(offset.magnitude+strideOffset),raycastParams)
			local footPos = raycastResult and raycastResult.Position or (hip + offset.unit*(offset.magnitude+strideOffset))
			
			--Do IK towards foot pos
			Leg.LimbChain:IterateOnce(footPos,0.1)
			Leg.LimbChain:UpdateMotors()
		end
	else--stand still
		for i, Leg in pairs(self.Legs) do
			local strideCF = Leg.StrideCF or self.DefaultStrideCF
			local strideOffset = Leg.StrideOffset or self.DefaultStrideOffset
			local raycastParams = self.RaycastParams

			local hip			=Leg.HipAttachment.WorldPosition
			--Position of where the lower leg should be, spread out
			local desiredPos		=Leg.FootAttachment.WorldPosition+DOWN
			local offset		=(desiredPos-hip)--vector from hip to the circle
			local raycastResult = workspace:Raycast(hip,offset.unit*(offset.magnitude+strideOffset),raycastParams)
			local footPos = raycastResult and raycastResult.Position or (hip + offset.unit*(offset.magnitude+strideOffset))
			
			--Do IK towards foot pos
			Leg.LimbChain:IterateOnce(footPos,0.1)
			Leg.LimbChain:UpdateMotors()
		end
	end
end


function ProceduralAnimatorClass:MoveTorso(stepCycle,dt10,rootVelocity)
	
	local lowercf = self.RootPart.CFrame
	local waistjoint = self.RootMotor
	local waist1 = self.RootMotorC1Store
	local rootvel = rootVelocity


	if self.rootVelocityMagnitude > 0.1 then

		self.WaistCycle = (self.WaistCycle+stepCycle)%360

		local relv0		=lowercf:vectorToObjectSpace(rootvel)
        local relv1		=relv0*0.2
        
		do -- Upper Torso
			local sway = math.rad(-relv1.X)+0.08*math.cos(self.WaistCycle+90)
			local goalCF = waist1*ANGLES(math.rad(relv1.Z),0.1*math.cos(self.WaistCycle)-2*math.rad(relv1.X),sway):inverse()
			goalCF *= CFrame.new(0,math.cos((self.WaistCycle+90+45)*2),0)
            --local rotationOnly = goalCF-goalCF.Position
            waistjoint.C1	=	waistjoint.C1:Lerp(goalCF,dt10)
        end

	else
		--when not moving go back to original position
		local goalCF = waistjoint.C1:Lerp(waist1, dt10)
		--local rotationOnly = goalCF-goalCF.Position
		waistjoint.C1	= goalCF
	end
end
	

function ProceduralAnimatorClass:Animate(dt,onScreen)

	-- Begin the step-------
	local dt10 = math.min(dt*10, 1) -- Normalize dt for our needs

	local rootpart = self.RootPart
	local rootvel0 = rootpart.Velocity -- Our movement velocity

	local rootVelocity = rootvel0 * x_and_y --XY plane velocity only
	local rootVelocityMagnitude = rootVelocity.Magnitude --root velocity magnitude
	self.rootVelocityMagnitude = rootVelocityMagnitude

	--if moving then lerp current direction
	if rootVelocityMagnitude > 0.1 then 
		--lerp current direction towards curren velocity
		self.MovementDirectionXZ = self.MovementDirectionXZ:Lerp(rootVelocity.unit, dt10) 
	end

	local relativizeToHumanoidSpeed = rootVelocityMagnitude/16 --default walk speed is 16
	local stepCycle = relativizeToHumanoidSpeed*dt*self.CycleSpeed

	self:MoveLegs(stepCycle)
	if self.RootMotor then
		self:MoveTorso(stepCycle,dt10,rootVelocity)
	end
	
end

return ProceduralAnimatorClass

But yeah I have been doing a lot of research on structuring my game through Aero framework which tbh felt strict while Selene keeps yelling at me, I’m still learning so haven’t had much chances for these rewarding tasks.

Anyways, any feedback on how the walk looks? The mech model could definitely be better that’s for sure, perhaps I will learn blender one day for its advantages with creating superior details.

Edit: Also the new first-person vehicle camera is really cool and simplifies my life creating a first-person view, too bad the sway and the way it resets can get unbearable hopefully it’s modifiable haven’t looked into it.

44 Likes

GImme and i make big game out of it. Lol but really nice job i love it!

2 Likes

Does the mech make any sounds when it s t o m p s? You should have materials have different particle affects when the mech s t o m p s on it. :eyes:

2 Likes

my recommendations:

3 Likes

A little bit of camera shake when the foot touches the ground, I found this recently: Camera Shaker - Roblox

2 Likes

Immediately I can see this being in a real Roblox game. The cycle itself is very streamline and the way I see it, not many games would have something that was animated like that. What else can I say other than keep going! :+1:

1 Like

Thanks for the advice, I like the second footsteps sounds more, the first one sounds like a printer lol. @Aegians I think there’s enough camera shake for the pilot, I think it would be a good idea for people on the ground to feel the tremor.

Overall seems like more polish is needed as everyone has mentioned as it’s still incomplete. Time to work on it more I guess.

3 Likes

wow, that is pretty cool can jump? if not can you make that?

1 Like

Yep.

It uses a Humanoid to move so it can jump as well. But it looks funny since the upper body isn’t animated. Might be a good gameplay idea for certain types of mechs to have thanks for the idea.

3 Likes

hahah so funny mech go stomp