Skip to content

Commit

Permalink
Merge pull request #423 from MSchmoecker/gameobject-mocking
Browse files Browse the repository at this point in the history
feat: mock GameObjects
  • Loading branch information
MSchmoecker committed Mar 15, 2024
2 parents 6ba217c + d04f08a commit 340a1ab
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 3 deletions.
24 changes: 21 additions & 3 deletions JotunnLib/Extensions/MockExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Reflection;
using Jotunn.Managers;
using Jotunn.Utils;
Expand Down Expand Up @@ -50,9 +51,26 @@ public static void FixReferences(this GameObject gameObject, bool recursive)
return;
}

foreach (Transform tf in gameObject.transform)
List<Tuple<Transform, GameObject>> mockChildren = new List<Tuple<Transform, GameObject>>();

foreach (Transform child in gameObject.transform)
{
var realPrefab = MockManager.GetRealPrefabFromMock<GameObject>(child.gameObject);

if (realPrefab)
{
mockChildren.Add(new Tuple<Transform, GameObject>(child, realPrefab));
}
else
{
child.gameObject.FixReferences(true);
}
}

// mock GameObjects have to be replaced in a second loop to avoid modifying the transform hierarchy while iterating over it
foreach (var mockChild in mockChildren)
{
tf.gameObject.FixReferences(true);
MockManager.ReplaceMockGameObject(mockChild.Item1, mockChild.Item2, gameObject);
}
}

Expand Down
28 changes: 28 additions & 0 deletions JotunnLib/Managers/MockSystem/MockManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ internal class MockManager : IManager
/// </summary>
public static MockManager Instance => _instance ??= new MockManager();

private static MethodInfo Object_IsPersistent { get; } = AccessTools.Method(typeof(Object), "IsPersistent");

/// <summary>
/// Hide .ctor
/// </summary>
Expand Down Expand Up @@ -221,6 +223,32 @@ internal static void FixReferences(object objectToFix, int depth)
}
}

internal static void ReplaceMockGameObject(Transform child, GameObject realPrefab, GameObject parent)
{
if (IsPersistent(parent))
{
Logger.LogWarning($"Cannot replace mock child {child.name} in persistent prefab {parent.name}. " +
$"Clone the prefab before replacing mocks, i.e. with PrefabManager.Instance.CreateClonedPrefab " +
$"or ZoneManager.Instance.CreateLocationContainer for locations");
return;
}

var newObject = Object.Instantiate(realPrefab, parent.transform);
newObject.name = realPrefab.name;
newObject.SetActive(child.gameObject.activeSelf);
newObject.transform.position = child.gameObject.transform.position;
newObject.transform.rotation = child.gameObject.transform.rotation;
newObject.transform.localScale = child.gameObject.transform.localScale;

int siblingIndex = child.GetSiblingIndex();
Object.DestroyImmediate(child.gameObject);
newObject.transform.SetSiblingIndex(siblingIndex);
}

private static bool IsPersistent(GameObject parent) {
return (bool)Object_IsPersistent.Invoke(null, new object[] { parent });
}

private static bool IsMockName(string name, out string assetName, out List<string> childNames)
{
if (name.StartsWith(JVLMockPrefix, StringComparison.Ordinal))
Expand Down

0 comments on commit 340a1ab

Please sign in to comment.