Animating Doors and similar
Blitz3D Forums/Blitz3D Programming/Animating Doors and similar
| ||
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 |
| ||
well..maybe you can use Turnentity instead?? Its working well in my projects and no need animated meshes.. |
| ||
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)? |
| ||
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. |
| ||
Nice one, Nicoust! I'll have that - (Grab). Err... I hope you don't mind? |
| ||
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. |
| ||
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. |
| ||
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 |
| ||
@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.) |
| ||
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. |
| ||
@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 |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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 |
| ||
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) |
| ||
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. |
| ||
thx jfk now i find out lol @john, thought u might have some suggestions as u want the code:P |
| ||
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. |
| ||
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. |
| ||
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... |
| ||
@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. |
| ||
.x and .3ds calculate each fram for collisions, but i prefer less hastle over textures. At least at the moment. |
| ||
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? |
| ||
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 |
| ||
John - B3D and 3DS work fundamentally diffrent. B3D are Bones based Vertex Animations, while 3ds is a child/parent-mesh hierarchy based pivot animation. |
| ||
Thanks, jfk. But sutely this means that (at least for doors) it's simpler to work with x/3ds? |
| ||
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 |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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 |
| ||
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. |
| ||
pfft cheat.:) have sliding as well myself, yeh is less code, except the double sliding ones. |