Announcement

Collapse
No announcement yet.

[Video][Code] Mult. Replication P2: Efficient Special Effects & Bouncing Projectiles

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    [Video][Code] Mult. Replication P2: Efficient Special Effects & Bouncing Projectiles

    Implementing Your Custom Game Mechanics With Unreal Multiplayer Network Replication System

    Replication Series
    Part 1: Change Pawn Materials Based On a Unique PlayerID
    Part 2: Efficiently Replicate Custom Special Effects & Projectile Bounces
    Part 3: Grapple Hook and Custom Pawn Movements
    Part 4: Listen Servers - Replicating Special Effects


    In this tutorial I show the most efficient solution I could come up with for replicating custom special effects, projectiles, and animations!


    In my solution the only data being replicated across the network is a single int and a single boolean that are only updated each time player fires weapon (not every tick / moment of projectile movement).

    Furthermore, the single integer is replicated in unreliable fashion (more efficient, but less accurate), while the projectile itself is replicated reliably as it causes game-changing effects to the game world and must occur and at the right time.

    My solution also handles the correct replication of complex projectile movement like bouncing off of surfaces.




    ~~~

    Efficiency Summary

    So in the video you see above where my game progresses from no replication to projectiles bouncing all over the place and special effects going off,

    1. Only a single boolean var is being replicated in reliable fashion (more costly but more accurate)

    2. The only other replicated data is a single integer that is replicated unreliably

    3. These two vars are only replicated once per Left Mouse Button click (not every moment of game time by any means).


    ~~~

    Code For You

    Here's the core of my code so that you can utilize the same system I use in the video with the same level of network efficiency (if anyone has any improvements to my network system let me know)

    ~~~

    controller class

    Code:
    //extending UTPlayercontroller
    
    //==========================
    //Left Mouse Button
    
    //unreliable server function
    
    //must run function on server instead of
    //client, to ensure that bNetDirty gets
    //activated.
    
    //This then causes the repnotify to fire
    //in pawn class, so that weapon effects show up
    //for all clients.
    
    //for info about why I am using unreliable
    //see Wormbo's awesome documentation
    
    //Everything You Wanted to Know About Replication(but were afraid to ask)
    
    //this visual effect is not game-changing,
    //unlike the replication of damage causing
    //projectiles,
    
    //so it is not made reliable to enable 
    //more important game mechanics to be replicated
    //precisely.
    unreliable server function ServerLMB() {
        pawn.PowerFired++;
    }
    
    
    //projectile itself MUST be accurate/reliable
    
    //this is only a single boolean that is being replicated, once each time player
    
    //presses LMB, so this is not a huge load to make into a reliable packet
    
    reliable server function ServerLMBProj() {
    	pawn.spawnPowerProj = !pawn.spawnPowerProj;
    }
    
    //decide network behavior
    simulated function LMBFired() {
    	
    	//single player or server + client in 1 comp
    	if (Role == ROLE_Authority) {
    		pawn.playSpecialEffect();
    		pawn.PowerFired++;
    		pawn.ProjectileFire();
    	}
    	
    	//multiplayer
    	else {
    		ServerLMB();
    		ServerLMBProj();
    	}
    }
    
    //linked via defaultinput.ini to LMB of real mouse
    exec Function JoyLMBDown() {
    
    	if(pawn != none){
    	if (!pawn.cannotFire) {
    			
    		LMBFired();
    	}
    	}
    	
    }
    ~~~

    Pawn Class

    Code:
    //extending utpawn
    
    var bool cannotFire;
    
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Understanding Replication
    
    //copies of all player units exist
    //on all clients
    
    //and start with vars set to default values
    
    //Only these variables will be constantly transferred
    
    //for those copied versions
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    //================
    // Multiplayer
    //================
    
    //when these value change ReplicatedEvent below is fired
    var repnotify int powerFired;
    var repnotify bool spawnPowerProj;
    
    //Notice that 0 info about velocity or direction of projectiles
    //or position of special efffects is being replicated
    //and those values would have to replicated every tick
    
    //Instead each client spawns the projectile in its own reality/game
    //and handles all the physics/movement itself
    
    //This leads to accurate behavior that is also efficient for the network
    
    replication
    {
    	if ( bNetDirty )
    		spawnPowerProj,powerFired;
    }
    
    simulated event ReplicatedEvent( name VarName )
    {
    	//very important line
    	super.ReplicatedEvent( VarName );
    	
    	if (varname == 'powerFired') {
    		playSpecialEffect();
    	}
    	else if (varname == 'spawnPowerProj') {
    		ProjectileFire();
    	}
    }
    
    //=========================================
    // Rama Power System
    //
    // I am creating my own weapon system so I have to
    // handle replication of special effects / muzzle flashes
    // and actual projectile creation myself.
    //
    // This tutorial is showing you how you can do the same!
    //=========================================
    simulated function playSpecialEffect() {
    	
    	//arms recoil
    	
    	//arm positions are not replicated
    	//the animation is run locally = very efficient
    	playBothRecoil();
    	
    	//special effect
    	
    	//get location of right hand (or could use skeletal mesh weapon socket)
    	Mesh.GetSocketWorldLocationAndRotation('WeaponPoint', vc, r);
    	
    	//adjust vc and r as needed to look right
    	
    	//spawn mesh particle emitter
    	//spawned locally, its position and properties are not replicated
    	//very efficient
    	powerFlash = WorldInfo.MyEmitterPool.SpawnEmitter(
    		ParticleSystem'VictoryPackage4.ParticleSystem.JoyPowerSwirlsEffect', 
    		vc, 		//point of attachment to actor,
    		r, 			//rotation of particle effect
    		Self		//actor to attach to
    	);		
    	
    	//particle system must have "use local space" set for
    	//every "required" module of every component of the system
    	//for the attachment to an actor to work correctly.
    	//and cause particle system to move with the actor
    
    	//See this tutorial of mine for more info: 
            // Creating Mesh Particle System Shield for your characters
    	
    }
    
    simulated function playBothRecoil() {
         //utpawn code, see postinitanimtree
         GunRecoilNode.bPlayRecoil = true;
    }
    
    simulated function ProjectileFire()
    {
    	local Projectile	SpawnedProjectile;
    	
    	/*
    	
    	code to determine exact projectile spawn loc
    	and rotation omitted, as it is not relevant.
    	
    	Just note that the projectile is being spawned
    	directly from the pawn class.
    	
    	And when the repnotify event fires,
    	
    	This code runs on each client!
    	
    	Which means
    	
    	1. projectile effects spawn locally, no data transferred
    	over network
    	
    	2. the bounces of projectile work correctly without having
    	to replicate each and every projectile's velocity / direction
    	constantly every tick/moment of time, which would be huge
    	waste of network bandwidth
    	
    	3. The only thing being replicated is the single boolean to say
    	"yes do fire another projectile"
    	
    	entire rest of code is handled locally by each client, 
    	
    	very efficient network-wise
    	
    	*/
    		
    	//~~~~~~~~~~~~~~~~~~~
    	// Spawn projectile
    	//~~~~~~~~~~~~~~~~~~~
    		
    	SpawnedProjectile = Spawn(class'CustomProjectileClass',,, vc);
    	if( SpawnedProjectile != None && !SpawnedProjectile.bDeleteMe )
    	{
    		CustomProjectileClass(SpawnedProjectile).Init(vc2);
    	}
    }
    ~~~

    Summary


    Using the core essence of what I am showing you in this video and tutorial you can

    1. Design your own game mechanics

    2. Fully integrate them with unreal multiplayer replication system

    3. Even if you are starting from scratch!




    Rama

    #2
    thanks again evernewjoy, your tutos are very usefull, any chance to get a sample for a switch camera replication, i have a simple problem trying to switch my camera in the client side but don't know how to do it.

    Comment


      #3
      good work on your tutorials, just one thing I was told in the past:
      replicating something from a client to the server doesn't mean the server will replicate it back to all clients.

      now I can't tell if what you're showing in the video is a client displaying particles, viewed from the server, or if viewed from another client. so I can't tell if the above statement is true in your case.
      so, have you tried this and ensured it works for everyone? (the local client, the server, other multiple clients) - just wanting to make sure people don't bang their heads against the wall in the future

      Comment


        #4
        Nice to hear from your Chosker!

        Well in the video I am actually playing on the other client, not the one who is filming the fraps video, and the particles were showing up for the actual client I was playing on as well

        So the particle were indeed showing up for everyone it seems

        I am very excited about your replicating custom animations tutorial Chosker, I will be checking it out for use with my project very soon!

        (it's in his signature Replicating Custom Animations to All Clients)



        Rama

        Comment


          #5
          Bumping this because I am seeing questions that this tutorial can help resolve

          Enjoy!

          Rama

          Comment


            #6
            Actual Multiplayer Game Footage

            Here's a video of replicating a custom muzzle flash using a custom weapon that is actually static mesh attachment, not a skeletal mesh

            This is actual Multiplayer Footage!

            Easily seen if you skip to 4:45 or even 4:00

            Comment


              #7
              I am a little confused.If you are using the pawn to spawn the visible component of a projectile, that would mean you would never see projectiles if you couldn't see their owning pawn. If you force all pawns to be relevant, you will replicating more then if you were to use a regular projectile.Projectiles can be setup in such a way as to be fired and forgotten. If they become relevant to a client, that client can is given relevant info it can use to simulate the rest, including bouncing, effects etc. And it won't care if you can see the pawn or not.

              Comment


                #8
                Are you using anim slots ? or what kind of node are you using for the aim stance ?

                Comment


                  #9
                  Originally posted by slowJusko View Post
                  I am a little confused.If you are using the pawn to spawn the visible component of a projectile, that would mean you would never see projectiles if you couldn't see their owning pawn. If you force all pawns to be relevant, you will replicating more then if you were to use a regular projectile.Projectiles can be setup in such a way as to be fired and forgotten. If they become relevant to a client, that client can is given relevant info it can use to simulate the rest, including bouncing, effects etc. And it won't care if you can see the pawn or not.

                  Great to hear from you slowJusko! You're awesome!

                  See my post directly below this one for a smile!



                  Yea that's something I forgot to explain, I am using remoterole = none for the projectiles, they are not simulated or replicated at all, because there are soooo many being fired all the time in my game and exact accuracy is not important, and I want to save on networking bandwidth

                  I spawn the projectiles client side and when they connect I do destruction event / effects server side so the player's worlds do always end up matching.


                  But for games where there are fewer projectiles and each one's location and rotation plays a pivotal role in the game, and they need to always look exactly accurate on both machines,

                  I do agree with you slowJusko a different approach should be used, care to post that code for ppl here, as to the method you use?



                  Once I have the code for slow/important/pivotal projectiles that HAVE to be replicated, I can write up something about it in the main tutorial, I just have not researched that as it has not mattered for my actual multiplayer testing with friends so far (sent you a PM about this).

                  Trying to keep my actor replication channels to a minimum

                  Comment


                    #10
                    Originally posted by Neongho View Post
                    Are you using anim slots ? or what kind of node are you using for the aim stance ?
                    Hahha the timing of your question is PERFECT

                    It is Slow Jusko himself who showed me how to setup the animations for different gun positions!

                    And it is that information from him that has saved me more time than you can possibly imagine with my various projects were different gun body poses were required!

                    Check this out in utpawn.uc:

                    Code:
                    enum EWeapAnimType
                    {
                    	EWAT_Default,
                    	EWAT_Pistol,
                    	EWAT_DualPistols,
                    	EWAT_ShoulderRocket,
                    	EWAT_Stinger
                    };

                    Each of these are different gun holding positions that come with the udk


                    you can set which pose your pawn is using with this code:

                    Code:
                    //pistol hold animation
                    SetWeapAnimType(EWAT_Pistol);

                    And then the animtree and utpawn handles the rest for you!


                    thanks so much for this info SlowJusko!

                    Rama

                    Comment


                      #11
                      Ah, nope, that explains it (remoterole = Role_none).
                      I have done the same thing with our basic bullet, as these are not something you will often see. I also replicate the resulting impact.
                      Another step I took due to the potential volume of spawning/destroying was to create a projectile 'pool' that each player/AI controller. May/may not be something to look into.

                      Comment


                        #12
                        Originally posted by slowJusko View Post
                        Another step I took due to the potential volume of spawning/destroying was to create a projectile 'pool' that each player/AI controller. May/may not be something to look into.
                        That's a great suggestion, thank you slow Jusko!



                        Rama

                        Comment


                          #13
                          you can just use a blendByList for that, well i do it for gota , with a blendPerBone ... anyways you are not telling me what node you are using .. i guess it's the UTNodeBlendByWeapon or something like that , that probably extends of blendBylist
                          I don't use UT i make everything from scratch with native clases because idk it's more challanging...

                          Anyways good job with your , Humandynosaurs game keep it up hehe is it playable already ? where's the download link ?

                          Comment


                            #14
                            thanks again evernewjoy, your tutos are very usefull, any chance to get a sample for a switch camera replication, i have a simple problem trying to switch my camera in the client side but don't know how to do it.
                            Hey daimaku i had same problem with the camera once , i couldn't really replicate variables for the camera , well what i did is , replicate from player controller since camera has a reference to it and seems to work .

                            But anyways you could maybe spawn a cameraReplicationClass idk if it would work though lol.

                            Comment


                              #15
                              Originally posted by Neongho View Post
                              , well what i did is , replicate from player controller since camera has a reference to it and seems to work .

                              I had to do the same thing for my HUD class with my in-game editor,

                              sending data back to the controller from the HUD and having the controller call the server functions.



                              Rama

                              Comment

                              Working...
                              X