Author Topic: Setting up controller script for Mecanim syncing  (Read 4860 times)

acronyte

  • Newbie
  • *
  • Thank You
  • -Given: 9
  • -Receive: 0
  • Posts: 46
    • View Profile
Setting up controller script for Mecanim syncing
« on: May 30, 2016, 04:23:04 PM »
My controller script has references to functions in an external script , where the mecanim animation functions are...

I tried and managed to sync the player movement (position and rotation) but not the mecanim animations. I did his using the default TNSync Rigidbody script that came with TNet. I have read in the forums that I need to sync the inputs but I don't know how to start as my script has the external reference....

Can someone please point me in the right direction in setting up my controller script below to send RFC's to the external script, so that the mecanim animation can sync? Below is the part of my controller script with the references to functions from the external script and input functions

  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityStandardAssets.CrossPlatformInput;
  4.  
  5. namespace Invector.CharacterController
  6. {
  7.     public class ThirdPersonController : ThirdPersonAnimator
  8.     {
  9.  
  10.                 private static ThirdPersonController _instance;
  11.         public static ThirdPersonController instance
  12.         {
  13.             get
  14.             {
  15.                 if (_instance == null)
  16.                 {
  17.                     _instance = GameObject.FindObjectOfType<ThirdPersonController>();
  18.                     //Tell unity not to destroy this object when loading a new scene
  19.                     //DontDestroyOnLoad(_instance.gameObject);
  20.                 }
  21.                 return _instance;
  22.             }
  23.         }
  24.  
  25.         private bool isAxisInUse;
  26.  
  27.        
  28.  
  29.         void Start()
  30.         {
  31.             InitialSetup();                                     // setup the basic information, created on Character.cs
  32.             Cursor.visible = false;
  33.         }
  34.  
  35.  
  36.  
  37. //////This is where the external functions begin////////////
  38.                 void FixedUpdate()
  39.         {
  40.                        
  41.                         UpdateMotor();                                  // call ThirdPersonMotor methods
  42.                     UpdateAnimator();                           // update animations on the Animator and their methods
  43.                     UpdateHUD();                    // update HUD elements like health bar, texts, etc
  44.             ControlCameraState();                       // change CameraStates    
  45.                        
  46.  
  47.         }
  48.  
  49.         void LateUpdate()
  50.         {            
  51.                        
  52.                         InputHandle();                                  // handle input from controller, keyboard&mouse or mobile touch            
  53.                     DebugMode();                                        // display information about the character on PlayMode
  54.  
  55.         }
  56.        
  57.         /// <summary>
  58.         /// INPUT - every input is been handle in this script, you can change the input map here or directly on the InputManager
  59.         /// </summary>
  60.                 void InputHandle()
  61.                 {
  62.                        
  63.                                 CloseApp ();
  64.                                 CameraInput ();
  65.                                 if (!lockPlayer && !ragdolled) {                
  66.                                         ControllerInput ();
  67.  
  68.                                         // we have mapped the 360 controller as our Default gamepad,
  69.                                         // you can change the keyboard inputs by chaging the Alternative Button on the InputManager.                
  70.                                         InteractInput ();
  71.                                         JumpInput ();
  72.                                         RollInput ();                
  73.                                         CrouchInput ();                
  74.                                         AttackInput ();                
  75.                                         DefenseInput ();                
  76.                                         SprintInput ();
  77.                                         LockOnInput ();
  78.                                         DropWeaponInput ("D-Pad Horizontal");
  79.                                 } else
  80.                                         LockPlayer ();            
  81.                        
  82.                 }
  83.  
  84.      
  85. ////The Input ///////////////
  86.         /// <summary>
  87.         /// CONTROLLER INPUT - gets input from keyboard, gamepad or mobile touch to move the character
  88.         /// </summary>
  89.                 public void ControllerInput()
  90.         {
  91.                        
  92.                                
  93.                                 if (inputType == InputType.Mobile)
  94.                                         input = new Vector2 (CrossPlatformInputManager.GetAxis ("Horizontal"), CrossPlatformInputManager.GetAxis ("Vertical"));
  95.                                 else if (inputType == InputType.MouseKeyboard)
  96.                                         input = new Vector2 (Input.GetAxis ("Horizontal"), Input.GetAxis ("Vertical"));
  97.                                 else if (inputType == InputType.Controler) {
  98.                                         float deadzone = 0.25f;
  99.                                         input = new Vector2 (Input.GetAxis ("LeftAnalogHorizontal"), Input.GetAxis ("LeftAnalogVertical"));
  100.                                         if (input.magnitude < deadzone)
  101.                                                 input = Vector2.zero;
  102.                                         else
  103.                                                 input = input.normalized * ((input.magnitude - deadzone) / (1 - deadzone));
  104.                                
  105.                                        
  106.                                
  107.                                 }
  108.  
  109.         }
  110.  
  111.        
  112.  
  113. }
  114.  

acronyte

  • Newbie
  • *
  • Thank You
  • -Given: 9
  • -Receive: 0
  • Posts: 46
    • View Profile
Re: Setting up controller script for Mecanim syncing
« Reply #1 on: May 30, 2016, 11:56:12 PM »
Also how would I add derive this script from TNBehaviour? Seeing that it is dependent on ThirdPersonAnimator?

  1. //////script is dependent on "ThirdPersonAnimator"/////
  2. public class ThirdPersonController : ThirdPersonAnimator
  3.  

if I do this....

  1. //////script is dependent on "ThirdPersonAnimator"/////
  2. public class ThirdPersonController : TNBehaviour
  3.  

It wont work because it depends on ThirdPersonAnimator....


ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Setting up controller script for Mecanim syncing
« Reply #2 on: June 01, 2016, 10:28:55 PM »
You see how your ControllerInput() sets the "input" value? That's what you should be synchronizing with other players. LateUpdate() should only process input if it's your own player:
  1. void LateUpdate()
  2. {
  3.         if (GetComponent<TNObject>().isMine)
  4.         {
  5.             InputHandle();
  6.             DebugMode();
  7.         }
  8. }
There is no need to derive from TNBehaviour if you don't want to. It's quite convenient if you can though as it makes quite a few things easier, such as calling "tno.isMine" instead of GetComponent() stuff above. In your case you would need to derive the ThirdPersonAnimator from it, if possible.

acronyte

  • Newbie
  • *
  • Thank You
  • -Given: 9
  • -Receive: 0
  • Posts: 46
    • View Profile
Re: Setting up controller script for Mecanim syncing
« Reply #3 on: June 02, 2016, 04:22:16 PM »
Thanks Aren....

I understand the syncing input. The problem is now deriving the thridpersonanimator from TNBehaviour... It faces the same issue as the thirdpersoncontroller.... Might I also mention , both thirdpersonanimator and thirdpersoncontroller are within a namespace ..... Could this be why I cannot derive them from TNBehaviour?

Both scripts have this format...

  1. using UnityEngine;
  2. using System.Collections;
  3. using TNet;
  4.  
  5. namespace Invector
  6. {
  7.        
  8.         public abstract class ThirdPersonAnimator : ThirdPersonMotor ///changing this to TNBehavour throws errors
  9.     {
  10. ///////stufff goes here////
  11. }
  12. }
  13.  

cmifwdll

  • Global Moderator
  • Sr. Member
  • *****
  • Thank You
  • -Given: 0
  • -Receive: 149
  • Posts: 285
  • TNet Alchemist
    • View Profile
Re: Setting up controller script for Mecanim syncing
« Reply #4 on: June 02, 2016, 05:14:27 PM »
Thanks Aren....

I understand the syncing input. The problem is now deriving the thridpersonanimator from TNBehaviour... It faces the same issue as the thirdpersoncontroller.... Might I also mention , both thirdpersonanimator and thirdpersoncontroller are within a namespace ..... Could this be why I cannot derive them from TNBehaviour?

Both scripts have this format...

  1. using UnityEngine;
  2. using System.Collections;
  3. using TNet;
  4.  
  5. namespace Invector
  6. {
  7.        
  8.         public abstract class ThirdPersonAnimator : ThirdPersonMotor ///changing this to TNBehavour throws errors
  9.     {
  10. ///////stufff goes here////
  11. }
  12. }
  13.  

C# doesn't support multiple inheritance. You can, however, inherit from one base class and multiple interfaces. What Aren was getting at is you'd traverse downwards until you find the root base class and derive from TNBehaviour there. Though, that might not be best practice. I'd go with the original suggestion of using GetComponent<TNObject>().
Or have your network syncing logic be a completely separate script attached to the gameobject (remember: Unity is built to encourage the component paradigm).

acronyte

  • Newbie
  • *
  • Thank You
  • -Given: 9
  • -Receive: 0
  • Posts: 46
    • View Profile
Re: Setting up controller script for Mecanim syncing
« Reply #5 on: June 03, 2016, 01:19:28 PM »
Thanks guys... Im getting somewhere with using
  1. GetComponent<TNObject>()

acronyte

  • Newbie
  • *
  • Thank You
  • -Given: 9
  • -Receive: 0
  • Posts: 46
    • View Profile
Re: Setting up controller script for Mecanim syncing
« Reply #6 on: June 03, 2016, 01:53:10 PM »
Ok....the players now sync position and rotation... But Im stuck at how to send the inputs..

Arenmook had mentioned I'd have to sync my inputs in order for the mecanim animation to work...

Is it done something like this?

  1. ////The Input ///////////////
  2.         /// <summary>
  3.         /// CONTROLLER INPUT - gets input from keyboard, gamepad or mobile touch to move the character
  4.         /// </summary>
  5.                 public void ControllerInput()
  6.         {
  7.                        
  8.                                
  9.                                 if (inputType == InputType.Mobile)
  10.                                         input = new Vector2 (CrossPlatformInputManager.GetAxis ("Horizontal"), CrossPlatformInputManager.GetAxis ("Vertical"));
  11.                                 else if (inputType == InputType.MouseKeyboard)
  12.                                         input = new Vector2 (Input.GetAxis ("Horizontal"), Input.GetAxis ("Vertical"));
  13.                                 else if (inputType == InputType.Controler) {
  14.                                         float deadzone = 0.25f;
  15.                                         input = new Vector2 (Input.GetAxis ("LeftAnalogHorizontal"), Input.GetAxis ("LeftAnalogVertical"));
  16.                                         if (input.magnitude < deadzone)
  17.                                                 input = Vector2.zero;
  18.                                         else
  19.                                                 input = input.normalized * ((input.magnitude - deadzone) / (1 - deadzone));
  20.                                
  21.                              
  22.                                 }
  23.  GetComponent<TNObject>().SendQuickly (1, Target.AllSaved, input); /// Which function do i send this to?
  24.         }
  25.  

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Setting up controller script for Mecanim syncing
« Reply #7 on: June 04, 2016, 01:59:42 PM »
You shouldn't be sending input so frequently. First, check to see if it has changed significantly enough since last time you did so -- this means storing a "lastInput" value to compare against. Next, check to see if enough time has elapsed since the last time you sent an update. This means storing a "lastSend" time. Only if both pass should you send the update. Check ExampleCar's Update() function:
  1.         protected override void Update ()
  2.         {
  3.                 // Only the player that actually owns this car should be controlling it
  4.                 if (!tno.isMine) return;
  5.  
  6.                 // Update the input axes
  7.                 base.Update();
  8.  
  9.                 float time = Time.time;
  10.                 float delta = time - mLastInputSend;
  11.                 float delay = 1f / inputUpdates;
  12.  
  13.                 // Don't send updates more than 20 times per second
  14.                 if (delta > 0.05f)
  15.                 {
  16.                         // The closer we are to the desired send time, the smaller is the deviation required to send an update.
  17.                         float threshold = Mathf.Clamp01(delta - delay) * 0.5f;
  18.  
  19.                         // If the deviation is significant enough, send the update to other players
  20.                         if (Tools.IsNotEqual(mLastInput.x, mInput.x, threshold) ||
  21.                                 Tools.IsNotEqual(mLastInput.y, mInput.y, threshold))
  22.                         {
  23.                                 mLastInputSend = time;
  24.                                 mLastInput = mInput;
  25.                                 tno.Send("SetAxis", Target.OthersSaved, mInput);
  26.                         }
  27.                 }
  28.  
  29.                 // Since the input is sent frequently, rigidbody only needs to be corrected every couple of seconds.
  30.                 // Faster-paced games will require more frequent updates.
  31.                 if (mNextRB < time)
  32.                 {
  33.                         mNextRB = time + 1f / rigidbodyUpdates;
  34.                         tno.Send("SetRB", Target.OthersSaved, mRb.position, mRb.rotation, mRb.velocity, mRb.angularVelocity);
  35.                 }
  36.         }