[Help] SetViewTraget

  • Please make sure you are familiar with the forum rules. You can find them here: https://forums.tripwireinteractive.com/index.php?threads/forum-rules.2334636/

forrestmark9

FNG / Fresh Meat
Nov 29, 2011
1,110
40
0
I need help with SetViewTraget, so far no matter what I try nothing works I've tried replicated the function from the Client to Server like said but nothing works

Here is the code, PossesZed is on the server and is called by the client I'm unsure but I think here SpectatePlayer needs to be from the server to client
Code:
state PreySpec extends BaseSpectating
{
ignores SwitchWeapon, RestartLevel, ClientRestart, Suicide, ThrowWeapon, NotifyPhysicsVolumeChange, NotifyHeadVolumeChange;

    function SpectatePlayer(Pawn Target)
    {
        local bool bWasSpec;
        
        bWasSpec = !bBehindView && ViewTarget != Pawn && ViewTarget != self;
        
        if( Target != none  )
        {
            SetViewTarget(Target);
            ClientSetViewTarget(Target);
            if ( ViewTarget == self || bWasSpec )
                bBehindView = false;
            else
                bBehindView = true;
            ClientSetBehindView(bBehindView);
        }
    }

    function PossessZed()
    {
        local vector HitLocation, HitNormal, TraceEnd, TraceStart;
        local rotator R;
        local Actor A;
        local KFMonster M;

        if( NextPossessTimer>Level.TimeSeconds )
            return;
        NextPossessTimer = Level.TimeSeconds+0.4f;
        
        PlayerCalcView(A, TraceStart, R);
        TraceEnd = TraceStart + 1000 * Vector(R);
        A = Trace(HitLocation, HitNormal, TraceEnd, TraceStart, true);
        if ( KFHumanPawn(A) != none)
        {
            SpectatePlayer(KFHumanPawn(A));
            return;
        }
        else if ( KFMonster(A) != none)
        {
            M = KFMonster(A);
            if( M!=None && M.Health>0 )
            {
                if( ( M.IsA('ZombieBoss') || M.IsA('ZombieFleshpound') || M.IsA('FemaleFP') || M.IsA('ZombieScrake') || M.IsA('ZombieJason') ) && !ForrestPRI(PlayerReplicationInfo).IsVIP )
                {
                    if( M.IsA('ZombieBoss') && bDisallowPatPossession )
                    {
                        ClientMessage("Can't possess: You suicided.");
                        return;
                    }
                    ClientMessage("Can't possess: You must be a VIP to possess this ZED.");
                    return;
                }
                VSGame(Level.Game).PlayerPossess(Self,M);
                return;
            }
        }
        ClientMessage("Can't possess: You must aim at the specimen to possess.");
    }
    
    exec function Fire( optional float F )
    {   
        if( NextPossessTimer<Level.TimeSeconds )
        {
            PossessZed();
            NextPossessTimer = Level.TimeSeconds+0.5f;
        }
    }
    
    exec function AltFire( optional float F )
    {
        if( ViewTarget != self )
            ServerViewSelf();
    }

    function Timer()
    {
        bFrozen = false;
    }

    function BeginState()
    {
        if ( Pawn != None )
        {
            SetLocation(Pawn.Location);
            UnPossess();
        }
        bCollideWorld = true;
        CameraDist = Default.CameraDist;
    }

    function EndState()
    {
        PlayerReplicationInfo.bIsSpectator = false;
        bCollideWorld = false;
    }
    
    function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)
    {
        bBehindView = false;
        if( ViewTarget!=Self )
            SetViewTarget(Self);
        Acceleration = NewAccel;
        MoveSmooth(SpectateSpeed * Normal(Acceleration) * DeltaTime);
    }
}
 

poosh

Grizzled Veteran
Jan 6, 2011
3,403
327
83
There is no need of using "simulated" function inside PlayerController, because its role is ROLE_AutonomousProxy, i.e. it can execute non-simulated functions on client side.
 

forrestmark9

FNG / Fresh Meat
Nov 29, 2011
1,110
40
0
There is no need of using "simulated" function inside PlayerController, because its role is ROLE_AutonomousProxy, i.e. it can execute non-simulated functions on client side.

Hmm I see so how would I get this system to work
 

Dr_Killjoy

FNG / Fresh Meat
Sep 30, 2012
260
0
0
There is no need of using "simulated" function inside PlayerController, because its role is ROLE_AutonomousProxy, i.e. it can execute non-simulated functions on client side.

Does this includes going to non-simulated states?

Here is the code, PossesZed is on the server and is called by the client I'm unsure but I think here SpectatePlayer needs to be from the server to client
Need more information about how it works. Which way you call it from client?
 
Last edited:

forrestmark9

FNG / Fresh Meat
Nov 29, 2011
1,110
40
0
Does this includes going to non-simulated states?


Need more information about how it works. Which way you call it from client?

The client goes into this state when he dies

Code:
state Spectating
{
    function BeginState()
    {
        Super.BeginState();
        if( VSGame(Level.Game)!=None && VSGame(Level.Game).ShouldGoHunt() && !PlayerReplicationInfo.bOnlySpectator )
            GoToState('PreySpec');
    }
}
 

poosh

Grizzled Veteran
Jan 6, 2011
3,403
327
83
Level.Game is always none on client side. So it never goes into PreySpec state on client side.
 

Dr_Killjoy

FNG / Fresh Meat
Sep 30, 2012
260
0
0
Hmm I see, so that means like it does for PossessZed I have to move the code to the gametype?

This is one of the options. Maybe it has sense to make some "proxy" actor between clients and game type to handle such things.

There is no need to use "simulated" keyword inside PlayerController at all.
Thanks, did'nt know about that.
 
Last edited:

Dr_Killjoy

FNG / Fresh Meat
Sep 30, 2012
260
0
0
There is already one since the beginning: GameReplicationInfo.

Sometimes it has sense not to push everything into one class. And Replication Info was made just to replicate properties, so maybe it's not good to use it for something else intensively.
 

forrestmark9

FNG / Fresh Meat
Nov 29, 2011
1,110
40
0
I tried doing the code from the gametype and still no dice

Code:
state PreySpec extends BaseSpectating
{
ignores SwitchWeapon, RestartLevel, ClientRestart, Suicide, ThrowWeapon, NotifyPhysicsVolumeChange, NotifyHeadVolumeChange;

    function PossessZed()
    {
        local vector HitLocation, HitNormal, TraceEnd, TraceStart;
        local rotator R;
        local Actor A;
        local KFMonster M;

        if( NextPossessTimer>Level.TimeSeconds )
            return;
        NextPossessTimer = Level.TimeSeconds+0.4f;
        
        PlayerCalcView(A, TraceStart, R);
        TraceEnd = TraceStart + 1000 * Vector(R);
        A = Trace(HitLocation, HitNormal, TraceEnd, TraceStart, true);
        if ( KFHumanPawn(A) != none)
        {
            VSGame(Level.Game).PlayerSpectate(Self,M);
            return;
        }
        else if ( KFMonster(A) != none)
        {
            M = KFMonster(A);
            if( M!=None && M.Health>0 )
            {
                VSGame(Level.Game).PlayerPossess(Self,M);
                return;
            }
        }
        ClientMessage("Can't possess: You must aim at the specimen to possess.");
    }
    
    exec function Fire( optional float F )
    {   
        if( NextPossessTimer<Level.TimeSeconds )
        {
            PossessZed();
            NextPossessTimer = Level.TimeSeconds+0.5f;
        }
    }
    
    exec function AltFire( optional float F )
    {
        if( ViewTarget != self )
            ServerViewSelf();
    }

    function Timer()
    {
        bFrozen = false;
    }

    function BeginState()
    {
        if ( Pawn != None )
        {
            SetLocation(Pawn.Location);
            UnPossess();
        }
        bCollideWorld = true;
        CameraDist = Default.CameraDist;
    }

    function EndState()
    {
        PlayerReplicationInfo.bIsSpectator = false;
        bCollideWorld = false;
    }
    
    function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)
    {
        bBehindView = false;
        if( ViewTarget!=Self )
            SetViewTarget(Self);
        Acceleration = NewAccel;
        MoveSmooth(SpectateSpeed * Normal(Acceleration) * DeltaTime);
    }
}

Code:
final function PlayerSpectate( FMXVersusPlayerController P, Pawn Target )
{
    local bool bWasSpec;
        
    bWasSpec = !P.bBehindView && P.ViewTarget != P.Pawn && P.ViewTarget != P;
        
    if( Target != none  )
    {
        P.SetViewTarget(Target);
        P.ClientSetViewTarget(Target);
        if ( P.ViewTarget == P || bWasSpec )
            P.bBehindView = false;
        else
            P.bBehindView = true;
        P.ClientSetBehindView(P.bBehindView);
    }
}
 
Last edited:

Marco

Active member
May 23, 2009
644
232
43
Finland
Pretty sure it isn't working because trace is hitting player bullet whiz, try to disable hitpoint tracing while doing trace:
bBlockHitPointTraces = false;
A = Trace(HitLocation, HitNormal, TraceEnd, TraceStart, true);
bBlockHitPointTraces = true;

@Poosh, it doesn't matter if code is executed serverside only because ClientAdjustMove does move the client state to correct state.
 
Last edited:

forrestmark9

FNG / Fresh Meat
Nov 29, 2011
1,110
40
0
Pretty sure it isn't working because trace is hitting player bullet whiz, try to disable hitpoint tracing while doing trace:


@Poosh, it doesn't matter if code is executed serverside only because ClientAdjustMove does move the client state to correct state.

Doesn't the PlayerController already have bBlockHitPointTraces set to false?
 

poosh

Grizzled Veteran
Jan 6, 2011
3,403
327
83
@Marco
What is ClientAdjustMove?

Anyway, as far as I see in the code, PossessZed() is called client-side. KFBulletWhipAttachment exists on server side only, so it isn't a case.

You are trying to execute this on client side, where Level.Game=none:
Code:
        if ( KFHumanPawn(A) != none)
        {
            [COLOR="Orange"]VSGame(Level.Game).PlayerSpectate(Self,M);[/COLOR]
            return;
        }
        else if ( KFMonster(A) != none)
        {
            M = KFMonster(A);
            if( M!=None && M.Health>0 )
            {
               [COLOR="orange"] VSGame(Level.Game).PlayerPossess(Self,M);[/COLOR]
                return;
            }
        }

Try something like this:
Code:
replication {
    reliable if ( Role < ROLE_Authority )
        ServerSpectateActor;
}

// server-side
function ServerSpectateActor(Actor A)
{
    if ( KFHumanPawn(A) != none)
    {
        VSGame(Level.Game).PlayerSpectate(Self,M);
        return;
    }
    else if ( KFMonster(A) != none)
    {
        M = KFMonster(A);
        if( M!=None && M.Health>0 )
        {
            VSGame(Level.Game).PlayerPossess(Self,M);
            return;
        }
    } 
    ClientMessage("Can't spectate this kind of actor: " $ A);
}

state PreySpec extends BaseSpectating
{
ignores SwitchWeapon, RestartLevel, ClientRestart, Suicide, ThrowWeapon, NotifyPhysicsVolumeChange, NotifyHeadVolumeChange;

    //client-side
    function PossessZed()
    {
        local vector HitLocation, HitNormal, TraceEnd, TraceStart;
        local rotator R;
        local Actor A;
        local KFMonster M;

        if( NextPossessTimer>Level.TimeSeconds )
            return;
        NextPossessTimer = Level.TimeSeconds+0.4f;
        
        PlayerCalcView(A, TraceStart, R);
        TraceEnd = TraceStart + 1000 * Vector(R);
        A = Trace(HitLocation, HitNormal, TraceEnd, TraceStart, true);
        if ( A != none )
            ServerSpectateActor(A);
        else 
            ClientMessage("Can't possess: You must aim at the specimen to possess.");
    }
    
    exec function Fire( optional float F )
    {   
        if( NextPossessTimer<Level.TimeSeconds )
        {
            PossessZed();
            NextPossessTimer = Level.TimeSeconds+0.5f;
        }
    }
    
    exec function AltFire( optional float F )
    {
        if( ViewTarget != self )
            ServerViewSelf();
    }

    function Timer()
    {
        bFrozen = false;
    }

    function BeginState()
    {
        if ( Pawn != None )
        {
            SetLocation(Pawn.Location);
            UnPossess();
        }
        bCollideWorld = true;
        CameraDist = Default.CameraDist;
    }

    function EndState()
    {
        PlayerReplicationInfo.bIsSpectator = false;
        bCollideWorld = false;
    }
    
    function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)
    {
        bBehindView = false;
        if( ViewTarget!=Self )
            SetViewTarget(Self);
        Acceleration = NewAccel;
        MoveSmooth(SpectateSpeed * Normal(Acceleration) * DeltaTime);
    }
}
 
Last edited:

Marco

Active member
May 23, 2009
644
232
43
Finland
Indeed, it was called ClientAdjustPosition in UE2 and not ClientAdjustMove.

to be honest, you should had taken same approach as I did with VS game:
Code:
	function ServerPossessZed()
	{
		local Pawn M;
		local vector HL,HN;

		if( NextPossessTimer>Level.TimeSeconds )
			return;
		NextPossessTimer = Level.TimeSeconds+0.4f;

		foreach TraceActors(Class'Pawn',M,HL,HN,Location+vector(Rotation)*1000.f,Location)
		{
			if( M!=None && M.Health>0 )
			{
				if( Monster(M)!=None )
					VSGame(Level.Game).PlayerPossess(Self,Monster(M));
				else if( KFPawn(M)!=None )
					SpectatePlayer(M);
				return;
			}
		}
		ClientMessage("Can't possess: You must aim at the specimen to possess.");
	}
	exec function Fire( optional float F )
	{
		if( NextPossessTimer<Level.TimeSeconds )
		{
			ServerPossessZed();
			NextPossessTimer = Level.TimeSeconds+0.5f;
		}
	}
 

forrestmark9

FNG / Fresh Meat
Nov 29, 2011
1,110
40
0
Indeed, it was called ClientAdjustPosition in UE2 and not ClientAdjustMove.

to be honest, you should had taken same approach as I did with VS game

But is using TraceActors the exact same but slower then doing Trace?
 

Marco

Active member
May 23, 2009
644
232
43
Finland
TracingActors is basically same as Trace (performance wise).
Trace creates a list of trace hit actors and returns the first hit, tracing actor iterates through the hit list.