UE2 - UT2kX Bone Rotating (client side)

  • 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.

EvilT-ModZ

Un-Gravitify
Aug 3, 2011
42
0
6
30
Russia
www.set-games.ru
Afraid not, it looks like they took that function out in the Postal2 build of UE2 (it's not uncommon for licensees to remove functions they don't need and I don't think multiplayer was thought about. Basically you can't use the method above by the looks of it.

So, you can't make it simulatedproxy and you can't do efficient replication on the actor so you'll have to attach the helper actor server-side and do your replication in there. The down side is that because you can't use PostNetReceive you'll have to tick the helper actor all the time and check the value of your replication flag every tick. It sucks and but I can't see there's much alternative really.
Ok, thank you for helping a lot, so, i'll try it anyway
 

EvilT-ModZ

Un-Gravitify
Aug 3, 2011
42
0
6
30
Russia
www.set-games.ru
I made helping actor, now bone rotation working on client, but vector and rotations doesn't read from kactor, because on client bones rotates to zero vector:

http://s013.radikal.ru/i325/1108/5c/b5f09f697bfa.jpg

Code:
class BoneRotatingActor extends Actor;

var EvilCatModern Chassis;
const TIRE_FRONT_RIGHT = 'TIRE';
const TIRE_FRONT_LEFT = 'TIRE03';
const TIRE_REAR_RIGHT = 'TIRE02';
const TIRE_REAR_LEFT	= 'TIRE04';

simulated event Tick(float DeltaTime)
{
	local rotator Tire1RotT, Tire2RotT, Tire3RotT, Tire4RotT, ChassisRot;
	local vector Dir;
	ChassisRot = Chassis.Rotation;
	Dir = vector(ChassisRot);

	Tire1RotT = Chassis.SteerTireRight.Rotation; // tires are invisible kactors
	Tire2RotT = Chassis.SteerTireLeft.Rotation;
	Tire3RotT = Chassis.EngTireRight.Rotation;
	Tire4RotT = Chassis.EngTireLeft.Rotation;

	Chassis.SetBoneDirection( TIRE_FRONT_RIGHT , Tire1RotT , Dir , 1 );
	Chassis.SetBoneDirection( TIRE_FRONT_LEFT , Tire2RotT , Dir , 1 );
	Chassis.SetBoneDirection( TIRE_REAR_RIGHT , Tire3RotT , Dir , 1 );
	Chassis.SetBoneDirection( TIRE_REAR_LEFT , Tire4RotT , Dir , 1 );
}

defaultproperties
{
	 RemoteRole=ROLE_None
}

Code:
class EvilCatModern extends KarmaCarVehicle;

var BoneRotatingActor HelperActor;

simulated event PreBeginPlay()
{
	Super.PreBeginPlay();

	// Only need the helper on client, listen server and SP
	if (Level.NetMode != NM_DedicatedServer)
	{
		HelperActor = Spawn( class'BoneRotatingActor' );
		HelperActor.Chassis = self;
	}
}

simulated function Destroyed()
{
	Super.Destroyed();
	if(HelperActor != None)
		HelperActor.Destroy();
}

defaultproperties
{
	 RemoteRole=ROLE_DumbProxy
}
 
Last edited:

EQ²

Code Monkey
Oct 30, 2004
244
0
16
41
Near Birmingham, UK
www.teambse.co.uk
Sorry I guess it's not very clear. The values you need aren't replicated on the KActor itself so you can either replicate them yourself on that Actor, or in your helper, it really doesn't make a huge difference. I've modified your code to show how this could be achieved, I've marked the changes in red so you can see what's changed.

One thing to note is that since we're now replicating the helper actor (remoterole is now simulatedproxy on the helper itself) you don't need to (in fact shouldn't) spawn it on the client, just on the server.

Code:
class BoneRotatingActor extends Actor;

const TIRE_FRONT_RIGHT = 'TIRE';
const TIRE_FRONT_LEFT = 'TIRE03';
const TIRE_REAR_RIGHT = 'TIRE02';
const TIRE_REAR_LEFT = 'TIRE04';

var EvilCatModern Chassis;
[B][COLOR="Red"]// These variables calculated server-side then sent to client
var rotator Tire1RotT, Tire2RotT, Tire3RotT, Tire4RotT;
var vector Dir;

replication
{
    // Send calculated variables to client
    unreliable if (Role == ROLE_Authority)
        Chassis, Dir, Tire1RotT, Tire2RotT, Tire3RotT, Tire4RotT;
}
[/COLOR][/B]
simulated event Tick(float DeltaTime)
{
    local rotator ChassisRot;

    [B][COLOR="Red"]// Check whether chassis is valid, otherwise will get
    // "Accessed None" before replication is completed
    if (Chassis == None) return;

    // Only update this stuff server-side
    if (Role == ROLE_Authority)
    {[/COLOR][/B]
        ChassisRot = Chassis.Rotation;
        Dir = vector(ChassisRot);

        Tire1RotT = Chassis.SteerTireRight.Rotation; // tires are invisible kactors
        Tire2RotT = Chassis.SteerTireLeft.Rotation;
        Tire3RotT = Chassis.EngTireRight.Rotation;
        Tire4RotT = Chassis.EngTireLeft.Rotation;
    [B][COLOR="Red"]}[/COLOR][/B]

    Chassis.SetBoneDirection( TIRE_FRONT_RIGHT , Tire1RotT , Dir , 1 );
    Chassis.SetBoneDirection( TIRE_FRONT_LEFT , Tire2RotT , Dir , 1 );
    Chassis.SetBoneDirection( TIRE_REAR_RIGHT , Tire3RotT , Dir , 1 );
    Chassis.SetBoneDirection( TIRE_REAR_LEFT , Tire4RotT , Dir , 1 );
}

defaultproperties
{
     RemoteRole=[B][COLOR="Red"]ROLE_SimulatedProxy[/COLOR][/B]
}
Code:
class EvilCatModern extends KarmaCarVehicle;

var BoneRotatingActor HelperActor;

simulated event PreBeginPlay()
{
    Super.PreBeginPlay();

    [B][COLOR="Red"]// Only spawn the helper server-side, it will be
    // replicated to the client[/COLOR][/B]
    if ([B][COLOR="Red"]Role == ROLE_Authority[/COLOR][/B])
    {
        HelperActor = Spawn( class'BoneRotatingActor' );
        HelperActor.Chassis = self;
    }
}

simulated function Destroyed()
{
    Super.Destroyed();

    if (HelperActor != None)
    [B][COLOR="Red"]{[/COLOR][/B]
        HelperActor.Destroy();
        [B][COLOR="Red"]HelperActor = None;
    }[/COLOR][/B]
}

defaultproperties
{
    RemoteRole=ROLE_DumbProxy
}

Hope this helps.
 

EvilT-ModZ

Un-Gravitify
Aug 3, 2011
42
0
6
30
Russia
www.set-games.ru
Sorry I guess it's not very clear. The values you need aren't replicated on the KActor itself so you can either replicate them yourself on that Actor, or in your helper, it really doesn't make a huge difference. I've modified your code to show how this could be achieved, I've marked the changes in red so you can see what's changed.

One thing to note is that since we're now replicating the helper actor (remoterole is now simulatedproxy on the helper itself) you don't need to (in fact shouldn't) spawn it on the client, just on the server.

Code:
class BoneRotatingActor extends Actor;

const TIRE_FRONT_RIGHT = 'TIRE';
const TIRE_FRONT_LEFT = 'TIRE03';
const TIRE_REAR_RIGHT = 'TIRE02';
const TIRE_REAR_LEFT = 'TIRE04';

var EvilCatModern Chassis;
[B][COLOR="Red"]// These variables calculated server-side then sent to client
var rotator Tire1RotT, Tire2RotT, Tire3RotT, Tire4RotT;
var vector Dir;

replication
{
    // Send calculated variables to client
    unreliable if (Role == ROLE_Authority)
        Chassis, Dir, Tire1RotT, Tire2RotT, Tire3RotT, Tire4RotT;
}
[/COLOR][/B]
simulated event Tick(float DeltaTime)
{
    local rotator ChassisRot;

    [B][COLOR="Red"]// Check whether chassis is valid, otherwise will get
    // "Accessed None" before replication is completed
    if (Chassis == None) return;

    // Only update this stuff server-side
    if (Role == ROLE_Authority)
    {[/COLOR][/B]
        ChassisRot = Chassis.Rotation;
        Dir = vector(ChassisRot);

        Tire1RotT = Chassis.SteerTireRight.Rotation; // tires are invisible kactors
        Tire2RotT = Chassis.SteerTireLeft.Rotation;
        Tire3RotT = Chassis.EngTireRight.Rotation;
        Tire4RotT = Chassis.EngTireLeft.Rotation;
    [B][COLOR="Red"]}[/COLOR][/B]

    Chassis.SetBoneDirection( TIRE_FRONT_RIGHT , Tire1RotT , Dir , 1 );
    Chassis.SetBoneDirection( TIRE_FRONT_LEFT , Tire2RotT , Dir , 1 );
    Chassis.SetBoneDirection( TIRE_REAR_RIGHT , Tire3RotT , Dir , 1 );
    Chassis.SetBoneDirection( TIRE_REAR_LEFT , Tire4RotT , Dir , 1 );
}

defaultproperties
{
     RemoteRole=[B][COLOR="Red"]ROLE_SimulatedProxy[/COLOR][/B]
}
Code:
class EvilCatModern extends KarmaCarVehicle;

var BoneRotatingActor HelperActor;

simulated event PreBeginPlay()
{
    Super.PreBeginPlay();

    [B][COLOR="Red"]// Only spawn the helper server-side, it will be
    // replicated to the client[/COLOR][/B]
    if ([B][COLOR="Red"]Role == ROLE_Authority[/COLOR][/B])
    {
        HelperActor = Spawn( class'BoneRotatingActor' );
        HelperActor.Chassis = self;
    }
}

simulated function Destroyed()
{
    Super.Destroyed();

    if (HelperActor != None)
    [B][COLOR="Red"]{[/COLOR][/B]
        HelperActor.Destroy();
        [B][COLOR="Red"]HelperActor = None;
    }[/COLOR][/B]
}

defaultproperties
{
    RemoteRole=ROLE_DumbProxy
}

Hope this helps.
Thank you a lot again ;)
Now bones rotates well :)