Posted: 14th Apr 2018 9:10
Hi
How to know when a physics character is in collision with another object (3d) ?

Thank you.
Posted: 15th Apr 2018 10:30
Something like this
Posted: 15th Apr 2018 10:34
Apologies that's not needed '
collision with two objects
+ Code Snippet
    x#=getObjectX(object)
    y#=GetObjectY(object)
    z#=getObjectZ(object)
    // calculate the start of the ray cast
    start_x# = x#
    start_y# = y#
    start_z# = z# 
    // calculate the end of the ray cast
    end_x# = x#+1.0   //dimensions of object x +width etc
    end_y# = y#-4.0
    end_z# = z#+2   
    hit=ObjectRayCast(0,start_x#,start_y#,start_z#,end_x#,end_y#,end_z#)
    

Collision with a object and a sprite but not yet tested
+ Code Snippet
        pointer_x = GetSpriteX(mySprite)
        pointer_y =GetSpriteX(mySprite)
        //pointer_y2 =screenHeight-GetPointerY()
    // get the x, y and z unit vectors based on the pointer position
        unit_x# = Get3DVectorXFromScreen(pointer_x,pointer_y)
        unit_y# = Get3DVectorYFromScreen(pointer_x,pointer_y)
        unit_z# = Get3DVectorZFromScreen(pointer_x,pointer_y)
   
        // calculate the start of the ray cast, which is the unit vector + the camera position
        start_x# = unit_x# + GetCameraX(1)
        start_y# = unit_y# + GetCameraY(1)
        start_z# = unit_z# - GetCameraZ(1)
   
        // calculate the end of the vector, which is the unit vector multiplied by the length of the ray cast and then add the camera position to it
        end_x# = 1000*unit_x# + GetCameraX(1)
        end_y# = 1000*unit_y# + GetCameraY(1)
        end_z# = 1000*unit_z# - GetCameraZ(1)
   
   
        // determine which object has been hit
        object_hit = ObjectRayCast(0,start_x#,start_y#,start_z#,end_x#,end_y#,end_z#)


replacing that line should work better you will have to play around with it
end_z# = 100*unit_z# - GetCameraZ(1)
Posted: 16th Apr 2018 10:04
Thank you, but it doesn't works properly

I have only collision with object at the right of my character : in x+width, y-h, Z + length

It doesn't work for example in ( x - width, , y-h, Z + length) or ( x + width, , y - h, Z - length) and so...
Posted: 17th Apr 2018 19:32
if x,y and z hold the center of the object these calculations should work for collision with another object
+ Code Snippet
x#=getObjectX(object)
y#=GetObjectY(object)
z#=getObjectZ(object)
// calculate the start of the ray cast
start_x# = x#-width
start_y# = y#+height
start_z# = z#-depth 
// calculate the end of the ray cast
end_x# = x#+width   //dimensions of object x +width etc
end_y# = y#-height
end_z# = z#+depth 
// determine which object has been hit
object_hit = ObjectRayCast(0,start_x#,start_y#,start_z#,end_x#,end_y#,end_z#)

the width height and depth may be calculated
+ Code Snippet
width=(GetObjectSizeMaxX(object)-GetObjectSizeMinX(object))/2 
height=(GetObjectSizeMaxY(object)-GetObjectSizeMinY(object))/2 
depth=(GetObjectSizeMaxZ(object)-GetObjectSizeMinZ(object))/2 
Posted: 17th Apr 2018 19:43
If you want to calculate collision with a sprite you may have to do same as above but change the calculations with the unit vectors
more like
+ Code Snippet
    width#=GetSpriteWidth(mySprite)/2
    height#=GetSprite?Height(mySprite)/2 

    pointer_x = GetSpriteX(mySprite)-width
    pointer_y =GetSpriteX(mySprite)+height
    // get the x, y and z unit vectors based on the pointer position
    unit_x# = Get3DVectorXFromScreen(pointer_x,pointer_y)
    unit_y# = Get3DVectorYFromScreen(pointer_x,pointer_y)
    unit_z# = Get3DVectorZFromScreen(pointer_x,pointer_y)
 
    // calculate the start of the ray cast, which is the unit vector + the camera position
    start_x# = unit_x# + GetCameraX(1)
    start_y# = unit_y# + GetCameraY(1)
    start_z# = unit_z# - GetCameraZ(1)
 

   // calculate the end of the vector, which is the unit vector multiplied by the length of the ray cast and then add the camera position to it
    pointer_x = GetSpriteX(mySprite)+width#
    pointer_y =GetSpriteX(mySprite)-height#
    // get the x, y and z unit vectors based on the pointer position
    unit2_x# = Get3DVectorXFromScreen(pointer_x,pointer_y)
    unit2_y# = Get3DVectorYFromScreen(pointer_x,pointer_y)
    unit2_z# = Get3DVectorZFromScreen(pointer_x,pointer_y)
 
    // calculate the start of the ray cast, which is the unit vector + the camera position
    end_x# = 1000*unit2_x# + GetCameraX(1)
    end_y# = 1000*unit2_y# + GetCameraY(1)
    end_z# = 1000*unit2_z# - GetCameraZ(1)
 
 
    // determine which object has been hit
    object_hit = ObjectRayCast(0,start_x#,start_y#,start_z#,end_x#,end_y#,end_z#)  
Posted: 17th Apr 2018 20:13
width height and depth need to be float values too
Posted: 18th Apr 2018 17:46
Hi

Thansk, i will try to see if its ok with my charactercontroller
Posted: 1st May 2018 18:25
Oh sorry Blendman I was guiding you in the wrong direction raycasting only detects the collision between two objects within a
declared area. But I think its possible to detect if the sprite was overlapping the object, if you use vectors to determine if the
vectors would intercept as if the sprite was placed in a 3d world
+ Code Snippet
function checkCollisionObjSpr(obj as integer,index as integer,spr as integer,camID as integer)
	local collision as integer
	
    //this checks for collision between a sprite with a 3d mesh and returns 1 if there would be a collision
    width=Ceil(GetSpriteWidth(Spr)/2.0)     
    height=Ceil(GetSpriteHeight(Spr)/2.0)  //because the calculations should take place from its centre
 
	check_x = GetSpriteXByOffset(spr)-width
	check_y = GetSpriteYByOffset(spr)+height
	// get the x, y and z unit vectors based on the sprite position
	start_x = Get3DVectorXFromScreen(check_x,check_y)
	start_y = Get3DVectorYFromScreen(check_x,check_y)
	start_z = Get3DVectorZFromScreen(check_x,check_y)

	check_x2 = GetSpriteXByOffset(spr)+width
	check_y2 = GetSpriteYByOffset(spr)-height
 
	end_x = Get3DVectorXFromScreen(check_x2,check_y2)
	end_y = Get3DVectorYFromScreen(check_x2,check_y2)
	end_z = Get3DVectorZFromScreen(check_x2,check_y2)
  
    objStart_x = GetObjectX(obj)+GetObjectMeshSizeMinX(obj,index) 
    objStart_y = GetObjectY(obj)-GetObjectMeshSizeMinY(obj,index)
    objStart_z = GetObjectZ(obj)-GetObjectMeshSizeMinY(obj,index)
    
    objEnd_x = GetObjectX(obj)-GetObjectMeshSizeMaxX(obj,index) 
    objEnd_y = GetObjectY(obj)+GetObjectMeshSizeMaxY(obj,index)
    objEnd_z = GetObjectZ(obj)+GetObjectMeshSizeMaxY(obj,index)
    
    for check=start_x to end_x
		if check>objStart_x and check>objEnd_x then coll1=1
	next check
	
	for check=start_y to end_y
		if check>objStart_y and check>objEnd_y then coll2=1
	next check
	//if start_z<objStart_z and start_z<objEnd_z then coll3=1
	coll3=1
	if coll1=1 and coll2=1 and coll3=1
		collision=1
    else 
		collision=0
	endif	
endfunction collision

hope that's a bit more helpful
Posted: 27th Jul 2023 13:54
HI

Sorry to re open an old thread, but I have always the same matter

When I use the code from your message :
+ Code Snippet
Function Get3DObjectCollision(object)
	
	// by fubark
	
	x#=getObjectX(object)
	y#=GetObjectY(object)
	z#=getObjectZ(object)
	
	width=(GetObjectSizeMaxX(object)-GetObjectSizeMinX(object))/2 
	height=(GetObjectSizeMaxY(object)-GetObjectSizeMinY(object))/2 
	depth=(GetObjectSizeMaxZ(object)-GetObjectSizeMinZ(object))/2

	// calculate the start of the ray cast
	start_x# = x#-width
	start_y# = y#+height
	start_z# = z#-depth 
	// calculate the end of the ray cast
	end_x# = x#+width   //dimensions of object x +width etc
	end_y# = y#-height
	end_z# = z#+depth 
	// determine which object has been hit
	object_hit = ObjectRayCast(0,start_x#,start_y#,start_z#,end_x#,end_y#,end_z#)

	
endfunction object_hit



it doesn't work, because object_hit is always the chracter or the model inside the character ^^.

So i have tried some changes but it doesn't work.

do you have an idea how to get the object wich collide with the character or how to fixe that ?

thank you
Posted: 27th Jul 2023 23:28
blendman,

i skimmed the above, got lost as to why sprites were a part of the discussion, but if you want collision detection between 2 known 3D physics objects, see HERE.

otherwise, if there's something i'm missing, please explain with a little more detail.

and, since you probably have limited experience with bullet, don't forget to delete any 3d object AND its physics body (separate calls).
Posted: 28th Jul 2023 7:55
HI

Thnak you for the example, but it doesn't work with a character and a box (kinematic or static) :

+ Code Snippet
// set display properties
// exemple by virtual nomad, modified to use a character
SetVirtualResolution( 1080, 720 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
 
 
 
Create3DPhysicsWorld() 
 
 
 n = CreateObjectPlane(500, 500)
 SetObjectRotation(n, 90, 0, 0)
 Create3DPhysicsStaticBody(n)
 
// a box to test collision
Box1 = CreateObjectBox(32,32,32)
SetObjectRotation(box1, 0, 45, 0)
Create3DPhysicsKinematicBody(Box1)
SetObjectPosition(Box1, 10, 0, 10)
    

// the character
Box2 = CreateObjectBox(32,32,32)
n = box2
SetObjectPosition(n,35,100,0)    
SetObjectColor(n,120,120,255,255)    


    characterOffsetVec = CreateVector3( 0.0, 0.0, 0.0 )
	//This vector indicates the axis your model faces forward.
	//For example if your model faces down the - Z axis use this vector.
	objectOrientationVec = CreateVector3( 0.0, 0.0, 0.0 )
	//The crouchScale parameter is 0.0 to 1.0, for examle 0.75 is 75% of the models standing height.
	Create3DPhysicsCharacterController(n, 1, characterOffsetVec, objectOrientationVec, 1)
	DeleteVector3( characterOffsetVec )
	DeleteVector3( objectOrientationVec )
	Set3DPhysicsCharacterControllerPosition(n, getobjectx(n), getobjecty(n), getobjectz(n))
	//~ Debug3DPhysicsCharacterController(n,1)
	Set3DPhysicsCharacterControllerMaxSlope(n, 30)
	Set3DPhysicsCharacterControllerGravity(n, 9.8 * 1.5 )
    
   
    //~ Create3DPhysicsKinematicBody(Box2)
 
 
 
MoveCameraLocalZ(1,-200)
 
a= 0
WalkVelocity as float
WalkVelocity= 50
finalRotation =0
x=0

do
    
    print("move character with arrow")
		//~ MoveObjectLocalX(Box1, GetRawKeyState(39)-GetRawKeyState(37) ) `RightKey-LeftKey
		//~ MoveObjectLocalZ(Box1, GetRawKeyState(38)-GetRawKeyState(40) ) `UPKey-DownKey
    
	// Move Character
	x=0
	Move3DPhysicsCharacterController(box2, x, WalkVelocity)
	if GetRawKeyState(38)
		x =1
		Move3DPhysicsCharacterController(box2, x, WalkVelocity)
	elseif GetRawKeyState(40)
		x=2
		Move3DPhysicsCharacterController(box2, x, WalkVelocity)
	endif
	if GetRawKeyState(39)
		inc finalRotation, 3
		Rotate3DPhysicsCharacterController(box2, finalRotation )
	elseif GetRawKeyState(37)
		dec finalRotation, 3
		Rotate3DPhysicsCharacterController(box2, finalRotation )
	endif
	
	
	
    
    inc a
	SetObjectPosition(Box1, 10*sin(a), 0, 10)

     
    If GetObjectCollision(Box1,Box2) // GetObjects3DPhysicsContactPositionVector(Box1,Box2,ThisV3) = 1
        SetObjectColor(Box1,255,0,0,255)
    Else
        SetObjectColor(Box1,255,255,255,255)
    Endif
     
    Step3DPhysicsWorld()
    Sync()
loop

Function GetObjectCollision(a,b)
    ThisV3 = CreateVector3()
    result = GetObjects3DPhysicsContactPositionVector(a,b,ThisV3)
EndFunction result




What I would like is just to know if the character has collision with another object (like in your example) but between a character (physics) and another object physics (static, kinematic, dynamic or character).

For example :
- if the character is on an area where it loses HP, I would like to know ^^.

For the moment, I use a sphere collision (distance), but its not enough precise.
Posted: 28th Jul 2023 13:41
I'm not sure Create3DPhysicsCharacterController() creates a 3D object the engine is polling for collisions? Interesting that the capsule does not show with the Debug3DPhysicsCharacterController(n,1) switch so I am wondering if there is something else going on I apologize for just guessing here...

I just tried using GetObject3DPhysicsFirstContact() / GetObject3DPhysicsNextContact() and GetObject3DPhysicsContactObjectB() and the collision registers but are a little flakey. I have no experience with Create3DPhysicsCharacterController() so may get chance to look further. In my experience AppGameKit display object and its corresponding 3D physics body are not one in the same (ie moving a static object will not update it's 3d physics body, so curious if the Move3DPhysicsCharacterController() is updating it's corresponding object's physics location or not.)

+ Code Snippet
if (GetObject3DPhysicsFirstContact(box2) = 1)             //Character box has registered a collision in last step
    obj_hit = GetObject3DPhysicsContactObjectB()       //Get ID of object box collided with
    if (Box1 = obj_hit)
        SetObjectColor(Box1,255,0,0,255)
    else   
        while (GetObject3DPhysicsNextContact() = 1)     //Likely the first collision was the floor, keep looking for others
            obj_hit = GetObject3DPhysicsContactObjectB()
            if (Box1 = obj_hit )
                SetObjectColor(Box1,255,0,0,255)
            endif
        endwhile
    endif
else
    SetObjectColor(Box1,255,255,255,255)
endif
Posted: 28th Jul 2023 15:48
HI

thnak you for your answer, I have tried, but it doesn't work I don't know why :

+ Code Snippet
// set display properties
// exemple by virtual nomad, modified to use a character
SetVirtualResolution( 1080, 720 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
  
  
  
Create3DPhysicsWorld() 
  
  
 n = CreateObjectPlane(500, 500)
 SetObjectRotation(n, 90, 0, 0)
 Create3DPhysicsStaticBody(n)
  
// a box to test collision
Box1 = CreateObjectBox(32,32,32)
SetObjectRotation(box1, 0, 45, 0)
Create3DPhysicsKinematicBody(Box1)
SetObjectPosition(Box1, 10, 0, 10)
     
 
// the character
Box2 = CreateObjectBox(32,64,32)
n = box2
SetObjectPosition(n,35,100,0)    
SetObjectColor(n,120,120,255,255)    
//~ SetObjectVisible(n, 0)
 
    characterOffsetVec = CreateVector3( 0.0, 0.0, 0.0 )
    //This vector indicates the axis your model faces forward.
    //For example if your model faces down the - Z axis use this vector.
    objectOrientationVec = CreateVector3( 0.0, 0.0, 0.0 )
    //The crouchScale parameter is 0.0 to 1.0, for examle 0.75 is 75% of the models standing height.
    Create3DPhysicsCharacterController(n, 1, characterOffsetVec, objectOrientationVec, 1)
    DeleteVector3( characterOffsetVec )
    DeleteVector3( objectOrientationVec )
    Set3DPhysicsCharacterControllerPosition(n, getobjectx(n), getobjecty(n), getobjectz(n))
    Debug3DPhysicsCharacterController(n,1)
    Set3DPhysicsCharacterControllerMaxSlope(n, 30)
    Set3DPhysicsCharacterControllerGravity(n, 9.8 * 1.5 )
     
 SetObjectScale(box2, 0.7, 0.7, 0.7) 
  
  
MoveCameraLocalZ(1,-200)
  
a= 0
WalkVelocity as float
WalkVelocity= 50
finalRotation =0
x=0
 
do
     
    print("move character with arrow")
     
    // Move Character
    x=0
    Move3DPhysicsCharacterController(box2, x, WalkVelocity)
    if GetRawKeyState(38)
        x =1
        Move3DPhysicsCharacterController(box2, x, WalkVelocity)
    elseif GetRawKeyState(40)
        x=2
        Move3DPhysicsCharacterController(box2, x, WalkVelocity)
    endif
    if GetRawKeyState(39)
        inc finalRotation, 3
        Rotate3DPhysicsCharacterController(box2, finalRotation )
    elseif GetRawKeyState(37)
        dec finalRotation, 3
        Rotate3DPhysicsCharacterController(box2, finalRotation )
    endif
     
     
     
     
    inc a
    SetObjectPosition(Box1, 10*sin(a), 0, 10)
 
    if (GetObject3DPhysicsFirstContact(box2) = 1)             //Character box has registered a collision in last step
		obj_hit = GetObject3DPhysicsContactObjectB() 
		      //Get ID of object box collided with
		      print("first object : "+str(obj_hit))
		if (Box1 = obj_hit)
			SetObjectColor(Box1,255,0,0,255)
		else  
			while (GetObject3DPhysicsNextContact() = 1)     //Likely the first collision was the floor, keep looking for others
				obj_hit = GetObject3DPhysicsContactObjectB()
				
				 print("other object : "+str(obj_hit))
				if (Box1 = obj_hit )
					SetObjectColor(Box1,255,0,0,255)
					
				endif
			endwhile
			
		endif
	else
		SetObjectColor(Box1,255,255,255,255)
	endif
    print(" object : "+str(obj_hit))
      
      
    Step3DPhysicsWorld()
    Sync()
loop



To see the "physics capsule" of the character, you can reduce the box2 object (or set it visible=0).

When we create a physics object, I think it's a 2nd object, depending of the "main object" (model3D for exemple).
This 2nd object (the physics object) can be box, sphere or polygon based on the mesh.

Static object can't update the physics object if we move the "main object", because it's static.
Only kinematic, dynamic and character can update the physics object, if we move the "main object", I guess.
Posted: 28th Jul 2023 18:50
I cannot seem to get it to return the object ID of the character from the collision, I suspect there is something else that we are missing here...

Try this and see the jump/crouch impacting the debug capsule. You are correct the move set is typically on loading with exception to kinematic objects, the engine will think the object hasn't moved when it comes to the 3D physics. You need to stick with the SetObject3DPhysicsLinearVelocity() commands when moving around dynamic objects during runtime. And to be honest I'm not sure how this even impacts the character controller I am hoping it will handle all this (the crouch/jump actually looks quite effective here just need a fancy animated model.)

+ Code Snippet
// Project: charAni 
// Created: 23-07-28

// show all errors

SetErrorMode(2)

// set window properties
SetWindowTitle( "charAni" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window

// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 )

SetPrintSize(20)
create3DPhysicsWorld(1)
Set3DPhysicsGravity(0, -10, 0)
SetAmbientColor(100, 100, 100)	
`SetCameraPosition(1, 0, 500, -500)
`RotateCameraLocalX(1, -15)
SetCameraRange(1, 1, 5000)

ground = CreateObjectPlane(50, 50)
	RotateObjectLocalX(ground, 90)
	SetObjectColor(ground, 0, 102, 0, 255)
	Create3DPhysicsStaticBody(ground)

box1 = CreateObjectBox(2, 2, 2)
	SetObjectPosition(box1, -5, 7, 0)
	SetObjectColor(box1, 252, 60, 12, 255)
	Create3DPhysicsDynamicBody(box1)

box2 = CreateObjectBox(3, 6, 3)
	SetObjectPosition(box2, 5, 3, 0)
	SetObjectColor(box2, 50, 220, 255, 255)
	Create3DPhysicsKinematicBody(box2)


dude = CreateObjectBox(1, 3.0, 0.5)
	SetObjectPosition(dude, 0, 1.5, 0)
	dudeAxis as integer = 1						//0 for X, 1 for Y (standing), 2 for Z (prone)
	dudePosVec = CreateVector3(0.0, 1.5, 0.0)		//Position Vector - offset from origin (model is 3 units high)
	dudeRotVec = CreateVector3(0.0, 0.0, 0.0)		//Rotation Vector (facing +z axis)
	dudeCrouch as float = 0.5						//Amount to scale model when crouching
	SetObjectTransparency(dude, 1)
	SetObjectColor(dude, 50, 50, 50, 200)
	Create3DPhysicsCharacterController(dude, dudeAxis, dudePosVec, dudeRotVec, dudeCrouch)
	Debug3DPhysicsCharacterController(dude, 1)


a= 0
WalkVelocity as float
WalkVelocity= 20
finalRotation =0
x=0

do
    print("move character with arrow")
    print("jump with space")
    print("crouch with ctrl")
    print("ground ID = " + str(ground))
    print("dynamic box1 ID = " + str(box1))
    print("kinematic box2 ID = " + str(box2))
    print("dude ID = " + str(dude))
    
    x=0
    Move3DPhysicsCharacterController(dude, x, WalkVelocity)
    if GetRawKeyState(38)
        x =1
        Move3DPhysicsCharacterController(dude, x, WalkVelocity)
    elseif GetRawKeyState(40)
        x=2
        Move3DPhysicsCharacterController(dude, x, WalkVelocity)
    endif
    if GetRawKeyState(39)
        inc finalRotation, 3
        Rotate3DPhysicsCharacterController(dude, finalRotation )
    elseif GetRawKeyState(37)
        dec finalRotation, 3
        Rotate3DPhysicsCharacterController(dude, finalRotation )
    endif
    
	if (GetRawKeyState(32) = 1)					//Space Bar
		Jump3DPhysicsCharacterController(dude)
	endif
    
	if (GetRawKeyState(17) = 1)					//Ctrl
		Crouch3DPhysicsCharacterController(dude)
	else
		Stand3DPhysicsCharacterController(dude)
	endif
    
    
    if (GetObject3DPhysicsFirstContact(box1) = 1)             //Character box has registered a collision in last step
		obj_hit = GetObject3DPhysicsContactObjectB()      	//Get ID of object box collided with
	    print("box has made contact with " + str(obj_hit))
	    if (dude = obj_hit)
	        SetObjectColor(Box1, 255, 0, 0, 255)
	        Message("dude hit the box")
	    else  
	        while (GetObject3DPhysicsNextContact() = 1)     //Likely the first collision was the floor, keep looking for others
				obj_hit = GetObject3DPhysicsContactObjectB()
				print("box has also made contact with " + str(obj_hit))
				if (dude = obj_hit)
	                SetObjectColor(Box1,255,0,0,255)
	                Message("dude hit the box")
	            endif
	        endwhile
	    endif
	else
	   ` SetObjectColor(Box1,255,255,255,255)
	endif
    
    Step3DPhysicsWorld()
    Sync()
loop


Edit - The GetObjectWorldX() coordinates for the character object are updated when moving the character controller. So in some walk-over cases could use the object position, but I think it should be populated in the contact report...
Posted: 29th Jul 2023 0:16
If I have understood correctly the things you are missing are that the character controller does return a unique value of -1 and contact will only happen momentarily unless a force is constantly applied. There are many moments when contact is clearly taking place but nothing reflects this other than the character visually showing this. If you move around constantly you will note rotation/position affects this significantly. I believe it may be a case of needing more triangles per mesh, perhaps something along the lines of the rest position is achieved instantly which would be more quickly than expected for the overall scale? I have changed the code to show the collisions of the character so that the boxes all change colour for that 1 frame being checked. Green for first contact and purple if at any point after this.

+ Code Snippet
// Project: charAni 
// Created: 23-07-28

// show all errors
SetErrorMode(2)

// set window properties
SetWindowTitle( "charAni" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window

// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 )

SetPrintSize(20)
create3DPhysicsWorld(1)
Set3DPhysicsGravity(0, -10, 0)
SetAmbientColor(100, 100, 100)	
SetCameraRange(1, 1, 5000)

type boxes
	boxID as integer
	red as integer
	green as integer
	blue as integer
endtype

boxIDs as boxes[2]

ground = CreateObjectPlane(50, 50)
	RotateObjectLocalX(ground, 90)
	SetObjectColor(ground, 0, 102, 0, 255)
	Create3DPhysicsStaticBody(ground)
	boxIDs[0].boxID=ground
	boxIDs[0].green=102

box1 = CreateObjectBox(2, 2, 2)
	SetObjectPosition(box1, -5, 7, 0)
	SetObjectColor(box1, 252, 60, 12, 255)
	Create3DPhysicsdynamicBody(box1)
	boxIDs[1].boxID=box1
	boxIDs[1].red=252
	boxIDs[1].green=60
	boxIDs[1].blue=12	

box2 = CreateObjectBox(3, 6, 3)
	SetObjectPosition(box2, 5, 3.5, 0)
	SetObjectColor(box2, 50, 220, 255, 255)
	Create3DPhysicsKinematicBody(box2)
	boxIDs[2].boxID=box2
	boxIDs[2].red=50
	boxIDs[2].green=220
	boxIDs[2].blue=255	

dude = CreateObjectBox(1, 3.0, 0.5)
	SetObjectPosition(dude, 0, 1.5, 0)
	dudeAxis as integer = 1						//0 for X, 1 for Y (standing), 2 for Z (prone)
	dudePosVec = CreateVector3(0.0, 1.5, 0.0)		//Position Vector - offset from origin (model is 3 units high)
	dudeRotVec = CreateVector3(0.0, 0.0, 0.0)		//Rotation Vector (facing +z axis)
	dudeCrouch as float = 0.5						//Amount to scale model when crouching
	SetObjectTransparency(dude, 1)
	SetObjectColor(dude, 50, 50, 50, 200)
	Create3DPhysicsCharacterController(dude, dudeAxis, dudePosVec, dudeRotVec, dudeCrouch)
	Debug3DPhysicsCharacterController(dude, 1)


a= 0
WalkVelocity as float
WalkVelocity= 20
finalRotation =0
x=0

do
    print("move character with arrow")
    print("jump with space")
    print("crouch with ctrl")
    print("ground ID = " + str(ground))
    print("dynamic box1 ID = " + str(box1))
    print("kinematic box2 ID = " + str(box2))
    print("dude ID = " + str(dude))
    
    x=0
    Move3DPhysicsCharacterController(dude, x, WalkVelocity)
    if GetRawKeyState(38)
        x =1
        Move3DPhysicsCharacterController(dude, x, WalkVelocity)
    elseif GetRawKeyState(40)
        x=2
        Move3DPhysicsCharacterController(dude, x, WalkVelocity)
    endif
    if GetRawKeyState(39)
        inc finalRotation, 3
        Rotate3DPhysicsCharacterController(dude, finalRotation )
    elseif GetRawKeyState(37)
        dec finalRotation, 3
        Rotate3DPhysicsCharacterController(dude, finalRotation )
    endif
    
	if (GetRawKeyState(32) = 1)					//Space Bar
		Jump3DPhysicsCharacterController(dude)
	endif
    
	if (GetRawKeyState(17) = 1)					//Ctrl
		Crouch3DPhysicsCharacterController(dude)
	else
		Stand3DPhysicsCharacterController(dude)
	endif
    
	for cycle=0 to boxIDs.length    
		SetObjectColor(boxIDs[cycle].boxID,boxIDs[cycle].red,boxIDs[cycle].green,boxIDs[cycle].blue,255)
		if (GetObject3DPhysicsFirstContact(boxIDs[cycle].boxID) = 1)             //Character box has registered a collision in last step
			obj_hit = GetObject3DPhysicsContactObjectB()      	//Get ID of object box collided with
			if obj_hit=-1 then obj_hit=dude
			if (dude = obj_hit)
				SetObjectColor(boxIDs[cycle].boxID, 0, 255, 0, 255)
				print("box " + str(boxIDs[cycle].boxID) + " is in contact with " + str(obj_hit))
			else  
				while (GetObject3DPhysicsNextContact() = 1)     //Likely the first collision was the floor, keep looking for others
					obj_hit = GetObject3DPhysicsContactObjectB()
					if obj_hit=-1 then obj_hit=dude
					if (dude = obj_hit)
						SetObjectColor(boxIDs[cycle].boxID,255,0,255,255)
						print("box " + str(boxIDs[cycle].boxID) + " is in contact with " + str(obj_hit))
					endif
				endwhile
			endif
		endif
	 next cycle   

    Step3DPhysicsWorld()
    Sync()
    
loop
Posted: 29th Jul 2023 14:35
the character controller does return a unique value of -1


I noticed the -1 but was stubbornly set on getting the specific character object ID to be returned... If the -1 is a unique return then Blendman you are likely off to the races here.
Posted: 30th Jul 2023 0:34
is there an advantage to using the character controller vs coding our own? from what i can tell, CCs are just a number of helper functions?

re: -1, i've only skimmed the code but there's an apparent ghost object involved internally that may be said "-1"? it would be nice if Create3DPhysicsCharacterController() returned some usable ID.

when we create a 3D object, then set them to bullet objects, the body has the same ID as the object; it would have been nice if character controllers followed the same train of thought.

so, yes, the CCs will work while bringing obstacles like this topic into play, along with some limitations we wouldn't have in coding our own?
Posted: 30th Jul 2023 3:45
+1 on the usable Id...although I said -1 is unique I must correct that as I was not thinking further than the code provided by jd_zoo - it might not be if there is another area of the 3d physics that might produce it as a result - just because I can't think of one doesn't mean there isn't.

However that is less important than catching all collisions which is what I see at my end - I think realistically using this hit detection method is too unreliable to be of any meaningful use, unless the usage/code is wrong. In DBP there was newton physics plugin and that had an extra boundary option you could set the thickness for. The boundary basically was like having a second invisible scaled object overlapping the physics object that defines the collision bounds. So the physics object can be sat on a surface where some physics frames the object might or might not penetrate the surface giving "hit and miss " results for hit detection. With the collision bounds set slightly larger contact/hit detection gave 100% reliability in the results. That would have been useful here.

I haven't played much with bullet, so no idea how hard coding our own would be, but it might well be the better option.
Posted: 30th Jul 2023 8:55
Thank you a lot for your answers.

I think I will add the collision object with player in a temporary array and check if there is an object in this array which has special behavior (trap for exemple).

is there an advantage to using the character controller vs coding our own?

I guess, the character can interact with all bullet rigid bodys (static, kinematic and dynamic).
I think it's not the case for the bullet kinematic or the other physics body.

How will you create your own character controller ?