forked from cgvr/DeltaVR
		
	
		
			
				
	
	
		
			428 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			428 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
#if UNITY_EDITOR
 | 
						|
#if MIRROR
 | 
						|
using UnityEditor;
 | 
						|
using UnityEngine;
 | 
						|
using FishNet.Object;
 | 
						|
using FishNet.Documenting;
 | 
						|
using System.Collections.Generic;
 | 
						|
using FNNetworkTransform = FishNet.Component.Transforming.NetworkTransform;
 | 
						|
using FNNetworkAnimator = FishNet.Component.Animating.NetworkAnimator;
 | 
						|
using FNNetworkObserver = FishNet.Observing.NetworkObserver;
 | 
						|
using FishNet.Observing;
 | 
						|
using FishNet.Component.Observing;
 | 
						|
using FishNet.Editing;
 | 
						|
using System.IO;
 | 
						|
using System.Collections;
 | 
						|
using Mirror;
 | 
						|
using MirrorNetworkTransformBase = Mirror.NetworkTransformBase;
 | 
						|
using MirrorNetworkTransformChild = Mirror.NetworkTransformChild;
 | 
						|
using MirrorNetworkAnimator = Mirror.NetworkAnimator;
 | 
						|
#if !MIRROR_57_0_OR_NEWER
 | 
						|
using MirrorNetworkProximityChecker = Mirror.NetworkProximityChecker;
 | 
						|
using MirrorNetworkSceneChecker = Mirror.NetworkSceneChecker;
 | 
						|
#endif
 | 
						|
 | 
						|
#if FGG_ASSETS
 | 
						|
using FlexNetworkAnimator = FirstGearGames.Mirrors.Assets.FlexNetworkAnimators.FlexNetworkAnimator;
 | 
						|
using FlexNetworkTransformBase = FirstGearGames.Mirrors.Assets.FlexNetworkTransforms.FlexNetworkTransformBase;
 | 
						|
using FastProximityChecker = FirstGearGames.Mirrors.Assets.NetworkProximities.FastProximityChecker;
 | 
						|
#endif
 | 
						|
 | 
						|
#if FGG_PROJECTS
 | 
						|
using FlexSceneChecker = FirstGearGames.FlexSceneManager.FlexSceneChecker;
 | 
						|
#endif
 | 
						|
 | 
						|
namespace FishNet.Upgrading.Mirror.Editing
 | 
						|
{
 | 
						|
 | 
						|
    /* IMPORTANT IMPORTANT IMPORTANT IMPORTANT 
 | 
						|
    * If you receive errors about missing Mirror components,
 | 
						|
    * such as NetworkIdentity, then remove MIRROR and any other
 | 
						|
    * MIRROR defines.
 | 
						|
    * Project Settings -> Player -> Other -> Scripting Define Symbols.
 | 
						|
    * 
 | 
						|
    * If you are also using my assets add FGG_ASSETS to the defines, and
 | 
						|
    * then remove it after running this script. */
 | 
						|
    [APIExclude]
 | 
						|
    [ExecuteInEditMode]
 | 
						|
    [InitializeOnLoad]
 | 
						|
    public class MirrorUpgrade : MonoBehaviour
 | 
						|
    {
 | 
						|
        /// <summary>
 | 
						|
        /// SceneCondition within FishNet.
 | 
						|
        /// </summary>
 | 
						|
        private SceneCondition _sceneCondition = null;
 | 
						|
        /// <summary>
 | 
						|
        /// DistanceCondition created for the user.
 | 
						|
        /// </summary>
 | 
						|
        private DistanceCondition _distanceCondition = null;
 | 
						|
        /// <summary>
 | 
						|
        /// 
 | 
						|
        /// </summary>
 | 
						|
        private int _replacedNetworkTransforms;
 | 
						|
        /// <summary>
 | 
						|
        /// 
 | 
						|
        /// </summary>
 | 
						|
        private int _replacedNetworkAnimators;
 | 
						|
        /// <summary>
 | 
						|
        /// 
 | 
						|
        /// </summary>
 | 
						|
        private int _replacedNetworkIdentities;
 | 
						|
        /// <summary>
 | 
						|
        /// 
 | 
						|
        /// </summary>
 | 
						|
        private int _replacedSceneCheckers;
 | 
						|
        /// <summary>
 | 
						|
        /// 
 | 
						|
        /// </summary>
 | 
						|
        private int _replacedProximityCheckers;
 | 
						|
        /// <summary>
 | 
						|
        /// True if anything was changed.
 | 
						|
        /// </summary>
 | 
						|
        private bool _changed;
 | 
						|
        /// <summary>
 | 
						|
        /// Index in gameObjects to iterate.
 | 
						|
        /// </summary>
 | 
						|
        private int _goIndex = -1;
 | 
						|
        /// <summary>
 | 
						|
        /// Found gameObjects to iterate.
 | 
						|
        /// </summary>
 | 
						|
        private List<GameObject> _gameObjects = new List<GameObject>();
 | 
						|
        /// <summary>
 | 
						|
        /// True if initialized.
 | 
						|
        /// </summary>
 | 
						|
        private bool _initialized;
 | 
						|
 | 
						|
 | 
						|
        private const string OBJECT_NAME_PREFIX = "MirrorUpgrade";
 | 
						|
 | 
						|
 | 
						|
        private void Awake()
 | 
						|
        {
 | 
						|
            gameObject.name = OBJECT_NAME_PREFIX;
 | 
						|
            Debug.Log($"{gameObject.name} is working. Please wait until this object is removed from your hierarchy.");
 | 
						|
            EditorApplication.update += EditorUpdate;
 | 
						|
        }
 | 
						|
 | 
						|
        private void OnDestroy()
 | 
						|
        {
 | 
						|
            EditorApplication.update -= EditorUpdate;
 | 
						|
        }
 | 
						|
 | 
						|
        private void EditorUpdate()
 | 
						|
        {
 | 
						|
            if (!_initialized)
 | 
						|
            {
 | 
						|
                FindConditions(true);
 | 
						|
                _gameObjects = Finding.GetGameObjects(true, false, true, new string[] { "/Mirror/" });
 | 
						|
                _goIndex = 0;
 | 
						|
                _initialized = true;
 | 
						|
            }
 | 
						|
 | 
						|
            if (_goIndex == -1)
 | 
						|
                return;
 | 
						|
            if (_goIndex >= _gameObjects.Count)
 | 
						|
            {
 | 
						|
                gameObject.name = $"{OBJECT_NAME_PREFIX} - 100%";
 | 
						|
                Debug.Log($"Switched {_replacedNetworkTransforms} NetworkTransforms.");
 | 
						|
                Debug.Log($"Switched {_replacedNetworkAnimators} NetworkAnimators.");
 | 
						|
                Debug.Log($"Switched {_replacedSceneCheckers} SceneCheckers.");
 | 
						|
                Debug.Log($"Switched {_replacedProximityCheckers} ProximityCheckers.");
 | 
						|
                Debug.Log($"Switched {_replacedNetworkIdentities} NetworkIdentities.");
 | 
						|
 | 
						|
                if (_changed)
 | 
						|
                    PrintSaveWarning();
 | 
						|
 | 
						|
                DestroyImmediate(gameObject);
 | 
						|
                return;
 | 
						|
            }
 | 
						|
 | 
						|
            float percentFloat = ((float)_goIndex / (float)_gameObjects.Count) * 100f;
 | 
						|
            int percentInt = Mathf.FloorToInt(percentFloat);
 | 
						|
            gameObject.name = $"{OBJECT_NAME_PREFIX} - {percentInt}%";
 | 
						|
 | 
						|
            GameObject go = _gameObjects[_goIndex];
 | 
						|
            _goIndex++;
 | 
						|
            //Go went empty?
 | 
						|
            if (go == null)
 | 
						|
                return;
 | 
						|
 | 
						|
            /* When a component is removed
 | 
						|
             * changed is set true and remove count is increased.
 | 
						|
             * _goIndex is also returned before exiting the method.
 | 
						|
             * This will cause the same gameObject to iterate
 | 
						|
             * next update. This is important because the components
 | 
						|
             * must be Switched in order, and I can only remove one
 | 
						|
             * component per frame without Unity throwing a fit and
 | 
						|
             * freezing. A while loop doesn't let Unity recognize the component
 | 
						|
             * is gone(weird right? maybe editor thing), and a coroutine
 | 
						|
             * doesn't show errors well, they just fail silently. */
 | 
						|
 | 
						|
            bool changedThisFrame = false;
 | 
						|
            if (IterateNetworkTransform(go))
 | 
						|
            {
 | 
						|
                changedThisFrame = true;
 | 
						|
                _changed = true;
 | 
						|
                _replacedNetworkTransforms++;
 | 
						|
            }
 | 
						|
            if (IterateNetworkAnimator(go))
 | 
						|
            {
 | 
						|
                changedThisFrame = true;
 | 
						|
                _changed = true;
 | 
						|
                _replacedNetworkAnimators++;
 | 
						|
            }
 | 
						|
 | 
						|
            if (IterateSceneChecker(go))
 | 
						|
            {
 | 
						|
                changedThisFrame = true;
 | 
						|
                _changed = true;
 | 
						|
                _replacedSceneCheckers++;
 | 
						|
            }
 | 
						|
            if (IterateProximityChecker(go))
 | 
						|
            {
 | 
						|
                changedThisFrame = true;
 | 
						|
                _changed = true;
 | 
						|
                _replacedProximityCheckers++;
 | 
						|
            }
 | 
						|
            if (changedThisFrame)
 | 
						|
            {
 | 
						|
                _goIndex--;
 | 
						|
                return;
 | 
						|
            }
 | 
						|
            //NetworkIdentity must be done last.
 | 
						|
            if (IterateNetworkIdentity(go))
 | 
						|
            {
 | 
						|
                _changed = true;
 | 
						|
                _replacedNetworkIdentities++;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Finds Condition scripts to be used with NetworkObserver.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="error"></param>
 | 
						|
        private void FindConditions(bool error)
 | 
						|
        {
 | 
						|
            List<UnityEngine.Object> scriptableObjects;
 | 
						|
 | 
						|
            if (_sceneCondition == null)
 | 
						|
            {
 | 
						|
                scriptableObjects = Finding.GetScriptableObjects<SceneCondition>(true, true);
 | 
						|
                //Use the first found scene condition, there should be only one.
 | 
						|
                if (scriptableObjects.Count > 0)
 | 
						|
                    _sceneCondition = (SceneCondition)scriptableObjects[0];
 | 
						|
 | 
						|
                if (_sceneCondition == null && error)
 | 
						|
                    Debug.LogError("SceneCondition could not be found. Upgrading scene checker components will not function.");
 | 
						|
            }
 | 
						|
 | 
						|
            if (_distanceCondition == null)
 | 
						|
            {
 | 
						|
                scriptableObjects = Finding.GetScriptableObjects<DistanceCondition>(false, true);
 | 
						|
                if (scriptableObjects.Count > 0)
 | 
						|
                {
 | 
						|
                    _distanceCondition = (DistanceCondition)scriptableObjects[0];
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    DistanceCondition dc = ScriptableObject.CreateInstance<DistanceCondition>();
 | 
						|
                    string savePath = "Assets";
 | 
						|
                    AssetDatabase.CreateAsset(dc, Path.Combine(savePath, $"CreatedDistanceCondition.asset"));
 | 
						|
                    Debug.LogWarning($"DistanceCondition has been created at {savePath}. Place this file somewhere within your project and change settings to your liking.");
 | 
						|
                }
 | 
						|
 | 
						|
                if (_distanceCondition == null && error)
 | 
						|
                    Debug.LogError("DistanceCondition could not be found. Upgrading proximity checker components will not function.");
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        private bool IterateNetworkTransform(GameObject go)
 | 
						|
        {
 | 
						|
            if (go.TryGetComponent(out MirrorNetworkTransformBase nt1))
 | 
						|
            {
 | 
						|
                Transform target;
 | 
						|
                if (nt1 is MirrorNetworkTransformChild mc1)
 | 
						|
                    target = mc1.target;
 | 
						|
                else
 | 
						|
                    target = go.transform;
 | 
						|
                Replace(nt1, target);
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
#if FGG_ASSETS
 | 
						|
            if (go.TryGetComponent(out FlexNetworkTransformBase fntb))
 | 
						|
            {
 | 
						|
                Replace(fntb, fntb.TargetTransform);
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
#endif
 | 
						|
 | 
						|
            void Replace(UnityEngine.Component component, Transform target)
 | 
						|
            {
 | 
						|
                EditorUtility.SetDirty(go);
 | 
						|
                DestroyImmediate(component, true);
 | 
						|
 | 
						|
                if (target != null && !target.TryGetComponent<FNNetworkTransform>(out _))
 | 
						|
                    target.gameObject.AddComponent<FNNetworkTransform>();
 | 
						|
            }
 | 
						|
 | 
						|
            //Fall through, nothing was replaced.
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
 | 
						|
        private bool IterateNetworkAnimator(GameObject go)
 | 
						|
        {
 | 
						|
            if (go.TryGetComponent(out MirrorNetworkAnimator mna))
 | 
						|
            {
 | 
						|
                Replace(mna, mna.transform);
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
#if FGG_ASSETS
 | 
						|
            if (go.TryGetComponent(out FlexNetworkAnimator fna))
 | 
						|
            {
 | 
						|
                Replace(fna, fna.transform);
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
#endif
 | 
						|
 | 
						|
            void Replace(UnityEngine.Component component, Transform target)
 | 
						|
            {
 | 
						|
                EditorUtility.SetDirty(go);
 | 
						|
                DestroyImmediate(component, true);
 | 
						|
 | 
						|
                if (target == null)
 | 
						|
                    return;
 | 
						|
                if (!target.TryGetComponent<FNNetworkAnimator>(out _))
 | 
						|
                    target.gameObject.AddComponent<FNNetworkAnimator>();
 | 
						|
            }
 | 
						|
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        private bool IterateSceneChecker(GameObject go)
 | 
						|
        {
 | 
						|
#if !MIRROR_57_0_OR_NEWER
 | 
						|
            if (_sceneCondition == null)
 | 
						|
                return false;
 | 
						|
 | 
						|
            if (go.TryGetComponent(out MirrorNetworkSceneChecker msc))
 | 
						|
            {
 | 
						|
                Replace(msc);
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
#if FGG_PROJECTS
 | 
						|
            if (go.TryGetComponent(out FlexSceneChecker fsc))
 | 
						|
            {
 | 
						|
                Replace(fsc);
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
#endif
 | 
						|
 | 
						|
            void Replace(UnityEngine.Component component)
 | 
						|
            {
 | 
						|
                EditorUtility.SetDirty(go);
 | 
						|
                DestroyImmediate(component, true);
 | 
						|
 | 
						|
                FNNetworkObserver networkObserver;
 | 
						|
                if (!go.TryGetComponent(out networkObserver))
 | 
						|
                    networkObserver = go.AddComponent<FNNetworkObserver>();
 | 
						|
 | 
						|
                bool conditionFound = false;
 | 
						|
                foreach (ObserverCondition condition in networkObserver.ObserverConditions)
 | 
						|
                {
 | 
						|
                    if (condition.GetType() == typeof(SceneCondition))
 | 
						|
                    {
 | 
						|
                        conditionFound = true;
 | 
						|
                        break;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                //If not able to find scene condition then add one.
 | 
						|
                if (!conditionFound)
 | 
						|
                    networkObserver.ObserverConditionsInternal.Add(_sceneCondition);
 | 
						|
            }
 | 
						|
 | 
						|
#endif
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
        private bool IterateProximityChecker(GameObject go)
 | 
						|
        {
 | 
						|
#if !MIRROR_57_0_OR_NEWER
 | 
						|
            if (_distanceCondition == null)
 | 
						|
                return false;
 | 
						|
 | 
						|
            if (go.TryGetComponent(out MirrorNetworkProximityChecker mnpc))
 | 
						|
            {
 | 
						|
                Replace(mnpc);
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
#if FGG_PROJECTS
 | 
						|
            if (go.TryGetComponent(out FastProximityChecker fpc))
 | 
						|
            {
 | 
						|
                Replace(fpc);
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
#endif
 | 
						|
 | 
						|
            void Replace(UnityEngine.Component component)
 | 
						|
            {
 | 
						|
                EditorUtility.SetDirty(go);
 | 
						|
                DestroyImmediate(component, true);
 | 
						|
 | 
						|
                FNNetworkObserver networkObserver;
 | 
						|
                if (!go.TryGetComponent(out networkObserver))
 | 
						|
                    networkObserver = go.AddComponent<FNNetworkObserver>();
 | 
						|
 | 
						|
                bool conditionFound = false;
 | 
						|
                foreach (ObserverCondition condition in networkObserver.ObserverConditions)
 | 
						|
                {
 | 
						|
                    if (condition.GetType() == typeof(DistanceCondition))
 | 
						|
                    {
 | 
						|
                        conditionFound = true;
 | 
						|
                        break;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                //If not able to find scene condition then add one.
 | 
						|
                if (!conditionFound)
 | 
						|
                    networkObserver.ObserverConditionsInternal.Add(_distanceCondition);
 | 
						|
            }
 | 
						|
#endif
 | 
						|
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        private bool IterateNetworkIdentity(GameObject go)
 | 
						|
        {
 | 
						|
            if (go.TryGetComponent(out NetworkIdentity netIdentity))
 | 
						|
            {
 | 
						|
                EditorUtility.SetDirty(go);
 | 
						|
                DestroyImmediate(netIdentity, true);
 | 
						|
 | 
						|
                //Add nob if doesn't exist.
 | 
						|
                if (!go.TryGetComponent<NetworkObject>(out _))
 | 
						|
                    go.AddComponent<NetworkObject>();
 | 
						|
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        private static void PrintSaveWarning()
 | 
						|
        {
 | 
						|
            Debug.LogWarning("You must File -> Save for changes to complete.");
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
}
 | 
						|
#endif
 | 
						|
#endif |