Hi
Thank you for your answer.
This example is great.
I have tried to adapt it for my code, but it doesn't work properly.
In some case, the sphere doesn"t move smoothly, and didn't take care of the 2 first box (the sphere check only the last box for collision).
Here is my code (I need a sort of "click and go" (sort of simple pathfinding, not a complexe A* ^^)
// Project: 3D_collision_obstacle
// Created: 2015-11-15
// this demo show simple sliding collision
// set window properties
SetWindowTitle( "3D_collision_obstacle" )
SetWindowSize( 1024, 768, 0 )
// set display properties
SetVirtualResolution( 1024, 768 )
SetOrientationAllowed( 1, 1, 1, 1 )
// use the wasd keys or the on screen joystick to move the sphere
// the sphere will hit and slide against the red blocks
// set a radius for the sphere which will also be used for the sphere cast
radius# = 5.0
// make a sphere, colour it, turns its collision off and position it
CreateObjectSphere(1,radius#*2,12,12)
SetObjectCollisionMode(1,0) // this is to stop it interfering with the collision with the map
SetObjectColor(1,0,255,0,255)
SetObjectPosition(1,-50,radius#,-50)
Cible = CreateObjectBox(5,5,5)
SetObjectColor(Cible,255,255,0,50)
SetObjectPosition(Cible,-25,5,-10)
SetObjectCollisionMode(Cible,0)
x1 = -25
y1 = -10
// make three blocks to act as a map
for i = 2 to 4
CreateObjectBox(i,25,5,25)
SetObjectColor(i,255,0,0,255)
SetObjectRotation(i,0,random(0,89),0)
SetObjectPosition(i,0,2.5,(i-3)*50)
next i
// create a plane, turn its collision off, rotate it and position it under the middle box to act as a ground
// this is purely cosmetic
CreateObjectPlane(5,200,200)
//SetObjectCollisionMode(5,0) // this is to stop it interfering with the collision with the map
SetObjectRotation(5,90,0,0)
SetObjectPosition(5,GetObjectX(3),0,GetObjectY(3))
ground = 5
// create a light
CreatePointLight(1,0,5,0,500,255,120,120)
// position and orientate camera
SetCameraPosition(1,0,150,-100)
SetCameraLookAt(1,0,0,0,0)
// main loop
do
if GetRawKeyPressed(27)
end
endif
if GetPointerState()
X# = Get3DVectorXFromScreen( GetPointerX(), GetPointerY() ) * 10000
Y# = Get3DVectorYFromScreen( GetPointerX(), GetPointerY() ) * 10000
Z# = Get3DVectorZFromScreen( GetPointerX(), GetPointerY() ) * 10000
X# = X# + GetCameraX(1)
Y# = Y# + GetCameraY(1)
Z# = Z# + GetCameraZ(1)
obj=ObjectRayCast(5,getcamerax(1),getcameray(1),getcameraz(1),x#,y#,z#)
if obj
n=0
x1=GetObjectRayCastX(n)
y1=GetObjectRayCastZ(n)
SetObjectPosition(cible,x1,2,y1)
endif
endif
print(str(obj))
// save the old position of the sphere
old_x# = GetObjectX(1)
old_y# = GetObjectY(1)
old_z# = GetObjectZ(1)
// get player input
//joystick_x# = GetJoyStickX()
//joystick_y# = GetJoyStickY()*-1
move = 0
if old_x# < x1
joystick_x# =1
move = 1
if abs(old_x#-x1)<=1
joystick_x# =0
endif
elseif old_x# > x1
joystick_x# =-1
move = 1
if abs(old_x#-x1)<=1
joystick_x# =0
endif
else
joystick_x# =0
endif
if old_z# < y1
joystick_y# =1
move =1
if abs(old_z#-y1)<=1
joystick_y# =0
endif
elseif old_z# > y1
joystick_y# =-1
move = 1
if abs(old_z#-y1)<=1
joystick_y# =0
endif
else
joystick_y# =0
endif
// move the green sphere based on the player input
MoveObjectLocalX(1,joystick_x#)
MoveObjectLocalZ(1,joystick_y#)
// get the new position of the sphere
new_x# = GetObjectX(1)
new_y# = GetObjectY(1)
new_z# = GetObjectZ(1)
// sphere cast between the old and new positions of the sphere
object_hit = ObjectSphereSlide(0,old_x#,old_y#,old_z#,new_x#,new_y#,new_z#,radius#)
// the sphere has collide with a box then calculate sphere new position to give sliding collision
// we do not need to know the Y component of the collision as the sphere only moves on the xz plane
if object_hit <> 0
SetObjectPosition(1, GetObjectRayCastSlideX(0), new_y#, GetObjectRayCastSlideZ(0) )
endif
sync()
loop
Do you have an idea how I can fixe that ?
Thanks again
EDIT :
OK, I have found a temporary solution ^^
I use a little radius for the raycast and some other changes. It's not perfect at all, but it work in some situation.
// Project: 3D_collision_obstacle
// Created: 2015-11-15
SetWindowTitle( "3D_collision_obstacle" )
SetWindowSize( 1024, 768, 0 )
SetVirtualResolution( 1024, 768 )
SetOrientationAllowed( 1, 1, 1, 1 )
// make a sphere, colour it, turns its collision off and position it
r =10
CreateObjectBox(1,r,r,r)
SetObjectCollisionMode(1,0) // this is to stop it interfering with the collision with the map
SetObjectColor(1,0,255,0,255)
SetObjectPosition(1,-50,r,-50)
// global joystick,x,y,z,old_x,old_y,old_z,new_x,new_y,new_z,x1,y1 as float
Cible = CreateObjectBox(5,5,5)
SetObjectColor(Cible,255,255,0,50)
SetObjectPosition(Cible,-25,5,-10)
SetObjectCollisionMode(Cible,0)
x1 = -25
y1 = -10
// make three blocks to act as a map
for i = 2 to 4
CreateObjectBox(i,25,5,25)
SetObjectColor(i,255,0,0,255)
SetObjectRotation(i,0,random(0,89),0)
SetObjectPosition(i,0,2.5,(i-3)*50)
next i
// create a plane, turn its collision off, rotate it and position it under the middle box to act as a ground
// this is purely cosmetic
CreateObjectPlane(5,200,200)
//SetObjectCollisionMode(5,0) // this is to stop it interfering with the collision with the map
SetObjectRotation(5,90,0,0)
SetObjectPosition(5,GetObjectX(3),0,GetObjectY(3))
ground = 5
// create a light
CreatePointLight(1,0,5,0,500,255,120,120)
// position and orientate camera
SetCameraPosition(1,0,150,-100)
SetCameraLookAt(1,0,0,0,0)
// main loop
do
if GetRawKeyPressed(27)
end
endif
if GetPointerState()
X# = Get3DVectorXFromScreen( GetPointerX(), GetPointerY() ) * 10000
Y# = Get3DVectorYFromScreen( GetPointerX(), GetPointerY() ) * 10000
Z# = Get3DVectorZFromScreen( GetPointerX(), GetPointerY() ) * 10000
X# = X# + GetCameraX(1)
Y# = Y# + GetCameraY(1)
Z# = Z# + GetCameraZ(1)
obj=ObjectRayCast(5,getcamerax(1),getcameray(1),getcameraz(1),x#,y#,z#)
if obj
n=0
x1=GetObjectRayCastX(n)
y1=GetObjectRayCastZ(n)
SetObjectPosition(cible,x1,2,y1)
walk=1
endif
endif
// save the old position of the sphere
old_x = GetObjectX(1)
old_y = GetObjectY(1)
old_z = GetObjectZ(1)
move = 0
if walk =1
if old_x <> x1 or old_z <> y1
joystick =1
move=1
if abs(old_x-x1)<=2
old_x = x1
endif
if abs(old_z-y1)<=2
old_z = y1
endif
SetObjectLookAt(1,x1,2,y1,0)
else
move =0
walk = 0
endif
if move =1
MoveObjectLocalZ(1,joystick)
// get the new position of the sphere
new_x = GetObjectX(1)
new_y = GetObjectY(1)
new_z = GetObjectZ(1)
// sphere cast between the old and new positions of the sphere
object_hit = ObjectSphereSlide(0,old_x,old_y,old_z,new_x,new_y,new_z,1)
// the sphere has collide with a box then calculate sphere new position to give sliding collision
// we do not need to know the Y component of the collision as the sphere only moves on the xz plane
if object_hit <> 0 and object_hit <> 5
x2 = GetObjectRayCastSlideX(0)
z2 = GetObjectRayCastSlideZ(0)
SetObjectPosition(1, x2, new_y, z2)
// SetObjectLookAt(1,x2+180,2,z2+180,0)
SetObjectRotation(1,GetObjectAngleX(1),GetObjectAngleY(1)+1,GetObjectAngleZ(1))
endif
endif
endif
print(str(object_hit)+"|"+str(x1)+"/"+str(old_x)+"-"+str(y1)+"/"+str(old_z))
sync()
loop
http://www.dracaena-studio.com