The following is how I do doors that hinge on one side, and open by swinging, and also for portcullis that go up and down. These doors/portcullis are being created inside B3D with no external meshes. The textures (ie t_door, t_port, etc) I use are just freebie royalty-free things, which you can get off the web at any number of sites. The variable EastWest is for whether the door should align itself in an East-West direction, or a North-South direction Yeah, it's a bit more code, but it works. Then, when someone "activates" the door/portcullis, I just run the animation that captured the movement (ie rotate or up-down). Finally, here's some code that I use to "activate" the door/portcullis (I click on the object in question). If it's within a certain range, ie within arm's reach, then the animation is run. Notice that I just use a negative value to run the animation "backwards" to close the doors. There may be a few extra code snippets in the folowing, so if you have any questions, post me.
Type entity ;a type to tell us what entity category we're looking at
Field parent
Field entity
Field child
Field kind ;wall, portcullis, door, fountian
Field state ;closed=1, opened=2
; Field del ;True/False, i.e. flag to delete this object
Field seq
End Type
.createdoor
e.entity = New entity ;create a new instance of the entity type variable
e\parent=CreatePivot()
e\entity=CreateCube(e\parent)
NameEntity e\entity,"Door"
EntityPickMode e\entity,2
PositionMesh e\entity,1,1,1 ;move "door" so that it hinges on left side
ScaleMesh e\entity,1.6,1.8,.125 ;reshape cube to look like door (flatten, etc)
EntityTexture e\entity,t_door ;paint the door to look like one
EntityType e\entity,2
If EastWest=False Then RotateEntity e\entity,0,90,0
epitch= EntityPitch(e\entity)
eyaw = EntityYaw(e\entity)
eroll = EntityRoll(e\entity)
For frame=1 To 45
TurnEntity e\entity,0,2.0,0 ;turn door on its hinges
SetAnimKey e\entity,frame
Next
e\seq = AddAnimSeq(e\entity,frame-1) ;minus 1 because For-Next loops end 1 too many
e\kind = door
e\state = closed
RotateEntity e\entity,epitch,eyaw,eroll ;undo the positioning done by the animation
Return
.createdoorframe
e.entity = New entity ;create a new instance of the entity type variable
e\entity=CreateCube() ;store entity handle in the Type variable
NameEntity e\entity,"Door Frame"
ScaleMesh e\entity,0.2,2.0,0.4 ;reshape it into a doorpost column
PositionMesh e\entity,0,.5,0
EntityPickMode e\entity,2
topframe = CreateCube(e\entity)
ScaleMesh topframe,1.6,0.2,0.4
PositionMesh topframe,1.8,2.3,0
doorframe2 = CopyMesh(e\entity,e\entity) ;copy the doorpost column
PositionMesh doorframe2,3.6,0,0
AddMesh topframe,e\entity
AddMesh doorframe2,e\entity
EntityTexture e\entity,t_stone ;paint doorframe with concrete pic
EntityType e\entity,2
FreeEntity topframe
FreeEntity doorframe2
Return
.createportcullis ;for now, just re-using code for vertical door opening
Const slatspace#=.291
e.entity = New entity ;create a new instance of the entity type variable
e\parent=CreatePivot()
e\entity=CreateCube(e\parent)
NameEntity e\entity,"Portcullis"
ScaleMesh e\entity,.16,1.8,.05 ;reshape cube to look like port slat (flatten, etc)
PositionMesh e\entity,.4,1.8,.1 ;move "portcullis"
EntityPickMode e\entity,2
; EntityTexture e\entity,t_port ;paint the port slat to look like one
bar1=CreateCube(e\entity)
ScaleMesh bar1,1.6,.16,.05
PositionMesh bar1,1.6,3.2,0
; EntityTexture bar1,t_port ;paint the port slat to look like one
bar2=CreateCube(e\entity)
ScaleMesh bar2,1.6,.16,.05
PositionMesh bar2,1.6,3.2-slatspace*2,0
; EntityTexture bar2,t_port ;paint the port slat to look like one
bar3=CreateCube(e\entity)
ScaleMesh bar3,1.6,.16,.05
PositionMesh bar3,1.6,3.2-slatspace*4,0
; EntityTexture bar3,t_port ;paint the port slat to look like one
bar4=CreateCube(e\entity)
ScaleMesh bar4,1.6,.16,.05
PositionMesh bar4,1.6,3.2-slatspace*6,0
; EntityTexture bar4,t_port ;paint the port slat to look like one
bar5=CreateCube(e\entity)
ScaleMesh bar5,1.6,.16,.05
PositionMesh bar5,1.6,3.2-slatspace*8,0
; EntityTexture bar5,t_port ;paint the port slat to look like one
bar6=CreateCube(e\entity)
ScaleMesh bar6,1.6,.16,.05
PositionMesh bar6,1.6,3.2-slatspace*10,0
; EntityTexture bar6,t_port ;paint the port slat to look like one
slat1=CreateCube(e\entity)
ScaleMesh slat1,.16,1.8,.05 ;reshape cube to look like port slat (flatten, etc)
PositionMesh slat1,.4+slatspace*2,1.8,.1 ;move "portcullis"
; EntityTexture slat1,t_port ;paint the port slat to look like one
slat2=CreateCube(e\entity)
ScaleMesh slat2,.16,1.8,.05 ;reshape cube to look like port slat (flatten, etc)
PositionMesh slat2,.4+slatspace*4,1.8,.1 ;move "portcullis"
; EntityTexture slat2,t_port ;paint the port slat to look like one
slat3=CreateCube(e\entity)
ScaleMesh slat3,.16,1.8,.05 ;reshape cube to look like port slat (flatten, etc)
PositionMesh slat3,.4+slatspace*6,1.8,.1 ;move "portcullis"
; EntityTexture slat3,t_port ;paint the port slat to look like one
slat4=CreateCube(e\entity)
ScaleMesh slat4,.16,1.8,.05 ;reshape cube to look like port slat (flatten, etc)
PositionMesh slat4,.4+slatspace*8,1.8,.1 ;move "portcullis"
; EntityTexture slat4,t_port ;paint the port slat to look like one
AddMesh bar1,e\entity : FreeEntity bar1
AddMesh bar2,e\entity : FreeEntity bar2
AddMesh bar3,e\entity : FreeEntity bar3
AddMesh bar4,e\entity : FreeEntity bar4
AddMesh bar5,e\entity : FreeEntity bar5
AddMesh bar6,e\entity : FreeEntity bar6
AddMesh slat1,e\entity: FreeEntity slat1
AddMesh slat2,e\entity: FreeEntity slat2
AddMesh slat3,e\entity: FreeEntity slat3
AddMesh slat4,e\entity: FreeEntity slat4
EntityType e\entity,2
; UpdateNormals e\entity
EntityTexture e\entity,t_port
If EastWest=False Then RotateEntity e\entity,0,90,0
ex=EntityX(e\entity)
ey=EntityY(e\entity)
ez=EntityZ(e\entity)
d=0.05
For frame=1 To 68
MoveEntity e\entity,0,d,0 ;for vertical portcullis effect
SetAnimKey e\entity,frame
Next
e\seq = AddAnimSeq(e\entity,frame-1) ;minus 1 because For-Next loops end 1 too many
e\kind = port
e\state = closed
PositionEntity e\entity,ex,ey,ez ;undo the positioning done by the animation
Return
.animate
If MouseDown(1)=True
CameraPick(camera,MouseX(),MouseY())
message$="PickedEntity is "
pe=PickedEntity()
px# = (EntityX(pcam)-PickedX#())
pz# = (EntityZ(pcam)-PickedZ#())
seerange# = Sqr((px*px)+(pz*pz))
If pe = 0
message$ = message$+"nothing."
ElseIf seerange => fogrange-3
message$ = message$+"Out of Range"
Else
message$ = message$+EntityName$(pe)+"."
For e.entity = Each entity
If e\entity=pe
If seerange <4.5
If e\kind = door
If Animating(e\entity) = False ;if door is not moving
If e\state=closed
Animate e\entity,3,.5
e\state = opened
ElseIf e\state = opened
Animate e\entity,3,-.5
e\state = closed
EndIf
EndIf
ElseIf e\kind = port
If Animating(e\entity) = False
If e\state=closed
Animate e\entity,3,.5 ;play animationm forward (ie raise port)
e\state = opened
ElseIf e\state = opened
Animate e\entity,3,-.5
e\state = closed
EndIf
EndIf
EndIf
Else
Text 0,220,"Too far to operate!"
EndIf
EndIf
Next
EndIf
picked$="PickedX: "+PickedX#()
picked$=picked$+" PickedY: "+PickedY#()
picked$=picked$+" PickedZ: "+PickedZ#()
Text 0, 200, message$ ;text here, so that renderworld does not overwrite it
EndIf
cam$="Camera X: "+EntityX(pcam)+" Camera Y: "+EntityY(pcam)+" Camera Z: "+EntityZ(pcam)
Text 0,100,cam$
Text 0,120, picked$
Text 0,140,"See Range = "+seerange
Flip
Wend