Animating Doors and similar

Blitz3D Forums/Blitz3D Programming/Animating Doors and similar

Nicstt(Posted 2005) [#1]
Hi looking for any suggestions on a better way than what I have done:)

I've created my Map with space for doors, I have now created my doors, and was thinking how to have them block access when closed, allow when opened.

I decided to create a copy of the door, which was positioned in the same space as the original door occupies when opened, it is hidden until needed, then shown, and the animated door hidden, this allows the character to walk through doorway.

I'm using function keys to open and close at them moment.

if KeyHit(62) ;open
	   seq = 1
	   Animate doorchurch, 3, 0.2, seq, 10
	   opening = true
EndIf
if KeyHit(63) ;close
	   seq = 2
	   ShowEntity doorchurch : HideEntity sparedoorCh
	   Animate doorchurch, 3, 0.2, seq, 10
EndIf
if Animating(doorchurch) = False And opening = True
	   HideEntity doorchurch : ShowEntity sparedoorCh : opening = False
endif



Naughty Alien(Posted 2005) [#2]
well..maybe you can use Turnentity instead?? Its working well in my projects and no need animated meshes..


Nicstt(Posted 2005) [#3]
was thinking that would be more coding than animated, but after finishing the code for doors i doubt it:)

; ****mouse open closes church door *****
MouseLeft = MouseHit(1)
If MouseLeft And CameraPick( Camera , MouseX(), MouseY() ) = doorchurch
   If opening = False And open = False And EntityDistance( playerbox , doorchurch ) < 15.01
     seq = 1 : doordelaytime = Millisecs()
     Animate doorchurch, 3, 0.2, seq, 10
     opening = true : open = False
   EndIf
EndIf
If MouseLeft And CameraPick( Camera , MouseX(), MouseY() ) = sparedoorCh
   If opening = False And Open = True And EntityDistance( playerbox , sparedoorch ) < 15.01
     ShowEntity doorchurch : HideEntity sparedoorCh
     seq = 2 : Animate doorchurch, 3, 0.2, seq, 10 : open = False : opening = False
   EndIf
EndIf
;makes sure animation has finished before allowing another action
if Animating(doorchurch) = False And opening = True
   HideEntity doorchurch : ShowEntity sparedoorCh
   opening = False : open = True
endif
if Animating(doorchurch) = False And opening = False And Open = True And Millisecs() > (doordelaytime + dooropenfor)
   ShowEntity doorchurch : HideEntity sparedoorCh 
   open = False : seq = 2 : Animate doorchurch, 3, 0.2, seq, 10
endif


i notice when rotating they turn on centre axis, can that be set so it turns on an edge (like a door)?


Shambler(Posted 2005) [#4]

i notice when rotating they turn on centre axis, can that be set so it turns on an edge (like a door)?



Model your door so that the hinge is the centre axis i.e. move it in your modelling package.


John Blackledge(Posted 2005) [#5]
Nice one, Nicoust!
I'll have that - (Grab).
Err... I hope you don't mind?


Braincell(Posted 2005) [#6]
Nicoust, you can make a pivot, put it at the edge of the door frame, parent the door to the pivot, and rotate the pivot. If you have a two piece door, then you make children as elements and do it for each one. You can also do what Shambler said if its a one piece door.


Nicstt(Posted 2005) [#7]
sorry maybe didnt explain properly.

My animated door, hinges correctly, was wondering if i used the RotateEntity command that it usually rotates in the centre, was wondering if it can be changed?

EDIT: no matter it doesnt turn on the centre, but the edge, im stupid, or perhaps tired:).

@John, sure be my guest.

Experimenting with another method atm, it works great what i use, but aligning the 'sparedoor' up with the animated open door for when i switch show/hide is time consuming, even with a couple of functions to change position size in game and buttons to save changes to a text file

I have the animated door as a child to the 'world' so it gets involved in collisions, however when its open the collision area is still the same, another reason for the second door.

I'm having fun (usually:p) and progressing too.


Rook Zimbabwe(Posted 2005) [#8]
Actually I had a similar issue when I first started. I had created a B3D animation of a door and when you were close enough and you right clicked on it you could open it... But you could not walk through it.

Even though the door animated open it was still CLOSED according to blitz collisions... SO

When I found a door OPEN I changed the collision mode for that door (since really you can only walk trough one at a time)and that seemed to work... until I left a door open and ALL doors were counted OPEN even though closed.

SO I simply rotated the door mesh out of the way AFTER the animation was finished and reset it before applying door close animation... Sloppy but OK


John Blackledge(Posted 2005) [#9]
@Rook - at that point why bother with the animation at all?

If your code rotated the door, and collisions were properly reset, why did you keep the animation?

(Yes, I will need to start doors soon, so I'm following this thread with great interest - it may save me a lot of work and blind alleys.)


(tu) sinu(Posted 2005) [#10]
why not create a alpha'd(alpha set to 0) door which has collisions on it so when the visible door is open and at a certain rotation, hide the alpha'd door to allow passing through and disabling collision on the entrance and then maybe rotating it to the visible doors rotation and unhiding it but still leaving it alpha'd at 0.


Nicstt(Posted 2005) [#11]
@John

here are two examples of what I use, stopped using animated completely.

Global doorguard7 = LoadMesh(dirpath$ + "MilkShape mods\DoormsAnim.b3d", level)
Global stonegateL = LoadMesh (dirpath$ + "B3D\Stone Door Left.b3d", level); is also a Right door as well

; setup guard door 7
ScaleEntity doorguard7, 7.35, 11.48, 10.5
PositionEntity doorguard7, -5646.98, 783.59, 3509.94
EntityPickMode doorguard7, 2, False
RotateEntity doorguard7, 0, -90, 0

; setup stone door keep
PositionEntity stonegateL, -4608.09, 1087.2, -1120.0
EntityPickMode stonegateL, 2, False
PositionEntity stonegateR, -4608.09, 1087.2, -1120.0
EntityPickMode stonegateR, 2, False

; * * * * * * * * * mouse open closes STONE Gates * * * * * * * * *
If MouseLeft And ( (CameraPick( Camera , MouseX(), MouseY() ) = stonegateL) Or (CameraPick( Camera , MouseX(), MouseY() ) = stonegateR) ); open
   If opening4 = False And open4 = False And closing4 = False And ( (EntityDistance( playerbox , stonegateL ) < 20.01) Or (EntityDistance( playerbox , stonegateR ) < 20.01) )
   	   doordelaytime4 = Millisecs()
		   opening4 = True : open4 = False : closing4 = False
   EndIf
EndIf
If MouseLeft And ( (CameraPick( Camera , MouseX(), MouseY() ) = stonegateL) Or (CameraPick( Camera , MouseX(), MouseY() ) = stonegateR) ) ; close
   If opening4 = False And Open4 = True And closing4 = False And ( (EntityDistance( playerbox , stonegateL ) < 20.01) Or (EntityDistance( playerbox , stonegateR ) < 20.01) )
            open4 = False : opening4 = False : closing4 = true
   EndIf
EndIf
;makes sure animation has finished before allowing another action
; open
if  open4 = False And opening4 = True  And closing4 = False
   gateup4 = gateup4 - 4 : gateup4b = gateup4b + 4
   if gateup4 < - 255 then gateup4 = -256 : gateup4b = 255 : opening4 = False : open4 = True : closing3 = False
	   PositionEntity stonegateL, -4608.09 + gateup4, 1087.2, -1120.0
	   PositionEntity stonegateR, -4608.09 + gateup4b, 1087.2, -1120.0
endif
; timed close
if opening4 = False And Open4 = True And closing4 = False And Millisecs() > (doordelaytime4 + dooropenfor)
   gateup4 = gateup4 + 4 : gateup4b = gateup4b - 4
   if gateup4 > 0 then gateup4 = 0 : gateup4b = 0 : opening4 = False : open4 = False
   PositionEntity stonegateL, -4608.09 + gateup4, 1087.2, -1120.0
   PositionEntity stonegateR, -4608.09 + gateup4b, 1087.2, -1120.0
endif
; close
if opening4 = False And Open4 = False And closing4 = True
   gateup4 = gateup4 + 4 : gateup4b = gateup4b - 4
   if gateup4 > 0 then gateup4 = 0 : gateup4b = 0 : opening4 = False : open4 = False : closing4 = False
   PositionEntity stonegateL, -4608.09 + gateup4, 1087.2, -1120.0
   PositionEntity stonegateR, -4608.09 + gateup4b, 1087.2, -1120.0
endif
; *********************************************************************
; * * * * * * * * * mouse open closes Guard Door 7 * * * * * * * * *
If MouseLeft And CameraPick( Camera , MouseX(), MouseY() ) = doorguard7
   If opening12 = False And open12 = False And closing12 = False And EntityDistance( playerbox , doorguard7 ) < 15.01
           doordelaytime12 = Millisecs() : opening12 = true : open12 = False : closing12 = False
   EndIf
EndIf
If MouseLeft And CameraPick( Camera , MouseX(), MouseY() ) = doorguard7
   If opening12 = False And Open12 = True  And closing12 = False And EntityDistance( playerbox , doorguard7 ) < 15.01
	   open12 = False : opening12 = False : closing12 = True
   EndIf
EndIf
;makes sure animation has finished before allowing another action
; open
if open12 = False And opening12 = True  And closing12 = False
   gateup12 = gateup12 + 5
   if gateup12 > 85 then gateup12 = 85 : opening12 = False : open12 = True : closing12 = False
   RotateEntity doorguard7, EntityPitch(doorguard7), EntityYaw(doorguard7) + 5, 0
endif
; close
If opening12 = False And Open12 = False And closing12 = True
   gateup12 = gateup12 - 5
   if gateup12 < 0 then gateup12 = 0 : opening12 = False : open12 = False : closing12 = False
   RotateEntity doorguard7, EntityPitch(doorguard7), EntityYaw(doorguard7) - 5, 0
EndIf
; timed close
If opening12 = False And Open12 = True And closing12 = False And Millisecs() > (doordelaytime12 + dooropenfor)
   gateup12 = gateup12 - 5
   if gateup12 < 0 then gateup12 = 0 : opening12 = False : open12 = False : closing12 = False
   RotateEntity doorguard7, EntityPitch(doorguard7), EntityYaw(doorguard7) - 5, 0
EndIf
; *********************************************************************


I'm also likely to swap the code into being controlled by types, take up less space, and will change the code to test distance from door first, then do further checks if distance is within range

So whilst there is a little more code in the method i have decided on, there is now only one mesh per door, and setting it up is a lot easier


John Blackledge(Posted 2005) [#12]
Nice work, but yes, you do need types to tidy this all up.
It will be worth the effort as you add other doors.
Nice to see you have timed closing, as well.

One thing I've noticed (which I approve of) in games, is that if you make a run for a closing door, it never actually 'traps' you - that would be tedious. Instead I think they kill the collisions on the door while it's moving. Not quite ultra-realism, but better than getting trapped, when the only way out is to exit.


Nicstt(Posted 2005) [#13]
Also thinking of using a bank to store the data instead of types

The collisions are killed, for blitz i think its the way it handles collisions, I make the doors children of the level, and use that collision, but if the door moves into player then no collide detected.


John Blackledge(Posted 2005) [#14]
Now I'm going to be naughty and request:
a) That you post it when finished (I have no scruples)
b) That you just use types not banks, coz then it would be easier to modify.


Nicstt(Posted 2005) [#15]
using types, if i need to start squeezing performance ill try banks

any suggestions for type fields?

Type doors
Field doorgfx
Field posx
Field posy
Field posz
Field rotx
Field roty
Field rotz
Field sclx
Field scly
Field sclz
Field open
Field opening
Field closing
Field moveup
Field delaytime
Field locked
Field keyref
Field number
Field name$
End Type


jfk EO-11110(Posted 2005) [#16]
Additional Note. don't use .B3D for animated Door Meshes, instead use .3ds or .X. (because the bones based B3D will use the inital collision for the whole animation (so it will stay closed forever, not matter if you play the open-sequence), while 3ds uses true mesh children with individual , autonomous collision shapes)


John Blackledge(Posted 2005) [#17]
Which type fields? Only you can say. That's the great thing about coding - you are in control!

I think the nice thing about types is that as you work and expand or add a function it becomes obvious that you need a new variable.
It's so easy to add a new variable to a type, then carry on working.

Also, I can't thank the person enough on these forums who stated the obvious - don't use globals, use types.
So I now have:
Camera\x
Camera\y
Camera\z
etc, etc.
What a difference that has made to my debugging.


Nicstt(Posted 2005) [#18]
thx jfk now i find out lol

@john, thought u might have some suggestions as u want the code:P


John Blackledge(Posted 2005) [#19]
Yes I do, but you seem to have it well covered.

I think the ideal situation would be a code-structure where it was fairly easy to add new doors via a call -
AddDoor(mesh$, x,y,z, behaviour, distance) etc
- even if you had to preset say max 10 doors to create the type-structure.


Nicstt(Posted 2005) [#20]
ive used data statements, they hold the info, the first item is how many doors there are. Got the code reduced by a huge amount, then one door caused loads of probs as it was a double one that slid. ended up being way too much code so it got changed:p

Even now its about as much code as the rest of the door function.

waiting to see what suggestions i get from a question i posted, will post the type setup after i see if it is going to change or not.




Rook Zimbabwe(Posted 2005) [#21]
If your code rotated the door, and collisions were properly reset, why did you keep the animation?
Well the problem was I animated the door in Milkshape 3D. NOT in code (sorry if that was not clear) that way clicking on it again was simply a reverse of the previous animation.

But even though the door animated open wonderfully... animated closed wonderfully... it was never really open. I guess the actual B3D object that contained the door did not move.

I admit it may have been in the method I used to animate the door, but I have been dealing with animation since I was 15 and computer animation since I was 25 (and they came out with it) The door hinge and all things attached to the door JOINT moved... but had no more collisions since the door OBJECT never really moved.

I am using version 1.7 of Milkshape though...


John Blackledge(Posted 2005) [#22]
@Rook. No, I think you're right.
Someone did mention that Blitz takes the collision data from the first frame only, so an animation does not change the collision calculations; whereas if you manually rotate the whole thing, then collisions are recalced.


Nicstt(Posted 2005) [#23]
.x and .3ds calculate each fram for collisions, but i prefer less hastle over textures. At least at the moment.


John Blackledge(Posted 2005) [#24]
Hang on, you're saying collision calculations work differently for animated B3D and X? - What, you can walk through an animated .X door, but not a .B3D door?


Nicstt(Posted 2005) [#25]
so i hear.

Btw solved my fps problem - anyone reading this, dont have program check for camera pick except on mouseclick, or however you deside to activate something that relies on camerapick.

It hogs FPS, turns it into SPF

I changed part of the above code, put the amendment below, is just the first 10ish lines.

if MouseLeft
   if CameraPick( Camera , MouseX(), MouseY() ) = more\doorgfx
           If more\opening = False And more\open = False And more\closing = False And EntityDistance( playerbox , more\doorgfx ) < more\distance#
	        more\delaytime = Millisecs() : more\opening = true : more\open = False : more\closing = False
	   EndIf
           If more\opening = False And more\open = True And more\closing = False And EntityDistance( playerbox , more\doorgfx ) < more\distance#
		more\open = False : more\opening = False : more\closing = True
           EndIf
   endif
endif



jfk EO-11110(Posted 2005) [#26]
John - B3D and 3DS work fundamentally diffrent. B3D are Bones based Vertex Animations, while 3ds is a child/parent-mesh hierarchy based pivot animation.


John Blackledge(Posted 2005) [#27]
Thanks, jfk.

But sutely this means that (at least for doors) it's simpler to work with x/3ds?


Nicstt(Posted 2005) [#28]
i prefer what ive done john, i dont have to mess with texturing the doors. If i didnt have to texture them, I would at least have tried .x 3ds


John Blackledge(Posted 2005) [#29]
If you do need to use .x instead of B3D (as I do sometines), for ease of use/great texturing try Metasequia:
http://www21.ocn.ne.jp/~mizno/main_e.html
- v2.1 saves as .X and is free.


Nicstt(Posted 2005) [#30]
looks decent, i have milkshape 1.7 and ultimate unwrap, and cartography shop, seems to be ok there, milkshape and UU3d im definitely still learning, its strange i find 3d easy to do than 2d, not that i can draw anything, i just seem to get by.


John Blackledge(Posted 2005) [#31]
I use Milkshape too, but only for animated characters, otherwise I end up tearing my hair out.

I know that the choice of an editor is always personal.
A lot of people use 3DSmax (how can they afford it?) but when I tried a copy I thought it was the silliest layout and design I've ever seen in any software.

For the opposite reason I like Metasequoia.
I knew nothing about modelling when I started, and the manual is in Japanese - and I learned! How good does that make the program???

Anyone who does take to it - I have a pretty much complete english manual I could send you.

One of the things I'd like to see on the Blitz site would be a chart (database?) of which modellers everyone uses, and why.
I must admit I still live in hope of finding the ideal modeller (instead of using 2,3 or even 4 to get a job done), but most of the time when I try a new one I just end up laughing hysterically.


Nicstt(Posted 2005) [#32]
yeh i noticed, was trying to model something earlier and it drove me crazy. CShop sure is more straight forward. I went for the copy and paste functions in milkshape to duplicate something, and couldnt find it. Found it since.

So yeh trying to find a 3d package i like, and can afford, im a hobiest. /agree on 3ds, least ways i think it was 3ds, spnding the first 30 minutes wondering what the heck to click on is bad. Of course im a novice at the genre which doesnt help


Gord(Posted 2005) [#33]
I use sliding doors in my level. When the player goes up on a platform it activates the door. Coding is minimal. I have a hidden cube on the platform which acts like a flag to open the door. It takes about 5 lines of code which includes EntityDistance( cam,cube)< 1. Simple but effective.


Nicstt(Posted 2005) [#34]
pfft cheat.:)

have sliding as well myself, yeh is less code, except the double sliding ones.