I tried to make the character controller stand on rigid bodies.
However the controller cannot stand properly on dynamic rigid bodies. The controller keeps on sliding off the dynamic bodies.
And when the controller is on static rigid bodies, it continuously keeps sliding to the side
Anybody knows what's going on?
Here's the code:
// Project: Test File City
// Created: 2015-04-01
SetVSync( 0 )
SetSyncRate( 100, 0 )
SetPrintSize( 40)
SetPrintColor( 0, 0, 0, 255 )
`#INCLUDE "FileSearch.agc"
REMSTART
// set window properties
deviceHeight# = GetDeviceHeight()
deviceWidth# = GetDeviceWidth()
SetWindowTitle( "Test World" )
IF deviceWidth# > deviceHeight#
practicalWidth# = deviceHeight#
practicalHeight# = deviceWidth#
ENDIF
IF deviceWidth# < deviceHeight#
practicalWidth# = deviceWidth#
practicalHeight# = deviceHeight#
ENDIF
SetWindowSize( practicalWidth#, practicalHeight#, 0 )
SetDisplayAspect( -1 )
REMEND
// set display properties
deviceHeight# = GetDeviceHeight()
deviceWidth# = GetDeviceWidth()
practicalWidth# = deviceWidth#
practicalHeight# = deviceHeight#
`SetVirtualResolution( 1024, 768 )
SetVirtualResolution( 1920, 1080 )
`SetVirtualResolution( practicalWidth#, practicalHeight# )
`SetVirtualResolution( deviceWidth#, deviceHeight# )
`SetWindowSize( practicalWidth#, practicalHeight#, 0 )
`SetOrientationAllowed( 1, 0, 0, 0 )
SetClearColor(255,255,255)
SetPrintColor(1,1,1, 100)
`SetVirtualJoystickAlpha( 0, 9, 9 )
//Setup camera
SetCameraPosition(1, 0, 2, -8)
SetCameraRotation(1, 1, 0, 0)
SetCameraRange( 1, 0.1, 10000 )
`---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`create a directional light
`createLightDirectional(1, 1, -1.5, 1, 255,255,255)
`create a point light
`createLightPoint(1,100,10,-500,10000000,255,255,255)
`---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Physic setup
Create3DPhysicsWorld()
Set3DPhysicsGravity(0,-1,0)
`---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
FOR t = 500 to 600
CreateText(t, "Player " + STR(t))
SetTextSize ( t, 30 )
SetTextColor( t, 1,1,1, 255)
SetTextVisible( t, 0 )
`SetTextPosition(t, GetScreenXFrom3D( GetObjectX(t), GetObjectY(t), GetObjectZ(t) ), GetScreenYFrom3D( GetObjectX(t), GetObjectY(t), GetObjectZ(t) ) )
`CreateText(t+10, "Player " + STR(t))
`SetTextSize ( t+10, 30 )
`SetTextColor( t+10, 1,1,1, 255)
NEXT t
`---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Load dummy doll
loadImage(10,"knight defense/FullKinghtClean.png")
`LoadObject(10,"knight defense/knight defense spear.obj")
CreateObjectBox(10, 2, 0.1, 2)
SetObjectImage(10,10,0)
setObjectCollisionMode(10,0)
SetObjectPosition(10,4.5,10,-3)
SetObjectScale(10,3,3,3)
Create3DPhysicsDynamicBody( 10 )
`SetObjectShapeBox(10)
remstart
//load dummy doll 2
loadImage(11,"knight defense/FullKinghtClean.png")
LoadObject(11,"knight defense/knight defense spear.obj")
SetObjectImage(11,11,0)
setObjectCollisionMode(11,1)
SetObjectPosition(11,-2.5,10,-3)
SetObjectScale(11,3,3,3)
remend
//Make player object
playerObj = 1
`CreateObjectCylinder(1,0.5,0.5,5)
CreateObjectBox(playerObj, 0.5, 0.5, 0.5)
SetObjectImage(playerObj,10,0)
`SetObjectPosition(playerObj,0,10,-15)
setObjectCollisionMode(playerObj,0)
characterOffsetVec = CreateVector3( 0.0, -0, 0.0 )
objectOrientationVec = CreateVector3( 0.0, 0.0, 0 )
Create3DPhysicsCharacterController( playerObj, 1, characterOffsetVec , objectOrientationVec, 0.5 )
DeleteVector3( characterOffsetVec )
DeleteVector3( objectOrientationVec )
Set3DPhysicsCharacterControllerJumpSpeed( playerObj, 0.5 )
Set3DPhysicsCharacterControllerFallSpeed( playerObj, 1 )
Set3DPhysicsCharacterControllerGravity( playerObj, 2 )
Set3DPhysicsCharacterControllerMaxSlope( playerObj, 90 )
//load animated object
REMSTART
LoadObjectWithChildren( 12, "sera.x" )
`SetObjectScale( 12, 4, 4, 4 )
SetObjectScalePermanent( 12, 2, 2, 2 )
SetObjectAnimationSpeed( 12, 20 )
PlayObjectAnimation( 12, "", 0, -1, 1, 0 )
REMEND
`LoadObject(12,"shu.x")
LoadObjectWithChildren( 12, "shu.x" )
LoadImage(12,"000.png")
SetObjectImage(12,12,0)
`SetObjectScalePermanent( 12, 0.02, 0.02, 0.02 )
SetObjectScale( 12, 0.02, 0.02, 0.02 )
SetObjectRotation(12,0,180,0)
`LoadImage(12,"000.png")
`SetObjectImage(12,12,0)
//Load ground
GLOBAL terrainObj = 200
CreateObjectBox(terrainObj, 0.5, 0.001, 0.5)
SetObjectScale(200, 20, 20, 20)
LoadImage(200, "tile17.png")
setImageWrapU(200,1) : setImageWrapV(200,1)
SetObjectImage(200,200,0)
setObjectCullMode( 200, 1 )
setObjectCollisionMode(200,1)
setObjectLightMode(200,0)
Create3DPhysicsStaticBody( terrainObj )
SetObjectShapeBox(terrainObj)
`makeBox(15, 2,2,2, 50,100,50,50, 0,2,0)
`---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// create sprite 1000 (reset sprite)
CreateSprite ( 1000, 200 )
SetSpritePosition ( 1000, practicalWidth#-200, practicalHeight#-(practicalHeight#/2) -400)
SetSpriteSize ( 1000, 200, -1 )
//Add buttons for movement
AddVirtualButton(1, practicalWidth#-200, practicalHeight#-(practicalHeight#/2)- 100, 150)
AddVirtualButton(2, practicalWidth#-200, practicalHeight#-(practicalHeight#/2)+ 100, 150)
AddVirtualButton(3, practicalWidth#-200 - 150, practicalHeight#-(practicalHeight#/2) + 0, 150)
AddVirtualButton(4, practicalWidth#-200 + 150, practicalHeight#-(practicalHeight#/2) + 0, 150)
SetVirtualButtonText(1, "^")
SetVirtualButtonText(2, "V")
SetVirtualButtonText(3, "<")
SetVirtualButtonText(4, ">")
`---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`cam movement values
cam_acceleration# = 0.3
cam_speed_max# = 0.2
cam_turn_speed# = 2.5
cam_friction# = 0.8
`game world values
wall_friction# = 0.95
gravity# = 0.15
`NPC jump values
jump# = 0.0485
JumpAdd# = 0.1
DIM NPCJumpVar#[20,5]
FOR X = 1 to 20
NPCJumpVar#[x,1] = 0.047
NPCJumpVar#[x,2] = 0.1
NEXT x
`---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Initialize File City
`DefineSearchVar()
`SearchDriveInitialize()
`---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//camera variable
prevCameraX# = GetRawMouseX()
prevCameraY# = GetRawMouseY()
`---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`openToWrite(1, "testtttttttttttttttttt", 0)
`writeFloat(1,123446457565678678)
`writeLine(1, "hello people")
`closeFile(1)
`CreateMemblockFromFile( 10, "ayano.mp3" )
`CreateFileFromMemblock( "testFile.mp3",10 )
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
DO
`-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//NPC jump
remstart
hitSprite = GetSpriteHit ( GetPointerX ( ), GetPointerY ( ) )
IF ( hitSprite = 1000 )
NPCJumpVar#[11,3] = 1
ELSE
NPCJumpVar#[11,3] = 0
ENDIF
NPCBobbing(10 , 1 )
NPCBobbing(11 , NPCJumpVar#[11,3] )
remend
`----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Rotate camera
gyroX# = GetRawGyroVelocityX()
gyroY# = GetRawGyroVelocityY()
gyroZ# = GetRawGyroVelocityZ()
`CameraRotX# = GetCameraAngleX(1) - gyroX#
`CameraRotY# = GetCameraAngleY(1) - gyroY#
`CameraRotZ# = GetCameraAngleZ(1) + gyroZ#
CameraRotX# = - gyroX#
CameraRotY# = - gyroY#
CameraRotZ# = gyroZ#
//Reset view when sprite pressed
if GetPointerPressed ( ) = 1
// find out which sprite was hit
hit = GetSpriteHit ( GetPointerX ( ), GetPointerY ( ) )
// green sprite - reset
if ( hit = 1000 )
setCameraRotation(1, 0, GetObjectAngleY(1) - gyroY#, 0)
`setObjectRotation(1, 0, GetObjectAngleY(1) - gyroY#, 0)
ENDIF
ENDIF
//Rotate camera and player object
RotateCameraLocalX(1, CameraRotX#)
RotateCameraLocalY(1, CameraRotY#)
RotateCameraLocalZ(1, CameraRotZ#)
RotateObjectLocalX(1, CameraRotX#)
RotateObjectLocalY(1, CameraRotY#)
RotateObjectLocalZ(1, CameraRotZ#)
REMSTART
//Move camera + player object on button press
IF getButtonState(1) = 1
`cam_speed# = cam_speed# + 0.05
cam_speed# = cam_speed_max#
if cam_speed# > cam_speed_max#
cam_speed# = cam_speed_max#
endif
ENDIF
IF getButtonState(2) = 1
cam_speed# = cam_speed# - 0.05
if cam_speed# > cam_speed_max#
cam_speed# = cam_speed_max#
endif
ENDIF
REMEND
//Move controller forward
Move3DPhysicsCharacterController( playerObj, 1, 0 )
IF GetRawKeyState( 87 ) > 0
Move3DPhysicsCharacterController( playerObj, 1, 2 )
ENDIF
//Jump controller
IF getButtonState(1) = 1 THEN Jump3DPhysicsCharacterController( playerObj )
`===========================================================================================================================================================================================
//Turn right and Left
`left
`IF getButtonState(4) > 0
IF GetRawKeyState( 39 ) > 0
`RotateCameraLocalY(1, CameraRotY# +1 )
`RotateObjectLocalY(1, CameraRotY# + 1)
SetObjectRotation(1, GetObjectAngleX(1), GetObjectAngleY(1) + 1 , GetObjectAngleZ(1))
SetCameraRotation(1, GetCameraAngleX(1), GetCameraAngleY(1) + 1 , GetCameraAngleZ(1))
ENDIF
`right
`IF getButtonState(3) > 0
IF GetRawKeyState( 37 ) > 0
SetObjectRotation(1, GetObjectAngleX(1), GetObjectAngleY(1) - 1 , GetObjectAngleZ(1))
SetCameraRotation(1, GetCameraAngleX(1), GetCameraAngleY(1) - 1 , GetCameraAngleZ(1))
ENDIF
`up
IF GetRawKeyState( 38 ) > 0 `UP
`RotateCameraLocalX(1, CameraRotX# - 1 )
`RotateObjectLocalX(1, CameraRotX# - 1)
SetObjectRotation(1, GetObjectAngleX(1) - 1, GetObjectAngleY(1) , GetObjectAngleZ(1))
SetCameraRotation(1, GetCameraAngleX(1) - 1, GetCameraAngleY(1) , GetCameraAngleZ(1))
ENDIF
`down
IF GetRawKeyState( 40 ) > 0
`RotateCameraLocalX(1, CameraRotX# + 1 )
`RotateObjectLocalX(1, CameraRotX# + 1)
SetObjectRotation(1, GetObjectAngleX(1) + 1, GetObjectAngleY(1) , GetObjectAngleZ(1))
SetCameraRotation(1, GetCameraAngleX(1) + 1, GetCameraAngleY(1) , GetCameraAngleZ(1))
ENDIF
//Mouse-camera rotation
cameraMovedX# = GetRawMouseX() - prevCameraX#
cameraMovedY# = GetRawMouseY() - prevCameraY#
`cameraMovedY# = GetRawMouseY() - prevCameraY#
SetRawMousePosition( practicalWidth#/2, practicalHeight#/2 )
cameraRotX# = GetCameraAngleX(1) + cameraMovedY#*0.1
cameraRotY# = GetCameraAngleY(1) + cameraMovedX#*0.1
objRotX# = GetObjectAngleX(1) + cameraMovedY#*0.1
objRotY# = GetObjectAngleY(1) + cameraMovedX#*0.1
PRINT("dumb: " )
PRINT("cameraRotX#: " + STR(cameraRotX#) )
PRINT("cameraRotY#: " + STR(cameraRotY#) )
//Limit camera rotation
IF cameraRotX# > 65 THEN cameraRotX# =65 `down
IF cameraRotX# < -65 THEN cameraRotX# = -65 `up
IF objRotX# > 65 THEN objRotX# =65 `down
IF objRotX# < -65 THEN objRotX# = -65 `up
SetCameraRotation(1, cameraRotX#, cameraRotY# , GetCameraAngleZ(1))
SetObjectRotation(1, objRotX#, objRotY# , GetObjectAngleZ(1))
Rotate3DPhysicsCharacterController( playerObj, objRotY# )
prevCameraX# = GetRawMouseX()
prevCameraY# = GetRawMouseY()
`===========================================================================================================================================================================================
REMSTART
`apply friction, this will slow the car down if the accelerator is not pressed
cam_speed# = cam_speed#*cam_friction#
if cam_speed# < 0.01 and cam_speed# > 0.000001
cam_speed# = 0.0
endif
//save the old player position
player_old_xpos# = getObjectX(1)
player_old_ypos# = getObjectY(1)
player_old_zpos# = getObjectZ(1)
//Move player
`MoveCameraLocalZ( 1, cam_speed# )
MoveObjectLocalZ( 1, cam_speed# )
SetObjectposition(1, getObjectX(1), getObjectY(1)- gravity#, getObjectZ(1) )
`SetCameraPosition(1, GetObjectX(1), GetObjectY(1)+2, GetObjectZ(1))
`--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Collisions
`get car position and angle
player_xpos# = getObjectX(1)
player_ypos# = getObjectY(1)
player_zpos# = getObjectZ(1)
player_xang# = getObjectAngleX(1)
player_yang# = getObjectAngleY(1)
player_zang# = getObjectAngleZ(1)
`collision check
hit = ObjectSphereCast(0,player_old_xpos#,player_old_ypos#,player_old_zpos#,player_xpos#,player_ypos#,player_zpos#,1.0)
if hit <> 0
if hit <= 2000
`hit a buidling, use sliding collision to reposition car
player_new_xpos# = GetObjectRayCastSlideX(0)
player_new_ypos# = GetObjectRayCastSlideY(0)
player_new_zpos# = GetObjectRayCastSlideZ(0)
setObjectPosition(1,player_new_xpos#,player_new_ypos#,player_new_zpos#)
`reduce speed
`cam_speed# = cam_speed#*wall_friction#
cam_speed# = cam_speed#
else
endif
endif
REMEND
//Position camera 3rd person
SetCameraPosition(1, GetObjectX(1), GetObjectY(1)+0, GetObjectZ(1))
moveCameraLocalZ(1,-10)
`---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Make File City
`MakeCity()
`PrintFileName()
`---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//QUit if F4 and F5 button
IF GetRawKeyState( 115 ) > 0 AND GetRawKeyState( 116 ) > 0 `THEN mouseLock = 1
END
ENDIF
`---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Step3DPhysicsWorld()
`---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`Print( ScreenFPS() )
`print("Gyro: "+str(GetGyroSensorExists()) + " X: "+formatnumber(GetRawGyroVelocityX()) + ", Y: " + formatnumber(GetRawGyroVelocityY()) + ", Z: " + formatnumber(GetRawGyroVelocityZ()))
`print("Accel: "+str(GetAccelerometerExists()) + " X: "+formatnumber(GetRawAccelX()) + ", Y: " + formatnumber(GetRawAccelY()) + ", Z: " + formatnumber(GetRawAccelZ()) )
`print( FileName$[500,1])
`print("Current folder: " + getFolder())
`print("Item size: " + str(FileNum[500,3]) + " bytes" )
`print("Read path: " + (GetReadPath()) )
`print("Write path: " + (GetWritePath()) )
`print("SetFolder successful: " + STR(SetFolder("C:\Users\Asus\Desktop\Neon")) )
`SetErrorMode ( 1)
`GetErrorOccurred ()
`GetLastError ()
`print("Error: " + (GetLastError ()) )
print("GetFileCount(): " + STR(GetFileCount()) )
print("lastObj : " + STR(lastObj) )
Print(GetRawLastKey())
Sync()
LOOP
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
`#########################################################################################################################################################################################
function formatnumber( f as float )
if ( f > 0 )
s$ = " " + str(f)
else
s$ = str(f)
endif
endfunction s$
`#########################################################################################################################################################################################
FUNCTION PositionLimb( childObjNum , parentObjNum , parentAngleX# , parentAngleY# , parentAngleZ# , XOffset# , YOffset# , ZOffset# )
//Position limb - put this function at the top of main loop
`Position limb on object, rotate limb same as object, move limb to location
`Then, limb can be rotated on local axis with RotateObjecLocalX()
IF parentAngleX# =>360 THEN parentAngleX# = parentAngleX#-360
IF parentAngleY# =>360 THEN parentAngleY# = parentAngleY#-360
IF parentAngleZ# =>360 THEN parentAngleZ# = parentAngleZ#-360
//Position limb on object
SetObjectPosition(childObjNum, GetObjectX(parentObjNum), GetObjectY(parentObjNum), GetObjectZ(parentObjNum))
//Rotate limb to make it angle same as body
SetObjectRotation(childObjNum, parentAngleX#,parentAngleY#,parentAngleZ# )
//Position limb on its intended position
MoveObjectLocalX(childObjNum, XOffset#)
MoveObjectLocalY(childObjNum, YOffset#)
MoveObjectLocalZ(childObjNum, ZOffset#)
ENDFUNCTION
`#########################################################################################################################################################################################
FUNCTION NPCBobbing( NPCObjNum , trigger )
//save the NPC old position for collision
NPC_old_xpos# = getObjectX(NPCObjNum)
NPC_old_ypos# = getObjectY(NPCObjNum)
NPC_old_zpos# = getObjectZ(NPCObjNum)
IF trigger = 1
NPCJumpVar#[NPCObjNum,1] = NPCJumpVar#[NPCObjNum,1] + NPCJumpVar#[NPCObjNum,2]
IF NPCJumpVar#[NPCObjNum,1] => 0.08 THEN NPCJumpVar#[NPCObjNum,2] = -0.027
IF NPCJumpVar#[NPCObjNum,1] <= -0.08 THEN NPCJumpVar#[NPCObjNum,2] = 0.027
ELSE
NPCJumpVar#[NPCObjNum,1] = -0.08
NPCJumpVar#[NPCObjNum,2] = 0.1
ENDIF
MoveObjectLocalY(NPCObjNum, NPCJumpVar#[NPCObjNum,1])
//Collisions
`get object position and angle
NPC_xpos# = getObjectX(NPCObjNum)
NPC_ypos# = getObjectY(NPCObjNum)
NPC_zpos# = getObjectZ(NPCObjNum)
NPC_xang# = getObjectAngleX(NPCObjNum)
NPC_yang# = getObjectAngleY(NPCObjNum)
NPC_zang# = getObjectAngleZ(NPCObjNum)
`collision check
hit = ObjectSphereCast(0,NPC_old_xpos#,NPC_old_ypos#,NPC_old_zpos#,NPC_xpos#,NPC_ypos#,NPC_zpos#,0.1)
if hit <> 0
if hit <= 2000
`hit a buidling, use sliding collision to reposition car
NPC_new_xpos# = GetObjectRayCastSlideX(0)
NPC_new_ypos# = GetObjectRayCastSlideY(0)
NPC_new_zpos# = GetObjectRayCastSlideZ(0)
setObjectPosition(NPCObjNum,NPC_new_xpos#,NPC_new_ypos#,NPC_new_zpos#)
`reduce speed
`cam_speed# = cam_speed#*wall_friction#
cam_speed# = cam_speed#*0.95
else
endif
endif
ENDFUNCTION
`###############################################################################################################################################################################################
FUNCTION PrintFileName()
`If filemade = 0 then cityMade = 1
`If (cityMade =1) and (mouseclick() = 2)
FOR x = (endObj +1) to (lastobj)
`If (object exist(x) = 1)
IF GetObjectInScreen(x) = 1
`print file names
textPosX = GetScreenXFrom3D( GetObjectX(x), GetObjectY(x), GetObjectZ(x) )
textPosY = GetScreenYFrom3D( GetObjectX(x), GetObjectY(x), GetObjectZ(x) )
``SetTextString(x, FileName$[x,1])
SetTextPosition(x, textPosX, textPosY )
`SetTextPosition(x+10, GetScreenXFrom3D( GetObjectX(x), GetObjectY(x), GetObjectZ(x) ) -80, GetScreenYFrom3D( GetObjectX(x), GetObjectY(x), GetObjectZ(x) )-90 )
remstart
`print file sizes
If FileNum(x,3) > 999999
center text object screen x(Filenum(x,1)) , object screen y(Filenum(x,1))+15 , str$(FileNum(x,3)/1000000) + " Mb"
ENDIF If (FileNum(x,3) < 1000000) and (FileNum(x,3) > 999)
center text object screen x(Filenum(x,1)) , object screen y(Filenum(x,1))+15 , str$(FileNum(x,3)/1000) + " Kb"
ENDIF
If FileNum(x,3) < 1000
center text object screen x(Filenum(x,1)) , object screen y(Filenum(x,1))+15 , str$(FileNum(x,3)) + " bytes"
ENDIF
remend
ENDIF
NEXT
ENDFUNCTION
`###############################################################################################################################################################################################
Use mouse to look around. 'W' key to move forward. Space key to jump