Author Topic: Scripting a camera change  (Read 1880 times)

I'm going to make a series of add-ons to mimic Kill-cams in games like TF2 and MW2, as well as the item get sequence from 3D Zelda games. I just need to know how to make the camera move to a specific position on the player or on the enemy, as well as displaying dialog boxes and moving body parts. Seems like there aren't many other addons that use camera changes, so I'm asking you advanced scripters out there to help.

I posted in your other topic. Those camera movements seem iffy, but I gave a suggestion for viewing items you pick up.

Also, can't move body parts unless you remodel them and hide the real ones.

Ah. Okay, no cupped hands above your head. A little sad, though, that's part of the Zelda-iness of it.

I have a somewhat working killcam. Problems are that it doesn't rotate the camera to face the player who killed you, the position isn't exactly perfectly infront of the player, and for some reason I can't figure out, it crashes the server when the add-on is enabled, regardless if anyone died. Also, it doesn't show a quick move to the player (can't figure that out, cameras aren't a strong point of mine) and a freezeframe like TF2 (don't think its possible) , just a delayed instant move to the player, with a freely rotatable camera.

If anyone wants to fix it up, go ahead, I've lost interest. Just give me some credit if you release it.

Code: [Select]
//Some portions of this work are copyright Jack Coady, aka Space Guy

if(isFile("Add-Ons/System_ReturnToBlockland/server.cs"))
{
if(!$RTB::RTBR_ServerControl_Hook)
exec("Add-Ons/System_ReturnToBlockland/RTBR_ServerControl_Hook.cs");
RTB_registerPref("Use Kill Cam", "Kill Cam", "$Pref::Server::KillCam", "bool", "Script_KillCam", 1, 0, 0);
RTB_registerPref("Kill Cam Delay", "Kill Cam", "$Pref::Server::KillCamDelay", "int 0 3000", "Script_KillCam", 1000, 0, 0);
RTB_registerPref("Kill Cam Time", "Kill Cam", "$Pref::Server::KillCamTime", "int 1000 10000", "Script_KillCam", 2000, 0, 0);
}

package KillCam
{
function GameConnection::onDeath(%this, %sourceObject, %sourceClient, %damageType, %damLoc)
{
Parent::onDeath(%this,%sourceObject,%sourceClient,%damageType,%damLoc);
if($Pref::Server::KillCam && isObject(%sourceClient.player))
{
%this.schedule($Pref::Server::KillCamDelay,killCam,%sourceClient);
if(%this.minigame.respawnTime >= 3000)
%this.schedule(%this.minigame.respawnTime-$Pref::Server::KillCamDelay,spawnPlayer);
else
%this.schedule(3000,spawnPlayer);
}

}
};

function GameConnection::killCam(%this,%sourceClient)
{
if(isObject(%sourceClient.player))
{
%this.setControlObject(%this.camera);
%this.camera.setClampMode(%sourceClient.player,VectorAdd(VectorScale(%sourceClient.player.getMuzzleVector(0),1),"0 5 2.5"));
%this.camera.setTransform(%this.camera.getPosition() SPC eulerToAxis(vectorAdd(getFireAimVector(%this.camera.getPosition(),%sourceClient.player.getPosition(),0,999999999),"0 0 180")));
}
}

ActivatePackage(KillCam);

//-------------------------------
//Found these in a post by Trader
//-------------------------------

function eulerToAxis(%euler)
{
%euler = VectorScale(%euler,$pi / 180);
%matrix = MatrixCreateFromEuler(%euler);
return getWords(%matrix,3,6);
}

function axisToEuler(%axis)
{
%angleOver2 = getWord(%axis,3) * 0.5;
%angleOver2 = -%angleOver2;
%sinThetaOver2 = mSin(%angleOver2);
%cosThetaOver2 = mCos(%angleOver2);
%q0 = %cosThetaOver2;
%q1 = getWord(%axis,0) * %sinThetaOver2;
%q2 = getWord(%axis,1) * %sinThetaOver2;
%q3 = getWord(%axis,2) * %sinThetaOver2;
%q0q0 = %q0 * %q0;
%q1q2 = %q1 * %q2;
%q0q3 = %q0 * %q3;
%q1q3 = %q1 * %q3;
%q0q2 = %q0 * %q2;
%q2q2 = %q2 * %q2;
%q2q3 = %q2 * %q3;
%q0q1 = %q0 * %q1;
%q3q3 = %q3 * %q3;
%m13 = 2.0 * (%q1q3 - %q0q2);
%m21 = 2.0 * (%q1q2 - %q0q3);
%m22 = 2.0 * %q0q0 - 1.0 + 2.0 * %q2q2;
%m23 = 2.0 * (%q2q3 + %q0q1);
%m33 = 2.0 * %q0q0 - 1.0 + 2.0 * %q3q3;
return mRadToDeg(mAsin(%m23)) SPC mRadToDeg(mAtan(-%m13, %m33)) SPC mRadToDeg(mAtan(-%m21, %m22));
}

//-------------------------------------------------------
//Took this from Space Guys' fireHomingProjectile event.
//-------------------------------------------------------
function getFireAimVector(%start,%end,%g,%u)
{
   %vec = vectorSub(%end,%start);

   //If the projectile isn't actually affected by gravity, then return the direct vector
   if(%g <= 0)
      return vectorNormalize(%vec);

   %xx = getWord(%vec,0);
   %yy = getWord(%vec,1);

   //Convert the 3-space vector to (xy, z)
   %sx = mSqrt(%xx*%xx + %yy*%yy);
   %sy = getWord(%vec,2);

   if(%sx == 0 && %sy > 0)
   {
    return "0 0 1";
   }

   %a = (-0.5*%g*%sx*%sx) / (%u*%u);
   %b = %sx;
   %c = ((-0.5*%g*%sx*%sx) / (%u*%u)) - %sy;

   //This seems to be badly implemented and returns negative versions of the answers
   //%str = mSolveQuadratic(%a,%b,%c);

   %d = %b*%b - 4*%a*%c;

   if(%d > 0)
   {
      %s1 = mATan((-%b+mSqrt(%d)) / (2*%a),1);
      %s2 = mATan((-%b-mSqrt(%d)) / (2*%a),1);

      //A lower angle is more direct and will hit the target quicker, so it's preferable
      if(%s1 < %s2)
         %ang = %s1;
      else
         %ang = %s2;
   }

   if(%d == 0)
   {
      %ang = mATan((-%b) / (2*%a),1);
   }

   if(%d < 0)
   {
      //No solution when sqrt(%d < 0).
      return "0 0 1";
   }

   //retVec must be normalized as it will return (0 0 -sin45) when directly below the point
   %nVec = vectorNormalize(%xx SPC %yy);
   %retVec = vectorNormalize(getWord(%nVec,0) * mCos(%ang) SPC getWord(%nVec,1) * mCos(%ang) SPC mSin(%ang));

   return %retVec;
}

As for zelda style item recieve animations, I'd just use bottom print. Otherwise you'd have to have a clientside add-on, and not everyone will have it.
Though you could use a gui for players who have it, and just bottom print to those who don't.
For the animation, if you're not too picky, you could just use the preexisting armReadyBoth
« Last Edit: June 30, 2010, 06:44:12 PM by Headcrab Zombie »

Ok, might try fixing that up or something as a project to strengthen camera skillz.
Is it clientside or serverside, or something else?

Topic about Zelda item get animation moved back to original (in Modification Discussion).
« Last Edit: June 30, 2010, 08:26:10 PM by sciberdude »

Entirely serverside, and that's all the script I have for it, didn't leave anything out.

Oh yeah, and if anyone does fix it up and release it, PM me a link. I rarely visit the add-ons section, I probably wouldn't see it, and I'd like to see the changes made for future scripting projects.
« Last Edit: July 01, 2010, 12:03:53 AM by Headcrab Zombie »

MMMkay. I foresee better Modern Warfare servers in the future... OoOoOooo...

Might lock this topic, we'll see in a few days.

MMMkay. I foresee better Modern Warfare servers in the future... OoOoOooo...

Might lock this topic, we'll see in a few days.

Uhh... So you give up on Zelda stuff? Dude, why give up on that. That was awesome. :(

Code: [Select]
function GameConnection::killcam(%client,%killer)
{
    %client.camera.setOrbitMode(%killer,%killer.gettransform(),0.5,4.5,4.5,0);
    %client.setControlObject(%client.camera);
}

-snip-

He wants the camera to fly to the guy, methinks. o_o

Why is "methinks" in my Firefox dictionary of correctly spelled words?

It's probably better than what I had though.
And eliminates a LOT of other functions I took from other places.
I couldn't get setOrbitMode to work for me though >:

I couldn't get setOrbitMode to work for me though >:

It works in Age of Time, why wouldn't it work here? D:

I didn't say it didn't work.
I said I couldn't get it to work for me.

The console hates me.

It said I syntaxed on a .gui file. :(

The console hates me.

It said I syntaxed on a .gui file. :(

Dude, GUI files are just Torque Script files that have object creation stuff in them. There are many Add-On's with .GUI files that have Torque Code at the bottom instead of in their own .CS.