Skip to content
This repository has been archived by the owner on Jan 22, 2022. It is now read-only.

Commit

Permalink
Automatically update NoVariableSync to try and match sync type on Gam…
Browse files Browse the repository at this point in the history
…eObject

- Automatically update sync type on UdonSharpBehaviours with NoVariableSync specified so they can exist on the same GameObject as manually synced UdonBehaviours. Will not update the sync type if there is a conflict on the GameObject.
  • Loading branch information
MerlinVR committed Jun 18, 2021
1 parent a9642c0 commit 98f8c87
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 15 deletions.
10 changes: 7 additions & 3 deletions Assets/UdonSharp/Editor/Editors/UdonSharpGUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,9 @@ internal static void DrawSyncSettings(UdonBehaviour behaviour)

foreach (UdonBehaviour otherBehaviour in behavioursOnObject)
{
if (otherBehaviour.programSource is UdonSharpProgramAsset otherBehaviourProgram && otherBehaviourProgram.behaviourSyncMode == BehaviourSyncMode.NoVariableSync)
continue;

if (otherBehaviour.Reliable)
hasReliableSync = true;
else
Expand All @@ -1369,9 +1372,10 @@ internal static void DrawSyncSettings(UdonBehaviour behaviour)

if (hasContinuousSync && hasReliableSync)
{
if (programAsset.behaviourSyncMode == BehaviourSyncMode.NoVariableSync)
EditorGUILayout.HelpBox("NoVariableSync mode uses Continuous sync mode internally. You are mixing sync methods between UdonBehaviours on the same game object, this will cause all behaviours to use the sync method of the last component on the game object.", MessageType.Error);
else
//if (programAsset.behaviourSyncMode == BehaviourSyncMode.NoVariableSync)
// EditorGUILayout.HelpBox("NoVariableSync mode uses Continuous sync mode internally. You are mixing sync methods between UdonBehaviours on the same game object, this will cause all behaviours to use the sync method of the last component on the game object.", MessageType.Error);
//else
if (programAsset.behaviourSyncMode != BehaviourSyncMode.NoVariableSync)
EditorGUILayout.HelpBox("You are mixing sync methods between UdonBehaviours on the same game object, this will cause all behaviours to use the sync method of the last component on the game object.", MessageType.Error);
}
}
Expand Down
64 changes: 52 additions & 12 deletions Assets/UdonSharp/Editor/UdonSharpEditorManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -567,41 +567,41 @@ static void UpdateSyncModes(List<UdonBehaviour> udonBehaviours)
if (behaviour.programSource == null || !(behaviour.programSource is UdonSharpProgramAsset programAsset))
continue;

int originalModificationcount = modificationCount;

behaviourGameObjects.Add(behaviour.gameObject);

if (behaviour.Reliable == true &&
(programAsset.behaviourSyncMode == BehaviourSyncMode.Continuous ||
programAsset.behaviourSyncMode == BehaviourSyncMode.NoVariableSync))
if (behaviour.Reliable == true && programAsset.behaviourSyncMode == BehaviourSyncMode.Continuous)
{
behaviour.Reliable = false;
modificationCount++;
PrefabUtility.RecordPrefabInstancePropertyModifications(behaviour);
}
else if (behaviour.Reliable == false && programAsset.behaviourSyncMode == BehaviourSyncMode.Manual)
{
behaviour.Reliable = true;
modificationCount++;
}

if (originalModificationcount != modificationCount)
PrefabUtility.RecordPrefabInstancePropertyModifications(behaviour);
}
}

if (modificationCount > 0)
EditorSceneManager.MarkAllScenesDirty();

// Validation for mixed sync modes which can break sync on things
// Validation for mixed sync modes which can break sync on things and auto update NoVariableSync behaviours to match the sync mode of other behaviours on the GameObject
foreach (GameObject gameObject in behaviourGameObjects)
{
UdonBehaviour[] objectBehaviours = gameObject.GetComponents<UdonBehaviour>();

bool hasManual = false;
bool hasContinuous = false;
bool hasUdonPositionSync = false;
bool hasNoSync = false;

foreach (UdonBehaviour objectBehaviour in objectBehaviours)
{
if (UdonSharpEditorUtility.IsUdonSharpBehaviour(objectBehaviour) &&
((UdonSharpProgramAsset)objectBehaviour.programSource).behaviourSyncMode == BehaviourSyncMode.NoVariableSync)
{
hasNoSync = true;
continue;
}

if (objectBehaviour.Reliable)
hasManual = true;
else
Expand All @@ -624,7 +624,47 @@ static void UpdateSyncModes(List<UdonBehaviour> udonBehaviours)
if (hasUdonPositionSync)
Debug.LogWarning($"[<color=#FF00FF>UdonSharp</color>] UdonBehaviours on GameObject '{gameObject.name}' are using manual sync while position sync is enabled on an UdonBehaviour on the GameObject, this can cause sync to work unexpectedly.", gameObject);
}

if (hasNoSync)
{
int conflictCount = 0;

if (hasManual && hasContinuous)
++conflictCount;
if (hasManual && (hasUdonPositionSync || gameObject.GetComponent<VRC.SDK3.Components.VRCObjectSync>()))
++conflictCount;

if (conflictCount > 0)
{
Debug.LogWarning($"[<color=#FF00FF>UdonSharp</color>] Cannot update sync mode on UdonSharpBehaviour with NoVariableSync on '{gameObject}' because there are conflicting sync types on the GameObject", gameObject);
continue;
}

foreach (UdonBehaviour behaviour in objectBehaviours)
{
if (behaviour.programSource is UdonSharpProgramAsset programAsset && programAsset.behaviourSyncMode == BehaviourSyncMode.NoVariableSync)
{
if (hasManual && !behaviour.Reliable)
{
behaviour.Reliable = true;
modificationCount++;

PrefabUtility.RecordPrefabInstancePropertyModifications(behaviour);
}
else if (behaviour.Reliable)
{
behaviour.Reliable = false;
modificationCount++;

PrefabUtility.RecordPrefabInstancePropertyModifications(behaviour);
}
}
}
}
}

if (modificationCount > 0)
EditorSceneManager.MarkAllScenesDirty();
}

static bool UdonSharpBehaviourTypeMatches(object symbolValue, System.Type expectedType, string behaviourName, string variableName)
Expand Down

0 comments on commit 98f8c87

Please sign in to comment.