public static bool Prefix(SubFire __instance, SubFire.RoomFire startInRoom, out bool __state) { __state = NitroxServiceLocator.LocateService <SimulationOwnership>().HasAnyLockType(NitroxIdentifier.GetId(__instance.subRoot.gameObject)); // Block any new fires if this player is not the owner return(__state); }
public static void Postfix(ref SubFire __instance, ref bool __result, float chance) { float fire; if (Config.NO_WAY.Equals(DeathRun.config.damageTaken2)) { fire = .5f; } else if (Config.INSANITY.Equals(DeathRun.config.damageTaken2)) { fire = .25f; } else if (Config.HARDCORE.Equals(DeathRun.config.damageTaken2)) { fire = .125f; } else if (Config.LOVETAPS.Equals(DeathRun.config.damageTaken2)) { fire = .0625f; } else { return; } if (chance != 2) { fire /= 2; } if (!__result && UnityEngine.Random.value < fire) { __result = true; } }
// Remake of the StartSystem Coroutine from original player. Some Methods are not used from the original coroutine // For example no temporaryClose as this will be initiated anyway from the originating Player // Also the fire extiguishing will not start cause the initial player is already extiguishing the fires. Else this could double/triple/... the extinguishing private IEnumerator StartFireSuppressionSystem(SubFire fire) { fire.subRoot.voiceNotificationManager.PlayVoiceNotification(fire.subRoot.fireSupressionNotification, false, true); yield return(new WaitForSeconds(3f)); fire.ReflectionSet("fireSuppressionActive", true); fire.subRoot.fireSuppressionState = true; fire.subRoot.BroadcastMessage("NewAlarmState", null, SendMessageOptions.DontRequireReceiver); fire.Invoke("CancelFireSuppression", fire.fireSuppressionSystemDuration); float doorCloseDuration = 30f; fire.gameObject.BroadcastMessage("TemporaryLock", doorCloseDuration, SendMessageOptions.DontRequireReceiver); yield break; }
/// <summary> /// Add/remove fires until it matches the <paramref name="roomFires"/> array. Can trigger <see cref="FireDoused"/> packets /// </summary> private void SetActiveRoomFires(SubRoot subRoot, CyclopsFireData[] roomFires) { SubFire subFire = subRoot.gameObject.RequireComponent <SubFire>(); Dictionary <CyclopsRooms, SubFire.RoomFire> roomFiresDict = (Dictionary <CyclopsRooms, SubFire.RoomFire>)subFire.ReflectionGet("roomFires"); string subRootGuid = GuidHelper.GetGuid(subRoot.gameObject); CyclopsFireData fireNode = null; if (roomFires != null && roomFires.Length > 0) { // Removing and adding fires will happen in the same loop foreach (KeyValuePair <CyclopsRooms, SubFire.RoomFire> keyValuePair in roomFiresDict) { for (int nodeIndex = 0; nodeIndex < keyValuePair.Value.spawnNodes.Length; nodeIndex++) { fireNode = roomFires.SingleOrDefault(x => x.Room == keyValuePair.Key && x.NodeIndex == nodeIndex); // If there's a matching node index, add a fire if there isn't one already. Otherwise remove a fire if there is one if (fireNode == null) { if (keyValuePair.Value.spawnNodes[nodeIndex].childCount > 0) { keyValuePair.Value.spawnNodes[nodeIndex].GetComponentInChildren <Fire>().Douse(10000); } } else { if (keyValuePair.Value.spawnNodes[nodeIndex].childCount < 1) { fires.Create(new CyclopsFireData(fireNode.FireGuid, subRootGuid, fireNode.Room, fireNode.NodeIndex)); } } } } } // Clear out the fires, there should be none active else { foreach (KeyValuePair <CyclopsRooms, SubFire.RoomFire> keyValuePair in roomFiresDict) { for (int nodeIndex = 0; nodeIndex < keyValuePair.Value.spawnNodes.Length; nodeIndex++) { if (keyValuePair.Value.spawnNodes[nodeIndex].childCount > 0) { keyValuePair.Value.spawnNodes[nodeIndex].GetComponentInChildren <Fire>().Douse(10000); } } } } }
} //EDNE private static void EngineOverheatSimulation_Patch private static void EngineOverheatSimulation(SubFire __instance, MethodBase __originalMethod) { /* * if (__instance.subControl.cyclopsMotorMode.cyclopsMotorMode == CyclopsMotorMode.CyclopsMotorModes.Flank) * { * QModServices.Main.AddCriticalMessage("Flank aktiviert"); * } * else if (__instance.subControl.cyclopsMotorMode.cyclopsMotorMode == CyclopsMotorMode.CyclopsMotorModes.Standard) * { * QModServices.Main.AddCriticalMessage("standart aktiviert"); * } * else if (__instance.subControl.cyclopsMotorMode.cyclopsMotorMode == CyclopsMotorMode.CyclopsMotorModes.Slow) * { * QModServices.Main.AddCriticalMessage("Slow aktiviert"); * } * else * { * QModServices.Main.AddCriticalMessage("geschwindigkeit gescheitert"); * } * //------------------------------------------------------------------------- * if (__instance.subControl.appliedThrottle == true) * { * QModServices.Main.AddCriticalMessage("Throttle true"); * } * else if(__instance.subControl.appliedThrottle == false) * { * QModServices.Main.AddCriticalMessage("Throttle false"); * } * else * { * QModServices.Main.AddCriticalMessage("Throttle Error"); * } * //------------------------------------------------------------------------- * if (__instance.cyclopsMotorMode.engineOn == true) * { * QModServices.Main.AddCriticalMessage("EngineOn"); * } * else if (__instance.cyclopsMotorMode.engineOn == false) * { * QModServices.Main.AddCriticalMessage("EngineOff"); * } * else * { * QModServices.Main.AddCriticalMessage("Engine Error"); * } */ }
/// <summary> /// Get all of the index locations of all the fires on the <see cref="SubRoot"/>. <see cref="SubFire.RoomFire.spawnNodes"/> contains /// a static list of all possible fire nodes. /// </summary> private IEnumerable <CyclopsFireData> GetActiveRoomFires(SubFire subFire) { string subRootGuid = GuidHelper.GetGuid(subFire.subRoot.gameObject); Dictionary <CyclopsRooms, SubFire.RoomFire> roomFires = (Dictionary <CyclopsRooms, SubFire.RoomFire>)subFire.ReflectionGet("roomFires"); foreach (KeyValuePair <CyclopsRooms, SubFire.RoomFire> roomFire in roomFires) { for (int i = 0; i < roomFire.Value.spawnNodes.Length; i++) { if (roomFire.Value.spawnNodes[i].childCount > 0) { yield return(new CyclopsFireData(GuidHelper.GetGuid(roomFire.Value.spawnNodes[i].GetComponentInChildren <Fire>().gameObject), subRootGuid, roomFire.Key, i)); } } } }
/// <summary> /// Get all of the index locations of all the fires on the <see cref="SubRoot"/>. <see cref="SubFire.RoomFire.spawnNodes"/> contains /// a static list of all possible fire nodes. /// </summary> private IEnumerable <CyclopsFireData> GetActiveRoomFires(SubFire subFire) { NitroxId subRootId = NitroxEntity.GetId(subFire.subRoot.gameObject); Dictionary <CyclopsRooms, SubFire.RoomFire> roomFires = subFire.roomFires; foreach (KeyValuePair <CyclopsRooms, SubFire.RoomFire> roomFire in roomFires) { for (int i = 0; i < roomFire.Value.spawnNodes.Length; i++) { if (roomFire.Value.spawnNodes[i].childCount > 0) { yield return(new CyclopsFireData(NitroxEntity.GetId(roomFire.Value.spawnNodes[i].GetComponentInChildren <Fire>().gameObject), subRootId, roomFire.Key, i)); } } } }
public static void Postfix(SubFire __instance, SubFire.RoomFire startInRoom, bool __state) { // Spent way too much time trying to get around a bug in dnspy that doesn't allow me to propery edit this method, so I'm going with the hacky solution. // Every time a Fire is created, the whole list of SubFire.availableNodes is cleared, then populated with any transforms that have 0 childCount. // Next, it chooses a random index, then spawns a fire in that node. // We can easily find where it is because it'll be the only Transform in SubFire.availableNodes with a childCount > 0 if (__state) { Fires fires = NitroxServiceLocator.LocateService <Fires>(); foreach (Transform transform in __instance.availableNodes) { if (transform.childCount > 0) { int nodeIndex = Array.IndexOf(__instance.roomFires[startInRoom.roomLinks.room].spawnNodes, transform); Fire fire = transform.GetComponentInChildren <Fire>(); fires.OnCreate(fire, startInRoom, nodeIndex); return; } } } }
/// <summary> /// Create a new <see cref="Fire"/>. Majority of code copied from <see cref="SubFire.CreateFire(SubFire.RoomFire)"/>. Currently does not support Fires created outside of a Cyclops /// </summary> /// <param name="fireGuid">Guid of the Fire. Used for identification when dousing the fire</param> /// <param name="subRootGuid">Guid of the Cyclops <see cref="SubRoot"/></param> /// <param name="room">The room the Fire will be spawned in</param> /// <param name="spawnNodeIndex">Each <see cref="CyclopsRooms"/> has multiple static Fire spawn points called spawnNodes. If the wrong index is provided, /// the clients will see fires in different places from the owner</param> public void Create(CyclopsFireData fireData) { SubFire subFire = GuidHelper.RequireObjectFrom(fireData.CyclopsGuid).GetComponent <SubRoot>().damageManager.subFire; Dictionary <CyclopsRooms, SubFire.RoomFire> roomFiresDict = (Dictionary <CyclopsRooms, SubFire.RoomFire>)subFire.ReflectionGet("roomFires"); // Copied from SubFire_CreateFire_Patch, which copies from SubFire.CreateFire() Transform transform2 = roomFiresDict[fireData.Room].spawnNodes[fireData.NodeIndex]; // If a fire already exists at the node, replace the old Guid with the new one if (transform2.childCount > 0) { Fire existingFire = transform2.GetComponentInChildren <Fire>(); if (GuidHelper.GetGuid(existingFire.gameObject) != fireData.CyclopsGuid) { Log.Error("[Fires.Create Fire already exists at node index " + fireData.NodeIndex + "! Replacing existing Fire Guid " + GuidHelper.GetGuid(existingFire.gameObject) + " with Guid " + fireData.CyclopsGuid + "]"); GuidHelper.SetNewGuid(existingFire.gameObject, fireData.CyclopsGuid); } return; } List <Transform> availableNodes = (List <Transform>)subFire.ReflectionGet("availableNodes"); availableNodes.Clear(); foreach (Transform transform in roomFiresDict[fireData.Room].spawnNodes) { if (transform.childCount == 0) { availableNodes.Add(transform); } } roomFiresDict[fireData.Room].fireValue++; PrefabSpawn component = transform2.GetComponent <PrefabSpawn>(); if (component == null) { return; } else { Log.Error("[FireCreatedProcessor Cannot create new Cyclops fire! PrefabSpawn component could not be found in fire node!" + " Fire Guid: " + fireData.FireGuid + " SubRoot Guid: " + fireData.CyclopsGuid + " Room: " + fireData.Room + " NodeIndex: " + fireData.NodeIndex + "]"); } GameObject gameObject = component.SpawnManual(); Fire componentInChildren = gameObject.GetComponentInChildren <Fire>(); if (componentInChildren) { componentInChildren.fireSubRoot = subFire.subRoot; GuidHelper.SetNewGuid(componentInChildren.gameObject, fireData.FireGuid); } subFire.ReflectionSet("roomFires", roomFiresDict); subFire.ReflectionSet("availableNodes", availableNodes); }
private static bool PreFix(SubFire __instance) { //EngineOverheatSimulation(__instance, __originalMethod); EngineOverheatSimulation_Patch(__instance); return(false); }
//If somebody ask..... //yes i am very bad at algorithm, math and shit..... private static void EngineOverheatSimulation_Patch(SubFire __instance) { CEO.Load(); if (!__instance.LOD.IsFull()) { return; } if (CEO.CyclopsHeat_generalmechanism) { //--- Startup ---------------------------------------- int makeitbigger = 3; int Warning_first = CEO.CyclopsHeat_aftertik_first * makeitbigger; int Warning_second = CEO.CyclopsHeat_aftertik_second * makeitbigger; int Warning_third = CEO.CyclopsHeat_aftertik_third * makeitbigger; int dmgchance_first = CEO.CyclopsHeat_dmgchance_first; int dmgchance_second = CEO.CyclopsHeat_dmgchance_second; int dmgchance_third = CEO.CyclopsHeat_dmgchance_third; int maxheatlimit = CEO.CyclopsHeat_TempMaxHeat * makeitbigger; int heatincreasepertik = 1 * makeitbigger; int cooling = 1 * makeitbigger; int lowspeedheat = 1; int lowspeedmax = CEO.CyclopsHeat_dmgchance_first - 1; float watertemp_float = WaterTemperatureSimulation.main.GetTemperature(__instance.subRoot.transform.position); int watertemp = (int)Math.Round(watertemp_float); //--- heating ---------------------------------------- if (watertemp > CEO.CyclopsHeat_coolingrefertemp && CEO.CyclopsHeat_fastcooling == true) { heatincreasepertik = +2; } if (watertemp < CEO.CyclopsHeat_heatingrefertemp && CEO.CyclopsHeat_slowheat == true) { heatincreasepertik--; } if (__instance.subControl.cyclopsMotorMode.cyclopsMotorMode == CyclopsMotorMode.CyclopsMotorModes.Flank && __instance.subControl.appliedThrottle && __instance.cyclopsMotorMode.engineOn) { __instance.engineOverheatValue = Mathf.Min(__instance.engineOverheatValue + heatincreasepertik, maxheatlimit); int num = 0; if (__instance.engineOverheatValue > Warning_third && CEO.CyclopsHeat_createthirdchance == true) { num = UnityEngine.Random.Range(1, dmgchance_third); if (CEO.CyclopsHeat_warning_third) { __instance.subRoot.voiceNotificationManager.PlayVoiceNotification(__instance.subRoot.engineOverheatCriticalNotification, true, false); } } else if (__instance.engineOverheatValue > Warning_second) { if (CEO.CyclopsHeat_damagesecond) { num = UnityEngine.Random.Range(1, dmgchance_second); } if (CEO.CyclopsHeat_mainwarning) { __instance.subRoot.voiceNotificationManager.PlayVoiceNotification(__instance.subRoot.engineOverheatCriticalNotification, true, false); } } else if (__instance.engineOverheatValue > Warning_first) { if (CEO.CyclopsHeat_damagefirst) { num = UnityEngine.Random.Range(1, dmgchance_first); } if (CEO.CyclopsHeat_prewarning) { __instance.subRoot.voiceNotificationManager.PlayVoiceNotification(__instance.subRoot.engineOverheatNotification, true, false); } } if ((num == 1 && CEO.CyclopsHeat_randomevent_disable == false) | (CEO.CyclopsHeat_randomevent_disable == true && __instance.engineOverheatValue > Warning_third)) { if (CEO.CyclopsHeat_FireonOverheat) { __instance.CreateFire(__instance.roomFires[CyclopsRooms.EngineRoom]); } return; } } else { if (CEO.CyclopsHeat_standardspeedheating && __instance.subControl.cyclopsMotorMode.cyclopsMotorMode == CyclopsMotorMode.CyclopsMotorModes.Standard && __instance.subControl.appliedThrottle && __instance.cyclopsMotorMode.engineOn) { if (__instance.engineOverheatValue < lowspeedmax) { __instance.engineOverheatValue = +lowspeedheat; } } if (watertemp < CEO.CyclopsHeat_heatingrefertemp && CEO.CyclopsHeat_fastheat == true) { cooling = +2; } if (watertemp > CEO.CyclopsHeat_coolingrefertemp && CEO.CyclopsHeat_slowheat == true) { cooling--; } if (CEO.CyclopsHeat_coolingrecover_double) { cooling = cooling * 2; } if (__instance.subControl.cyclopsMotorMode.cyclopsMotorMode == CyclopsMotorMode.CyclopsMotorModes.Flank) { __instance.engineOverheatValue = Mathf.Max(1, __instance.engineOverheatValue - cooling); return; } __instance.engineOverheatValue = Mathf.Max(0, __instance.engineOverheatValue - cooling); } } } //EDNE private static void EngineOverheatSimulation_Patch
private void DrawCyclopsDebugMenu() { if (GUILayout.Button("Destroy Cyclops static mesh")) { Ray ray4 = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray4, out RaycastHit raycastHit4)) { if (raycastHit4.rigidbody.gameObject.name.ToLower().Contains("cyclops")) { Transform transform = raycastHit4.rigidbody.gameObject.transform.Find("CyclopsMeshStatic"); Log.Print("Size 1: " + transform.GetComponentInChildren <MeshFilter>().mesh.triangles.Length); Log.Print("Size 2: " + transform.GetComponentInChildren <MeshFilter>().mesh.vertices.Length); Destroy(transform.gameObject); } } } if (GUILayout.Button("Cyclops Engine RPM SFX Manager")) { Ray ray4 = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray4, out RaycastHit raycastHit4)) { if (raycastHit4.rigidbody.gameObject.name.ToLower().Contains("cyclops")) { EngineRpmSFXManager engine = raycastHit4.rigidbody.GetComponentInChildren <EngineRpmSFXManager>(); if (engine == null) { Utilities.Log.Print("EngineRpmSFXManager not found"); return; } Log.Print("engineRpmSFX: " + engine.engineRpmSFX?.asset?.path); Log.Print("stopSoundInterval: " + engine.engineRpmSFX?.stopSoundInterval); Log.Print("engineRevUp: " + engine.engineRevUp?.asset?.path); Log.Print("rampUpSpeed: " + engine.rampUpSpeed); Log.Print("rampDownSpeed: " + engine.rampDownSpeed); } } } if (GUILayout.Button("Cyclops render materials")) { Ray ray4 = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray4, out RaycastHit raycastHit4)) { if (raycastHit4.rigidbody.gameObject.name.ToLower().Contains("cyclops")) { //Transform gggg1 = raycastHit4.rigidbody.gameObject.transform.Find("CyclopsMeshStatic").transform.Find("undamaged").Find("cyclops_LOD0").Find("cyclops_submarine_exterior"); Transform gggg1 = raycastHit4.rigidbody.gameObject.transform.Find("CyclopsMeshStatic").transform.Find("undamaged").Find("cyclops_LOD0").Find("Cyclops_submarine_exterior_glass"); //Transform gggg1 = raycastHit4.rigidbody.gameObject.transform.Find("CyclopsMeshStatic").transform.Find("undamaged").Find("cyclops_LOD0").Find("cyclops_submarine_exterior_decals"); //Transform gggg1 = raycastHit4.rigidbody.gameObject.transform.Find("CyclopsMeshStatic").transform.Find("undamaged").Find("cyclops_LOD0"); /*foreach (MeshRenderer mr in gggg1.gameObject.GetComponentsInChildren<MeshRenderer>()) * { * Utilities.Log.Print("Gameobject: " + mr.gameObject.name); * foreach (Material mat2 in mr.materials) * { * Utilities.Log.Print("Material: " + mat2.name); * Utilities.Log.Print("keywords: " + mat2.shaderKeywords.Length); * foreach(var s in mat2.shaderKeywords) * { * Utilities.Log.Print("Keyword: " + s); * } * Utilities.Log.Print("-"); * } * Utilities.Log.Print("--"); * }*/ Log.Print("Materials count: " + gggg1.GetComponent <MeshRenderer>().materials.Length); Material mat = gggg1.GetComponent <MeshRenderer>().material; mat.PrintAllMarmosetUBERShaderProperties(); } } } if (GUILayout.Button("Cyclops Oxygen Manager")) { Ray ray4 = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray4, out RaycastHit raycastHit4)) { if (raycastHit4.rigidbody.gameObject.name.ToLower().Contains("cyclops")) { OxygenManager[] oxygenManager = raycastHit4.rigidbody.GetComponentsInChildren <OxygenManager>(); Log.Print("Oxygen Manager Found Count " + oxygenManager.Length); } } } if (GUILayout.Button("Cyclops Depth Cleaer")) { Ray ray4 = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray4, out RaycastHit raycastHit4)) { if (raycastHit4.rigidbody.gameObject.name.ToLower().Contains("cyclops")) { SubRoot subRoot = raycastHit4.rigidbody.GetComponent <SubRoot>(); MeshRenderer mr = subRoot.depthClearer as MeshRenderer; Log.Print("DepthClearer type: " + subRoot.depthClearer.GetType()); Log.Print("DepthClearer name: " + subRoot.depthClearer.name); Log.Print("DepthClearer material: " + subRoot.depthClearer.material); Log.Print("DepthClearer mesh: " + subRoot.depthClearer.GetComponent <MeshFilter>().mesh); Log.Print("DepthClearer mesh name: " + subRoot.depthClearer.GetComponent <MeshFilter>().mesh.name); Log.Print("DepthClearer Children count: " + subRoot.depthClearer.transform.childCount); Log.Print("DepthClearer transform pos: " + subRoot.depthClearer.transform.localPosition); Log.Print("DepthClearer transform size: " + subRoot.depthClearer.transform.localScale); Log.Print("DepthClearer transform Parent: " + subRoot.depthClearer.transform.parent?.name); subRoot.depthClearer.material.color = new Color(1f, 0f, 0f, 1f); Log.Print("DepthClearer mat color: " + subRoot.depthClearer.material.color); Log.Print("DepthClearer enabled?: " + subRoot.depthClearer.enabled); Log.Print("DepthClearer Component cound: " + subRoot.depthClearer.GetComponents(typeof(Component)).Length); foreach (Component c in subRoot.depthClearer.GetComponents(typeof(Component))) { Utilities.Log.Print("Component: " + c); } } } } if (GUILayout.Button("Cyclops Ladder")) { Ray ray4 = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray4, out RaycastHit raycastHit4)) { if (raycastHit4.rigidbody.gameObject.name.ToLower().Contains("cyclops")) { Utilities.Log.Print(raycastHit4.rigidbody.gameObject.name); foreach (SkinnedMeshRenderer smr in raycastHit4.rigidbody.gameObject.GetComponentsInChildren <SkinnedMeshRenderer>()) { if (smr.gameObject.name.ToLower().Equals("submarine_ladder_04") || smr.gameObject.name.ToLower().Equals("cyclops_ladder_long") || smr.gameObject.name.ToLower().Equals("cyclops_ladder_short_right") || smr.gameObject.name.ToLower().Equals("cyclops_ladder_short_left") || smr.gameObject.name.ToLower().Equals("submarine_ladder_02")) { Utilities.Log.Print("Mesh: " + smr.gameObject.GetComponent <SkinnedMeshRenderer>()?.sharedMesh?.name); Utilities.Log.Print("Bones Length: " + smr.gameObject.GetComponent <SkinnedMeshRenderer>()?.bones?.Length); smr.gameObject.GetComponent <SkinnedMeshRenderer>()?.material?.PrintAllMarmosetUBERShaderProperties(); } } } } } if (GUILayout.Button("Cyclops Force Damage Point")) { Ray ray4 = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray4, out RaycastHit raycastHit4)) { if (raycastHit4.rigidbody.gameObject.name.ToLower().Contains("cyclops")) { CyclopsExternalDamageManager damage = raycastHit4.rigidbody.GetComponentInChildren <CyclopsExternalDamageManager>(); if (damage == null) { Log.Print("CyclopsExternalDamageManager not found"); return; } MethodInfo mi = SMLHelper.V2.Utility.ReflectionHelper.GetInstanceMethod(damage, "CreatePoint"); if (mi == null) { Log.Print("CreatePoint method not found"); return; } mi.FastInvoke(damage); } } } if (GUILayout.Button("Cyclops Print Damage Info")) { Ray ray4 = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray4, out RaycastHit raycastHit4)) { if (raycastHit4.rigidbody.gameObject.name.ToLower().Contains("cyclops")) { CyclopsExternalDamageManager damage = raycastHit4.rigidbody.GetComponentInChildren <CyclopsExternalDamageManager>(); if (damage == null) { Log.Print("CyclopsExternalDamageManager not found"); return; } CyclopsDamagePoint[] damagePoints = raycastHit4.rigidbody.gameObject.GetComponentsInChildren <CyclopsDamagePoint>(); foreach (var dp in damagePoints) { dp.gameObject.GetComponentInChildren <LiveMixin>().PrintAllLiveMixinDetails(); Log.Print(" "); } } } } if (GUILayout.Button("Subfire information.")) { Ray ray4 = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray4, out RaycastHit raycastHit4)) { if (raycastHit4.rigidbody.gameObject.name.ToLower().Contains("cyclops")) { SubFire subFire = raycastHit4.rigidbody.GetComponentInChildren <SubFire>(); if (subFire == null) { Log.Print("Cyclop's subfire not found."); return; } Utilities.Log.Print("Fire prefab: " + subFire.firePrefab); } } } }