|
Re: [Movement]: The thing about "grinding"...
[Re: Damocles_]
#295028
10/22/09 16:08
10/22/09 16:08
|
Joined: Oct 2005
Posts: 4,771 Bay City, MI
lostclimate
Expert
|
Expert
Joined: Oct 2005
Posts: 4,771
Bay City, MI
|
Traces are not needed (and they are quite slow)
The simplest Method is to create a "trail" in Med as a simple string of vertecies. (Or know the important vertecies in a more complex trail model)
And then read out the position of the vertecies by code.
Once the player enters the trail (touching the trailobject), he is "locked" to it. (the movement code goes into "slide on trail" mode) The playerposition during the movement can be interpolated along the vertecies of the trailobject. You just need to be shure wich vertexnumbers to use from the model.
Another method would be to export the trailobject to a textfile, and use this textfile as basis for the trailpositions. he is asking if it is a possible to have a system that dynamically detects grindable angles. and yes traces are slow but your main character does 6 traces a frame, thats not that bad at all. especially in a skate game where there isnt a massive amount of other traces going on at a time. @ OP: where did you ever get that you can only do one trace? trace 45 degrees down, if its not there, go from that point and trace downwards a few quants, do it at different angles to try to detect a curve.
|
|
|
Re: [Movement]: The thing about "grinding"...
[Re: lostclimate]
#295031
10/22/09 16:26
10/22/09 16:26
|
Joined: Oct 2007
Posts: 306 Austria
Alan
OP
Senior Member
|
OP
Senior Member
Joined: Oct 2007
Posts: 306
Austria
|
Hi,
I just tried to do the following:
1) Created a rail in MED (a very simple one for testing purposes) 2) Saved it 3) Opened a new Level in WED 4) Added the rail and a PATH which follows the top side of the rail (like the player is supposed to do...) 5) Compiled it to a map entity 6) Added in that map entity (rail model + path) in my level. 7) When starting, EACH AND EVERY c_trace command causes the engine to crash! wtf...
Well, I think that paths are not the way to go if they can cause crashes like this so I thought about a new method:
The main problem is that it is difficult to detect the rail with line-traces, right? So why don't we use area-wide traces? In theory, this looks like this: a) Place a cube model a few quants in front of the player (of course "in front of" takes into account the player's angle) b) Do a c_trace right downwards, using USE_BOX enabled c) The trace should hit the rail, no matter what. If it doesn't, the rail has a sharp bend (90° or more) somewhere which I don't want to include anyway.
And the "target" vector will automatically get us the position for our next c_move()-command. The faster we want to grind, the further away we have to place our block. Sounds good to me in theory, however, I see one major problem. If there is any obstacle between the block and the rail (one that would not end the grind normally but only causes the block-trace to hit a target to soon), the trace will hit an object which has it's FLAG 3 not set (therefore it has hit a non-grindable object) allthough the grind is supposed to continue normally. The big question is: how do we do this c_trace and ignore all other entities except for the one we are currently grinding on...?
Greets,
Alan
@Rei_Ayanami: If you can provide us with a tutorial for this topic, I would really like to read it ^^
|
|
|
Re: [Movement]: The thing about "grinding"...
[Re: Damocles_]
#295658
10/26/09 18:53
10/26/09 18:53
|
Joined: Oct 2007
Posts: 306 Austria
Alan
OP
Senior Member
|
OP
Senior Member
Joined: Oct 2007
Posts: 306
Austria
|
So I've tried now the following: 1) (During runtime) created a block-shaped model-entity in front of the player (taking into account his angles of course) 2) Traced downwards from the block position using "USE_BOX" with the "me" flag set to the block 3) moving the player using the "target"-vector minus the current player position as the absolute movement distance Well, works. ALLMOST. I use a straight rail for testing purposes and at one certain point the player just stops, in other words: gets stuck somehow. Ive been looking at my code for hours now and I just can't figure out why the hell he gets stuck halfway on the rail for no visible reason whatsoever. Here's my current code, it is being called once per frame:
ENTITY* grindblock;
ENTITY* current_rail;
VECTOR* grindtrace = {x=0; y=0; z=0;}
VECTOR* grindheight = {x=0; y=0; z=0;}
VECTOR* grindtest = {x=0; y=0; z=0;}
[...]
void movement_state_grind()
{
if(grindblock == NULL) // has the block already been created? If not, create it
{
grindblock = ent_create("grindblock.mdl", nullvector, NULL);
set(grindblock, TRANSLUCENT);
set(grindblock, PASSABLE);
grindblock.alpha = 0;
}
vec_set(grindblock.x, nullvector);
grindblock.x = 1;
vec_rotate(grindblock.x, player.pan); // take into account the player's angles
vec_normalize(grindblock.x, 3); // place it 3 quants in front of him (speed = 3 quants per frame for testing)
vec_add(grindblock.x, player.x); // the final position of the block
vec_set(grindblock.pan, player.pan); // to make sure the block and the player are facing into the same direction
vec_set(grindtrace, nullvector);
grindtrace.z = -1; // trace downwards
vec_rotate(grindtrace, grindblock.pan); // "downwards" is relative - rotate it and align the angle to the player angle
vec_normalize(grindtrace, 100); // trace 100 quants downwards (should always be enough to hit the rail)
vec_add(grindtrace, grindblock.x); // final position of the trace target
me = grindblock;
you = player;
c_trace(grindblock.x, grindtrace, IGNORE_ME|IGNORE_YOU|IGNORE_PASSABLE|USE_BOX); // ignore the grindblock itself and the player
vec_set(grindtest, target);
if(you == current_rail)
{
if is(your, FLAG3)
{
vec_set(grindheight, nullvector);
grindheight.z = -1;
vec_rotate(grindheight, player.pan);
vec_normalize(grindheight, -47); // go up 47 quants from the target vector to get the new position of the player model
vec_set(move_reldist, nullvector); // no relative movement
vec_diff(move_absdist, target, player.x); // absolute movement is the difference between current and new absolute position
vec_to_angle(player.pan, move_absdist); // force the player to look into that direction
vec_add(move_absdist, grindheight); // add in the 47 quants for player hight
}
}
else
{
player_movement = falling; // if the rail was NOT hit, the end of the rail has been reached (most likely ^^')
}
}
The c_move itself is done in the player-action main loop, but it's very simple:
c_move(player, move_reldist, move_absdist, IGNORE_PASSABLE|GLIDE);
... with move_reldist being equal to the nullvector while grinding. There's really nothing (much) else going on, I even tried to completely switch off gravity during grinding, didn't change anything about the result so there HAS to be some problem with my code above... The code is very well documented and easy to understand, I hope, however, I can't find the mistake...
|
|
|
Re: [Movement]: The thing about "grinding"...
[Re: Alan]
#295660
10/26/09 19:08
10/26/09 19:08
|
Joined: Apr 2006
Posts: 737 Ottawa, Canada
Ottawa
User
|
User
Joined: Apr 2006
Posts: 737
Ottawa, Canada
|
Hi!
Should this : vec_normalize(grindblock.x, 3); be vec_normalize(grindblock, 3);
Hope this helps! Ottawa  Ver 7.86.2 Pro and Lite-C
|
|
|
Re: [Movement]: The thing about "grinding"...
[Re: Ottawa]
#295732
10/27/09 07:20
10/27/09 07:20
|
Joined: Oct 2007
Posts: 306 Austria
Alan
OP
Senior Member
|
OP
Senior Member
Joined: Oct 2007
Posts: 306
Austria
|
No, because ...is an entity, therefore if we want to change its position we have to refer to the three coordinates using .x After all, "normalizing" an entire entity wouldn't make much sense, right? ^^ But thanks for looking through the code. I think that the mistake has nothing to do with typo's and stuff like that but is a "error in reasoning"... Greets, Alan
|
|
|
Re: [Movement]: The thing about "grinding"...
[Re: Alan]
#295773
10/27/09 14:51
10/27/09 14:51
|
Joined: Apr 2006
Posts: 737 Ottawa, Canada
Ottawa
User
|
User
Joined: Apr 2006
Posts: 737
Ottawa, Canada
|
Hi!
I gave your code another look and I have a few suggestions Change : vec_set(grindblock.x, nullvector); grindblock.x = 1; to vec_set(grindblock, vector(1,0,0));
and vec_set(grindtrace, nullvector); grindtrace.z = -1; to vec_set (grindtrace, vector(0,0,-1));
and vec_set(grindheight, nullvector); grindheight.z = -1; to vec_set(grindheight, vector(0,0,-1));
//------------------- What vector are you changing? vec_normalize(grindtrace, 100); vec_normalize(grindheight, -47); //----------------------
Last edited by Ottawa; 10/27/09 19:59.
Hope this helps! Ottawa  Ver 7.86.2 Pro and Lite-C
|
|
|
|