Jump to content
nick.ace

Change crouch height

Recommended Posts

One problem I found is that there is no way to change the crouch height which creates a big problem when you want the character to go into small spaces such as vents. A command such as SetCrouchHeight(float height) would be ideal.

Share this post


Link to post

Actually, I just tested it out. Paths that the controller can go through while crouched are not created in the navmesh, so this shouldn't have an effect with navigation.

Share this post


Link to post

I got a crouch-able player working, What it does is if the user lets go of ctrl, a picker test is made to see if the player can stand up. Here is the entire code with unfinished features:

 

import "Scripts/Functions/ReleaseTableObjects.lua"
--[[
Purpose: A FPS Player that walks, jumps, crouch, and can use and pickup stuff.
This is ment to be a alternative version than the one shipped with the SDK.
Keywords:
#Camera
#Movement
#Water
#KeyInput
#Flashlight
#Use
#Pickup
#Health
#Respawn
#Death
#Life
#Damage
#Hurt
#Kill
#Weapons
]]--
Script.input={}
-- Life
Script.health = 100 --float "Starting Health"
Script.savedhealth=nil
Script.maxHealth = 100
Script.alive=true
Script.bregenghealth=false --bool "Regen. Health"
Script.RegenTimer = 0
Script.RegenWaitTimer = 0
-- Camera
Script.camSmoothing = 4
Script.mouseSensitivity = 15
Script.mouseDifference = Vec2(0,0)
Script.eyeheight=1.30
-- Movement
Script.moveSpeed = 5.0
Script.footstepwalkdelay = 500
Script.footsteprundelay = 300
Script.jumpForce = 8
Script.supressmovement = false --bool "Freeze Player"
Script.allowcrouching = false -- bool "Allow Crouching"
Script.canuncrouch = false
Script.falldamage=true --bool "Fall Damage"
Script.falldamagekills=true --bool "Fall Can Kill"
Script.FallTimer= 0
-- Water
Script.UnderWater= false
-- Respawn
Script.RectangleAlpha = 0
Script.RespawnPoint=nil --entity "Respawn Point"
Script.RespawnPointPosition=Vec3(0,0,0)
Script.RespawnPointRotation=Vec3(0,0,0)
Script.RespawnTimer = 0
Script.RespawnDelay = 1.0 --float "Respawn Time"
-- Use
Script.useDistance = 2
Script.maxcarryweight=80
Script.throwforce = 500 --float "Throw Force"
-- Weapon
Script.weaponfile=""--path "Starting Weapon" "Prefab (*.pfb):pfb|Prefabs"
--Script.weaponfile="Prefabs/Gameplay/VecGun.pfb"
-- Flashlight
Script.useflashlight = false --bool "Flashlight"
Script.flashlighton= false
-- Crosshair + HUD
Script.supresscrosshair=false --bool "Hide Crosshair"
Script.supresshud=false --bool "Hide Health"
function Script:Start()
--Set the type for this object to player
self.entity:SetKeyValue("type","player")

-- If we are not a pivot, then make the editor model invisible.
if (self.entity:GetClass() ~= Object.PivotClass) then --1
System:Print("Player is not a pivot. Making entity invisible.")
material = Material:Create()
material:SetBlendMode(5)--Blend.Invisible
self.entity:SetMaterial(material)
material:Release()
end

self.savedhealth = self.health

-- Draw HUD/Crosshair
self.image={}
self.image.crosshair = Texture:Load("Materials/HUD/crosshair.tex")
self.hudfont = Font:Load("Fonts/Arial.ttf",36)

-- Sounds
self.sound={}--table to store sound in

-- Flashlight (Only if enabled.)
if self.useflashlight then
--self.sound.flashlight=Sound:Load("Sound/Player/flashlight_02_on.wav")
self.sound.flashlight=Sound:Load("Sound/Player/body_punch_03.wav")
end

-- Damage
self.sound.damage={}
self.sound.damage[1]=Sound:Load("Sound/Player/body_punch_03.wav")
self.sound.damage[2]=Sound:Load("Sound/Player/body_punch_04.wav")


self.sound.damage.fall=Sound:Load("Sound/Player/damage_fall_01.wav")
self.playfellsound= false

self.sound.damage.dead=Sound:Load("Sound/Player/death.wav")
self.playdeathsound = false

-- Footsteps
self.sound.footsteps={}
self.sound.footsteps[1] = Sound:Load("Sound/Player/Footsteps/concrete1.wav")
self.sound.footsteps[2] = Sound:Load("Sound/Player/Footsteps/concrete2.wav")
self.sound.footsteps[3] = Sound:Load("Sound/Player/Footsteps/concrete3.wav")
self.sound.footsteps[4] = Sound:Load("Sound/Player/Footsteps/concrete4.wav")

-- Jump and Land
self.sound.footsteps.jump = Sound:Load("Sound/Player/Footsteps/concrete2.wav")
self.sound.footsteps.land = Sound:Load("Sound/Player/Footsteps/concrete4.wav")

-- Use
self.sound.pickup=Sound:Load("Sound/Player/pickup.wav")
self.sound.usedeny=Sound:Load("Sound/Player/use_deny.wav")

-- Water
--self.sound.underwater=Sound:Load("Sound/Player/underwater.wav")
--self.playUnderWatersound= false

-- Ignore pickers from picking us!
self.entity:SetPickMode(0)

-- Physics
self.entity:SetCollisionType(Collision.Character)
self.entity:SetPhysicsMode(Entity.CharacterPhysics)
self.entity:SetGravityMode(true)
self.crouched=false

self.entity:SetMass(10)
if self.entity:GetMass()==0 then Debug:Error("Player mass should be greater than 0.") end
-- Create a camera
local window = Window:GetCurrent()
local context = Context:GetCurrent()

self.camera = Camera:Create()
self.camera:SetFOV(74)
self.camera:SetRange(0.05,1000)
self.camera:SetMultisampleMode((System:GetProperty("multisample","1")))
-- Set the camera's rotation to match the player
self.camRotation = self.entity:GetRotation(true)
self.camera:SetRotation(self.entity:GetRotation(true))

-- Set the camera position at eye height
self.camera:SetPosition(self.entity:GetPosition(true)+Vec3(0,self.eyeheight,0))

-- Tie the mouse position to the camera's rotation
window:SetMousePosition(Math:Round(context:GetWidth()/2), Math:Round(context:GetHeight()/2))
self.camera:SetRotation(self.camRotation)

--Create listener
self.listener = Listener:Create(self.camera)

--#Flashlight
if self.useflashlight then
self.flashlight = SpotLight:Create()
self.flashlight:SetParent(self.camera,false)
self.flashlight:SetPosition(0.2,-0.1,0)
self.flashlight:SetRotation(10,-3,0)
self.flashlight:SetConeAngles(25,15)
self.flashlight:SetShadowMode(Light.Dynamic+Light.Static)

if self.flashlighton==false then
self.flashlight:Hide()
end
end

-- Weapons
self.weapons={}
self.currentweaponindex=-1
self.weaponlowerangle=0
self.weapontag = Pivot:Create(self.camera)
self:LoadWeapon()

end
--This function will be called once per world update
function Script:UpdateWorld()
self:UpdateCamera()
self:UpdateOverlay()

if self.bregenghealth then
self:RegenHealth()
end

self:UpdateUse()
self:Weapon()

self:ListenForKeys()

-- If our health is 0, then we are dead.
if self.health <= 0 then
self:Kill()
-- If we have a respawn point vaild, repspawn the player after a second or so.
self.RespawnTimer = self.RespawnTimer + (Time:GetSpeed() /100)
if self.RespawnTimer > self.RespawnDelay then
self:Respawn()
end
end

end
--This function will be called once per physics update
function Script:UpdatePhysics()
if not self.supressmovement then
self:UpdateMovement()
end

self:UpdatePickupObject()
end
-- #KeyInput
function Script:ListenForKeys()
local window = Window:GetCurrent()
-- If we are in devmode, Show the camera physics models.
if System:GetProperty("dev","0")=="1" then
if window:KeyHit(Key.P) then
physics = not physics
self.camera:SetDebugPhysicsMode(physics)
end
end
--Exit the function early if the player is dead
if self:IsAlive() <= 0 then return end
self:FireWeapon(window)

if window:KeyHit(Key.R) then
if self.weapons[self.currentweaponindex]~=nil then
if type(self.weapons[self.currentweaponindex].CanReload)=="function" then
if self.weapons[self.currentweaponindex]:CanReload() then
 self.suspendfire=false
 self.weapons[self.currentweaponindex]:Reload()
end
end
end
end

--Toggle the #Flashlight
if self.useflashlight then
if window:KeyHit(Key.F) then
self.sound.flashlight:Play()
if self.flashlight:Hidden() then
self.flashlight:Show()
else
self.flashlight:Hide()
end
end
end

--Throw object if holding one
if self.throwforce > 0 then
if self.carryingEntity then
if window:MouseHit(1) then
local dir = Transform:Vector(0,0,self.throwforce,self.camera,nil)
self.carryingEntity:AddForce(dir)
self:DropEntityCarrying()
end
end
end

-- Check for crouching
if window:KeyDown(Key.ControlKey) and self.allowcrouching then
self.crouched = true
else
if self.crouched then
self:CanUnCrouch()
if self.canuncrouch then
self.crouched = false
end
end
end
end
-- #Camera
-- Update the camera with mouse look.
function Script:UpdateCamera()
local window = Window:GetCurrent()
local context=Context:GetCurrent()

--Mouse look
self.currentMousePos = window:GetMousePosition()
window:SetMousePosition(Math:Round(context:GetWidth()/2), Math:Round(context:GetHeight()/2))
self.currentMousePos.x = Math:Round(self.currentMousePos.x)
self.currentMousePos.y = Math:Round(self.currentMousePos.y)
self.mouseDifference.x = Math:Curve(self.currentMousePos.x - Math:Round(context:GetWidth()/2),self.mouseDifference.x,3)
self.mouseDifference.y = Math:Curve(self.currentMousePos.y - Math:Round(context:GetHeight()/2),self.mouseDifference.y,3)
self.camRotation.x = Math:Clamp(self.camRotation.x + self.mouseDifference.y / self.mouseSensitivity,-90,90)
self.camRotation.y = self.camRotation.y + (self.mouseDifference.x / self.mouseSensitivity)

self.camera:SetRotation(self.camRotation)

-------------------------------------------
--With smoothing
local playerPos = self.entity:GetPosition()
local newCameraPos = self.camera:GetPosition()
newCameraPos = Vec3(playerPos.x, newCameraPos.y ,playerPos.z)
self.crouchedheight = 1.5

if self.crouched==true then
if newCameraPos.y<playerPos.y + self.crouchedheight then
newCameraPos.y = Math:Curve(playerPos.y + self.crouchedheight, newCameraPos.y, self.camSmoothing)
else
newCameraPos.y = playerPos.y + self.crouchedheight
end
elseif newCameraPos.y<playerPos.y + self.eyeheight then
newCameraPos.y = Math:Curve(playerPos.y + self.eyeheight, newCameraPos.y, self.camSmoothing)
else
newCameraPos.y = playerPos.y + self.eyeheight
end

if self:IsAlive() >= 1 and not self.crouched then
self.camera:SetPosition(newCameraPos)
else
deathCameraPos = Vec3(playerPos.x, newCameraPos.y-0.25,playerPos.z)
self.camera:SetPosition(deathCameraPos)
end

--[[
--Not done!
local world = World:GetCurrent()
local waterenabled= world:GetWaterMode()
local height= world:GetWaterHeight()

if waterenabled then
if (self.camera:GetPosition().y < height) then
self.UnderWater = true
else
self.UnderWater = false
end
end
]]--

end
-- Test crouching. If we are undersomething, don't get up.
function Script:CanUnCrouch()
local pickInfo = PickInfo()
local p0 = self.entity:GetPosition()
local p1 = Transform:Point(0,1.6,0,self.entity,nil)
--if self.entity.world:Pick(p0,p1, pickInfo, 0, true, 3 ) then
if self.entity.world:Pick(p0,p1, pickInfo, 0, true, Collision.Prop ) then
--System:Print("NO")
self.canuncrouch = false
else
--System:Print("YES")
self.canuncrouch = true
end
end
-- Change the camera's rotation
function Script:SetCameraRotation(rot)
self.camRotation = rot
end
-- #Movement
-- Update movement
function Script:UpdateMovement()
--Exit the function early if the player is dead
if self:IsAlive() <= 0 then return end

local window = Window:GetCurrent()

--Player Movement
local movex=0
local movez=0
self.input[0]=0
self.input[1]=0
if window:KeyDown(Key.W) then self.input[1]=self.input[1]+1 end
if window:KeyDown(Key.S) then self.input[1]=self.input[1]-1 end
if window:KeyDown(Key.D) then self.input[0]=self.input[0]+1 end
if window:KeyDown(Key.A) then self.input[0]=self.input[0]-1 end

local playerMovement = Vec3(0)
playerMovement.x = self.input[0] * self.moveSpeed
playerMovement.z = self.input[1] * self.moveSpeed

if self.crouched then
playerMovement.x = self.input[0] * self.moveSpeed / 2
playerMovement.z = self.input[1] * self.moveSpeed /2
else
playerMovement.x = self.input[0] * self.moveSpeed
playerMovement.z = self.input[1] * self.moveSpeed

--Update the footstep sounds when walking
self:UpdateFootsteps()

end

--This prevents "speed hack" strafing due to lazy programming
if self.input[0]~=0 and self.input[1]~=0 then
playerMovement = playerMovement * 0.70710678
end
-- Check for jumping
local jump = 0
if window:KeyHit(Key.Space) and not self.crouched then
-- If we are not under the water, jump normally.
if not self.UnderWater and self:IsAirborne() == 0 then
jump = self.jumpForce
self.sound.footsteps.jump:Play()

if self.weapons[self.currentweaponindex]~=nil then
self.weapons[self.currentweaponindex]:BeginJump()
end
--Give the player an extra boost when jumping
playerMovement = playerMovement * 1.6
else
-- self.entity:AddForce(0,5,0)
end
end

--Position camera at correct height and playerPosition
self.entity:SetInput(self.camRotation.y, playerMovement.z, playerMovement.x, jump , self.crouched, 1.0, 0.5, true)
if self.isairborne==true then
if self.entity:GetAirborne()==false then
if self.weapons[self.currentweaponindex]~=nil then
self.weapons[self.currentweaponindex]:BeginLand()
end

--System:Print("Landed! Fell for " ..self.FallTimer)

if self.FallTimer > 1 then -- 0.1001
self.sound.footsteps.land:Play()
end

self.FallTimer = 0

if not self.UnderWater then
--self.camera:EmitSound(self.sound.footsteps.jump,50,1,1,false)
end
end

--System:Print("InAir")
self.FallTimer = self.FallTimer + (Time:GetSpeed() /10)

end

self.isairborne = self.entity:GetAirborne()

-- #Water
-- Handle under water movement
--[[
local world = World:GetCurrent()
local waterenabled= world:GetWaterMode()

if waterenabled then
self:UnderWaterMovement()
end
--]]
end
--[[
-- #Water (Not Done)
function Script:UnderWaterMovement()

if self.UnderWater then
self.entity:SetGravityMode(false)

if not self.playUnderWatersound then
--self.sound.underwater:Play()
self.playUnderWatersound = true
end

else
self.entity:SetGravityMode(true)
self.playUnderWatersound = false
end
end
--]]
-- Don't allow any walking movement
function Script:FreezePlayer()--in
self.supressmovement = true
end
function Script:UnFreezePlayer()--in
self.supressmovement = false
end
--Return whether the player is airborne
function Script:IsAirborne()
return self.entity:GetAirborne() and 1 or 0
end
--Return whether the player is crouching
function Script:IsCrouched()
return self.crouched and 1 or 0
end
--Return whether the player is underwater
function Script:IsUnderWater()
return self.UnderWater and 1 or 0
end
--This function plays footstep sounds in regular intervals as the player walks
function Script:UpdateFootsteps()
if self.UnderWater then return end
if self.lastfootsteptime==nil then self.lastfootsteptime=0 end
if self.input[0]~=0 or self.input[1]~=0 then
local speed = self.entity:GetVelocity():xz():Length()
if self.entity:GetAirborne()==false then
if (speed>self.moveSpeed*0.5) then
local t = Time:GetCurrent()
local repeatdelay = self.footstepwalkdelay
--if speed>self.moveSpeed * (1+(self.speedMultiplier-1)*0.5) then repeatdelay = self.footsteprundelay end
if t-self.lastfootsteptime>repeatdelay then
 self.lastfootsteptime = t
 local index = math.random(1,4)
 self.sound.footsteps[index]:Play()
end
end
end
end
end
-- #Use + #Pickup
function Script:UpdateUse()
--Exit the function early if the player is dead
if self:IsAlive() <= 0 then return end
local window = Window:GetCurrent()
local context=Context:GetCurrent()

local pickInfo = PickInfo()

--Raycast Pick that is being send from the camera in to the world
self.canUse = false
if window:KeyHit(Key.E) then
if self.carryingEntity then
self:DropEntityCarrying()
else
local p0 = self.camera:GetPosition(true)
local p1 = Transform:Point(0,0,self.useDistance,self.camera,nil)
--if self.entity.world:Pick(p0,p1, pickInfo, 0, true, 3 ) then
if self.entity.world:Pick(p0,p1, pickInfo, 0, true, Collision.Prop ) then

--Looks for any entity in the hierarchy that has a "Use" function
local usableentity = self:FindUsableEntity(pickInfo.entity)

if usableentity~=nil then
 --Use the object, whatever it may be
 usableentity.script:Use(self)
else
 if not self.iscarryingEntity and self.carryingEntity == nil then
 mass = pickInfo.entity:GetMass()
 if mass>0 and mass<=self.maxcarryweight then
 self.carryingEntity = pickInfo.entity
 self.iscarryingEntity = true
 self.carryingobjectcollisiontype = self.carryingEntity:GetCollisionType()
 self.carryingEntity:SetCollisionType(Collision.PickedUpProp)
 self.sound.pickup:Play()
 self.carryrotation = Transform:Rotation(pickInfo.entity:GetQuaternion(true),nil,self.camera)
 self.carryposition = Transform:Point(pickInfo.entity:GetPosition(true),nil,self.camera)
 end
 end

 -- If it's just basic geometry, play the deny sound.
 local infocollisiontype = pickInfo.entity:GetCollisionType()
 local infoscript = pickInfo.entity.script
 if infocollisiontype==Collision.Scene and infoscript == nil then
 self.sound.usedeny:Play()
 end
end
else
self.sound.usedeny:Play()
--self.entity:EmitSound(self.sound.usedeny, 45 / 100, 0.5, 1, false)
end
end
end

if self.carryingEntity == nil then
local p0 = self.camera:GetPosition(true)
local p1 = Transform:Point(0,0,self.useDistance,self.camera,nil)
-- Fixed pickinfo hitting triggers! -reep
--if self.entity.world:Pick(p0,p1, pickInfo, 0, true, 3 ) then
if self.entity.world:Pick(p0,p1, pickInfo, 0, true, Collision.Prop ) then
local collisiontype = pickInfo.entity:GetCollisionType()
if (collisiontype==Collision.Prop or collisiontype==Collision.Character or 10) then
if self:FindUsableEntity(pickInfo.entity)~=nil then
 self.canUse=true
else
 local mass = pickInfo.entity:GetMass()
 -- Has to be atleast 1kg -reep
 if mass>1 and mass<=self.maxcarryweight then
 self.canUse = true
 end
end
end
end
end

end
-- Update the Pickuped item
function Script:UpdatePickupObject()
if self.carryingEntity then
local currentpos = self.carryingEntity:GetPosition(true)

local pos = Transform:Point(self.carryposition,self.camera,nil)
local rot = Transform:Rotation(self.carryrotation,self.camera,nil)
local maxdiff = 0.5
local diff = pos:DistanceToPoint(currentpos)

--Drop the carryinItem when the distance between camera and item exceed the pickdistance
if diff>1.5 then
self:DropEntityCarrying()
else
if diff>maxdiff then
pos = currentpos + (pos-currentpos):Normalize()*maxdiff
diff = maxdiff
end
self.carryingEntity:PhysicsSetPosition(pos.x,pos.y,pos.z,0.25)
self.carryingEntity:PhysicsSetRotation(rot,0.5)
end
end
end
function Script:DropEntityCarrying()
self.carryingEntity:SetCollisionType(self.carryingobjectcollisiontype)
self.iscarryingEntity = false
self.carryingEntity = nil
end
-- Find a useable entitiy
function Script:FindUsableEntity(entity)
while entity~=nil do
if entity.script then
if type(entity.script.Use)=="function" then
--If "enable" has not been set, it still won't be "false" so this will pass:
if entity.script.enabled~=false or entity.script.canuse~=false then
 return entity
else
 self.sound.usedeny:Play()
 --self.entity:EmitSound(self.sound.usedeny, 45 / 100, 0.5, 1, false)
 return nil
end
end
end
entity = entity:GetParent()
end
-- If we've got nothing, play the deny use sound.
--self.sound.usedeny:Play()
return nil
end
-- #UI
-- Toggle some of the drawing
function Script:SupressCrosshair()--in
self.supresscrosshair = true
end
function Script:UnSupressCrosshair()--in
self.supresscrosshair = false
end
function Script:SupressHUD()--in
self.supresshud = true
end
function Script:UnSupressHUD()--in
self.supresshud = false
end
function Script:PostRender(context)
-- Open the context
context:SetBlendMode(Blend.Alpha)
context:SetColor(1,1,1,0.8)

-- If we are alive, draw our crosshair
if self:IsAlive() >= 1 and not self.iscarryingEntity then
-- Don't draw if the image is missing or we are hiding it.
if self.image.crosshair and not self.supresscrosshair then
local crossHairX = math.floor((context:GetWidth() - self.image.crosshair:GetWidth()))/2
local crossHairY = math.floor((context:GetHeight() - self.image.crosshair:GetHeight()))/2
context:DrawImage(self.image.crosshair, crossHairX, crossHairY)
end
end

--- DRAW ALL OTHER UI ELEMENTS YOU WISH TO BE UNDER THE OVERLAY BEFORE THIS LINE --

-- Draw a rectangle for damage indication
local x = System:GetProperty("screenwidth","1024")
local y = System:GetProperty("screenheight","768")

if not self.alive then
self.RectangleAlpha = 0.35
end

context:SetColor(1,0,0,self.RectangleAlpha)
context:DrawRect(0,0,x,y)

context:SetColor(1,1,1,1)

--- DRAW ALL OTHER UI ELEMENTS YOU WISH TO BE OVER THE OVERLAY AFTER THIS LINE --

-- If we are alive, draw our health on screen
if self:IsAlive() >= 1 and not self.supresshud then

-- Draw the background
context:SetColor(0,0,0,0.5) -- Color of Background
--context:DrawRect(8,670,140,50)
local RectX = 140
local RectY = 50
context:DrawRect(8, context:GetHeight() - RectY - 8, RectX, RectY)


-- Now the actual display of the numbers.

-- Change color depending on the health.
if self.health >= 100 or self.health > 50 then
context:SetColor(0,1,0,1) -- Green
else
if self.health <= 50 then
context:SetColor(1,1,0,1) -- Yellow
end

if self.health < 20 then
context:SetColor(1,0,0,1) -- Red
end
end

context:SetFont(self.hudfont)
--context:DrawText("+",14,684)
context:DrawText("+",14, context:GetHeight() - 46)
--context:DrawText(self.health,60,678)
context:DrawText(self.health,60,context:GetHeight() - 50)
end
context:SetColor(1,1,1,1)
context:SetBlendMode(1)
end
-- #Health
-- #Respawn
-- #Death
-- #Life
-- #Damage
-- #Hurt
-- #Kill
--Return whether the player is Alive
function Script:IsAlive()
return self.alive and 1 or 0
end
-- Fall and Physics Damage
function Script:Collision(entity,position,normal,speed)
if speed >= 20 and self.FallTimer >= 5.0 then
if self.falldamagekills then
self:Kill()
else
self:TakeDamage(1)
if not self.playfellsound then
self.camera:EmitSound(self.sound.damage.fall,5,1,1,false)
self.playfellsound = true
end
end
else
if not self.falldamage then return end
if speed > 18 then
self:TakeDamage(1)
--local index = math.random(1,4)
--self.sound.damage.fall[index]:Play()
if not self.playfellsound then
self.camera:EmitSound(self.sound.damage.fall,5,1,1,false)
self.playfellsound = true
end
else
self.playfellsound = false
end
end
--System:Print(speed)
end
--Increase health
function Script:GiveHealth(healthPoints)--in
--Increase health
self.health = self.health + healthPoints;
--Health can not be more then maximum health
if self.health > self.maxHealth then
self.health = self.maxHealth
end

--Call Health received output
self.component:CallOutputs("GiveHealth")
end
function Script:RegenHealth()
--Exit the function early if the player is dead
if self:IsAlive() <= 0 then return end
if self.health >= self.maxHealth then return end
self.RegenTimer = self.RegenTimer + (Time:GetSpeed() /100)
self.RegenWaitTimer = self.RegenWaitTimer + (Time:GetSpeed() /100)
if self.RegenWaitTimer > 0.5 then
if self.RegenTimer > 0.01 then

--Increase health
self.health = self.health + 1;
--Health can not be more then maximum health
if self.health > self.maxHealth then
self.health = self.maxHealth
end

self.RegenTimer=0
end
end
end
--TakeDamage
function Script:TakeDamage(damage)
if self.health>0 then
--Decrease health
self.health = self.health - damage;

--Stop Timer
self.RegenTimer=0
self.RegenWaitTimer=0
self.component:CallOutputs("OnTakeDamage")
-- Add redness to the overlay!
if (self.RectangleAlpha < 0.35) then
self.RectangleAlpha=self.RectangleAlpha+0.10
self.sound.damage[math.random(#self.sound.damage)]:Play()
end
end

end
-- Life, Death, and Getting Hurt...
function Script:UpdateOverlay()
if self.savedhealth ~= self.health then
if (self.RectangleAlpha ~= 0) then
self.RectangleAlpha=self.RectangleAlpha-.08*Time:GetSpeed()/10 --use getspeed to be fps independant.
end

if self.RectangleAlpha <= 0 then
self.savedhealth = self.health
end
end
end
-- Same as TakeDamage.
function Script:Hurt(damage,distributorOfPain)
self:TakeDamage(damage)
end
function Script:Kill()--in
if self:IsAlive() then
self.health = 0
self.alive = false
self.entity:SetCollisionType(Collision.Prop)
self.entity:SetPhysicsMode(Entity.RigidBodyPhysics)
self.entity:SetGravityMode(false)
self.component:CallOutputs("Kill")

if self.iscarryingEntity then
self:DropEntityCarrying()
end

if self.useflashlight then
self.flashlight:Hide()
end

if not self.playdeathsound then
self.sound.damage.dead:Play()
self.playdeathsound = true
end

end
end
-- Respawn if we have a vaild respawn point.
-- You can also make it reload a save file in this function instead of this.
function Script:Respawn()
if self.RespawnPoint ~= nil then
-- Set the health back to 100, and we are no longer dead.
self.health = 100
self.savedhealth = self.health
self.alive = true
-- Teleport to the respawn point.
local pos = self.RespawnPoint:GetPosition()
local rot = self.RespawnPoint:GetRotation()
self.RespawnPointPosition = pos
self.RespawnPointRotation = rot
self.entity:SetPosition(self.RespawnPointPosition)
self.camRotation = self.RespawnPointRotation
-- Reset other values.
self.entity:SetCollisionType(Collision.Character)
self.entity:SetPhysicsMode(Entity.CharacterPhysics)
self.entity:SetGravityMode(true)
self.RectangleAlpha = 0
self.RespawnTimer = 0
self.playdeathsound = false
self.crouched = false
end

end
function Script:SetNewRespawnPoint(entity)--in
self.RespawnPoint = entity
end
-- #Weapons
function Script:LoadWeapon()
if self.weaponfile~="" then
local prefab = Prefab:Load(self.weaponfile)
if prefab~=nil then
if prefab.script~=nil then
self:AddWeapon(prefab.script)
else
prefab:Release()
end
end
end
end

function Script:AddWeapon(weapon)
if weapon.index==nil then
weapon.index=1
end
if self.weapons[weapon.index]==nil then
self.weapons[weapon.index]=weapon
self.weapons[weapon.index].player = self
self.weapons[weapon.index].entity:SetParent(self.weapontag)
self.weapons[weapon.index].entity:SetPosition(self.weapons[weapon.index].offset)
if self.weapons[weapon.index].rotation~=nil then
self.weapons[weapon.index].entity:SetPosition(self.weapons[weapon.index].rotation)
end
self.weapons[weapon.index].entity:Hide()
if weapon.index>self.currentweaponindex then self:SelectWeapon(weapon.index) end
--if self.sound.pickupweapon~=nil then self.sound.pickupweapon:Play() end
return true
end
return false
end
function Script:Weapon()
local currenttime = Time:GetCurrent()

if self.lastweaponhittesttime==nil then self.lastweaponhittesttime=0 end

if currenttime - self.lastweaponhittesttime>100 then
self.lastweaponhittesttime=currenttime
local pickinfo=PickInfo()
local p1 = Transform:Point(0,0,0,self.camera,nil)
local p2 = Transform:Point(0,0,0.6,self.camera,nil)
local pickmode = self.entity:GetPickMode()
self.entity:SetPickMode(0)
self.entity:SetPickMode(pickmode)
end

if self.weaponlowered then
self.weaponlowerangle = self.weaponlowerangle + 4 * Time:GetSpeed()
else
self.weaponlowerangle = self.weaponlowerangle - 4 * Time:GetSpeed()
end

self.weaponlowerangle = math.max(0,math.min(self.weaponlowerangle,90))
self.weapontag:SetRotation(self.weaponlowerangle,0,0)
end
function Script:FireWeapon(window)
-- Listen for Mouse clicks
local fire = false
local fire2 = false
local currentime = Time:GetCurrent()
if self.carryingEntity==nil then
if self.weapons[self.currentweaponindex]~=nil then
if self.weapons[self.currentweaponindex].automatic then
if window:MouseDown(1) then
 fire=true
else
 self.suspendfire=false
end

if window:MouseDown(2) then
 fire2=true
else
 self.suspendfire=false
end
else
if window:MouseHit(1) then
 fire=true
end

if window:MouseHit(2) then
 fire2=true
end
end
end
end

--Fire weapon
if self.carryingEntity==nil then

-- Primary
if fire then
if self.suspendfire~=true then
if self.weapons[self.currentweaponindex].clipammo==0 and self.weapons[self.currentweaponindex].automatic==true then
 self.suspendfire=true
end
self.weapons[self.currentweaponindex]:Fire(1)
end
end

-- Secondary
if fire2 then
if self.suspendfire~=true then
if self.weapons[self.currentweaponindex].clipammo==0 and self.weapons[self.currentweaponindex].automatic==true then
 self.suspendfire=true
end
self.weapons[self.currentweaponindex]:Fire(2)
end
end

end
end
function Script:CycleWeapon(direction)
local n,weapon
local foundindex=false
local prevweapon
if direction==1 then
for n,weapon in pairs(self.weapons) do
if foundindex then
self:SelectWeapon(n)
return
end
if self.currentweaponindex==n then
foundindex=true
end
end
if foundindex then
for n,weapon in pairs(self.weapons) do
self:SelectWeapon(n)
return
end
end
else
for n,weapon in pairs(self.weapons) do
if prevweapon then
if self.currentweaponindex==n then
 self:SelectWeapon(prevweapon)
 return
end
end
prevweapon=n
end
if prevweapon then
self:SelectWeapon(prevweapon)
end
end
end
function Script:SelectWeapon(index)
if index~=self.currentweaponindex then

if self.weapons[self.currentweaponindex]~=nil then
self.weapons[self.currentweaponindex].entity:Hide()
end

self.currentweaponindex = index

if self.weapons[self.currentweaponindex]~=nil then
self.weapons[self.currentweaponindex].entity:Show()
end

self.weaponlowerangle=90
self.suspendfire=false
self.weapontag:SetRotation(self.weaponlowerangle,0,0)

end
end
function Script:Release()
-- Release Listener
self.listener:Release()

-- Release #Flashlight if we have one.
if self.useflashlight then
self.flashlight:Release()
end

-- Release Tables
ReleaseTableObjects(self.sound)
ReleaseTableObjects(self.image)

-- Release weapons
local k,v
for k,v in pairs(self.weapons) do
v:Release()
end

-- Release Fonts
self.hudfont:Release()
end

 

Hopes this helps.

Share this post


Link to post

Thanks, I have it working, but I would like control over the crouch height (so you can go through shorter spaces or even crawl). Currently, the character controller doesn't allow that.

Share this post


Link to post

Thanks, I have it working, but I would like control over the crouch height (so you can go through shorter spaces or even crawl). Currently, the character controller doesn't allow that.

 

Alright, I would look at this a bit and see if there are any adjustments you can do to get what you want. I'm sure changing the value of self.crouchedheight would do the trick.

Share this post


Link to post

That would only change the camera height. The problem is that when you put the controller into crouched mode, the controller actually gets shorter (the physics mesh or whatever it is built of). So that means that you can't go under regions where the ceiling is too low. My problem is that I want to be able to control the height of the controller so that I can go under shorter regions. The default crouch height is like someone kneeling, which makes it impossible to have a character go through vents and stuff like that without massively changing the level's physics.

Share this post


Link to post

There are a few things about the character controller and the navmesh I would love to control. 1. Is the controller height. I would love to add a standing/crouching/prone ability to my game. And 2. The navmesh minimum height. If the headspace for a map is too low a nav mesh is not created. I would like to add airducts or walls the ai need to crawl under. It's somewhat trivial to do obstical avoidance, if a raycast hits object, jump over, if nav mesh area head height blocked but crouch height is not, crouch. Other than having the ability to change nav mesh properties, you could solve this by scaling all models by 2.

Share this post


Link to post

The problem is that the character controller stays the same radius and then navmeshes get inaccurate (so AI could bust their way through cracks, etc., although you could work around this by enabling and disabling physics, but it's kind of a hassle).

 

These would be nice options (I get why Josh removed them, but it would be nice for users to have them):

http://www.leadwerks.com/werkspace/page/Documentation/le2/_/command-reference/controllers/createcontroller-r101

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...