You can write your topic however you want, but you need to answer these questions:
- What do you want to achieve? Keep it simple and clear!
I want to make titans from Attack On Titans, and I have already made the titan model and a bit of the AI.
- What is the issue? Include screenshots / videos if possible!
The issue is that the titans keep tripping and falling over:
- What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I have already disabled all the states except for running, jumping, falling, dead, and none (because it errors if you turn it off)
I also tried changing all the densities of all the parts in the titans to 10.
Spawn code:
local CS = game:GetService("CollectionService")
local Titans = script.Titans:GetChildren()
local RAND = Random.new()
local TitanCount = 0
local MaxCount = 5
local function recalculateHipHeight(character)
local bottomOfHumanoidRootPart = character.HumanoidRootPart.Position.Y - (1/2 * character.HumanoidRootPart.Size.Y)
local bottomOfFoot = character.LeftFoot.Position.Y - (1/2 * character.LeftFoot.Size.Y)
local newHipHeight = bottomOfHumanoidRootPart - bottomOfFoot
local humanoid = character:FindFirstChildOfClass("Humanoid")
humanoid.HipHeight = newHipHeight
end
while true do
wait(RAND:NextNumber(5,7.5))
if TitanCount > MaxCount then continue end
local clone = Titans[RAND:NextInteger(1,#Titans)]:Clone()
clone:SetPrimaryPartCFrame(CFrame.new(RAND:NextNumber(-100,100),25,RAND:NextNumber(-100,100)))
recalculateHipHeight(clone)
for i,v in ipairs(clone:GetChildren()) do
if v:IsA("BasePart") then
local BaseProperties = PhysicalProperties.new(10,0.3,0.5,1,1)
v.CustomPhysicalProperties = BaseProperties
end
end
clone.Parent = workspace
clone:WaitForChild("Humanoid").Died:Connect(function()
local descendants = clone:GetDescendants()
for i = 1, #descendants do
local desc = descendants[i]
if desc:IsA("Motor6D") then
local socket = Instance.new("BallSocketConstraint")
local part0 = desc.Part0
local joint_name = desc.Name
local attachment0 = desc.Parent:FindFirstChild(joint_name.."Attachment") or desc.Parent:FindFirstChild(joint_name.."RigAttachment")
local attachment1 = part0:FindFirstChild(joint_name.."Attachment") or part0:FindFirstChild(joint_name.."RigAttachment")
if attachment0 and attachment1 then
socket.Attachment0, socket.Attachment1 = attachment0, attachment1
socket.Parent = desc.Parent
desc:Destroy()
end
end
end
local HRP = clone:FindFirstChild("HumanoidRootPart")
if HRP then
HRP.CanCollide = false
end
TitanCount = TitanCount - 1
if not clone.Parent then return end
clone:WaitForChild("Nape"):WaitForChild("Attachment"):WaitForChild("Slice"):Play()
clone:WaitForChild("Nape"):WaitForChild("BodyThrust").Force = clone:WaitForChild("Nape").CFrame:VectorToWorldSpace(Vector3.FromNormalId(Enum.NormalId.Front) * 40000)
for i = 1,4 do
clone:WaitForChild("Nape"):WaitForChild("Attachment"):WaitForChild("BloodEmitter"):Emit(25)
wait()
end
--clone:WaitForChild("Nape"):WaitForChild("Attachment"):WaitForChild("Hit"):Emit(25)
wait(0.25)
for i = 1,4 do
clone:WaitForChild("Nape"):WaitForChild("Attachment"):WaitForChild("BloodEmitter"):Emit(25)
wait()
end
clone:WaitForChild("Nape"):WaitForChild("BodyThrust").Force = Vector3.new()
game.Debris:AddItem(clone,10)
end)
TitanCount = TitanCount + 1
end
Titan behavior:
local TitanBehavior = {}
TitanBehavior.__index = TitanBehavior
local function findClosestCharacter(RootPart)
local character
local lastPos = Vector3.new()
local lastDist = math.huge
for i,v in ipairs(game.Players:GetPlayers()) do
local char = v.Character
if not char then continue end
local hum = char:FindFirstChild("Humanoid")
if not hum or not hum.Health then continue end
local rpPos = char:FindFirstChild("HumanoidRootPart").Position
local dist = (RootPart.Position - rpPos).Magnitude
if (dist < lastDist) then
lastPos = rpPos
lastDist = dist
character = char
else
continue
end
end
if character then
return character:FindFirstChild("HumanoidRootPart")
else
return nil
end
end
function TitanBehavior:New(hum)
local self = {}
self.Humanoid = hum
self.Model = hum.Parent
self.Type = hum.Parent.Name
self.State = "Idle"
self.Switch = false
self.Animations = {}
self.StateChangedEvent = Instance.new("BindableEvent")
self.StateChanged = self.StateChangedEvent.Event
self.StateChanged:Connect(function(old,new)
local newState = tostring(new)
if self.Animations[newState] then
local AnimData = self.Animations[newState]
for i,v in ipairs(self.Humanoid:GetPlayingAnimationTracks()) do
v:Stop()
end
if AnimData.Looped then
AnimData.Playing = true
AnimData.Anim:Play()
else
AnimData.Playing = true
AnimData.Anim:Play()
AnimData.Anim.Stopped:Wait()
AnimData.Playing = false
end
end
end)
for i,v in ipairs(script:GetChildren()) do
if v:IsA("Animation") then
self.Animations[v.Name] = {
Playing = false;
Anim = hum:LoadAnimation(v);
}
self.Animations[v.Name].Looped = self.Animations[v.Name].Anim.Looped
self.Animations[v.Name].Anim.Priority = Enum.AnimationPriority.Action
end
end
for i,v in ipairs(Enum.HumanoidStateType:GetEnumItems()) do
local state = string.sub(tostring(v),24,-1)
if state == "Dead" or state == "None" then continue end
if not script:FindFirstChild(state) then
self.Humanoid:SetStateEnabled(v,false)
else
self.Humanoid:SetStateEnabled(v,true)
end
end
return setmetatable(self,TitanBehavior)
end
function TitanBehavior:SeekCharacter(switch)
assert(self,"Variable 'self' misssing; use function 'SeekCharacter' as a method.")
self.Switch = switch
while self.Switch do
wait(2)
if not self.Model:FindFirstChild("HumanoidRootPart") then break end
local rp = findClosestCharacter(self.Model.HumanoidRootPart)
if (self.Model.HumanoidRootPart.Position - rp.Position).Magnitude <= 5 then break end
self.Humanoid:Move(CFrame.new(self.Model.HumanoidRootPart.Position,rp.Position).LookVector,false)
end
end
function TitanBehavior:SetupAnimations()
assert(self,"Variable 'self' misssing; use function 'SetupAnimations' as a method.")
local StateFunctions = {
Running = function(speed)
if (speed > 0) then
if self.State ~= "Running" then
self.StateChangedEvent:Fire(self.State,"Running")
self.State = "Running"
end
else
if self.State ~= "Idle" then
self.StateChangedEvent:Fire(self.State,"Idle")
self.State = "Idle"
end
end
end;
Jumping = function(active)
if active then
if self.State ~= "Jumping" then
self.StateChangedEvent:Fire(self.State,"Jumping")
self.State = "Jumping"
end
else
if self.State ~= "Idle" then
self.StateChangedEvent:Fire(self.State,"Idle")
self.State = "Idle"
end
end
end;
FreeFalling = function(active)
if active then
if self.State ~= "Falling" then
self.StateChangedEvent:Fire(self.State,"Falling")
self.State = "Falling"
end
else
if self.State ~= "Idle" then
self.StateChangedEvent:Fire(self.State,"Idle")
self.State = "Idle"
end
end
end;
Died = function()
self.State = "Died"
end;
}
for i,v in pairs(StateFunctions) do
self.Humanoid[i]:Connect(v)
end
end
function TitanBehavior:Destroy()
assert(self,"Variable 'self' misssing; use function 'Destroy' as a method.")
setmetatable(self,nil)
return nil
end
return TitanBehavior
Thanks ahead of time