Author Topic: How to Sync 2D Toolkit Current Animation  (Read 4076 times)

Danim3D

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
    • http://www.Danim3D.com
How to Sync 2D Toolkit Current Animation
« on: July 31, 2014, 08:50:19 PM »
I'm trying to sync the current playing animation from 2D Toolkit.
It seem to try to sync only for the first frame of the clip than the animation flicker from walkleft to walkright.
I'm following the code structure show in Tutorial 2 and I came up with this:

  1.         public tk2dSpriteAnimator playerAnim;
  2.  
  3.         public string currentAnim{
  4.                 set{
  5.                         tno.Send(7, TNet.Target.AllSaved, value);
  6.                 }
  7.         }
  8.  
  9.         void Update(){
  10.                 if(Input.GetKey("left"))
  11.                         currentAnim = "walkleft";
  12.                 if(Input.GetKey("right"))
  13.                         currentAnim = "walkright";
  14.         }
  15.  
  16.         [RFC(7)]
  17.         void OnSetCurrentAnim(string currentAnim){
  18.                 playerAnim.Play(currentAnim);
  19.         }
  20.  

My animation is not sync with this code above but I it seem to work with the TNAutoSync script with my playerAnim variable.
I would appreciate tips to make it work in scripting.
Thanks
« Last Edit: August 01, 2014, 04:12:13 PM by Danim3D »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: How to Sync 2D Toolkit Current Animation
« Reply #1 on: August 01, 2014, 09:41:16 PM »
You should be checking for Input.GetKeyDown, not GetKey. You're basically spamming network packets while the key is held. AutoSync script actually checks to see if the value changed first, and if it didn't it does nothing, which is why it works. You keep spamming the network, which in turn spams the animation.Play() commands.

Danim3D

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
    • http://www.Danim3D.com
Re: How to Sync 2D Toolkit Current Animation
« Reply #2 on: August 05, 2014, 04:34:45 PM »
Input.GetKeyDown is now doing the animation.Play change and it is working well without TNAutoSync script.
But I still have to use Input.GetKey to keep moving the character in one direction while the key is press.
I could not get the Player position to move smoothly, I always get strange gap in the motion.

Here is what my code look like:

  1.         public Vector3 target{
  2.                 set{
  3.                         tno.Send(5, TNet.Target.AllSaved, value);
  4.                 }
  5.         }
  6.  
  7.         void Update(){
  8.                 if(tno.isMine){
  9.                         if(Input.anyKey)
  10.                                 target = transform.position;
  11.                         if(Input.GetKey("left"))
  12.                                 moveDir = -1;
  13.                         if(Input.GetKey("right"))
  14.                                 moveDir = 1;
  15.                         if(Input.GetKeyDown("left"))
  16.                                 currentAnim = "walkleft";
  17.                         if(Input.GetKeyDown("right"))
  18.                                 currentAnim = "walkright";
  19.                 }
  20.         }
  21.  
  22.         [RFC(5)]
  23.         void OnSetTarget(Vector3 pos){
  24.                 nTarget = pos;
  25.         }

I was expecting that target = transform.position; could sync the position but the character is not moving smoothly at all. The Player move well alone but as soon as the second player Join the motion has strange gap on both side for both Player. My Player Prefab has TNObject, TNSyncRigidBody script attach to it. TNAutoSync is not active but was not working for the transform.position either.
I have try to increase the TNSyncRigidBody to 20 Update Per Second which is probably too much but it is still not smooth.
Thank for any advices.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: How to Sync 2D Toolkit Current Animation
« Reply #3 on: August 06, 2014, 07:58:10 PM »
This is how I would do it:
  1. int mDir = 0;
  2.  
  3. void Update ()
  4. {
  5.     if (tno.isMine)
  6.     {
  7.         bool sync = false;
  8.         bool left = Input.GetKey("left");
  9.         bool right = Input.GetKey("right");
  10.         int dir = left ? -1 : (right ? 1 : 0);
  11.         if (mDir != dir) tno.Send("SetDir", TNet.Target.AllSaved, dir);
  12.     }
  13.  
  14.     // move the 'target' here using the 'mDir' value
  15.     //if (mDir == -1) then move left
  16.     //else if (mDir == 1) then move right
  17. }
  18.  
  19. [RFC]
  20. void SetDir (int dir)
  21. {
  22.     mDir = dir;
  23.     if (dir == -1) currentAnim = "walkleft";
  24.     else if (dir == 1) currentAnim = "walkRight";
  25.     //else currentAnim = "idle";
  26. }
This way all you're synchronizing is the current state of your keys, and you're only doing so when the state changes. All clients will then perform their own movement logic based on the latest known state. Sync the position periodically afterwards to make sure they're in the right place. Once every 2 seconds should be more than enough.
« Last Edit: August 08, 2014, 07:00:01 AM by ArenMook »

Danim3D

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
    • http://www.Danim3D.com
Re: How to Sync 2D Toolkit Current Animation
« Reply #4 on: August 07, 2014, 04:25:57 PM »
Thank, it is an interesting way of doing the character movement direction from left to right. I got rid of all my code happening in FixedUpdate() fonction and use your solution. I did a test with just a moving cube and it is moving smoothly. My character with Rigidbody still have a little weird motion only when the second character Join, but it does look a lot better than before. Should I always use TNSyncRigidbody script with Rigidbody object? Currently I use it on my GamePlayer with Update Per Second at 1 only.

I am confuse about why you use  if (!tno.isMine)  instead of   if (tno.isMine)  and why we do move the target using the mDir value outside of if(tno.isMine) ? I understand the use of tno.isMine for Player but for Enemy should I use this as well if I don't want them to spawn in double.

I have to think differently about my jump code. What will be the best to sync for the jump? Should I sync the key Input.GetKeyDown, the position.y or the rigidbody velocity? What will happen if the character start to jump and the position is being sync in the middle of the jump, will the jump stop syncing? Should I sync as well the grounded and doubleJump state as well? I use something like this:

  1. if(Physics.Raycast(thisTransform.position, raycastDir, 1f)) {
  2.         if(!grounded){
  3.                 grounded = true;
  4.                 doubleJump = false;
  5.         }
  6. }else{
  7.         grounded = false;
  8. }
  9.  
  10. if(Input.GetKeyDown("space")){
  11.         if(grounded)
  12.                 rigidbody.velocity = new Vector3(0f,jumpHeight,0f);
  13.         if(!grounded && !doubleJump){
  14.                 doubleJump = true;
  15.                 rigidbody.velocity = new Vector3(0f,jumpHeight,0f);
  16. }

I tried this solution and it seem to work
  1.         [RFC]
  2.         void SetPosY(float jumpHeight){
  3.                 rigidbody.velocity = new Vector3(0f,jumpHeight,0f);
  4.         }

Tutorial 2 was very great to explain TNet, it would be great to do a video tutorial about the key press sync for character movement since it is a very different approach when we have to consider networking.
Thank!
« Last Edit: August 08, 2014, 06:11:48 AM by Danim3D »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: How to Sync 2D Toolkit Current Animation
« Reply #5 on: August 08, 2014, 07:03:56 AM »
"if (!tno.isMine)" was a typo, it should have been "if (tno.isMine)".

TNSyncRigidbody is a convenience script. Use it if it's helpful in your case. As I mentioned, with input sync like this you don't need to sync the rigidbody more than once per second at most.

Also note that you shouldn't be modifying the rigidbody's velocity after checking for the jump key. You need to sync this by sending it via an RFC, or simply doing this:
  1. if (tno.isMine)
  2. {
  3.     if(Input.GetKeyDown("space"))
  4.     {
  5.         if(grounded)
  6.         {
  7.             rigidbody.velocity = new Vector3(0f,jumpHeight,0f);
  8.             GetComponent<TNSyncRigidbody>().Sync();
  9.         }
  10.         else if(!doubleJump)
  11.         {
  12.             doubleJump = true;
  13.             rigidbody.velocity = new Vector3(0f,jumpHeight,0f);
  14.             GetComponent<TNSyncRigidbody>().Sync();
  15.         }
  16.     }
  17. }