diff --git a/WurstMod/Exporter.cs b/WurstMod/Exporter.cs index 1fe8c88..dd1220d 100644 --- a/WurstMod/Exporter.cs +++ b/WurstMod/Exporter.cs @@ -35,6 +35,9 @@ public static void ExportBundle() if (!choice) return; } + // Pre-save, grab the skybox. + levelComponent.skybox = RenderSettings.skybox; + if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) { // Setup build options. @@ -110,10 +113,13 @@ public static string Validate(Scene scene, List warnings) return "You must have at least two Hold Points."; } // Hold points must have at least 9 defenders spawnpoints. + // NavBlockers must be disabled. foreach (TNH.TNH_HoldPoint hold in holds) { if (hold.SpawnPoints_Sosigs_Defense.AsEnumerable().Count() < 9) return "All holds must have at least 9 entries in SpawnPoints_Sosigs_Defense."; + if (hold.NavBlockers.activeSelf) + return "All NavBlockers must be disabled before exporting."; } // UNVERIFIED Must have at least 3 Supply Points. diff --git a/WurstMod/Extensions.cs b/WurstMod/Extensions.cs index ed8c48c..3174e99 100644 --- a/WurstMod/Extensions.cs +++ b/WurstMod/Extensions.cs @@ -30,23 +30,70 @@ public static IEnumerable AsEnumerable(this Transform transform) #endregion #region Reflection - // Reflection shortcuts. + // Reflection shortcuts with caching. A smidge less verbose than InvokeMember. + // Currently doesn't work for overloaded methods. + // Cross that bridge when we come to it, I guess. + private struct ReflectDef + { + public Type type; + public string name; + public ReflectDef(Type type, string name) + { + this.type = type; + this.name = name; + } + } + private static Dictionary methodCache = new Dictionary(); + private static Dictionary fieldCache = new Dictionary(); public static object ReflectInvoke(this T target, string methodName, params object[] parameters) where T : UnityEngine.Object { - MethodInfo method = target.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); + MethodInfo method; + ReflectDef def = new ReflectDef(target.GetType(), methodName); + if (methodCache.ContainsKey(def)) + { + method = methodCache[def]; + } + else + { + method = target.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); + methodCache[def] = method; + } + return method.Invoke(target, parameters); } public static object ReflectGet(this T target, string fieldName) where T : UnityEngine.Object { - FieldInfo field = target.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + FieldInfo field; + ReflectDef def = new ReflectDef(target.GetType(), fieldName); + if (fieldCache.ContainsKey(def)) + { + field = fieldCache[def]; + } + else + { + field = target.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + fieldCache[def] = field; + } + return field.GetValue(target); } public static void ReflectSet(this T target, string fieldName, object value) where T : UnityEngine.Object { - FieldInfo field = target.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + FieldInfo field; + ReflectDef def = new ReflectDef(target.GetType(), fieldName); + if (fieldCache.ContainsKey(def)) + { + field = fieldCache[def]; + } + else + { + field = target.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + fieldCache[def] = field; + } + field.SetValue(target, value); } @@ -66,6 +113,11 @@ public static List GetAllGameObjectsInScene(this Scene scene) } return allGameObjects; } + + public static void RefreshShader(this Material mat) + { + mat.shader = Shader.Find(mat.shader.name); + } #endregion #region Gizmos diff --git a/WurstMod/LevelSelector.cs b/WurstMod/LevelSelector.cs index d36384e..4571f72 100644 --- a/WurstMod/LevelSelector.cs +++ b/WurstMod/LevelSelector.cs @@ -44,6 +44,7 @@ public static void SetupLevelSelector(Scene loaded) currentLevelIndex = 0; GatherReferences(); InitDirectories(); + FixLevelNameSize(); SetupLevelDatas(); SetupButtons(); @@ -79,12 +80,20 @@ private static void InitDirectories() } } + private static void FixLevelNameSize() + { + RectTransform levelNameRect = levelNameText.transform as RectTransform; + levelNameRect.sizeDelta = new Vector2(860, 80); + } + /// /// Create our own LevelData objects for the original level, and all loaded levels. /// private static void SetupLevelDatas() { - levels.Add(new LevelData(levelImage.sprite, levelNameText.text, "H3VR", levelDescriptionText.text, "")); + levels.Add(new LevelData(levelImage.sprite, "Classic", "H3VR", levelDescriptionText.text, "")); + //TODO TEST THIS Update information of original level for consistency with new format. + levels[0].SetLevel(); foreach(string ii in Directory.GetDirectories(levelDir)) { diff --git a/WurstMod/Loader.cs b/WurstMod/Loader.cs index 9189853..1d75ec6 100644 --- a/WurstMod/Loader.cs +++ b/WurstMod/Loader.cs @@ -142,7 +142,6 @@ private static void SetWhitelistedStates(bool state) static FistVR.AudioEvent success; static FistVR.AudioEvent failure; static GameObject vfx; - static Shader shader; static GameObject[] barrierPrefabs = new GameObject[2]; /// /// A wide variety of existing objects are needed for importing a new TNH scene. @@ -174,11 +173,6 @@ private static void CollectRequiredObjects() // We need VFX_HoldWave prefab. vfx = sourceHoldPoint.VFX_HoldWave; - // We need the correct shader for hotswapping. - //TODO this is terrible, but I can't fix the right eye bug... - MeshRenderer mr = currentScene.GetAllGameObjectsInScene().Where(x => x.name == "SciHalls_Support_A").First().GetComponent(); - shader = mr.materials[0].shader; - // We need barrier prefabs. FistVR.TNH_DestructibleBarrierPoint barrier = currentScene.GetAllGameObjectsInScene().Where(x => x.name == "Barrier_SpawnPoint").First().GetComponent(); barrierPrefabs[0] = barrier.BarrierDataSets[0].BarrierPrefab; @@ -243,6 +237,7 @@ private static IEnumerator MergeInScene() /// private static void ResolveAll() { + Resolve_Skybox(); Resolve_Shaders(); Resolve_PMats(); Resolve_FVRReverbEnvironments(); @@ -258,10 +253,25 @@ private static void ResolveAll() #region Resolves /// - /// Steal a properly-formatted shader from an existing object. - /// This is required because using any other shader seems to break VR (at least in one eye). - /// I'm not sure what the deal is with this. I'm sure there's a solution, but for now - /// everything is going to have to have a simple shader. + /// Use the skybox of the imported level. + /// Requires GI Update to fix lighting. + /// + private static void Resolve_Skybox() + { + TNH.TNH_Level levelComponent = loadedRoot.GetComponent(); + if (levelComponent.skybox != null) + { + RenderSettings.skybox = levelComponent.skybox; + RenderSettings.skybox.RefreshShader(); + DynamicGI.UpdateEnvironment(); + } + } + + + /// + /// Shaders, when imported from an assetbundle, become garbage. + /// Set them to themselves and bam, it works. + /// Unity 5 bugs sure were something. /// private static void Resolve_Shaders() { @@ -269,7 +279,7 @@ private static void Resolve_Shaders() { foreach (Material jj in ii.materials) { - jj.shader = shader; + jj.RefreshShader(); } } } @@ -328,7 +338,6 @@ private static void Resolve_FVRHandGrabPoints() Collider proxyCol = proxy.GetComponent(); Vector3 extents = proxyCol.bounds.extents; real.EndInteractionDistance = 2.5f * Mathf.Abs(Mathf.Max(extents.x, extents.y, extents.z)); - Debug.Log("INTERACTION DISTANCE: " + real.EndInteractionDistance); } } diff --git a/WurstMod/Patches.cs b/WurstMod/Patches.cs index 03f867d..280ed97 100644 --- a/WurstMod/Patches.cs +++ b/WurstMod/Patches.cs @@ -74,7 +74,6 @@ static bool Prefix(Sosig __instance) // Force fields on the fake link to match the type of jump. Vector3 jump = __instance.Agent.currentOffMeshLinkData.endPos - __instance.Agent.currentOffMeshLinkData.startPos; - float totalMag = jump.magnitude; float horzMag = new Vector3(jump.x, 0, jump.z).magnitude; float vertMag = Mathf.Abs(jump.y); bool jumpDown = jump.y < 0; @@ -83,11 +82,8 @@ static bool Prefix(Sosig __instance) else if (jumpDown && vertMag > (2 * horzMag)) fakeLink.Type = NavMeshLinkExtension.NavMeshLinkType.Drop; else fakeLink.Type = NavMeshLinkExtension.NavMeshLinkType.LateralJump; - // TODO These numbers may require more tweaking. - if (fakeLink.Type == NavMeshLinkExtension.NavMeshLinkType.Climb) fakeLink.TimeToClear = 40f; - else fakeLink.TimeToClear = 40f; - - fakeLink.ReflectSet("m_xySpeed", totalMag / fakeLink.TimeToClear); + // Arbitrary number. + fakeLink.ReflectSet("m_xySpeed", 0.5f); // Clean up the dictionary. Keep an eye on the counts for this... diff --git a/WurstMod/TNH/TNH_Level.cs b/WurstMod/TNH/TNH_Level.cs index 6149dba..a25b715 100644 --- a/WurstMod/TNH/TNH_Level.cs +++ b/WurstMod/TNH/TNH_Level.cs @@ -14,5 +14,7 @@ public class TNH_Level : MonoBehaviour [TextArea(15, 20)] public string levelDescription; + + public Material skybox; } } diff --git a/WurstModWorkbench.unitypackage b/WurstModWorkbench.unitypackage index 12d7872..161aa28 100644 Binary files a/WurstModWorkbench.unitypackage and b/WurstModWorkbench.unitypackage differ