3D Rad - Free 3D game maker - Forum

This forum is now archived!

This forum is locked, and is a read-only version. A new community-ran forum can be found at classdev.net

News:

The 3DRad community can be found at classdev.net.

Pages: [1] 2 3 ... 10

Author Topic: MouseLook, WASD drive  (Read 13078 times)

« on: January 29, 2013, 05:14:25 AM »
Pans the camera around the car, and drive in a camera-relative direction using the WASD keys, like in a FPS game.
Look to the car's left while it drives to the right as you hold D, for example.
I haven't thoroughly tested it, so I'm not sure I should go plugin with it yet, but it's plugin_ named.
1st, link a CamChase, then a car. Disable all the car's keys. Add terrain and g-force, and it should be good to go.

Here's the script:
Code: [Select]
int objCam= OBJ_0;
int objCar= OBJ_22;

///                                                           
///   Modifiable parameters                                   
string dikU= "DIK_W";
string dikD= "DIK_S";
string dikL= "DIK_A";
string dikR= "DIK_D";
string dikBrake= "DIK_SPACE";

string dikZoomIn= "DIK_PRIOR";   // PGUP
string dikZoomOut="DIK_NEXT";    // PGDN

float lookSmoothX= 0.75;
float lookSmoothY= 0.9;
float lookSpeedX= 300;
float lookSpeedY= 150;
float turnRate=360;   // degrees/sec

float zStep= 15.0/16.0; // zoom step size
float wheelFactor=0.75; // wheel+-= zStep*wheelFactor



///                                                           

bool isBehind;    // should be called inReverse. I'll rename that later
bool moving;      // WASD key(s) are being pressed. Going forward or reverse
bool newBeginning; // Just began moving. isBehind/inReverse will be assigned a value
                  //          (makes WASD circling possible)

float moveAngle=0;
void moveDirection() {  // determine if player is WASDing, and which way
   float x=0, z=0;
   if (iKeyDown(iKeyCode(dikU))) z+= 1;
   if (iKeyDown(iKeyCode(dikD))) z-= 1;
   if (iKeyDown(iKeyCode(dikL))) x-= 1;
   if (iKeyDown(iKeyCode(dikR))) x+= 1;
   bool _moving= (x!=0 or z!=0);
   newBeginning= _moving and not moving;
   
   if (moving= isMoving) // assignment, not compair-fail
      moveAngle= 57.295779*R_atan2(x, z);
}

Quaternion qCam, qCar;
//   Get RadMath2.dll from Quaternion_to_cartesian.zip here:http://3dfoundry.net/forum/index.php?topic=32.0
int MathDLLHandle=0;   //   R_atan2 needs RadMath2.dll
void Main() {            ///   Main   
   if(iInitializing()) {
      MathDLLHandle = iDLLLoad(".\\3DRad_res\\objects\\Script\\RadMath2.dll");
      if (MathDLLHandle==0)
         MathDLLHandle = iDLLLoad(".\\3DRad_res\\objects\\Script\\RadMath.dll");
     
      iMouseLookSet(0, 0);
      iMouseLookSpeedSet(lookSpeedY, lookSpeedX);
   } else if (iDeinitializing()) {
      if (MathDLLHandle != 0) iDLLUnload(MathDLLHandle);
   } else if (MathDLLHandle != 0) {
      iObjectOrientation(objCam, qCam);
      iObjectOrientation(objCar, qCar);
     
      mouseLook2D();
      float a;
      moveDirection();  // if so, updates moveAngle
      steerToCamVec();
      OUT_23= (moving ? (isBehind ? -5 : 5) : 0);  // throttle
      OUT_24= (moving ? 0 : 1);  // brakes
   }
}


///                                                           

float dist= 4;   //   objCam distance from objCar. Initial zoom level
float mouseX=0, mouseY=0;  // for motion smoothing
void mouseLook2D() {
   //   camera zoom control. Scroll wheel & PgUp/PgDn
   float mz= (iMouseZ(true));
   if (mz<0) dist/= wheelFactor*zStep; else if (mz>1) dist*= wheelFactor*zStep;
   if (iKeyDown(iKeyCode(dikZoomIn))) dist*= zStep;
   if (iKeyDown(iKeyCode(dikZoomOut)))  dist/= zStep;
   
   mouseX= fInterpolate(iMouseLookX(), mouseX, lookSmoothY); // up/down, obviously
   mouseY= fInterpolate(iMouseLookY(), mouseY, lookSmoothX); // left/right
   qCam= qEulers(mouseX, mouseY, 0);
   
   setQuat(objCam, qCam);
   setLoc(objCam, getLoc(objCar) + dist*vecRot(qCam, Vector3(0,0.5,-1)));
}



float revAngle= 60; // go in reverse if car's rear vector is within this many degrees of desired heading. 0-180
///                                                           
void steerToCamVec() {
   float s= yAngle(qDelta(qCar, qCam));
   
   float rDir= degFix((degFix(moveAngle)-degFix(s)));
   s= degFix(s - moveAngle);
   if (newBeginning) isBehind= iFloatAbs(rDir)>(180-revAngle);
   if (isBehind) s= sign(s)*(180-iFloatAbs(s));
   setSteering(s);
}
float degFix(float a) {while (a<-180) a+=360; while (a>180) a-=360; return a;}

float RelativeSpeed() {
   Vector3 SpeedVec, LocalZVec;
   iObjectVelocity(objCar, SpeedVec);
   iVectorRotate(LocalZVec, Vector3(0,0,1), qCar);
   return iVectorDot(LocalZVec, SpeedVec);
}

float steerPos=0;
void setSteering(float f) {
   float d= f-steerPos, s= turnRate/iFrameRate(false);
   if (iFloatAbs(d)>s) d= s*sign(d);
   steerPos+= d;
   OUT_22= steerPos/IN_23;
}

float fInterpolate(float f1, float f2, float f2p) {return (1-f2p)*f1 + f2p*f2;}

///                                                                     
// the brick - shorthand form for nesting expressions                             
float sign(float f) {return f<0?-1:f>0?1:0;}
float yAngle(Quaternion q) {return yAngle(vecRot(q, Vector3(0,0,1)));}
float yAngle(Vector3 v) {return 57.295779*R_atan2(v.x, v.z);}
Vector3 vecRot(Quaternion q, Vector3 d) {Vector3 r;iVectorRotate(r,d,q);return r;}
Quaternion qMul(Quaternion q1, Quaternion q2) {Quaternion qt;iQuaternionMultiply(qt,q1,q2);return qt;} // q1+q2
Quaternion qDelta(Quaternion q1, Quaternion q2) {return qMul(q1, qInv(q2));} // q1-q2
Quaternion qInv(Quaternion q) {return Quaternion(q.x,q.y,q.z,-q.w);} // -q
Vector3 getLoc(int obj) {Vector3 l; iObjectLocation(obj, l); return l;}
Vector3 setLoc(int obj, Vector3 l) {iObjectLocationSet(obj, l); return l;}
Quaternion getQuat(int obj) {Quaternion q; iObjectOrientation(obj, q); return q;}
Quaternion setQuat(int obj, Quaternion q) {iObjectOrientationSet(obj, q); return q;}
Quaternion qAxisAngle(Vector3 vUp, float dy) {Quaternion q; iQuaternionFromAxisAngle(q, vUp, dy); return q;}
Quaternion qEulers(float x, float y, float z) {Quaternion q;iQuaternionFromEulerAngles(q,x,y,z,"xyz");return q;}
Quaternion qInterpolate(Quaternion q1, Quaternion q2, float q1percent) {Quaternion q;iQuaternionInterpolate(q,q1,q2,q1percent);return q;}
float RelativeSpeed(int obj) {return iVectorDot(vecRot(getQuat(obj), Vector3(0,0,1)), objVelocity(obj));}
Vector3 objVelocity(int obj) {Vector3 SpeedVec;iObjectVelocity(obj, SpeedVec);return SpeedVec;}

float R_atan2(float value1, float value2) { // requires RadMath2.dll. Returns value1 without it
   iDLLArraySet(0,value1); iDLLArraySet(1,value2);
   iDLLCall(MathDLLHandle,"R_atan2",0);
   return iDLLArrayGet(0);
}
Requires RadMath2.dll (zipped courtesy of XingBat)
« Last Edit: January 30, 2013, 02:09:32 PM by chronocide »
« Reply #1 on: January 29, 2013, 10:55:45 PM »
Nice maths functions. Compact and useful stuff. Thanks.
Here's the RadMath2.dll zipped, so you don't have to download that old project if you just need the dll.
« Last Edit: January 29, 2013, 11:01:53 PM by XingBat »
« Reply #2 on: January 29, 2013, 11:24:52 PM »
Thanks. Most of it is re-hashing of what others have done. I just keep hitting pur�e until it works  :D

Check out what I did with it in the Tank_template-based project I attached. Took longer than I care to admit to get the turret aiming correctly. It aims at where you're looking.

[edit] Something wasn't right when aiming above 45 degrees, though, because in the turret control script, I should have used R_asin instead of R_atan to get AngleX. Attached project revised.
« Last Edit: January 30, 2013, 05:55:05 PM by chronocide »
« Reply #3 on: January 30, 2013, 09:20:42 PM »
I see the atan2/asin problem. Inverse trigs takes a lot of concentration to visualize properly. I'd do it slightly differently, but I like your approach.  At least you are having a lot of fun. Let's hope some future budding game makers will learn from your marvelous efforts. Its very neat.
« Reply #4 on: January 30, 2013, 10:16:19 PM »
Thanks.  ;D

I knew it was arc-something.

I'm curious what you would do differently. I'm sure there's more optimal ways to do some or all of this.
« Last Edit: January 31, 2013, 12:52:34 AM by chronocide »
« Reply #5 on: January 31, 2013, 02:10:13 AM »
Nice project.. as you may or may not know, i'm into the tank war fare projects, have quite a few projects started and none finished for different reasons.

I would love to use your project as a base and turn it into a multi-player tank battle project...

Would you mind ?
« Reply #6 on: January 31, 2013, 04:29:48 AM »
Nope, wouldn't mind. Feel free.
Have you got the weapon part worked out? I saw you were working on that, and the high velocity collision problem.
« Last Edit: January 31, 2013, 04:52:35 AM by chronocide »
« Reply #7 on: January 31, 2013, 12:20:48 PM »
Nice Thankyou .

The networked weapon problem..
Not yet
but i have a couple ideas to work with.

As for high velocity, the best idea i think is to increase the collision model size and to slow them down a bit.

Actual on-line testing will be a big help to see what needs to be changed or adjusted..

So getting a project together and on-line i think is the first step of a few ...
« Reply #8 on: January 31, 2013, 12:59:49 PM »
Maybe an elongated radius bounding sphere would work for collision. ([1,.5,.5] didn't work with wheels. 3drad treated it as [1,1,1])
Since a tank shell is so fast, the impact point could also be acquired from the turret control script.

[edit] I made something that drives like a tank.
What do you think about the controls?
« Last Edit: January 31, 2013, 08:47:12 PM by chronocide »
« Reply #9 on: February 01, 2013, 12:41:01 AM »
That's a little weird to drive.

I noticed couple problems ..

#1
    The Car(tank) can drive backwards when pressing the "W" forward key.. steering seems to be based on what direction the turret is facing.
The last project does this too (follows the turret) but it seems to be different in this version...

No so sure that's a good thing.

#2 the cannon's aim is way off if even shooting at all.

The cam zoom although not a problem, it really IMO should probably have an offset (on the Y axis) so it zooms the target (or front of the car(tank)) rather then zooming into the car body.
« Reply #10 on: February 01, 2013, 08:36:47 AM »
Yeah. Takes a little getting use to.
You can disable driving in reverse. Set revAngle to 0 in the MouseLookWASD script.
You think W & S should exclusively be forwards & backwards?
(as it is now,) Steering is based on the direction you go, relative to the direction the car faces. The heading direction is based on the WASD direction, relative to where the camera faces (based on the mouse). The turret is based on the camera.
I fixed up the zoom and figured out wheels can be used instead of RBs & hinge motors. They come with brakes! Yay ok so oh also added impact effect when firing. Cuts out the middleman :D Borrowed from GForceImposters. Instances exactly where you're targeting, if anything's there. Needs a new raytrace though, from gun instead of camera.
I removed the projectile. I just left the barrel's firing effect.
Still need to tweak vehicle's physics. Just restarted with wheels instead of joints and RBs.
« Reply #11 on: February 01, 2013, 01:57:07 PM »
Looking good

The WASD keys need some work, they dont work together quite right, the car starts doing acrobatics and i had it actually flipped up side down once only by pressing WASD keys together and alternating.

The zoom is working good now, targets perfectly.

Is it possible to add a zoom adjustment that slows down the movement when zoomed in ( make's it finer & slower the more zoomed the cam is)

As it is when zoomed all the way in, it's a little hard to fine target at a distance because the cam movement is a little to jumpy.

I like to use a gamepad for car tank projects.

What i use to allow both keys and a gamepad is to set the EOI as the input to the vehicle like this.

if (IN_22 > 0) OUT_220 = IN_22;

This allows a gamepads direct & proportional input to adjust the float between 0 & 1 or negitive input for the car object with OUT_22 = -IN_22.
« Reply #12 on: February 02, 2013, 05:49:38 PM »
The acrobatics were just a result of a bad physics setup.
It's an AutoBoatHouse now. Six wheels makes adjusting physics a little tedius, so I wrote an ahk script to automate edits for multiple wheels ;D. I'll share that after generalizing it's usability.
The gamepad control fix is easy. x=right-left, z=up-down. Works fine with keyboard, should be good with a gamepad too.
Mouse speed can be factored with FOV, but it affects mouse position. Some offset compensation will be needed. I'll address that after getting the tank driving correctly. I'm not really considering zoom for something that just blows stuff up a priority :p
I'll attach the project so you can see where I'm at. Still need to fix the target explosion thing. It should determine impact point from the gun, not the camera.
« Last Edit: February 02, 2013, 06:04:38 PM by chronocide »
« Reply #13 on: February 02, 2013, 06:44:02 PM »
I like it .

The boathouse is special.. you don't see those often anymore :P

I'll need to adjust my model size's though if you keep the 6wheel design , but thats not a problem

EDIT:

The gamepad input doesnt seem to be proportional , but the carboat is moving fairly slow too so ...
« Last Edit: February 02, 2013, 06:48:07 PM by TinSoldier »
« Reply #14 on: February 02, 2013, 07:06:58 PM »
What's your model look like?

Not sure what you mean by not proportional.
Pages: [1] 2 3 ... 10