UE1 - UT ViewRotation and Base

  • Two Factor Authentication is now available on BeyondUnreal Forums. To configure it, visit your Profile and look for the "Two Step Verification" option on the left side. We can send codes via email (may be slower) or you can set up any TOTP Authenticator app on your phone (Authy, Google Authenticator, etc) to deliver codes. It is highly recommended that you configure this to keep your account safe.

Neo_b

New Member
Jul 2, 2008
72
0
0
Hello, I have a problem. I've recently found out about an UnrealEngine 1.0 problem. I can't seem to change the ViewRotation of a player, who has just been teleported and his feet are nearly touching the ground at that time. It's totally strange, I can't find what's wrong.

Code:
function bool ReceivedObject(actor Other, vector offset, vector Vel, vector Acc, vector Dir, int Roll)
{
	local pawn POther;
	local rotator NewRot, TempRot;
	local vector TempDir, Loc;
	local nRestoreCol R;

	Current.Received++;

	offset*=GateSize;

	if(FindTeleLoc(Other, offset)) //searching for an alternative offset, if the one specified is blocked
	{
		Log("Found valid location");

		POther=Pawn(Other);

		R=CtrlMut.StoreCollision(Other); //disabling Other's collision and keeping it for restoring after several ticks - prevents crashes and telefragging

		if(R==None)
		{
			Log("R==None");
			DestroyObject(Other);
			return false;
		}

		offset.X+=1; // just in case

		Loc=Location+(offset>>EmitterRotation); //the teleport location

		if(Other.Base!=None) //if the actors' on the floor (walking, for instance) - let it fall out of the other stargate
		{
			Other.SetBase(None);
			Other.SetPhysics(PHYS_Falling);
		}

		if(POther!=None)
		{
			//just some player viewrotation tweaks:

			NewRot=EmitterRotation;
			NewRot.Pitch=0;

			TempRot.Pitch=EmitterRotation.Pitch;
			TempRot.Yaw=0;
			TempRot.Roll=0;

			TempDir=Dir>>TempRot;

			if(TempDir dot (Dir*vect(1,1,0))<=0)
			{
				if((TempRot.Pitch>0)==(Dir.X>0))
				{
					TempRot.Pitch=16384;
				}else{
					TempRot.Pitch=49152;
				}
			}else{
				TempRot.Pitch=Rotator(TempDir).Pitch;
			}

			NewRot=Rotator(Dir>>NewRot);
			NewRot.Pitch=FixViewPitch(TempRot.Pitch);
			NewRot.Roll=Roll+EmitterRotation.Roll;

			TempRot=NewRot;
			TempRot.Pitch=0;
			TempRot.Roll=0;

			POther.ViewRotation=NewRot;
			Other.SetRotation(TempRot);
		}else{
			NewRot=Rotator(Dir>>EmitterRotation);
			NewRot.Roll=Roll+EmitterRotation.Roll;

			Other.SetRotation(NewRot);
		}

		if(Other.SetLocation(Loc))
		{
			Vel.X=FMax(Vel.X, 128);
			Other.Velocity=Vel>>EmitterRotation;
			Other.Acceleration=Acc>>EmitterRotation;

			CtrlMut.Replicate(Other, Other.Location, NewRot, Other.Velocity, Other.Acceleration, Other.Physics, Other.Base); //this function just replicates a function to all clients, setting the client-side variables to the ones on the server - it's for the replication torn-off actors like projectiles, also for the ViewRotation replication of the player

			Log("Successful teleport of"@Other);

			SetSound(2, 4); //the sound number 2 is to be played after 4 ticks, so that the player exiting the Stargate can hear it

			Current.Rematerialized++;

			return true;
		}

		Log("Location found, but still couldn't teleport! This isn't supposed to happen, ever!");

		R.Destroy();
	}

	Log("Valid loc not found");

	DestroyObject(Other); //actors get destroyed, players die and their corpses are destroyed

	return false;
}

This function gets the actor the enters the in-stargate (and is called in the out-stargate) and it processes the location, rotation etc. variables so that the direction of the exit is correct. But after the actor is teleported and after the teleport it's near the ground, the viewrotation doesn't change (so if I jump inside the Stargate it all works perfectly, but when I walk inside the viewrotation won't change). I would appreciate any help. ;-)
 

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
It might have something to do with the state. Also, from testing it appears that a Pawn's viewrotation is reset when going through a teleporter. Finally, it's best to access the Pawn's variables directly as casting to a rotator causes some information to be lost.
 
Last edited:

Neo_b

New Member
Jul 2, 2008
72
0
0
I think the state when the player is walking and falling is the same... Also, the precision might be lost, while I cast to rotator from a vector, although in this case, the rotation simpy is not changed at all. Perhaps I should change the player's state? I think whatever is causing this must be native...
 

Wormbo

Administrator
Staff member
Jun 4, 2001
5,913
36
48
Germany
www.koehler-homepage.de
It seems you are trying to reinvent the wheel there. Not only teleporters, but also warp zones perform the required transformations on player orientation. Why don't you just reuse those?
 

Neo_b

New Member
Jul 2, 2008
72
0
0
From what I know, the teleporters teleport to a constant location, not a dynamic offset. Also, without replicating the ViewRotation myself with a replicated function, it won't be apparent to the client...
 

Wormbo

Administrator
Staff member
Jun 4, 2001
5,913
36
48
Germany
www.koehler-homepage.de
You are free to modify the Teleporter.Accept() function to include the offset of the teleported actor from the source actor in the calculations for the target location. Also, teleporters seem to be able to change the ViewRotation without requiring additional replicated functions.
 

Neo_b

New Member
Jul 2, 2008
72
0
0
What I meant was that the simple ViewRotation and Rotation changes won't work in the network play if the player is teleported with his feet very close to the ground after the teleportation (which sounds totally nonsense, but my experiments' results show that it is most likely so). I feel backed into a corner.
 

Bi()ha2arD

Toxic!
Jun 29, 2009
2,808
0
0
Germany
phobos.qml.net
What I did in a map where I created Quake style teleporters taht "spit" you out isntead of just making you reapear I just adjusted the collissions so that you would get dropped out of the teleporter a bit above the ground. Else the force I applied to get the push out effect did not work.
 

Neo_b

New Member
Jul 2, 2008
72
0
0
Well, I tried adjusting the location where you reappear, but haven't thought of changing the collision size of the player... If the player appears slightly above the ground, it still doesn't work. I have to place the player at least approximately 24 units above the ground from what I learned while experimenting

Btw, what's weird is that the higher lag I simulated for my server, the lesser chance of the rotation change succeeding. Totally weird. Yet it seems as though the problem was server-side, but it works fine in a standalone game...
 

Bi()ha2arD

Toxic!
Jun 29, 2009
2,808
0
0
Germany
phobos.qml.net
Here is what I did: Players always exit teleporter facing forward, a bit up in the air and get pushed forward.

Code:
/** Bio's quake style teleporter */
class UTQuakeTeleporter extends UTTeleporterCustomMesh;

var() rotator NewRot;



defaultproperties
{
Begin Object Name=CollisionCylinder
   CollisionHeight=100
End Object
}

simulated event bool Accept( actor Incoming, Actor Source )
{
    local rotator oldRot;
    local float mag;
    local vector oldDir;
    local Controller C;

    if ( Incoming == None )
        return false;

    // Move the actor here.
    Disable('Touch');
    //NewRot = Incoming.Rotation;
    if (bChangesYaw)
    {
        oldRot = Incoming.Rotation;
        //NewRot.Yaw = Rotation.Yaw;
        if ( Source != None )
        {
            //NewRot.Yaw = ExitRotation;
        }
    }

    if ( Pawn(Incoming) != None )
    {
        //tell enemies about teleport
        if ( Role == ROLE_Authority )
        {
            foreach WorldInfo.AllControllers(class'Controller', C)
            {
                if ( C.Enemy == Incoming )
                {
                    C.EnemyJustTeleported();
                }
            }
        }

        if ( !Pawn(Incoming).SetLocation(Location) )
        {
            LogInternal(self$" Teleport failed for "$Incoming);
            return false;
        }
        if ( (Role == ROLE_Authority)
            || (WorldInfo.TimeSeconds - LastFired > 0.5) )
        {
            NewRot.Roll = 0;
            Pawn(Incoming).SetRotation(NewRot);
            Pawn(Incoming).SetViewRotation(NewRot);
            Pawn(Incoming).ClientSetRotation(NewRot);
            LastFired = WorldInfo.TimeSeconds;
        }
        if ( Pawn(Incoming).Controller != None )
        {
            Pawn(Incoming).Controller.MoveTimer = -1.0;
            Pawn(Incoming).SetAnchor(self);
            Pawn(Incoming).SetMoveTarget(self);
        }
        Incoming.PlayTeleportEffect(false, true);
    }
    else
    {
        if ( !Incoming.SetLocation(Location) )
        {
            Enable('Touch');
            return false;
        }
        if ( bChangesYaw )
            Incoming.SetRotation(NewRot);
    }
    Enable('Touch');

    if (bChangesVelocity)
        Incoming.Velocity = TargetVelocity;
    else
    {
        if ( bChangesYaw )
        {
            if ( Incoming.Physics == PHYS_Walking )
                OldRot.Pitch = 0;
            oldDir = vector(OldRot);
            mag = Incoming.Velocity Dot oldDir;
            Incoming.Velocity = Incoming.Velocity - mag * oldDir + mag * vector(Incoming.Rotation);
        }
        if ( bReversesX )
            Incoming.Velocity.X *= -1.0;
        if ( bReversesY )
            Incoming.Velocity.Y *= -1.0;
        if ( bReversesZ )
            Incoming.Velocity.Z *= -1.0;
    }
    Incoming.PostTeleport(self);
    return true;
}
 

War_Master

Member
May 27, 2005
702
0
16
Btw, what's weird is that the higher lag I simulated for my server, the lesser chance of the rotation change succeeding. Totally weird. Yet it seems as though the problem was server-side, but it works fine in a standalone game...

I get this bug whenever I use 2 teleporters of different classes but it works correctly offline. Try using the same teleporter class on both ends and see if they spawn facing the right way.
 

Neo_b

New Member
Jul 2, 2008
72
0
0
@Warmaster: This is not a teleporter sub-class. It's fully coded by myself, both the class and its parent classes.

@Biohazard: This piece of code appears to be for an UnrealEngine version different than 1.0. Btw, is it necessary to cast Incoming actor to pawn in order to call SetLocation? Does it get called differently then? Do Teleporter subclasses natively cope with this problem, so that I can't cope with it in any other class?

Thank you for your responses.
 
Last edited:

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
SetLocation is a native method in Actor:
native(267) final function bool SetLocation( vector NewLocation );

Also, state change seems to be handled natively.
 

Neo_b

New Member
Jul 2, 2008
72
0
0
I've made an experiment - I created an actor that was supposed to attempt to change the ViewRotation & Rotation of the player for 16 ticks server-side. With player walking while teleporting (no matter if I set the Base to None and set Physics to PHYS_Falling), the ViewRotation & Rotation won't change until several ticks have passed (more than 4, but the number is not always the same). Also if I pause the game in the exact moment that the teleport occurs (1 or 2 ticks after), the rotation changes within the tick that I paused the game before.

Also I've realized, that my other transporter (which teleports a player while he stands on a platform motionlessly) will work fine if I move the player several units up, while the Stargate won't (the only difference is that the player entering the stargate has to have a velocity.
 

Neo_b

New Member
Jul 2, 2008
72
0
0
I have not thought of a certain fact that might possibly be causing the problem. The code is for Tactical Ops, UT1 modification. (I should've mentioned that, sorry) It turned out that it works fine with UT alone. Then it makes sense, because my server does have a protection tool, TOST, which replaces the Tactical Ops player class. What I am experiencing could be some strange no-recoil cheat protection, but the TOST doesn't have a public source code. I don't think it's possible for me to figure out what exactly is causing it, now that I've realized that TOST is at fault. I also checked that default UT warp-zones do not properly work with it either.

Thank you for your time, though. :)