/**
         * @brief Returns true if the given layers can collide.
         *
         * @param layerA Layer of the first object
         * @param layerB Layer of the second object
         **/
        public static bool CollisionEnabled(int layerA, int layerB)
        {
            TrueSyncConfig tsConfig = TrueSyncManager.Config;

            if (tsConfig == null)
            {
                return(true);
            }

            return(!tsConfig.GetIgnoreLayerCollision(layerA, layerB));
        }
Пример #2
0
        public static int ComputeCollisionMask(int i_Layer)
        {
            TrueSyncConfig tsConfig = TrueSyncManager.configMain;

            if (tsConfig == null)
            {
                return(0);
            }

            return(tsConfig.ComputeCollisionMask(i_Layer));
        }
Пример #3
0
        /**
         * @brief Returns true if the given layers can collide.
         *
         * @param layerA Layer of the first object
         * @param layerB Layer of the second object
         **/
        public static bool CollisionEnabled(int i_LayerA, int i_LayerB)
        {
            TrueSyncConfig tsConfig = TrueSyncManager.configMain;

            if (tsConfig == null)
            {
                return(true);
            }

            return(tsConfig.CollisionEnabled(i_LayerA, i_LayerB));
        }
Пример #4
0
        void Awake()
        {
            TrueSyncConfig currentConfig = ActiveConfig;

            lockedTimeStep = currentConfig.lockedTimeStep;

            StateTracker.Init();

            if (currentConfig.physics2DEnabled || currentConfig.physics3DEnabled)
            {
                PhysicsManager.New(currentConfig);
                PhysicsManager.instance.LockedTimeStep = lockedTimeStep;
                PhysicsManager.instance.Init();
            }
        }
        void Awake()
        {
            TrueSyncConfig currentConfig = ActiveConfig;
            lockedTimeStep = currentConfig.lockedTimeStep;

            StateTracker.Init(currentConfig.rollbackWindow);
            TSRandom.Init();

            if (currentConfig.physics2DEnabled || currentConfig.physics3DEnabled) {
                PhysicsManager.New(currentConfig);
                PhysicsManager.instance.LockedTimeStep = lockedTimeStep;
                PhysicsManager.instance.Init();
            }

            StateTracker.AddTracking(this, "time");
        }
Пример #6
0
        //=================================================================================================================
        void Awake()
        {
            TrueSyncConfig currentConfig = ActiveConfig;

            lockedTimeStep = currentConfig.lockedTimeStep;

            // 初始化状态跟踪
            StateTracker.Init(currentConfig.rollbackWindow);
            // 初始化随机数
            TSRandom.Init(randomseed);

            // 初始化物理管理器
            if (currentConfig.physics2DEnabled || currentConfig.physics3DEnabled)
            {
                PhysicsManager.New(currentConfig);
                PhysicsManager.instance.LockedTimeStep = lockedTimeStep;
                PhysicsManager.instance.Init();
            }
            // 跟踪 时间
            StateTracker.AddTracking(this, "time");
        }
Пример #7
0
        private static void CreateTrueSyncConfigAsset()
        {
            TrueSyncConfig asset = ScriptableObject.CreateInstance <TrueSyncConfig>();

            string path = AssetDatabase.GetAssetPath(Selection.activeObject);

            if (path == "")
            {
                path = "Assets";
            }
            else if (Path.GetExtension(path) != "")
            {
                path = path.Replace(Path.GetFileName(AssetDatabase.GetAssetPath(Selection.activeObject)), "");
            }

            string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath(path + "/TrueSyncConfig.asset");

            AssetDatabase.CreateAsset(asset, assetPathAndName);

            AssetDatabase.SaveAssets();
            EditorUtility.FocusProjectWindow();
            Selection.activeObject = asset;
        }
Пример #8
0
        void Start()
        {
            instance = this;
            Application.runInBackground = true;

            ICommunicator communicator = null;

            //if (!PhotonNetwork.connected || !PhotonNetwork.inRoom) {
            //    Debug.LogWarning("You are not connected to Photon. TrueSync will start in offline mode.");
            //} else {
            //    communicator = new PhotonTrueSyncCommunicator(PhotonNetwork.networkingPeer);
            //}
            Debug.LogWarning("You are not connected to Photon. TrueSync will start in offline mode.");

            TrueSyncConfig activeConfig = ActiveConfig;

            lockstep = AbstractLockstep.NewInstance(
                lockedTimeStep,
                communicator,
                PhysicsManager.instance,
                activeConfig.syncWindow,
                activeConfig.panicWindow,
                activeConfig.rollbackWindow,
                OnGameStarted,
                OnGamePaused,
                OnGameUnPaused,
                OnGameEnded,
                OnPlayerDisconnection,
                OnStepUpdate,
                GetLocalData,
                ProvideInputData
                );

            //if (ReplayRecord.replayMode == ReplayMode.LOAD_REPLAY) {
            //    ReplayPicker.replayToLoad.Load();

            //    ReplayRecord replayRecord = ReplayRecord.replayToLoad;
            //    if (replayRecord == null) {
            //        Debug.LogError("Replay Record can't be loaded");
            //        gameObject.SetActive(false);
            //        return;
            //    } else {
            //        lockstep.ReplayRecord = replayRecord;
            //    }
            //}

            if (activeConfig.showStats)
            {
                this.gameObject.AddComponent <TrueSyncStats>().Lockstep = lockstep;
            }

            scheduler = new CoroutineScheduler(lockstep);

            if (ReplayRecord.replayMode != ReplayMode.LOAD_REPLAY)
            {
                lockstep.AddPlayer(0, "Local_Player", true);
                //if (communicator == null) {
                //    lockstep.AddPlayer(0, "Local_Player", true);
                //} else {
                //    List<PhotonPlayer> players = new List<PhotonPlayer>(PhotonNetwork.playerList);
                //    players.Sort(UnityUtils.playerComparer);

                //    for (int index = 0, length = players.Count; index < length; index++) {
                //        PhotonPlayer p = players[index];
                //        lockstep.AddPlayer((byte) p.ID, p.NickName, p.IsLocal);
                //    }
                //}
            }

            TrueSyncBehaviour[] behavioursArray = FindObjectsOfType <TrueSyncBehaviour>();
            for (int index = 0, length = behavioursArray.Length; index < length; index++)
            {
                generalBehaviours.Add(NewManagedBehavior(behavioursArray[index]));
            }

            initBehaviors();
            initGeneralBehaviors(generalBehaviours, false);

            PhysicsManager.instance.OnRemoveBody(OnRemovedRigidBody);

            startState = StartState.BEHAVIOR_INITIALIZED;
        }
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            TrueSyncConfig settings = (TrueSyncConfig)target;

            Undo.RecordObject(settings, "Edit TrueSyncConfig");

            EditorGUILayout.LabelField("General", EditorStyles.boldLabel);

            settings.syncWindow = EditorGUILayout.IntField("Sync Window", settings.syncWindow);
            if (settings.syncWindow < 0)
            {
                settings.syncWindow = 0;
            }

            settings.rollbackWindow = EditorGUILayout.IntField("Rollback Window", settings.rollbackWindow);
            if (settings.rollbackWindow < 0)
            {
                settings.rollbackWindow = 0;
            }

            settings.panicWindow = EditorGUILayout.IntField("Panic Window", settings.panicWindow);
            if (settings.panicWindow < 0)
            {
                settings.panicWindow = 0;
            }

            settings.lockedTimeStep = EditorGUILayout.FloatField("Locked Time Step", settings.lockedTimeStep.AsFloat());
            if (settings.lockedTimeStep < 0)
            {
                settings.lockedTimeStep = 0;
            }

            settings.showStats = EditorGUILayout.Toggle("Show Stats", settings.showStats);

            GUILayout.Space(10);

            EditorGUILayout.LabelField("Physics", EditorStyles.boldLabel);

            Vector2 gField2D = EditorGUILayout.Vector2Field("Gravity", settings.gravity.ToVector());

            settings.gravity.x = gField2D.x;
            settings.gravity.y = gField2D.y;

            settings.speculativeContacts = EditorGUILayout.Toggle("Speculative Contacts", settings.speculativeContacts);

            EditorGUILayout.LabelField("Layer Collision Matrix");

            DrawLayerMatrix(settings.collisionMatrix);

            if (GUILayout.Button("Align from standard matrix"))
            {
                AlignFromStandardMatrix(settings.collisionMatrix);
            }

            serializedObject.ApplyModifiedProperties();

            if (GUI.changed)
            {
                EditorUtility.SetDirty(target);
            }
        }
Пример #10
0
        void Start()
        {
            instance = this;
            Application.runInBackground = true;

            ICommunicator communicator = null;
            //初始化通信
            //if (!PhotonNetwork.connected || !PhotonNetwork.inRoom) {
            //    Debug.LogWarning("You are not connected to Photon. TrueSync will start in offline mode.");
            //} else {
            //    communicator = new PhotonTrueSyncCommunicator(PhotonNetwork.networkingPeer);
            //}

            TrueSyncConfig activeConfig = ActiveConfig;

            //创建lockstep
            lockstep = AbstractLockstep.NewInstance(
                lockedTimeStep.AsFloat(),
                communicator,
                PhysicsManager.instance,
                activeConfig.syncWindow,
                activeConfig.panicWindow,
                activeConfig.rollbackWindow,
                OnGameStarted,
                OnGamePaused,
                OnGameUnPaused,
                OnGameEnded,
                OnPlayerDisconnection,
                OnStepUpdate,
                ProvideInputData
                );
            //==========================================================================
            mFrameData = new FrameData();
            mLockStep  = gameObject.AddComponent <LockStep>();
            gameObject.AddComponent <GameProcessManager_Dota>();
            gameObject.AddComponent <MyTimerDriver>();

            PB_MatchTeamFight_FMS2GS2C mMatchTeamFight = (PB_MatchTeamFight_FMS2GS2C)NetData.Instance.Query(MsgID.S2CMatch, (uint)MatchMsgID.Fms2Gs2CMatchFight);

            FRS2C_Host  = mMatchTeamFight.Frs2Chost;
            FRS2C_Port  = mMatchTeamFight.Frs2Cport;
            guanqia     = mMatchTeamFight.Guanqia;
            teamid      = mMatchTeamFight.Teamid;
            fightroomid = mMatchTeamFight.Fightroomid;
            randomseed  = mMatchTeamFight.Seed;
            fps         = mMatchTeamFight.Fps;
            foreach (PB_FightPlayerInfo mFightPlayerInfo in mMatchTeamFight.Playersdata)
            {
                GameObject actorobj;
                Actor      actor;
                if (mFightPlayerInfo.ChooseHero == 1)
                {
                    actorobj = _AssetManager.GetGameObject("prefab/hero/yase/yase_prefab");
                    actor    = actorobj.GetComponent <PlayerActor_yase>();
                }
                else
                {
                    actorobj = _AssetManager.GetGameObject("prefab/hero/houyi/houyi_prefab");
                    actor    = actorobj.GetComponent <PlayerActor_houyi>();
                }
                //actor.ownerIndex =(int) mFightPlayerInfo.Playeridx;
                if (mFightPlayerInfo.Pid == NetData.Instance.PlayerID)
                {
                    actor.IsETCControl = true;
                    playeridx          = mFightPlayerInfo.Playeridx;
                    hellokey           = mFightPlayerInfo.Hellokey;
                    //actor.localOwner = new TSPlayerInfo((byte)mFightPlayerInfo.Pid, mFightPlayerInfo.Name);
                }
                else
                {
                    actor.IsETCControl = false;
                    //actor.owner = new TSPlayerInfo((byte)mFightPlayerInfo.Pid, mFightPlayerInfo.Name);
                }
                if (mActorParent == null)
                {
                    mActorParent = GameObject.Find("ActorParent").transform;
                }
                actor.transform.parent = mActorParent;
                //actor.Position = new CustomVector3(0, 0, 0);
                actor.Speed            = (FP)0.1f;
                actor.mActorAttr.HpMax = (FP)100;
                actor.mActorAttr.Hp    = (FP)50;
                actor.mActorAttr.Name  = mFightPlayerInfo.Name;
                actor.RotateTSTransform.LookAt(TSVector.left);
                actor.AllTSTransform.LookAt(TSVector.left);
                actor.Angle   = new TSVector();
                actor.OwnerID = mFightPlayerInfo.Playeridx;
                if (actor.OwnerID % 2 == 0)                //临时的阵营分配规则
                {
                    actor.OwnerCamp = GameCamp.BLUE;
                }
                else
                {
                    actor.OwnerCamp = GameCamp.RED;
                }
                AddPlayerActor(actor.OwnerID, actor);
            }
            OnBattleStart();
            //==========================================================================
            //检测是否是录像模式, 如果是就加载录像
            //if (ReplayRecord.replayMode == ReplayMode.LOAD_REPLAY) {
            //    ReplayPicker.replayToLoad.Load();

            //    ReplayRecord replayRecord = ReplayRecord.replayToLoad;
            //    if (replayRecord == null) {
            //        Debug.LogError("Replay Record can't be loaded");
            //        gameObject.SetActive(false);
            //        return;
            //    } else {
            //        lockstep.ReplayRecord = replayRecord;
            //    }
            //}

            //如果配置了显示TrueSyncStats,那就初始化
            if (activeConfig.showStats)
            {
                this.gameObject.AddComponent <TrueSyncStats>().Lockstep = lockstep;
            }

            //创建协程调度
            scheduler = new CoroutineScheduler(lockstep);

            //非录像模式下 初始化帧的玩家列表
            if (ReplayRecord.replayMode != ReplayMode.LOAD_REPLAY)
            {
                lockstep.AddPlayer(0, "Local_Player", true);
                //if (communicator == null) {
                //    lockstep.AddPlayer(0, "Local_Player", true);
                //} else {
                //    List<PhotonPlayer> players = new List<PhotonPlayer>(PhotonNetwork.playerList);
                //    players.Sort(UnityUtils.playerComparer);

                //    for (int index = 0, length = players.Count; index < length; index++) {
                //        PhotonPlayer p = players[index];
                //        lockstep.AddPlayer((byte) p.ID, p.NickName, p.IsLocal);
                //    }
                //}
            }

            //初始化场景中现有的帧同步行为
            TrueSyncBehaviour[] behavioursArray = FindObjectsOfType <TrueSyncBehaviour>();
            for (int index = 0, length = behavioursArray.Length; index < length; index++)
            {
                generalBehaviours.Add(NewManagedBehavior(behavioursArray[index]));
            }

            //实例化玩家预设playerPrefabs和同步其行为的拥有者
            initBehaviors();
            //初始化行为拥有者,并分配给对于玩家。没有继承TrueSyncBehaviour的就继续放到普通行为列表
            initGeneralBehaviors(generalBehaviours, false);

            //添加物理对象移除监听
            PhysicsManager.instance.OnRemoveBody(OnRemovedRigidBody);

            //设置启动状态
            startState = StartState.BEHAVIOR_INITIALIZED;
        }
Пример #11
0
        void Start()
        {
            instance = this;
            Application.runInBackground = true;

            if (ReplayRecord.replayMode == ReplayMode.LOAD_REPLAY)
            {
                ReplayRecord replayRecord = ReplayRecord.replayToLoad;
                if (replayRecord == null)
                {
                    Debug.LogError("Replay Record can't be loaded");
                    gameObject.SetActive(false);
                    return;
                }
            }

            ICommunicator communicator = null;

            if (!PhotonNetwork.connected || !PhotonNetwork.inRoom)
            {
                Debug.LogWarning("You are not connected to Photon. TrueSync will start in offline mode.");
            }
            else
            {
                communicator = new PhotonTrueSyncCommunicator(PhotonNetwork.networkingPeer);
            }

            TrueSyncConfig activeConfig = ActiveConfig;

            lockstep = AbstractLockstep.NewInstance(
                lockedTimeStep,
                communicator,
                PhysicsManager.instance,
                activeConfig.syncWindow,
                activeConfig.panicWindow,
                activeConfig.rollbackWindow,
                OnGameStarted,
                OnGamePaused,
                OnGameUnPaused,
                OnGameEnded,
                OnPlayerDisconnection,
                OnStepUpdate,
                GetLocalData
                );

            if (activeConfig.showStats)
            {
                this.gameObject.AddComponent <TrueSyncStats>().Lockstep = lockstep;
            }

            scheduler = new CoroutineScheduler(lockstep);

            if (ReplayRecord.replayMode != ReplayMode.LOAD_REPLAY)
            {
                if (communicator == null)
                {
                    lockstep.AddPlayer(0, "Local_Player", true);
                }
                else
                {
                    List <PhotonPlayer> players = new List <PhotonPlayer>(PhotonNetwork.playerList);
                    players.Sort(UnityUtils.playerComparer);

                    foreach (PhotonPlayer p in players)
                    {
                        lockstep.AddPlayer((byte)p.ID, p.NickName, p.IsLocal);
                    }
                }
            }

            generalBehaviours = new List <TrueSyncManagedBehaviour>();
            foreach (TrueSyncBehaviour tsb in FindObjectsOfType <TrueSyncBehaviour>())
            {
                generalBehaviours.Add(NewManagedBehavior(tsb));
            }

            initBehaviors();
            initGeneralBehaviors(generalBehaviours, false);

            PhysicsManager.instance.OnRemoveBody(OnRemovedRigidBody);

            startState = StartState.BEHAVIOR_INITIALIZED;
        }
        // LOGIC

        public void Initialize(TrueSyncConfig i_Config = null)
        {
            TrueSyncConfig config = (i_Config != null) ? i_Config : (Resources.Load <TrueSyncConfig>(s_TrueSyncConfigResourcePath));

            // Load config.

            m_Config = config;

            if (config == null)
            {
                return;
            }

            m_LockedTimeStep = config.lockedTimeStep;

            // Init state tracker.

            StateTracker.Init(config.rollbackWindow);

            // Init time.

            m_TimeScaler = new TSTimeScaler();
            m_TimeScaler.Init();

            // Create physics world.

            IPhysicsManager worldManager = new Physics2DWorldManager();

            worldManager.Gravity             = new TSVector(config.gravity.x, config.gravity.y, 0);
            worldManager.SpeculativeContacts = config.speculativeContacts;
            worldManager.LockedTimeStep      = config.lockedTimeStep;

            worldManager.Init();

            // Create communicator.

            ICommunicator communicator = null;

            if (isOnline)
            {
                communicator = new PhotonTrueSyncCommunicator(PhotonNetwork.networkingPeer);
            }
            else
            {
                Debug.Log("You are not connected to Photon. TrueSync will start in offline mode.");
            }

            // Create lockstep.

            m_Lockstep = AbstractLockstep.NewInstance(m_LockedTimeStep, communicator, worldManager, m_Config.syncWindow, m_Config.panicWindow, m_Config.rollbackWindow, OnGameStarted, OnGamePaused, OnGameUnPaused, OnGameEnded, OnPlayerDisconnection, OnStepUpdate, GetLocalData);

            Debug.Log("Lockstep initialized (Sync: " + m_Config.syncWindow + ", Rollback: " + m_Config.rollbackWindow + ")");

            // Stats

            if (m_Config.showStats)
            {
                TrueSyncStats statsComponent = gameObject.AddComponent <TrueSyncStats>();
                statsComponent.Lockstep = m_Lockstep;
            }

            // Add player on lockestep.

            if (isOnline)
            {
                List <PhotonPlayer> photonPlayers = new List <PhotonPlayer>(PhotonNetwork.playerList);
                photonPlayers.Sort(UnityUtils.playerComparer);

                for (int photonPlayerIndex = 0; photonPlayerIndex < photonPlayers.Count; ++photonPlayerIndex)
                {
                    PhotonPlayer photonPlayer = photonPlayers[photonPlayerIndex];
                    m_Lockstep.AddPlayer((byte)photonPlayer.ID, photonPlayer.NickName, photonPlayer.IsLocal);
                }
            }
            else
            {
                m_Lockstep.AddPlayer(0, "Local_Player", true);
            }

            // Fill behaviours per player dictionary.

            foreach (TSPlayer player in m_Lockstep.Players.Values)
            {
                List <TrueSyncManagedBehaviour> behaviours = new List <TrueSyncManagedBehaviour>();
                m_BehavioursPerPlayer.Add(player.ID, behaviours);
            }

            // Initialize Physics Manager.

            PhysicsManager.Initialize(worldManager);
            PhysicsManager.OnRemoveBody(OnRemovedRigidbody);
        }
Пример #13
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            TrueSyncConfig settings = (TrueSyncConfig)target;

            Undo.RecordObject(settings, "Edit TrueSyncConfig");

            EditorGUILayout.LabelField("General", EditorStyles.boldLabel);
            EditorGUI.indentLevel++;

            settings.syncWindow = EditorGUILayout.IntField("Sync Window", settings.syncWindow);
            if (settings.syncWindow < 0)
            {
                settings.syncWindow = 0;
            }

            settings.rollbackWindow = EditorGUILayout.IntField("Rollback Window", settings.rollbackWindow);
            if (settings.rollbackWindow < 0)
            {
                settings.rollbackWindow = 0;
            }

            settings.panicWindow = EditorGUILayout.IntField("Panic Window", settings.panicWindow);
            if (settings.panicWindow < 0)
            {
                settings.panicWindow = 0;
            }

            settings.lockedTimeStep = EditorGUILayout.FloatField("Locked Time Step", settings.lockedTimeStep.AsFloat());
            if (settings.lockedTimeStep < 0)
            {
                settings.lockedTimeStep = 0;
            }

            settings.showStats = EditorGUILayout.Toggle("Show Stats", settings.showStats);

            EditorGUI.indentLevel--;

            GUILayout.Space(10);

            settings.physics2DEnabled = EditorGUILayout.BeginToggleGroup("2D Physics", settings.physics2DEnabled);

            if (settings.physics2DEnabled)
            {
                settings.physics3DEnabled = false;

                EditorGUI.indentLevel++;

                Vector2 gField2D = EditorGUILayout.Vector2Field("Gravity", settings.gravity2D.ToVector());
                settings.gravity2D.x = gField2D.x;
                settings.gravity2D.y = gField2D.y;

                settings.speculativeContacts2D = EditorGUILayout.Toggle("Speculative Contacts", settings.speculativeContacts2D);

                physics2DCollisionFoldout = EditorGUILayout.Foldout(physics2DCollisionFoldout, "Layer Collision Matrix");
                if (physics2DCollisionFoldout)
                {
                    DrawLayerMatrix(settings.physics2DIgnoreMatrix);
                }

                EditorGUI.indentLevel--;
            }

            EditorGUILayout.EndToggleGroup();

            settings.physics3DEnabled = EditorGUILayout.BeginToggleGroup("3D Physics", settings.physics3DEnabled);

            if (settings.physics3DEnabled)
            {
                settings.physics2DEnabled = false;

                EditorGUI.indentLevel++;

                Vector3 gField3D = EditorGUILayout.Vector3Field("Gravity", settings.gravity3D.ToVector());
                settings.gravity3D.x = gField3D.x;
                settings.gravity3D.y = gField3D.y;
                settings.gravity3D.z = gField3D.z;

                settings.speculativeContacts3D = EditorGUILayout.Toggle("Speculative Contacts", settings.speculativeContacts3D);

                physics3DCollisionFoldout = EditorGUILayout.Foldout(physics3DCollisionFoldout, "Layer Collision Matrix");
                if (physics3DCollisionFoldout)
                {
                    DrawLayerMatrix(settings.physics3DIgnoreMatrix);
                }

                EditorGUI.indentLevel--;
            }

            EditorGUILayout.EndToggleGroup();

            serializedObject.ApplyModifiedProperties();

            GUILayout.Space(20);

            if (GUILayout.Button("Highlight Settings"))
            {
                EditorGUIUtility.PingObject(target);
            }

            if (GUI.changed)
            {
                EditorUtility.SetDirty(target);
            }
        }
Пример #14
0
        void Start()
        {
            instance = this;
            Application.runInBackground = true;

            //离线状态 就AbstractLockstep的OnEventDataReceived接收网络数据不会执行
            //更换网络接口 可以从ICommunicator接口 入手
            ICommunicator communicator = null;

            if (!PhotonNetwork.connected || !PhotonNetwork.inRoom)
            {
                Debug.LogWarning("You are not connected to Photon. TrueSync will start in offline mode.");
            }
            else
            {
                communicator = new PhotonTrueSyncCommunicator(PhotonNetwork.networkingPeer);
            }

            TrueSyncConfig activeConfig = ActiveConfig;

            lockstep = AbstractLockstep.NewInstance(
                lockedTimeStep.AsFloat(),
                communicator,
                PhysicsManager.instance,
                activeConfig.syncWindow,
                activeConfig.panicWindow,
                activeConfig.rollbackWindow,
                OnGameStarted,
                OnGamePaused,
                OnGameUnPaused,
                OnGameEnded,
                OnPlayerDisconnection,
                OnStepUpdate,
                GetLocalData,
                ProvideInputData
                );

            if (ReplayRecord.replayMode == ReplayMode.LOAD_REPLAY)
            {
                ReplayPicker.replayToLoad.Load();

                ReplayRecord replayRecord = ReplayRecord.replayToLoad;
                if (replayRecord == null)
                {
                    Debug.LogError("Replay Record can't be loaded");
                    gameObject.SetActive(false);
                    return;
                }
                else
                {
                    lockstep.ReplayRecord = replayRecord;
                }
            }

            if (activeConfig.showStats)
            {
                this.gameObject.AddComponent <TrueSyncStats>().Lockstep = lockstep;
            }

            scheduler = new CoroutineScheduler(lockstep);

            if (ReplayRecord.replayMode != ReplayMode.LOAD_REPLAY)
            {
                if (communicator == null)
                {
                    lockstep.AddPlayer(0, "Local_Player", true);
                }
                else
                {
                    List <PhotonPlayer> players = new List <PhotonPlayer>(PhotonNetwork.playerList);
                    players.Sort(UnityUtils.playerComparer);

                    for (int index = 0, length = players.Count; index < length; index++)
                    {
                        PhotonPlayer p = players[index];
                        lockstep.AddPlayer((byte)p.ID, p.NickName, p.IsLocal); //更新players activePlayers
                    }
                }
            }

            //搜寻场景预先挂载的TrueSyncBehaviour脚本,为它生成TrueSyncManagedBehaviour脚本
            //可能这部分脚本有些属于玩家 有些属于公共部分,都根据OwnerIndex来区分
            TrueSyncBehaviour[] behavioursArray = FindObjectsOfType <TrueSyncBehaviour>();
            for (int index = 0, length = behavioursArray.Length; index < length; index++)
            {
                generalBehaviours.Add(NewManagedBehavior(behavioursArray[index]));//一个TrueSyncBehaviour对应TrueSyncManagedBehaviour
            }

            initBehaviors();                                //初始化玩家prefab和挂在prefab上的TrueSyncBehaviour
            initGeneralBehaviors(generalBehaviours, false); //公用和玩家的区分,公用分给generalBehaviours,玩家分给behaviorsByPlayer

            PhysicsManager.instance.OnRemoveBody(OnRemovedRigidBody);

            startState = StartState.BEHAVIOR_INITIALIZED;//初始化完毕状态
        }