Mob Look
by Erik Madison · 07/30/2008 (3:18 pm) · 7 comments
If you have AFX installed, you have the beginnings of some very cool control over your AI's head. In my playing around, I have an AIGuard who truly scans, looking left and right without jumping his body around in circles.
Again, you must be using AFX. I merely built upon the >> player-look code.
player.h
player.cpp
Thats it for code. If you've set the lookoverride on your mobs (as the player is in the AFX demo), you can now control the head thread's position.
I played around with trying to use Plastic Gems awesome ease code, but it didn't do what I'd hoped. Perhaps because the head threads tend to be just 2 keys? Instead, I opted for a simple schedule setup.
You could easily use the get methods before adjusting, but I didn't really see the point in any more complexity. This looks good.
I used AIGuard, but anything should work...
AIGuard.cs
Sprinkle throughout your scanning routines. AIGuard already has an fov, perhaps anytime it's expanded the mob does a look see?
Some incredible control can be had if you string multiple calls together with a timer here and there, through the task system. I highly recommend getting one of the 3D-Diggers animals (they're cheap!) for some serious indepth look at just how powerful the task system can be.
You only call this with the direction, the other variables are added as needed.
Again, you must be using AFX. I merely built upon the >> player-look code.
player.h
[i]public, under setLook....[/i]
void setHeadRotation(F32);
void setHeadAngle(F32);
// called 2, as its pretty different than stock one
F32 getHeadRotation2() { return headHLookOverridePos; }
F32 getHeadAngle() { return headVLookOverridePos; }player.cpp
void Player::setHeadRotation(F32 pos)
{
headHLookOverridePos = pos;
setMaskBits(LookOverrideMask);
}
void Player::setHeadAngle(F32 pos)
{
headVLookOverridePos = pos;
setMaskBits(LookOverrideMask);
}
ConsoleMethod(Player, setHeadRotation, void, 3, 3, "setHeadRotation(thread pos) Left-Right")
{
object->setHeadRotation(dAtof(argv[2]));
}
ConsoleMethod(Player, setHeadAngle, void, 3, 3, "setHeadAngle(thread pos) Up-Down")
{
object->setHeadAngle(dAtof(argv[2]));
}
ConsoleMethod(Player, getHeadRotation, F32, 2, 2, "returns 0-1")
{
return object->getHeadRotation2();
}
ConsoleMethod(Player, getHeadAngle, F32, 2, 2, "returns 0-1")
{
return object->getHeadAngle();
}Find the underutilized LookOverrideMask in the pack/unpack and add the followingstream->writeSignedFloat(headVLookOverridePos/* / mDataBlock->maxLookAngle*/, 6);
stream->writeSignedFloat(headHLookOverridePos/* / mDataBlock->maxLookAngle*/, 6);
headVLookOverridePos = stream->readSignedFloat(6)/* * mDataBlock->maxLookAngle*/;
headHLookOverridePos = stream->readSignedFloat(6)/* * mDataBlock->maxLookAngle*/;I'm debating some other possible ideas, so I tend to comment various methods in/out. Clean up as desired.Thats it for code. If you've set the lookoverride on your mobs (as the player is in the AFX demo), you can now control the head thread's position.
I played around with trying to use Plastic Gems awesome ease code, but it didn't do what I'd hoped. Perhaps because the head threads tend to be just 2 keys? Instead, I opted for a simple schedule setup.
You could easily use the get methods before adjusting, but I didn't really see the point in any more complexity. This looks good.
I used AIGuard, but anything should work...
AIGuard.cs
// This will only work if setLookAnimationOverride is true
function AIGuard::LookDirection(%this, %dir, %a, %r)
{
%angle = %rotation = -1;
switch$ (%dir)
{
case "down":
%angle = 0;
if (%a $= "") %a = %angle;
%a = %a + 0.1;
case "up":
%angle = 1;
if (%a $= "") %a = %angle;
%a = %a - 0.1;
case "right":
%rotation = 0;
if (%r $= "") %r = %rotation;
%r = %r + 0.1;
case "left":
%rotation = 1;
if (%r $= "") %r = %rotation;
%r = %r - 0.1;
default:
// 0 them out, then return
%this.setHeadRotation(0.5);
%this.setHeadAngle(0.5);
%rotation = -1;
%angle = -1;
}
// are we done with either/or/both directions?
if ((%a >= 1 || %a <= 0) && (%r >= 1 || %r <= 0))
return;
// we should need one of the two at this point
if (%r >= 0)
%this.setHeadRotation(%r);
if (%a >= 0)
%this.setHeadAngle(%a);
// let's do the time warp again...
%this.schedule(100, "LookDirection", %dir, %a, %r);
}Sprinkle throughout your scanning routines. AIGuard already has an fov, perhaps anytime it's expanded the mob does a look see?
Some incredible control can be had if you string multiple calls together with a timer here and there, through the task system. I highly recommend getting one of the 3D-Diggers animals (they're cheap!) for some serious indepth look at just how powerful the task system can be.
You only call this with the direction, the other variables are added as needed.
MobIDNum.lookdirection("left"); // left, right, up, down
MobIDNum.lookdirection(); // to revert back...About the author
Recent Blogs
• Dynamic GUI• Faster Polysoup
• DreamGames and Titas
• Working with pickActionAnimation()
• TSE Interior Decals
#2
07/30/2008 (3:37 pm)
Sexy, very sexy!
#3
Awesome, thanks!
07/30/2008 (7:15 pm)
O.O I've been thinking about doing this, never got around to it though. Mind if I stick some calls to this in my Aiming Resource?Awesome, thanks!
#4
07/31/2008 (2:39 am)
@Nathan Sure, I stuck your calls in my code :) Aiming does need an additional sanity check or two though... I've found a few cases where it could crash because it couldn't find what it expected.
#5
08/01/2008 (10:55 am)
I've been thinking about trying this for some time now...this is really going to help!
#6
08/07/2008 (7:54 am)
I think it's nice... really
#7
08/22/2008 (6:31 pm)
Plugged it in and it's working great. Nice resource! 
Torque 3D Owner Dave Young
Dave Young Games