Jump to content

Character Controller Tutorial


SlipperyBrick
 Share

Recommended Posts

I was hoping for something similar to the prefab, where a camera is created and you can move using the WASD keys. Without any of the fancy weapon stuff and footstep stuff.

 

Starting with an empty project and then using the FPS script causes problems because it tries to find all the assets that are linked to that which aren't in my project.

 

A cube and a camera and the WASD keys is all I need for now biggrin.png

 

I haven't used Leadwerks for ages now so I have forgotten most things I learnt in regards to Lua and the commands for creating these simple things sad.png

Link to comment
Share on other sites

Ok so this is a work in progress. Just want to say a massive thank you to nice.ace the guy is a f***ing wizard! biggrin.png

 

function Script:Start()
--self.camera = players camera
--self.entity = temporary box to use for player movement
self.camera = Camera:Create(self.entity)
self.camera:SetPosition(self.entity:GetPosition(true))

end
function Script:UpdatePhysics()
--xmove = left/right speed
--zmove = forward/backwards speed
local xmove = 0
local zmove = 0
local window = Window:GetCurrent()
--key bindings for movement
if window:KeyDown(Key.W) then
zmove = 1
end
if window:KeyDown(Key.S) then
zmove = -1
end
if window:KeyDown(Key.A) then
xmove = -1
end
if window:KeyDown(Key.D) then
xmove = 1
end
self.entity:SetInput(self.camera:GetRotation(true).y, zmove, xmove)

end

 

Will work on mouse input soon. I am hoping to do leaning and also automatic crouching like in Alien: Isolation.

Link to comment
Share on other sites

I have hit a problem with my script. Again I would like to say a big thank you to nick.ace.

 

I have just started to program in the functionality of the mouse to move left and right but the issue is that there is a long drift when I move the mouse.

 

For example, when I move right I will stop my mouse but the camera keeps drifting off to the right and the only way I can stop it drifting off to the right is to move my mouse slowly to the left to compensate, eventually I can steady the view again.

 

Here is the code:

 

function Script:Start()

local window = Window:GetCurrent()

window:SetMousePosition(window:GetWidth()/2, window:GetHeight()/2)

--self.camera = players camera
--self.entity = temporary box to use for player movement

--creates a camera in the scene and parents to the entity

self.camera = Camera:Create(self.entity)

--sets the position of the camera to the position of the entity

self.camera:SetPosition(self.entity:GetPosition(true))

end

function Script:UpdateWorld()

local window = Window:GetCurrent()

--mousex = left/right movement
--mousey = up/down movement

local mousex = 0
local mousey = 0

--gets the position of the mouse each frame

mousex = window:GetMousePosition().x
mousey = window:GetMousePosition().y

mousex = (-5*(window:GetWidth()/2 - mousex))/window:GetWidth()

--repositions mouse cursor to center of screen after each frame

window:SetMousePosition(window:GetWidth()/2, window:GetHeight()/2)

self.camera:SetRotation(Vec3(0, self.camera:GetRotation(true).y + mousex, 0), true)

end

function Script:UpdatePhysics()

--xmove = left/right speed
--zmove = forward/backwards speed

local xmove = 0
local zmove = 0

local window = Window:GetCurrent()

--key bindings for movement

if window:KeyDown(Key.W) then

zmove = 1
end

if window:KeyDown(Key.S) then

zmove = -1
end

if window:KeyDown(Key.A) then

xmove = -1
end

if window:KeyDown(Key.D) then

xmove = 1
end

self.entity:SetInput(self.camera:GetRotation(true).y, zmove, xmove)

end

function Script:PostRender(context)

local window = Window:GetCurrent()

end

 

If you spot the problem I will get a maria chi band to come to your door and deliver you beers and sing you a song.

Link to comment
Share on other sites

Well I see a couple of issues with the script. The drifting in a lua controller is typically caused by rounding errors when setting the mouse position, so you need to round the 'GetWidth/GetHeight'. The code for setting the position of the camera is using the entity's global coordinates but applied as the camera's local coordinates from the entity. This will offset the camera depending on where the entity is placed within the scene. Global coordinates are based on location in the scene, Local coordinates are based on location from the parent. If no parent, then local and global coordinates are the same. I suggest that you also set up the initial camera rotation to match that of the controller.

 

I have no idea what this line is trying to accomplish, so cannot comment:

mousex = (-5*(window:GetWidth()/2 - mousex))/window:GetWidth()

 

Assuming you wanted a fps camera not sitting on the ground, you also need to offset the Y position of the camera from the entity position. Also you state that you are just using a cube for a character at the moment, so remember to set the physics mode to character controller and to give it mass greater than zero or the SetInput command will not work.

 

example code:

function Script:Start()
 self.camera = Camera:Create(self.entity)
 local entpos = self.entity:GetPosition(true)
 self.camera:SetPosition(entpos.x,entpos.y+1,entpos.z,true) --set camera 1m off of ground
 self.camrotation = self.entity:GetRotation(true) --sets default cam rotation variable
 self.camera:SetRotation(self.camrotation,true)

 local window = Window:GetCurrent()
 self.gx = Math:Round(window:GetWidth()/2) --must round or camera will drift
 self.gy = Math:Round(window:GetHeight()/2) --must round or camera will drift
 self.move = 0
 self.strafe = 0
end

function Script:UpdateWorld()
 local window = Window:GetCurrent()
 local mouseposition = window:GetMousePosition()
 window:SetMousePosition(self.gx, self.gy)
 local dx = mouseposition.x - self.gx
 local dy = mouseposition.y - self.gy
 self.camrotation.x = self.camrotation.x + dy / 10--look up an down
 self.camrotation.y = self.camrotation.y + dx / 10--look left and right
 self.camera:SetRotation(0,self.camrotation.y,0,true)
end

function Script:UpdatePhysics()
 local window = Window:GetCurrent()
 self.move = Math:Curve(((window:KeyDown(Key.W)and 1 or 0) - (window:KeyDown(Key.S) and 1 or 0)),self.move,10)
 self.strafe = Math:Curve(((window:KeyDown(Key.D)and 1 or 0) - (window:KeyDown(Key.A) and 1 or 0)),self.strafe,10)
 self.entity:SetInput(self.camrotation.y, self.move, self.strafe)
end

 

Since your above code only has the camera being able to rotate side to side and not up and down, I made the example code to match above. There are other code tidbits that you can add to make the camera movement smoother, consistent based on FPS, etc... which can be found in the inherent LE 'fpsplayer' script. I suggest you review that script for more insight.

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

After working on this for the majority of the day and trying to familiarize myself with the Lua stuff again. This is what I have so far.

 

function Script:Start()
local window = Window:GetCurrent()
--self.camera = players camera
--self.entity = temporary box to use for player movement
--creates a camera in the scene and parents to the entity
self.camera = Camera:Create(self.entity)
--sets the type of the object to player
self.entity:SetKeyValue("type", "player")
local mass = self.entity:GetMass()
if self.entity:GetMass() == 0 then
Debug:Error("Player mass should be greater than 0.")
end
--gets the entity position
local entpos = self.entity:GetPosition(true)
--sets the camera height
self.camera:SetPosition(entpos.x, entpos.y + 3.5, entpos.z, true)
--sets the camera rotation variable
self.camrotation = self.entity:GetRotation(true)
self.camera:SetRotation(self.camrotation, true)
mousex = Math:Round(window:GetWidth()/2)
mousey = Math:Round(window:GetHeight()/2)
end
function Script:UpdateWorld()
local window = Window:GetCurrent()
--gets the position of the mouse
local mouseposition = window:GetMousePosition()
window:SetMousePosition(mousex, mousey)
local dx = mouseposition.x - mousex
local dy = mouseposition.y - mousey
self.camrotation.x = self.camrotation.x + dy / 10
self.camrotation.y = self.camrotation.y + dx / 10
self.camera:SetRotation(0, self.camrotation.y, 0, true)
end
function Script:UpdatePhysics()
local window = Window:GetCurrent()
--xmove = left/right speed
--zmove = forward/backwards speed
local xmove = 0
local zmove = 0
--key bindings for movement
if window:KeyDown(Key.W) then
zmove = 1
end
if window:KeyDown(Key.S) then
zmove = -1
end
if window:KeyDown(Key.A) then
xmove = -1
end
if window:KeyDown(Key.D) then
xmove = 1
end
self.entity:SetInput(self.camera:GetRotation(true).y, zmove, xmove)
end

 

I am hoping when the script becomes more complete I can put it up on the Workshop so users can customize it and make it their own. There is to many assets involved with the FPS script and when you start changing things problems happen and it all gets a bit messy. So part of this script can serve as a more simplified version of the FPS script for users if they want it.

 

I will try and put lean functionality in there and also crouching etc.

 

Big thanks to nice.ace and macklebee for their help! smile.png

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

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.

 Share

×
×
  • Create New...