I map a level for a team game (Thievery UT), and I wish to create a boat, that would carry players of one team, but only if they are inside. To achieve it, I have coded a Trigger that I will call from now a controller. The controller checks every tick id there is a player of this particular team in boat, and how many of them, if boat is not interpolating it checks its keys, and modifies KeyPos and KeyRot values, as well as MoveSpeed - the more players are in boat, the faster it moves - then it triggers it. The boat is also coded, for by default KeyPos and KeyRot values do not replicate to client.
- Code: Select all
var vector DesiredLocation;
var rotator DesiredRotationAdv;
var float NewMoveTime;
var int DesiredKeyNum;
var() name AttachTag;
replication
{
reliable if(Role==Role_Authority)
DesiredLocation, DesiredRotationAdv, DesiredKeyNum, NewMoveTime;
}
A simulated Tick overrides KeyPos, KeyRot, and MoveTime variables, just like that:
- Code: Select all
simulated function Tick(float DeltaTime)
{
Super.Tick(DeltaTime);
if(KeyPos[DesiredKeyNum]!=DesiredLocation)
KeyPos[DesiredKeyNum]=DesiredLocation;
if(KeyRot[DesiredKeyNum]!=DesiredRotationAdv)
{
KeyRot[DesiredKeyNum]=DesiredRotationAdv;
}
if(MoveTime!=NewMoveTime)
MoveTime=NewMoveTime;
}
If I try to play it solo, everything works as I desired, however if I try it online, the moment boat turns left - and mover starts to rotate - mover starts shaking very fast, and player on the boat starts to spin around. Perhaps there is something more I should replicate to the client?
edit: in case it was helpful, here are source codes:
The controller:
- Code: Select all
//=============================================================================
// ThHaxersBoatController.
//=============================================================================
class ThHaxersBoatController expands Triggers;
var vector HaxersKeyPos[128];
var rotator HaxersKeyRot[128];
var int HaxersActualKeyNum;
var ThHaxersAdvancedBoat Boat;
var rotator SavedRotatorTest;
var() float Speedmps;
var float MoveTime;
var bool bInitialized;
function InitializeBoat()
{
local int i;
log("Boat is initializing");
HaxersKeyPos[0].X=0;
HaxersKeyPos[0].Y=0;
HaxersKeyPos[0].Z=0;
HaxersKeyRot[0]=Rotation-Rotation;
for(i=1; i<28; i++)//first 28 keys boat moves straight forward
{
HaxersKeyPos[i].X=HaxersKeyPos[i-1].X;
HaxersKeyPos[i].Y=HaxersKeyPos[i-1].Y+64;
HaxersKeyPos[i].Z=HaxersKeyPos[i-1].Z;
HaxersKeyRot[i]=Rotation-Rotation;
}
for(i=28; i<63; i++)//then it moves diagonally
{
HaxersKeyPos[i].X=HaxersKeyPos[i-1].X+46;
HaxersKeyPos[i].Y=HaxersKeyPos[i-1].Y+46;
HaxersKeyPos[i].Z=HaxersKeyPos[i-1].Z;
HaxersKeyRot[i]=Rotation-Rotation;
HaxersKeyRot[i].Yaw=HaxersKeyRot[i-1].Yaw - 468.114;
}
for(i=63; i<122; i++)//the last part of boats movement is almost perpendicular to the first part
{
HaxersKeyPos[i].X=HaxersKeyPos[i-1].X+64;
HaxersKeyPos[i].Y=HaxersKeyPos[i-1].Y+4;
HaxersKeyPos[i].Z=HaxersKeyPos[i-1].Z;
HaxersKeyRot[i]=HaxersKeyRot[i-1];
}
foreach AllActors(class'ThHaxersAdvancedBoat', Boat, Event)
{
break;
}
MoveTime = 1/Speedmps;
bInitialized=true;
}
function SetKeys()
{
HaxersActualKeyNum++;
if(Boat.KeyNum==0)
{
Boat.DesiredKeyNum=1;
}
if(Boat.KeyNum==1)
{
Boat.DesiredKeyNum=0;
}
Boat.DesiredLocation=HaxersKeyPos[HaxersActualKeyNum];
Boat.DesiredRotationAdv=HaxersKeyRot[HaxersActualKeyNum];
}
function Tick(float DeltaTime)
{
local int ThievesStanding;
local Actor A;
local Pawn P;
local Pawn SavedPawn;
//count thieves standing on a boat
Super.Tick(DeltaTime);
if(!bInitialized)
return;
if(HaxersActualKeyNum==120)
{
log("Boat Reached!");
if(!binterpolating)
{
foreach AllActors(class 'Actor', A, 'BoatReached') {
A.Trigger(None, None);}
bInitialized=false;
}
return;
}
for (P=Level.PawnList; P!=None; P=P.nextPawn)
{
if(ThieveryPPawn(P)!=None&&ThieveryPPawn(P).PlayerReplicationInfo!=None&&ThieveryPPawn(P).PlayerReplicationInfo.Team==0)
{
if(VSize(ThieveryPPawn(P).Location - Boat.Location)<140&&ThieveryPPawn(P).Location.Z>Boat.Location.Z)
{
SavedPawn=P;
ThievesStanding++;
}
}
}
if(ThievesStanding>0)
{
// some taffer is sitting in a boat - let's set sail
if(!Boat.bInterpolating)
{
SetKeys();
Boat.NewMoveTime=MoveTime+(ThievesStanding-1)*MoveTime*0.5;
Boat.Trigger(SavedPawn, SavedPawn);
}
}
}
And the boat:
- Code: Select all
//=============================================================================
// ThHaxersAdvancedBoat.
//=============================================================================
class ThHaxersAdvancedBoat expands Mover;
var vector DesiredLocation;
var rotator DesiredRotationAdv;
var float NewMoveTime;
var int DesiredKeyNum;
var() name AttachTag;
replication
{
reliable if(Role==Role_Authority)
DesiredLocation, DesiredRotationAdv, DesiredKeyNum, NewMoveTime;
}
function PostBeginPlay()
{
local Actor Act;
local Mover Mov;
Super.PostBeginPlay();
// Initialize all slaves.
if ( AttachTag != '' )
foreach AllActors( class 'Actor', Act, AttachTag )
{
Mov = Mover(Act);
if (Mov == None) {
Act.SetBase( Self );
}
else if (Mov.bSlave) {
Mov.GotoState('');
Mov.SetBase( Self );
}
}
}
simulated function Tick(float DeltaTime)
{
local Actor A;
Super.Tick(DeltaTime);
if(KeyPos[DesiredKeyNum]!=DesiredLocation)
KeyPos[DesiredKeyNum]=DesiredLocation;
if(KeyRot[DesiredKeyNum]!=DesiredRotationAdv)
{
KeyRot[DesiredKeyNum]=DesiredRotationAdv;
}
if(MoveTime!=NewMoveTime)
MoveTime=NewMoveTime;
}
edit2:
To make it more clear, I recorded a video:
http://www.youtube.com/watch?v=hW4urDPoJj8

