Did you know? Every one of these messages is hand-typed live, just for you.

Third-Person Camera/State Switcher for Camera (FINISHED AND WORKING)

For questions and discussion about UnrealEd, UnrealScript, and other aspects of Unreal Engine design.

Moderators: Semfry, ividyon

User avatar LannFyre
Skaarj Scout Skaarj Scout
Posts: 31
Joined: 29 Dec 2014, 02:55

Subject: Third-Person Camera/State Switcher for Camera (FINISHED AND WORKING)

Post Posted: 13 Feb 2015, 17:10

EDIT: This has been done now, so this post is now changing from a question to posting the script itself!

> To the creator of Firetrucks: is it okay if I implement the code in these scripts into Firetrucks? Also would I have your permission to use Firetrucks in my mod(s)?

> RPG_Camera

Code: Select all

//=============================================================================
// RPG_Camera.
// Operates independently now
// There should only be one camera
//=============================================================================
class RPG_Camera expands Pawn;


//Some dummy Camera values that might be coded at a later date
enum ECamMode
{
    CM_Fixed, //Fixed camera, useful for putting the camera at a certain spot
    CM_TrackFixedXY, //Track player and rotate instead of moving
    CM_Track, //Track player
    CM_EventInterpolation, //Interpolate a path (one of these days...)
    CM_Unused1,
    CM_Unused2,
    CM_Unused3,
    CM_Unused4
};

//The visible properties are kept here to allow map save/loading as well as letting the mapper
//specify the initial camera mode without using a trigger
var() ECamMode CameraMode;
var PlayerPawn LocalPlayer;
var() float CamDistance;
var float TargetDistance;
//These already exist, putting these here for informative purposes
//var (Movement) rotator DesiredRotation;
//var (Movement) rotator RotationRate;

//Disabling some superclass functions
function ClientDying(name DamageType, vector HitLocation);
function ClientGameEnded();
function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType);
function Died(pawn Killer, name damageType, vector HitLocation);
event FellOutOfWorld();

//The () makes it appear as a selectable InitialState
state() Camera
{
    //This event is called by the player when viewing this actor in first person view
    event Tick( float DeltaTime )
    {
        local vector NewLoc;
        local int OldPitch;

        if ( LocalPlayer == none )
            return;
        switch CameraMode
        {
            case CM_Fixed:
                break;
            case CM_TrackFixedXY:
                OldPitch = DesiredRotation.Pitch; //Conserve DesiredRotation's pitch
                DesiredRotation = rotator( LocalPlayer.Location - Location); //Aim at local player
                DesiredRotation.Pitch = OldPitch; //Restore pitch
                NewLoc = Location; //Conserve location, but alter Z if necessar... useful for spiral stairs!
                NewLoc.Z = LocalPlayer.Location.Z - vector(DesiredRotation).Z * VSize(Location - LocalPlayer.Location);
                SetLocation( NewLoc );
                break;
            case CM_Track:
                if ( TargetDistance < CamDistance ) //Interpolate camera distance in a very arbitrary way
                    CamDistance = fMax( CamDistance - LocalPlayer.GroundSpeed * 0.5 * DeltaTime, TargetDistance);
                else if ( TargetDistance > CamDistance )
                    CamDistance = fMin( CamDistance + LocalPlayer.GroundSpeed * 0.5 * DeltaTime, TargetDistance);
                NewLoc = LocalPlayer.Location - vector(DesiredRotation) * CamDistance;
                SetLocation( NewLoc);
                break;
            default:
                break;
        }
    }
Begin:
    //Loop if no player
    if ( LocalPlayer == none && !FindLocalPlayer() )
    {
        Sleep(0.0);
        Goto('Begin');
    }
    SetPhysics( PHYS_Flying);
CheckViewTarget:
    LocalPlayer.ViewTarget = self;
    LocalPlayer.bBehindView = false;
}


//Unrealscript functions always have a return value, said value is zero'd before function call.
//Meaning, if we return nothing, the function still return False
function bool FindLocalPlayer()
{
    local PlayerPawn P;
    ForEach AllActors (class'PlayerPawn', P)
        if ( ViewPort(P.Player) != none )
        {
            LocalPlayer = P;
            return true;
        }
}


event PostBeginPlay()
{
    Super.PostBeginPlay();
    //The rotation the mapper uses will be the initial rotation
    DesiredRotation = Rotation;
    ViewRotation = Rotation;
    TargetDistance = CamDistance;
}


> RPG_CameraSwitcher

Code: Select all

//=============================================================================
// RPG_CameraSwitcher.
//
// Extra notes:
// Cannot be destroyed
// Operates on both server and client instances
//=============================================================================
class RPG_CameraSwitcher expands Triggers;

var RPG_Camera ActiveCamera;

enum ECamMode
{
    CM_Fixed,
    CM_TrackFixedXY,
    CM_Track,
    CM_EventInterpolation,
    CM_Unused1,
    CM_Unused2,
    CM_Unused3,
    CM_Unused4
};
var() ECamMode NewCameraMode;

var(Events) bool bOnlyLocalTrigger; //Event is only triggered on the local machine
//var(Events) name Event; //Left here for informative purposes, works like a normal trigger
var() bool bTriggerOnceOnly;
var() bool bSmoothTransition;
var() float NewDistance;
var() float SmoothFactor; //To be described later
var() rotator NewOrientation;
var() vector FixedCamPos; //For fixed or X,Y track mode, if Zero, use camera's current


function Touch( Actor Other)
{
    local Actor A;

    //This is the local player
    if ( PlayerPawn(Other) != none && ViewPort(PlayerPawn(Other).Player) != none )
    {
        //Trigger additional event if there's one
        if ( !bOnlyLocalTrigger )
            TriggerEvent( Event, self, Pawn(Other) );
        if ( HasActiveCamera() )
        {
            if ( NewCameraMode <= CM_TrackFixedXY && FixedCamPos != vect(0,0,0) ) //Move the camera if Fixed or TrackXY
                ActiveCamera.SetLocation( FixedCamPos);
            ActiveCamera.CameraMode = ECamMode(NewCameraMode);
            ActiveCamera.TargetDistance = NewDistance; //Linear distance interpolation
            ActiveCamera.DesiredRotation = NewOrientation; //Linear rotation interpolation (layer 1) towards this orientation
            if ( !bSmoothTransition )
            {
                ActiveCamera.SetRotation( ActiveCamera.DesiredRotation);
                ActiveCamera.ViewRotation = ActiveCamera.DesiredRotation;
                ActiveCamera.CamDistance = NewDistance;
            }
            if ( bOnlyLocalTrigger )
                TriggerEvent( Event, self, Pawn(Other) );
            if ( bTriggerOnceOnly )
                SetCollision( false);
            ActiveCamera.Tick( 0.0); //Force immediate camera update
        }
    }
}

//Sanity check and camera finder
function bool HasActiveCamera()
{
    if ( ActiveCamera != none )
        return true;
    //No camera, find it
    ForEach AllActors (class'RPG_Camera', ActiveCamera)
        return true;
}


SPECIAL THANKS TO UT99.ORG USER HIGOR FOR BASICALLY WRITING THESE TWO SCRIPTS PLUS TWO OTHERS FOR ME TO STUDY.

RPG_Camera is an offset actor of any playerpawn (only appearing for individual local machines so each player pawn can have their own camera), it being where the player sees from. RPG_CameraSwitcher is intended to send signals to RPG_Camera, depending on whether or not the player is touching it (it is now a trigger. RPG_CameraHook actors change the state of RPG_Camera to make it either stay at a location and track the player, follow the player, or being fixed in one area). Do not intersect the RPG_CameraSwitcher collision radii as I don't think that they will function properly.
Last edited by LannFyre on 21 Feb 2015, 17:02, edited 1 time in total.
way2goslugger

User avatar LannFyre
Skaarj Scout Skaarj Scout
Posts: 31
Joined: 29 Dec 2014, 02:55

Subject: UPDATE BUMP

Post Posted: 21 Feb 2015, 16:55

I am going to bump this topic because relevant information has been added to the OP. I'm not sure if this would be inappropriate double post or not. :<
way2goslugger


Who is online

Users browsing this forum: No registered users and 46 guests

Copyright © 2001-2024 UnrealSP.org

Powered by phpBB® Forum Software © phpBB Limited