Deleted post deleted post

Very cool, just for the place to give off a more og feel as @RoninQV said above, change the lighting and decrease the gravity and jump power to get that og jump

Alright, I did it last night, and touched it up today:

It’s a bit more complicated… cause I like that I guess. But I made sure everything was well-commented, efficient, and organized.

The best viewing experience will be if you open the script in studio and right click “Collapse all Folds”

--=========================================================================================>
-- NAME: 2012 Animate Revamped
-- ORIGINAL AUTHOR: carrot (@KyjiPaws)
-- CURRENT AUTHOR: Sato (@IISato)
--==========================================================================================--
--!strict
--==========================================================================================--

-- DEFINE VARIABLES:

-- Service and Instance Variables:
local RunService : RunService, Humanoid : Humanoid, HumanoidRootPart: BasePart
-- Table Variables:
local TorsoData : any, PoseData : any, EventData: any

--==========================================================================================--
--[ UTILITY FUNCTIONS: ]

-- Function which returns whether the Character is moving based on MoveDirection magnitude:
local function IsMoving() : boolean
	
	--=====================================================================--
	
	-- Get Velocity of the HumanoidRootPart (Character Velocity)
	local Velocity = math.floor(HumanoidRootPart.AssemblyLinearVelocity.Magnitude)
	
	-- If MoveDirection Mag is greater than .99 (Meaning Player is trying to move)
	-- AND the actual HumanoidRootPart Velocity (Actual Movement) is greater than 0
	-- Will stop the Run Animation when walking into a wall. (New Feature..)
	return Humanoid.MoveDirection.Magnitude > .99 and Velocity > 0
	
	--=====================================================================--
	
end

-- Function which Changes the Pose from Standing to Running based on whether the Character is moving every frame:
local function RunningUpdate()
	if PoseData.CurrentPose == "Standing" or PoseData.CurrentPose == "Running" then 
		PoseData.CurrentPose = if IsMoving() then "Running" else "Standing"	
	end
end

-- Function which will play the Animation for whichever Pose is active
local function PlayAnimations()

	--=====================================================================--

	-- Assign the CurrentPose value to a local Variable for looks.
	local CurrentPose : string = PoseData.CurrentPose :: string

	--=====================================================================--

	if CurrentPose == "Dead" then

		-- Clear the Event Connections:
		for Index, Event in pairs(EventData) do Event:Disconnect() end

		-- Destroy the Script:
		script:Destroy() 

	end

	if CurrentPose == "Jumping" or CurrentPose == "Freefall" then

		TorsoData['Left Shoulder'].MaxVelocity = 0.5
		TorsoData['Right Shoulder'].MaxVelocity = 0.5
		TorsoData['Left Shoulder']:SetDesiredAngle(-math.pi)
		TorsoData['Right Shoulder']:SetDesiredAngle(math.pi)
		TorsoData['Left Hip']:SetDesiredAngle(0)
		TorsoData['Right Hip']:SetDesiredAngle(0)

	end

	if CurrentPose == "Seated" then

		TorsoData['Left Shoulder'].MaxVelocity = 0.15
		TorsoData['Right Shoulder'].MaxVelocity = 0.15
		TorsoData['Left Shoulder']:SetDesiredAngle(-math.pi / 2)
		TorsoData['Right Shoulder']:SetDesiredAngle(math.pi / 2)
		TorsoData['Left Hip']:SetDesiredAngle(-math.pi / 2)
		TorsoData['Right Hip']:SetDesiredAngle(math.pi / 2)

	end

	if CurrentPose == "Running" or CurrentPose == "Swimming" then

		TorsoData['Left Shoulder'].MaxVelocity = 0.15
		TorsoData['Right Shoulder'].MaxVelocity = 0.15

		local DesiredAngle = 1 * math.sin(os.clock() * 9)

		TorsoData['Left Shoulder']:SetDesiredAngle(DesiredAngle - 0)
		TorsoData['Right Shoulder']:SetDesiredAngle(DesiredAngle + 0)
		TorsoData['Left Hip']:SetDesiredAngle(-DesiredAngle)
		TorsoData['Right Hip']:SetDesiredAngle(-DesiredAngle)

	end

	if CurrentPose == "Climbing" then

		if IsMoving() then

			TorsoData['Left Shoulder'].MaxVelocity = 0.5
			TorsoData['Right Shoulder'].MaxVelocity = 0.5
			TorsoData['Left Hip'].MaxVelocity = 0.1
			TorsoData['Right Hip'].MaxVelocity = 0.1

		else

			TorsoData['Left Shoulder'].MaxVelocity = 0
			TorsoData['Right Shoulder'].MaxVelocity = 0
			TorsoData['Left Hip'].MaxVelocity = 0
			TorsoData['Right Hip'].MaxVelocity = 0
		end

		local DesiredAngle = 1 * math.sin(os.clock() * 9)

		TorsoData['Left Shoulder']:SetDesiredAngle(DesiredAngle - math.pi)
		TorsoData['Right Shoulder']:SetDesiredAngle(DesiredAngle + math.pi)
		TorsoData['Left Hip']:SetDesiredAngle(-DesiredAngle)
		TorsoData['Right Hip']:SetDesiredAngle(-DesiredAngle)

	end

	if CurrentPose == "Standing" then

		TorsoData['Left Shoulder']:SetDesiredAngle(0)
		TorsoData['Right Shoulder']:SetDesiredAngle(0)
		TorsoData['Left Hip']:SetDesiredAngle(0)
		TorsoData['Right Hip']:SetDesiredAngle(0)

	end

	--=====================================================================--

end

--==========================================================================================--
--[ SETUP FUNCTIONS: ]

-- Function which will set and declare any global variables, and setup Data:
local function SetVariables()

	--=====================================================================--

	-- Character Model Instance
	local Character: Model = script:FindFirstAncestorOfClass("Model") :: Model

	-- Character Torso Instance
	local Torso : BasePart = Character:WaitForChild("Torso") :: BasePart

	--=====================================================================--

	-- Roblox RunService
	RunService = game:GetService("RunService") :: RunService

	-- Character Humanoid Instance
	Humanoid = Character:WaitForChild("Humanoid") :: Humanoid
	
	-- Character HumanoidRootPart Instance
	HumanoidRootPart = Character:WaitForChild("HumanoidRootPart") :: BasePart
	
	-- PoseData Dictionary, containing the humanoid states that are allowed as poses, and the currentpose.
	PoseData = {
		-- Allowed Humanoid States as Poses Array:
		Poses = {"Running", "Climbing", "Jumping", "Freefall", "Seated", "Dead", "Swimming"},
		-- CurrentPose the Character is in
		CurrentPose = "Standing"
	}

	-- Empty TorsoData Dictionary to be filled with Instances
	TorsoData = {
		["Left Shoulder"] = "", ["Right Shoulder"] = "", ["Left Hip"] = "", ["Right Hip"] = "", ["Neck"] = ""
	}
	
	-- Declare EventData as an empty table
	EventData = {}
	
	--=====================================================================--

	-- Fill the TorsoData Dict by waiting for each Index in the Torso Instance and adding it to the Dictionary.
	for Index, TorsoChild in TorsoData do TorsoData[Index] = Torso:WaitForChild(Index) end

	--=====================================================================--

end

-- Function which will Connect all the needed events in the script:
local function ConnectEvents()
	
	--=====================================================================--

	EventData["State"] = Humanoid.StateChanged:Connect(function(OldEnmuState, NewEnumState)
		
		--===============================================================--
		-- [ Format Variables: ]

		-- Initiate new Variables which will be the formatted string version of the Enums:
		local NewState: string, OldState: string = tostring(NewEnumState), tostring(OldEnmuState)
		
		-- Replacement Pattern (so that I can one line the variable sets):
		local Pattern = "Enum.HumanoidStateType."
		
		-- Format the String Enums to not have the Enum parts:
		NewState, OldState = string.gsub(NewState, Pattern, ""), string.gsub(OldState, Pattern, "")	
	
		--===============================================================--
		
		-- If Pose is not in the PoseData poses table, return
		if not table.find(PoseData.Poses, NewState) then return end
		
		--===============================================================--
		-- [ Set the changed Pose: ]
		
		if NewState == "Running" then 
			PoseData.CurrentPose = if IsMoving() then "Running" else "Standing"	
		else
			PoseData.CurrentPose = NewState	
		end
		
		--===============================================================--
		
	end)

	EventData["Anim"] = RunService.PreAnimation:Connect(function()

		--===============================================================--
		
		-- Update the Pose if Moving:	
		RunningUpdate()

		-- Motor Animations Function:
		PlayAnimations()
		
		--===============================================================--

	end)

	--=====================================================================--

end

--==========================================================================================--
--[ MAIN SCRIPT FUNCTION: ]

-- Function which will run the Script Setup Functions:
local function Main()
	
	--=====================================================================--
	
	-- Set Script global variables:
	SetVariables()
	
	-- Connect Events:
	ConnectEvents()
	
	--=====================================================================--
	
end

--==========================================================================================--

Main() -- Start the script:

--==========================================================================================--

Some Extras:

  • Movement checker to determine whether the Character is moving to stop Animations from playing otherwise.
  • Used movement check to have Climb Animation only play when moving and climbing and to freeze when still.

Looks like a massive amount of code for something that pretty much does the same thing…
Might look into adding a check for stopping the climbing animation, but at that point I think it’d become its own thing.

Intentionally making my game look ugly just to give off a “classic” vibe is not something I intend on doing.

Be honest, this looks awful.

This on the other hand… :smiling_face_with_three_hearts:

2 Likes

I mean half the lines are comments, and I opted for the one state change event rather than individual state connections.

I’m just a little confused on why, considering the script was already like… 80 lines of code excluding comments. Just seems odd to over complicate what already works fine.

Your code is I believe 120.

Yeah, yours does work fine, it’s good. I just wanted to make it a little more advanced I guess.

My script is about 107 lines in it’s readable form (the condensed version is what i was referring to when I said 80 lines), While yours is about 265 lines.

I don’t really think nearly tripling the length of the script for like, two visible changes, is really worth it in my opinion, at least in the case of a simple little animate script that already takes less than about 10 microseconds to run.

You’re vastly over exaggerating the effect of a 100 lines of code.

1 Like

Alright, I did a load time test of the scripts:
Miniscule difference, but not worse.

Sato’s:
image
Carrot’s
image

My point was that it didn’t matter. Saving 4 microseconds on startup isn’t significant. ;w;

Might need to work on the brightness for compatibility there.

Why are you coping so hard? I told you originally, I was just going to try writing it differently myself.

You’re the one who wanted to one-up my script so I think me criticizing your script is fair… (Which, now that I’m looking again, you deleted your message saying that… Odd…)

Yea that’s the problem… there’s a reason why Legacy and Compatibility were replaced!

Heh no I did not delete it, some dimwit reported it.

1 Like

Works great with contrast adjustment. Adjusting by 0.5 is good.

Both of these images are compatibility:



The 2nd one is the one you posted, and I didn’t make any modifications to the lighting other than changing the contrast to .3 and changing technology to compatibility.

So please, don’t consider compatibility ugly when it looks like shadowmap but without the shadows.


I just realized that the tool animations are missing! I improved the animate script as well to include this and also slow down the update frequency when animations are “idle” (it makes it look more classic as well).

Additionally, it will also adjust the speed of the walk animation depending on the running speed. Here’s the updated script if you want to include some additions or ideas from it:

local RunService = game:GetService("RunService")

local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local Torso = Character:WaitForChild("Torso")
local LeftShoulder = Torso:WaitForChild("Left Shoulder")
local RightShoulder = Torso:WaitForChild("Right Shoulder")
local LeftHip = Torso:WaitForChild("Left Hip")
local RightHip = Torso:WaitForChild("Right Hip")
local Neck = Torso:WaitForChild("Neck")
local GlobalSpeed = 0
local toolAnim = "None"
local toolAnimTime = .3

local updateFrequency = 0.2
local dynamicUpdateFrequency = true --Throttle the animations when necessary.

-- Current Animation
local Pose = "Standing"

-- Connect Events

Humanoid.Died:Connect(function()
	-- No need to animate the dead!
	script:Destroy()
end)

Humanoid.Running:Connect(function(Speed)
	-- Sometimes the speed can get stuck at extremely small values, so this prevents the character running in place
	-- Change '0.1' to '0' for the original behavior
	if Speed > 0.1 then
		Pose = "Running"
		GlobalSpeed = Speed / 16 --default walkspeed
	else
		Pose = "Standing"
		GlobalSpeed = 0
	end
end)

Humanoid.Swimming:Connect(function()
	Pose = "Running"
end)

Humanoid.Jumping:Connect(function()
	Pose = "Jumping"
end)

Humanoid.Climbing:Connect(function()
	Pose = "Climbing"
end)

Humanoid.FreeFalling:Connect(function()
	Pose = "FreeFall"
end)

Humanoid.Seated:Connect(function()
	Pose = "Seated"
end)

-- Update

local function JumpAnimation()
	LeftShoulder.MaxVelocity = 0.5
	RightShoulder.MaxVelocity = 0.5
	LeftShoulder:SetDesiredAngle(-math.pi)
	RightShoulder:SetDesiredAngle(math.pi)
	LeftHip:SetDesiredAngle(0)
	RightHip:SetDesiredAngle(0)
end

local function SitAnimation()
	LeftShoulder.MaxVelocity = 0.15
	RightShoulder.MaxVelocity = 0.15
	LeftShoulder:SetDesiredAngle(-math.pi / 2)
	RightShoulder:SetDesiredAngle(math.pi / 2)
	LeftHip:SetDesiredAngle(-math.pi / 2)
	RightHip:SetDesiredAngle(math.pi / 2)
end

function getTool()	
	for _, kid in ipairs(Character:GetChildren()) do
		if kid.className == "Tool" then return kid end
	end
	return nil
end

function getToolAnim(tool)
	for _, c in ipairs(tool:GetChildren()) do
		if c.Name == "toolanim" and c.className == "StringValue" then
			return c
		end
	end
	return nil
end

function animateTool()

	if (toolAnim == "None") then
		RightShoulder:SetDesiredAngle(1.57)
		return
	end

	if (toolAnim == "Slash") then
		RightShoulder.MaxVelocity = 0.5
		RightShoulder:SetDesiredAngle(0)
		return
	end

	if (toolAnim == "Lunge") then
		RightShoulder.MaxVelocity = 0.5
		LeftShoulder.MaxVelocity = 0.5
		RightHip.MaxVelocity = 0.5
		LeftHip.MaxVelocity = 0.5
		RightShoulder:SetDesiredAngle(1.57)
		LeftShoulder:SetDesiredAngle(1.0)
		RightHip:SetDesiredAngle(1.57)
		LeftHip:SetDesiredAngle(1.0)
		return
	end
end

local lastUpdate = 0
RunService.RenderStepped:Connect(function()
	local time = time()
	if time - lastUpdate < updateFrequency then
		return
	end
	lastUpdate = time
	if Pose == "Jumping" or Pose == "FreeFall" then
		JumpAnimation()
		return
	end

	if Pose == "Seated" then
		SitAnimation()
		return
	end

	local Amplitude = 0.1
	local Frequency = 1
	-- I have no idea why this is called 'ClimbFudge'
	local ClimbFudge = 0

	if Pose == "Running" then
		LeftShoulder.MaxVelocity = 0.15
		RightShoulder.MaxVelocity = 0.15
		Amplitude = 1
		Frequency = 9 * GlobalSpeed
	elseif Pose == "Climbing" then
		LeftShoulder.MaxVelocity = 0.5
		RightShoulder.MaxVelocity = 0.5
		Amplitude = 1
		Frequency = 9
		ClimbFudge = math.pi
	end

	local DesiredAngle = Amplitude * math.sin(time * Frequency)

	LeftShoulder:SetDesiredAngle(DesiredAngle - ClimbFudge)
	RightShoulder:SetDesiredAngle(DesiredAngle + ClimbFudge)
	LeftHip:SetDesiredAngle(-DesiredAngle)
	RightHip:SetDesiredAngle(-DesiredAngle)
	
	local tool = getTool()

	if tool then

		local animStringValueObject = getToolAnim(tool)

		if animStringValueObject then
			toolAnim = animStringValueObject.Value
			-- message recieved, delete StringValue
			animStringValueObject:Destroy()--.Parent = nil
			toolAnimTime = time + .3
		end

		if time > toolAnimTime then
			toolAnimTime = 0
			toolAnim = "None"
		end

		animateTool()


	else
		toolAnim = "None"
		toolAnimTime = 0
	end
	
	if dynamicUpdateFrequency then
		updateFrequency = (Frequency > 1 and 0) or .1
	end
end)

I apologize in advance for using camelCase variable names.

Sounds like a good idea! Not only would this be more performant, but it could possibly work with R15 using this thing I made to create animations with both rigs:

If you don’t choose to use it, that’s fine. I think it would be neat though.