Announcement

Collapse
No announcement yet.

Third Person Aiming [Updated]

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Third Person Aiming [Updated]

    I'm trying to fix a third person camera, and I'm having problems with aiming. As it is, the player pawn does not aim where the crosshairs indicate, because the camera is offset. How can I get the pawn to shoot / aim where the crosshairs point? I presume it has something to do with AdjustAim() in the PlayerController and taking the result of an additional trace, but beyond that, I'm lost.

    To clarify, I don't want to simply aim the camera or move the crosshair where the pawn is looking. I need to use the camera itself to control aiming.

    #2
    I would try asking Mr. Evil as he has already done this. Other than that, I would not be sure where to start.

    Comment


      #3
      Check out this site out http://gamestudies.cdis.org/~jgiles/
      It has a tutorial on making a max pain style camera, similar to what you want.

      Comment


        #4
        Originally posted by Dash
        Check out this site out http://gamestudies.cdis.org/~jgiles/
        It has a tutorial on making a max pain style camera, similar to what you want.
        Already looked at that, actually. Aiming aside, my camera system is already finished, anyway. Unfortunately, that tutorial there simply says to figure out the aiming correction for yourself. While I have some idea as to what I'm doing, I've yet to get any satisfactory results.

        Edit: After playing around some more with AdjustAim(), things are working better.

        Important changes to the original code are in red.

        Code:
        function rotator AdjustAim(FireProperties FiredAmmunition, vector projStart, int aimerror)
        {
            local vector FireDir, AimSpot, HitNormal, HitLocation, OldAim, AimOffset, ViewTargetLoc;
            local actor BestTarget;
            local float bestAim, bestDist, projspeed;
            local actor HitActor;
            local bool bNoZAdjust, bLeading;
            local rotator AimRot;
        
            FireDir = vector(CalcViewRotation);
            projStart = CalcViewLocation;
        
            if (FiredAmmunition.bInstantHit)
                HitActor = Trace(HitLocation, HitNormal, projStart + 10000 * FireDir, projStart, true);
            else
                HitActor = Trace(HitLocation, HitNormal, projStart + 4000 * FireDir, projStart, true);
        
            if ((HitActor != None) && HitActor.bProjTarget)
            {
                BestTarget = HitActor;
                bNoZAdjust = true;
                OldAim = HitLocation;
                BestDist = VSize(BestTarget.Location - Pawn.Location);
            }
            else // (HitActor == None)
            {
                // adjust aim based on FOV
                bestAim = 0.90;
                if ((Level.NetMode == NM_Standalone) && bAimingHelp)
                {
                    bestAim = 0.93;
                    if (FiredAmmunition.bInstantHit)
                        bestAim = 0.97;
                    if (FOVAngle < DefaultFOV - 8)
                        bestAim = 0.99;
                }
                else if(FiredAmmunition.bInstantHit)
                         bestAim = 1.0;
                BestTarget = PickTarget(bestAim, bestDist, FireDir, projStart, FiredAmmunition.MaxRange);
                if (BestTarget == None)
                {
                    ViewTargetLoc = ViewTarget.Location;
                    ViewTargetLoc.Z += 40;
                    return rotator(HitLocation - ViewTargetLoc);
                }
                OldAim = projStart + FireDir * bestDist;
            }
        
            InstantWarnTarget(BestTarget, FiredAmmunition, FireDir);
            ShotTarget = Pawn(BestTarget);
        
            if (!bAimingHelp || (Level.NetMode != NM_Standalone))
            {
                return Rotation;
            }
        
            // aim at target - help with leading also
            if (!FiredAmmunition.bInstantHit)
            {
                projspeed = FiredAmmunition.ProjectileClass.default.speed;
                BestDist = vsize(BestTarget.Location + BestTarget.Velocity * FMin(2, 0.02 + BestDist/projSpeed) - projStart);
                bLeading = true;
                FireDir = BestTarget.Location + BestTarget.Velocity * FMin(2, 0.02 + BestDist/projSpeed) - projStart;
                AimSpot = projStart + bestDist * Normal(FireDir);
                // if splash damage weapon, try aiming at feet - trace down to find floor
                if ( FiredAmmunition.bTrySplash
                    && ((BestTarget.Velocity != vect(0,0,0)) || (BestDist > 1500)))
                {
                    HitActor = Trace(HitLocation, HitNormal, AimSpot - BestTarget.CollisionHeight * vect(0,0,2), AimSpot, false);
                    if ((HitActor != None) && FastTrace(HitLocation + vect(0,0,4),projstart))
                        return rotator(HitLocation + vect(0,0,6) - projStart);
                }
            }
            else
            {
                FireDir = BestTarget.Location - projStart;
                AimSpot = projStart + bestDist * Normal(FireDir);
            }
        
            // adjust Z of shooter if necessary
            if (bNoZAdjust || (bLeading && (Abs(AimOffset.Z) < BestTarget.CollisionHeight)))
                AimSpot.Z = OldAim.Z;
            else if (AimOffset.Z < 0)
                AimSpot.Z = BestTarget.Location.Z + 0.4 * BestTarget.CollisionHeight;
            else
                AimSpot.Z = BestTarget.Location.Z - 0.7 * BestTarget.CollisionHeight;
        
            if (!bLeading)
            {
                // if not leading, add slight random error (significant at long distances)
                if (!bNoZAdjust)
                {
                    AimRot = rotator(AimSpot - projStart);
                    if (FOVAngle < DefaultFOV - 8)
                        AimRot.Yaw = AimRot.Yaw + 200 - Rand(400);
                    else
                        AimRot.Yaw = AimRot.Yaw + 375 - Rand(750);
                    return AimRot;
                }
            }
            else if (!FastTrace(projStart + 0.9 * bestDist * Normal(FireDir), projStart))
            {
                FireDir = BestTarget.Location - projStart;
                AimSpot = projStart + bestDist * Normal(FireDir);
            }
        
            return rotator(AimSpot - projStart);
        }
        The only major bug appears to be when certain weapons, particularly projectiles, are aimed into the sky. Things like rockets will then shoot off at bizzare angles.

        Comment

        Working...
        X