diff --git a/.gitignore b/.gitignore
index 662c08252..00057fb13 100644
--- a/.gitignore
+++ b/.gitignore
@@ -77,4 +77,6 @@ crashlytics-build.properties
# Temporary auto-generated Android Assets
/[Aa]ssets/[Ss]treamingAssets/aa.meta
-/[Aa]ssets/[Ss]treamingAssets/aa/*
\ No newline at end of file
+/[Aa]ssets/[Ss]treamingAssets/aa/*
+# Standalone build output
+/Latest/
diff --git a/Assets/Compatibility/ImageEffects/UberUnityFallbackImageEffect.cs b/Assets/Compatibility/ImageEffects/UberUnityFallbackImageEffect.cs
new file mode 100644
index 000000000..95cbba0d4
--- /dev/null
+++ b/Assets/Compatibility/ImageEffects/UberUnityFallbackImageEffect.cs
@@ -0,0 +1,91 @@
+using UnityEngine;
+
+[ExecuteInEditMode]
+[RequireComponent(typeof(Camera))]
+[AddComponentMenu("UberUnity/Compatibility/Fallback Image Effect")]
+public class UberUnityFallbackImageEffect : MonoBehaviour
+{
+ [Header("Bloom And Flares")]
+ public int tweakMode;
+ public int screenBlendMode;
+ public bool hdr;
+ public float sepBlurSpread = 2.5f;
+ public int quality;
+ public float bloomIntensity = 0.5f;
+ public float bloomThreshhold = 0.4f;
+ public Color bloomThreshholdColor = Color.white;
+ public int bloomBlurIterations = 2;
+ public int hollywoodFlareBlurIterations = 2;
+ public float flareRotation;
+ public int lensflareMode = 1;
+ public float hollyStretchWidth = 2.5f;
+ public float lensflareIntensity;
+ public float lensflareThreshhold = 0.3f;
+ public float lensFlareSaturation = 0.75f;
+ public Color flareColorA = new Color(0.4f, 0.4f, 0.8f, 0.75f);
+ public Color flareColorB = new Color(0.4f, 0.8f, 0.8f, 0.75f);
+ public Color flareColorC = new Color(0.8f, 0.4f, 0.8f, 0.75f);
+ public Color flareColorD = new Color(0.8f, 0.4f, 0f, 0.75f);
+ public float blurWidth = 1f;
+ public Texture2D lensFlareVignetteMask;
+ public Shader lensFlareShader;
+ public Shader screenBlendShader;
+ public Shader blurAndFlaresShader;
+ public Shader brightPassFilterShader;
+
+ [Header("Color Correction")]
+ public AnimationCurve redChannel = AnimationCurve.Linear(0f, 0f, 1f, 1f);
+ public AnimationCurve greenChannel = AnimationCurve.Linear(0f, 0f, 1f, 1f);
+ public AnimationCurve blueChannel = AnimationCurve.Linear(0f, 0f, 1f, 1f);
+ public bool useDepthCorrection;
+ public AnimationCurve zCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f);
+ public AnimationCurve depthRedChannel = AnimationCurve.Linear(0f, 0f, 1f, 1f);
+ public AnimationCurve depthGreenChannel = AnimationCurve.Linear(0f, 0f, 1f, 1f);
+ public AnimationCurve depthBlueChannel = AnimationCurve.Linear(0f, 0f, 1f, 1f);
+ public float saturation = 1f;
+ public bool selectiveCc;
+ public Color selectiveFromColor = Color.gray;
+ public Color selectiveToColor = Color.gray;
+ public int mode;
+ public bool updateTextures = true;
+ public Shader colorCorrectionCurvesShader;
+ public Shader simpleColorCorrectionCurvesShader;
+ public Shader colorCorrectionSelectiveShader;
+
+ [Header("Sun Shafts")]
+ public int resolution = 1;
+ public Transform sunTransform;
+ public int radialBlurIterations = 1;
+ public Color sunColor = Color.white;
+ public float sunShaftBlurRadius = 2.5f;
+ public float sunShaftIntensity = 1f;
+ public float useSkyBoxAlpha = 0.75f;
+ public float maxRadius = 0.75f;
+ public bool useDepthTexture = true;
+ public Shader sunShaftsShader;
+ public Shader simpleClearShader;
+
+ [Header("Fog")]
+ public int fogMode;
+ public float startDistance = 10f;
+ public float globalDensity = 0.01f;
+ public float heightScale = 1f;
+ public float height;
+ public Color globalFogColor = Color.gray;
+ public Shader fogShader;
+
+ [Header("Contrast")]
+ public float intensity = 0.5f;
+ public float threshhold;
+ public float blurSpread = 1f;
+ public Shader separableBlurShader;
+ public Shader contrastCompositeShader;
+
+ // These scene components came from missing post-processing scripts.
+ // The fallback keeps scenes loadable and simply passes the image through.
+ // NOTE: destination can be null — that means "render to screen" (final effect).
+ private void OnRenderImage(RenderTexture source, RenderTexture destination)
+ {
+ Graphics.Blit(source, destination);
+ }
+}
diff --git a/Assets/Compatibility/ImageEffects/UberUnityFallbackImageEffect.cs.meta b/Assets/Compatibility/ImageEffects/UberUnityFallbackImageEffect.cs.meta
new file mode 100644
index 000000000..6bdfa80a2
--- /dev/null
+++ b/Assets/Compatibility/ImageEffects/UberUnityFallbackImageEffect.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c9d5f92c4e6549e4876a7a8f55ad4b11
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {fileID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Compatibility/ImageEffects/UberUnityFallbackImageEffect.shader b/Assets/Compatibility/ImageEffects/UberUnityFallbackImageEffect.shader
new file mode 100644
index 000000000..103e80062
--- /dev/null
+++ b/Assets/Compatibility/ImageEffects/UberUnityFallbackImageEffect.shader
@@ -0,0 +1,32 @@
+Shader "Hidden/UberUnity/FallbackImageEffect"
+{
+ Properties
+ {
+ _MainTex ("Base (RGB)", 2D) = "white" {}
+ }
+
+ SubShader
+ {
+ Cull Off
+ ZWrite Off
+ ZTest Always
+
+ Pass
+ {
+ CGPROGRAM
+ #pragma vertex vert_img
+ #pragma fragment frag
+ #include "UnityCG.cginc"
+
+ sampler2D _MainTex;
+
+ fixed4 frag(v2f_img i) : SV_Target
+ {
+ return tex2D(_MainTex, i.uv);
+ }
+ ENDCG
+ }
+ }
+
+ Fallback Off
+}
diff --git a/Assets/Compatibility/ImageEffects/UberUnityFallbackImageEffect.shader.meta b/Assets/Compatibility/ImageEffects/UberUnityFallbackImageEffect.shader.meta
new file mode 100644
index 000000000..dd812a1b4
--- /dev/null
+++ b/Assets/Compatibility/ImageEffects/UberUnityFallbackImageEffect.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: f6a1a33524f74984ac8b71f5968b272a
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Editor/MapPopulator.cs b/Assets/Editor/MapPopulator.cs
new file mode 100644
index 000000000..ca6b3e1b5
--- /dev/null
+++ b/Assets/Editor/MapPopulator.cs
@@ -0,0 +1,260 @@
+using UnityEngine;
+using System.Collections.Generic;
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
+
+///
+/// Editor tool: Place spawn points, pickups, and death areas from extracted original data.
+/// Add this to any GameObject in the scene, select the map, and click "Populate Map" in Inspector.
+/// Data is embedded from the UnityPy extraction of the original UberStrike level files.
+///
+public class MapPopulator : MonoBehaviour
+{
+ [Header("Map Selection")]
+ public string mapName = "AqualabResearchHub";
+
+ [Header("Prefab References (assign in Inspector)")]
+ public GameObject spawnPointPrefab;
+ public GameObject healthPickupPrefab;
+ public GameObject armorPickupPrefab;
+ public GameObject ammoPickupPrefab;
+ public GameObject deathAreaPrefab;
+
+ [Header("Options")]
+ public bool placeSpawns = true;
+ public bool placePickups = true;
+ public bool placeDeathAreas = true;
+ public bool clearExistingFirst = false;
+
+ ///
+ /// Call this from an Editor button or context menu to populate the current scene.
+ ///
+ [ContextMenu("Populate Map")]
+ public void PopulateMap()
+ {
+ // The actual data would be loaded from the JSON files at runtime/editor time.
+ // For now, this demonstrates the placement approach.
+ // In practice, use: JsonUtility or Newtonsoft to load {MapName}_v2.json
+ Debug.Log("[MapPopulator] To use: load " + mapName + "_v2.json from UberStrike_Extracted/");
+ Debug.Log("[MapPopulator] Or use the MapPopulatorEditor window for automatic placement.");
+ }
+}
+
+#if UNITY_EDITOR
+///
+/// Editor window that reads the extracted JSON and places objects in the scene.
+/// Window > UberStrike > Map Populator
+///
+public class MapPopulatorEditor : EditorWindow
+{
+ private string jsonFolder = @"C:\Users\Shadow\Downloads\UberStrike_Extracted";
+ private string selectedMap = "AqualabResearchHub";
+ private bool placeSpawns = true;
+ private bool placePickups = true;
+ private bool placeDeathAreas = true;
+ private Vector2 scrollPos;
+
+ private static readonly string[] MAP_NAMES = {
+ "ApexTwin", "AqualabResearchHub", "Catalyst", "CuberSpace", "CuberStrike",
+ "FortWinter", "GhostIsland", "GideonsTower", "MonkeyIsland", "LostParadise2",
+ "SkyGarden", "SuperPRISMReactor", "TempleOfTheRaven", "TheHangar", "TheWarehouse"
+ };
+
+ [MenuItem("Window/UberStrike/Map Populator")]
+ public static void ShowWindow()
+ {
+ GetWindow("Map Populator");
+ }
+
+ void OnGUI()
+ {
+ GUILayout.Label("UberStrike Map Populator", EditorStyles.boldLabel);
+ GUILayout.Space(5);
+
+ jsonFolder = EditorGUILayout.TextField("JSON Folder", jsonFolder);
+
+ GUILayout.Space(5);
+ GUILayout.Label("Select Map:");
+ scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Height(200));
+ foreach (var map in MAP_NAMES)
+ {
+ if (GUILayout.Toggle(selectedMap == map, map, "Button"))
+ selectedMap = map;
+ }
+ EditorGUILayout.EndScrollView();
+
+ GUILayout.Space(10);
+ placeSpawns = EditorGUILayout.Toggle("Place Spawn Points", placeSpawns);
+ placePickups = EditorGUILayout.Toggle("Place Pickups", placePickups);
+ placeDeathAreas = EditorGUILayout.Toggle("Place Death Areas", placeDeathAreas);
+
+ GUILayout.Space(10);
+ if (GUILayout.Button("Populate Scene", GUILayout.Height(30)))
+ {
+ PopulateScene();
+ }
+
+ if (GUILayout.Button("Clear Populated Objects", GUILayout.Height(25)))
+ {
+ ClearPopulated();
+ }
+ }
+
+ void PopulateScene()
+ {
+ string path = System.IO.Path.Combine(jsonFolder, selectedMap + "_v2.json");
+ if (!System.IO.File.Exists(path))
+ {
+ EditorUtility.DisplayDialog("Error", "JSON file not found: " + path, "OK");
+ return;
+ }
+
+ string json = System.IO.File.ReadAllText(path);
+ var data = JsonUtility.FromJson(json);
+
+ // Create parent containers
+ GameObject root = new GameObject("[Populated_" + selectedMap + "]");
+ Undo.RegisterCreatedObjectUndo(root, "Populate Map");
+
+ int count = 0;
+
+ if (placeSpawns)
+ {
+ GameObject spawnRoot = new GameObject("SpawnPoints");
+ spawnRoot.transform.SetParent(root.transform);
+
+ count += PlaceSpawnGroup(data.spawns.DM, "DM", spawnRoot.transform);
+ count += PlaceSpawnGroup(data.spawns.TDM_Red, "TDM_Red", spawnRoot.transform);
+ count += PlaceSpawnGroup(data.spawns.TDM_Blue, "TDM_Blue", spawnRoot.transform);
+ count += PlaceSpawnGroup(data.spawns.TE_Red, "TE_Red", spawnRoot.transform);
+ count += PlaceSpawnGroup(data.spawns.TE_Blue, "TE_Blue", spawnRoot.transform);
+ }
+
+ if (placePickups)
+ {
+ GameObject pickupRoot = new GameObject("Pickups");
+ pickupRoot.transform.SetParent(root.transform);
+
+ foreach (var pickup in data.pickups)
+ {
+ GameObject go = new GameObject(pickup.type + "_" + pickup.name);
+ go.transform.SetParent(pickupRoot.transform);
+ go.transform.position = new Vector3(pickup.position.x, pickup.position.y, pickup.position.z);
+ go.tag = "Powerup";
+ count++;
+ }
+ }
+
+ if (placeDeathAreas)
+ {
+ GameObject deathRoot = new GameObject("DeathAreas");
+ deathRoot.transform.SetParent(root.transform);
+
+ foreach (var da in data.death_areas)
+ {
+ GameObject go = new GameObject("DeathArea_" + da.name);
+ go.transform.SetParent(deathRoot.transform);
+ go.transform.position = new Vector3(da.position.x, da.position.y, da.position.z);
+ // Add a large trigger collider
+ BoxCollider col = go.AddComponent();
+ col.isTrigger = true;
+ col.size = new Vector3(100, 5, 100);
+ count++;
+ }
+ }
+
+ Debug.Log("[MapPopulator] Placed " + count + " objects for " + selectedMap);
+ }
+
+ int PlaceSpawnGroup(List spawns, string groupName, Transform parent)
+ {
+ if (spawns == null || spawns.Count == 0) return 0;
+
+ GameObject group = new GameObject(groupName);
+ group.transform.SetParent(parent);
+
+ foreach (var sp in spawns)
+ {
+ GameObject go = new GameObject(groupName + "_" + sp.name);
+ go.transform.SetParent(group.transform);
+ go.transform.position = new Vector3(sp.position.x, sp.position.y, sp.position.z);
+ go.transform.rotation = new Quaternion(sp.rotation.x, sp.rotation.y, sp.rotation.z, sp.rotation.w);
+ }
+
+ return spawns.Count;
+ }
+
+ void ClearPopulated()
+ {
+ var populated = GameObject.FindObjectsByType(FindObjectsSortMode.None);
+ int removed = 0;
+ foreach (var t in populated)
+ {
+ if (t != null && t.name.StartsWith("[Populated_"))
+ {
+ Undo.DestroyObjectImmediate(t.gameObject);
+ removed++;
+ }
+ }
+ Debug.Log("[MapPopulator] Cleared " + removed + " populated roots");
+ }
+
+ // JSON data classes
+ [System.Serializable]
+ public class MapData
+ {
+ public string map_name;
+ public int level_index;
+ public SpawnData spawns;
+ public List pickups;
+ public List death_areas;
+ public List teleporters;
+ }
+
+ [System.Serializable]
+ public class SpawnData
+ {
+ public List DM;
+ public List TDM_Red;
+ public List TDM_Blue;
+ public List TE_Red;
+ public List TE_Blue;
+ }
+
+ [System.Serializable]
+ public class SpawnEntry
+ {
+ public string name;
+ public Vec3 position;
+ public Vec4 rotation;
+ }
+
+ [System.Serializable]
+ public class PickupEntry
+ {
+ public string name;
+ public string type;
+ public Vec3 position;
+ }
+
+ [System.Serializable]
+ public class PositionEntry
+ {
+ public string name;
+ public Vec3 position;
+ }
+
+ [System.Serializable]
+ public class Vec3
+ {
+ public float x, y, z;
+ }
+
+ [System.Serializable]
+ public class Vec4
+ {
+ public float x, y, z, w;
+ }
+}
+#endif
diff --git a/Assets/Editor/MapPopulator.cs.meta b/Assets/Editor/MapPopulator.cs.meta
new file mode 100644
index 000000000..8b46431be
--- /dev/null
+++ b/Assets/Editor/MapPopulator.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 2a4773a1bff633943879076ac658a8f4
\ No newline at end of file
diff --git a/Assets/Editor/SetupBootstrapScene.cs b/Assets/Editor/SetupBootstrapScene.cs
new file mode 100644
index 000000000..cfe014a8e
--- /dev/null
+++ b/Assets/Editor/SetupBootstrapScene.cs
@@ -0,0 +1,85 @@
+using UnityEngine;
+using UnityEditor;
+using UnityEditor.SceneManagement;
+using UnityEngine.SceneManagement;
+using System.Collections.Generic;
+
+public class SetupBootstrapScene
+{
+ [MenuItem("UberStrike/Create Bootstrap Scene")]
+ public static void CreateBootstrapScene()
+ {
+ // Create a new empty scene
+ var scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
+
+ // 1. Main Camera
+ var cameraGO = new GameObject("Main Camera");
+ cameraGO.tag = "MainCamera";
+ var cam = cameraGO.AddComponent();
+ cam.clearFlags = CameraClearFlags.SolidColor;
+ cam.backgroundColor = Color.black;
+ cameraGO.AddComponent();
+
+ // 2. GlobalSceneLoader — the bootstrap entry point
+ var loaderGO = new GameObject("GlobalSceneLoader");
+ loaderGO.AddComponent();
+
+ // 3. Save the scene
+ string scenePath = "Assets/Scenes/GlobalScene.unity";
+ // Ensure directory exists
+ if (!System.IO.Directory.Exists("Assets/Scenes"))
+ System.IO.Directory.CreateDirectory("Assets/Scenes");
+
+ EditorSceneManager.SaveScene(scene, scenePath);
+ Debug.Log("Bootstrap scene created at: " + scenePath);
+
+ // 4. Update Build Settings — put GlobalScene first
+ UpdateBuildSettings(scenePath);
+
+ Debug.Log("Build settings updated. GlobalScene is now Scene 0.");
+ Debug.Log("Press Play to test authentication with HaZard's server!");
+ }
+
+ static void UpdateBuildSettings(string bootstrapScenePath)
+ {
+ var scenes = new List();
+
+ // Scene 0: Bootstrap (GlobalScene)
+ scenes.Add(new EditorBuildSettingsScene(bootstrapScenePath, true));
+
+ // Scene 1: MainMenu
+ scenes.Add(new EditorBuildSettingsScene("Assets/Menus/MainMenu.unity", true));
+
+ // Scene 2: Intro (optional, can skip to MainMenu)
+ scenes.Add(new EditorBuildSettingsScene("Assets/Menus/Intro.unity", true));
+
+ // Add all map scenes
+ string[] mapScenes = new string[]
+ {
+ "Assets/Maps/Apex_Twin/Apex_Twin.unity",
+ "Assets/Maps/Catalyst/Catalyst.unity",
+ "Assets/Maps/Cuberspace/Cuberspace.unity",
+ "Assets/Maps/Danger_Zone/Danger_Zone.unity",
+ "Assets/Maps/Fort_Winter/Fort_Winter.unity",
+ "Assets/Maps/Gideons_Tower_II/Gideons_Tower_II.unity",
+ "Assets/Maps/Lost_Paradise_II/Lost_Paradise_2.unity",
+ "Assets/Maps/Monkey_Island/Monkey_Island.unity",
+ "Assets/Maps/Research_Hub/Research_Hub.unity",
+ "Assets/Maps/Sky_Garden/Sky_Garden.unity",
+ "Assets/Maps/Space_City/Space_City.unity",
+ "Assets/Maps/Spaceport_Alpha/Spaceport_Alpha.unity",
+ "Assets/Maps/SuperPRISM_Reactor/SuperPRISM_Reactor.unity",
+ "Assets/Maps/Temple_Of_The_Raven/Temple_Of_The_Raven.unity",
+ "Assets/Maps/The_Hangar/The_Hangar.unity",
+ "Assets/Maps/The_Warehouse/The_Warehouse.unity",
+ };
+
+ foreach (var mapScene in mapScenes)
+ {
+ if (System.IO.File.Exists(mapScene))
+ scenes.Add(new EditorBuildSettingsScene(mapScene, true));
+ }
+
+ EditorBuildSettings.scenes = scenes.ToArray();
+ }
+}
diff --git a/Assets/Editor/SetupBootstrapScene.cs.meta b/Assets/Editor/SetupBootstrapScene.cs.meta
new file mode 100644
index 000000000..3d96d0bb4
--- /dev/null
+++ b/Assets/Editor/SetupBootstrapScene.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 0b936e1c4be1b2e4f8afbec01f53fb4a
\ No newline at end of file
diff --git a/Assets/Gameplay/Network Scripts/Client.cs b/Assets/Gameplay/Network Scripts/Client.cs
index a0397b8a4..bc9e1dcef 100644
--- a/Assets/Gameplay/Network Scripts/Client.cs
+++ b/Assets/Gameplay/Network Scripts/Client.cs
@@ -53,9 +53,14 @@ void Start()
if (PlayerPrefs.HasKey("username")) localName = PlayerPrefs.GetString("username");
statsCanvas = GameObject.Find("Lobby Stats UI");
- globalResources = GameObject.Find("/Global Resources").GetComponent();
- log = GameObject.Find("/MenuSystem/Game Log UI/1_log_container").GetComponent();
- spawnPoints = GameObject.Find("/Environment/spawns").GetComponentsInChildren();
+ GameObject globalResourcesObject = GameObject.Find("/Global Resources");
+ if (globalResourcesObject != null) globalResources = globalResourcesObject.GetComponent();
+
+ GameObject logObject = GameObject.Find("/MenuSystem/Game Log UI/1_log_container");
+ if (logObject != null) log = logObject.GetComponent();
+
+ GameObject spawnPointRoot = GameObject.Find("/Environment/spawns");
+ if (spawnPointRoot != null) spawnPoints = spawnPointRoot.GetComponentsInChildren();
AssignLocalPlayer(null);
ConnectNotBlocking(host, port);
@@ -68,49 +73,64 @@ private void CheckTheLead()
foreach (object o in playerDatas.Values)
{
- PlayerData p = (PlayerData)o;
+ PlayerDataOriginal p = (PlayerDataOriginal)o;
if (maxValue < p.kills) maxValue = p.kills;
}
bool lead = kills>maxValue;
- if (hasTheLead != lead && GameObject.Find("/Player"))
+ GameObject playerObject = GameObject.Find("/Player");
+ if (hasTheLead != lead && playerObject != null)
{
- GameObject.Find("/Player").SendMessage("HasTheLead", lead);
- hasTheLead = lead;
+ playerObject.SendMessage("HasTheLead", lead);
}
+
+ hasTheLead = lead;
}
// Hide / Show stats
void ToggleStats(bool show)
{
- statsCanvas.transform.GetChild(0).gameObject.SetActive(show);
+ if (statsCanvas != null && statsCanvas.transform.childCount > 0)
+ statsCanvas.transform.GetChild(0).gameObject.SetActive(show);
}
// Hide / show chat
void ToggleChat()
{
+ if (log == null) return;
+
if (!log.chatActive)
{
log.ToggleChat(true);
- if (GameObject.Find("/Player"))
+ GameObject playerObject = GameObject.Find("/Player");
+ if (playerObject != null)
{
- GameObject p = GameObject.Find("/Player");
- p.GetComponent().enabled = false; // Stop inputs
- p.GetComponent().Move(0f, 0f); // Stop player
- p.GetComponent().MouseLook(0f, 0f);
+ PlayerInput playerInput = playerObject.GetComponent();
+ if (playerInput != null) playerInput.enabled = false;
+
+ PlayerMotor playerMotor = playerObject.GetComponent();
+ if (playerMotor != null)
+ {
+ playerMotor.Move(0f, 0f);
+ playerMotor.MouseLook(0f, 0f);
+ }
}
}
else
{
log.ToggleChat(false);
- if (GameObject.Find("/Player")) {
- if(!GameObject.Find("/Player").GetComponent().gamePaused)
- GameObject.Find("/Player").GetComponent().enabled = true;
- //Cursor.visible = false;
- //Cursor.lockState = CursorLockMode.Locked;
+ GameObject playerObject = GameObject.Find("/Player");
+ if (playerObject != null)
+ {
+ PlayerManager playerManager = playerObject.GetComponent();
+ PlayerInput playerInput = playerObject.GetComponent();
+ if (playerManager != null && playerInput != null && !playerManager.gamePaused)
+ {
+ playerInput.enabled = true;
+ }
}
}
@@ -121,13 +141,16 @@ public void AssignLocalPlayer(Transform newLocalPlayer)
{
if (newLocalPlayer != null) player = newLocalPlayer;
else player = fakeLocalPlayer;
-
- playerCamera = player.GetChild(0);
+
+ if (player != null && player.childCount > 0) playerCamera = player.GetChild(0);
+ else playerCamera = null;
}
// Send chat message to everyone
void SendChatMessage(string message)
{
+ if (!IsConnected()) return;
+
ByteBuffer buffer = new ByteBuffer();
buffer.Put((byte)2);
buffer.Put(4); // put int
@@ -138,6 +161,8 @@ void SendChatMessage(string message)
// Send information when local player dies
internal void LocalPlayerDied(int killerID, int criticalCode)
{
+ if (!IsConnected()) return;
+
ByteBuffer buffer = new ByteBuffer();
buffer.Put((byte)2);
buffer.Put(3); // put int
@@ -149,6 +174,8 @@ internal void LocalPlayerDied(int killerID, int criticalCode)
// Send damage caused to other players
internal void DamageDealedTo(int receiverID, float amount, int criticalCode, Vector3 sourcePos)
{
+ if (!IsConnected()) return;
+
//send to network
ByteBuffer buffer = new ByteBuffer();
buffer.Put((byte)2);
@@ -165,6 +192,8 @@ internal void DamageDealedTo(int receiverID, float amount, int criticalCode, Vec
// send weapon swap to network
void LocalPlayerChangedToWeapon(int weaponId)
{
+ if (!IsConnected()) return;
+
ByteBuffer buffer = new ByteBuffer();
buffer.Put((byte)2);
buffer.Put(0); // put int
@@ -181,6 +210,8 @@ void LocalPlayerCrouch(bool value)
void DetonateFinalWord()
{
+ if (globalResources == null) return;
+
//detonate id is weapons lenght + 1
int wid = globalResources.weapons.Count+1;
LocalPlayerChangedToWeapon(wid);
@@ -189,6 +220,8 @@ void DetonateFinalWord()
// Send primary fire to network
void LocalPlayerFiredWeapon()
{
+ if (!IsConnected()) return;
+
ByteBuffer buffer = new ByteBuffer();
buffer.Put((byte)2);
buffer.Put(1); // put int
@@ -198,13 +231,19 @@ void LocalPlayerFiredWeapon()
// Spawn client to the game
public void LocalPlayerSpawn()
{
- ByteBuffer buffer = new ByteBuffer();
- buffer.Put((byte)2);
- buffer.Put(2); // put int
- Send(buffer.Trim().Get());
+ // Send spawn packet to server if connected (optional — offline play still works)
+ if (IsConnected())
+ {
+ ByteBuffer buffer = new ByteBuffer();
+ buffer.Put((byte)2);
+ buffer.Put(2); // put int
+ Send(buffer.Trim().Get());
+ }
- // player obj
- if (GameObject.Find("/Dead Player")) Destroy(GameObject.Find("/Dead Player"));
+ // Always create player locally (camera is on the player prefab)
+ GameObject deadPlayer = GameObject.Find("/Dead Player");
+ if (deadPlayer != null) Destroy(deadPlayer);
+ if (spawnPoints == null || spawnPoints.Length <= 1) return;
int randomSpawn = UnityEngine.Random.Range(1,spawnPoints.Length);//dont include [0]
GameObject pClone = Instantiate(localPlayerClone,spawnPoints[randomSpawn].position,spawnPoints[randomSpawn].rotation);
pClone.name = "Player";
@@ -216,6 +255,8 @@ public void LocalPlayerSpawn()
// Send equipped appereances to network
void SendAppereances()
{
+ if (!IsConnected() || globalResources == null) return;
+
List a = globalResources.appereances;
int holo = a.IndexOf(Resources.Load(PlayerPrefs.GetString("equipped_holo"), typeof(GameObject)) as GameObject);
@@ -258,7 +299,7 @@ public override void ConnectionResolve(bool success)
// Update is called once per frame
void Update()
{
- if (!isHandshaking)
+ if (!isHandshaking && player != null && playerCamera != null && IsConnected())
{
playerPos = player.position;
playerRot = player.rotation.eulerAngles;
@@ -293,8 +334,15 @@ void Update()
ToggleStats(Input.GetKey(KeyCode.Tab));
// Toggle chat
- if (Input.GetKeyDown("return")) { if (log.chatActive) log.ChatEditEnd(); ToggleChat(); }
- if (Input.GetKeyDown(KeyCode.Escape)) { if (log.chatActive) ToggleChat();}
+ if (Input.GetKeyDown("return"))
+ {
+ if (log != null && log.chatActive) log.ChatEditEnd();
+ ToggleChat();
+ }
+ if (Input.GetKeyDown(KeyCode.Escape))
+ {
+ if (log != null && log.chatActive) ToggleChat();
+ }
}
public override void Packet(byte[] data)
@@ -328,7 +376,7 @@ public override void Packet(byte[] data)
ByteBuffer z = sendBuffer.Trim();
- Send(z.Get());
+ if (IsConnected()) Send(z.Get());
int playerCount = buffer.GetInt();
@@ -410,7 +458,7 @@ internal void UpdatePlayerPositions(ByteBuffer buffer)
if (pid != id)
{
- PlayerData pData = (PlayerData)playerDatas[pid];
+ PlayerDataOriginal pData = (PlayerDataOriginal)playerDatas[pid];
if (pData != null) {
pData.position = new Vector3(buffer.GetFloat(), buffer.GetFloat(), buffer.GetFloat());
pData.rotation = new Vector3(buffer.GetFloat(), buffer.GetFloat(), buffer.GetFloat());
@@ -452,7 +500,7 @@ internal void UpdatePlayerPositions(ByteBuffer buffer)
// Network player joined
internal void PlayerJoined(int playerID, string playerName)
{
- playerDatas.Add(playerID, new PlayerData(playerName));
+ playerDatas.Add(playerID, new PlayerDataOriginal(playerName));
RunOnMainThread.Enqueue(() =>{
NetworkPlayer clone = Instantiate(playerClone);
@@ -465,7 +513,7 @@ internal void PlayerJoined(int playerID, string playerName)
internal void PlayerLeft(int playerID)
{
//Debug.Log("leaved player: " + playerID);
- ((PlayerData)playerDatas[playerID]).destroy = true;
+ ((PlayerDataOriginal)playerDatas[playerID]).destroy = true;
playerDatas.Remove(playerID);
}
@@ -476,8 +524,8 @@ internal void PlayerChangeWeapon(int playerID, int weaponID)
if (weaponID == globalResources.weapons.Count + 1 && playerID != id) PlayerDetonatedFinalWord(playerID);
else
{
- ((PlayerData)playerDatas[playerID]).weapon = weaponID;
- ((PlayerData)playerDatas[playerID]).weaponChanged = true;
+ ((PlayerDataOriginal)playerDatas[playerID]).weapon = weaponID;
+ ((PlayerDataOriginal)playerDatas[playerID]).weaponChanged = true;
}
// lead
RunOnMainThread.Enqueue(() => {
@@ -488,7 +536,7 @@ internal void PlayerChangeWeapon(int playerID, int weaponID)
// Network player fires weapon
internal void PlayerFireWeapon(int playerID)
{
- ((PlayerData)playerDatas[playerID]).pendingPrimaryFire = true;
+ ((PlayerDataOriginal)playerDatas[playerID]).pendingPrimaryFire = true;
}
// Receive chat messages
@@ -509,20 +557,20 @@ void ReceiveChatMessage(int senderID, string message)
void PlayerCrouch(int playerId, byte value)
{
if (playerId == id) return; // self
- ((PlayerData)playerDatas[playerId]).crouch = Convert.ToBoolean(value);
+ ((PlayerDataOriginal)playerDatas[playerId]).crouch = Convert.ToBoolean(value);
}
void PlayerDetonatedFinalWord(int playerId)
{
if (playerId == id) return; // self
- ((PlayerData)playerDatas[playerId]).pendingFinalWord = true;
+ ((PlayerDataOriginal)playerDatas[playerId]).pendingFinalWord = true;
}
// Network player dies
internal void PlayerDied(int killedID, int killerID, int criticalCode)
{
// kill network players
- if (killedID != id) ((PlayerData)playerDatas[killedID]).die = true;
+ if (killedID != id) ((PlayerDataOriginal)playerDatas[killedID]).die = true;
RunOnMainThread.Enqueue(() => {
// Get critical type
@@ -539,27 +587,32 @@ internal void PlayerDied(int killedID, int killerID, int criticalCode)
// stats
if (killedID == id) { deaths++; kills--; }
- else { ((PlayerData)playerDatas[killedID]).deaths++; ((PlayerData)playerDatas[killedID]).kills--; }
+ else { ((PlayerDataOriginal)playerDatas[killedID]).deaths++; ((PlayerDataOriginal)playerDatas[killedID]).kills--; }
}
else // kills
{
//data
- if (killedID != id) ((PlayerData)playerDatas[killedID]).lastKiller=killerID;
+ if (killedID != id) ((PlayerDataOriginal)playerDatas[killedID]).lastKiller=killerID;
// log
log.LogMessage((killerID == id) ? localName : GetLatestDatas(killerID).name, " " + criticalType + " ",(killedID == id) ? localName : GetLatestDatas(killedID).name, false, false);
// stats kills
if (killerID == id) kills++;
- else ((PlayerData)playerDatas[killerID]).kills++;
+ else ((PlayerDataOriginal)playerDatas[killerID]).kills++;
//stats deaths
if (killedID == id) deaths++;
- else ((PlayerData)playerDatas[killedID]).deaths++;
+ else ((PlayerDataOriginal)playerDatas[killedID]).deaths++;
}
// Add my kills
- if (killerID == id && isAlive) GameObject.Find("/Player").GetComponent().GotKill(killedID, criticalCode);
+ if (killerID == id && isAlive)
+ {
+ GameObject playerObject = GameObject.Find("/Player");
+ PlayerManager playerManager = playerObject != null ? playerObject.GetComponent() : null;
+ if (playerManager != null) playerManager.GotKill(killedID, criticalCode);
+ }
});
}
@@ -571,7 +624,9 @@ internal void DamageReceived(int dealerID, float amount, int criticalCode, Vecto
{
//Debug.Log("client "+dealerID+" dealed you "+amount+" damage");
RunOnMainThread.Enqueue(() => {
- GameObject.Find("/Player").GetComponent().TakeDamage(amount, sourcePos, criticalCode, dealerID);
+ GameObject playerObject = GameObject.Find("/Player");
+ PlayerManager playerManager = playerObject != null ? playerObject.GetComponent() : null;
+ if (playerManager != null) playerManager.TakeDamage(amount, sourcePos, criticalCode, dealerID);
});
}
}
@@ -584,7 +639,7 @@ internal void ReceiveAppereances(int playerID, int holo, int head, int face, int
//print(playerID+", "+ holo + ", " + head + ", " + face + ", " + gloves + ", " + upperbody + ", " + lowerbody + ", " + boots);
// save to playerdata
- PlayerData pd = ((PlayerData) playerDatas[playerID]);
+ PlayerDataOriginal pd = ((PlayerDataOriginal) playerDatas[playerID]);
pd.holo = holo;
pd.head = head;
pd.face = face;
@@ -599,8 +654,8 @@ internal void ReceiveAppereances(int playerID, int holo, int head, int face, int
// init player stats if join during the game
void InitPlayerStats(int pID, int kills, int deaths)
{
- ((PlayerData)playerDatas[pID]).kills = kills;
- ((PlayerData)playerDatas[pID]).deaths = deaths;
+ ((PlayerDataOriginal)playerDatas[pID]).kills = kills;
+ ((PlayerDataOriginal)playerDatas[pID]).deaths = deaths;
}
// Close connection and disable this client gameObject
@@ -612,16 +667,16 @@ internal void Quit()
}
// This is called every frame by every NetworkPlayer
- public PlayerData GetLatestDatas(int networkId)
+ public PlayerDataOriginal GetLatestDatas(int networkId)
{
foreach (object i in playerDatas.Keys)
{
if (((int)i) == networkId)
{
- return (PlayerData)playerDatas[i];
+ return (PlayerDataOriginal)playerDatas[i];
}
}
return null;
}
-}
\ No newline at end of file
+}
diff --git a/Assets/Gameplay/Network Scripts/LobbyLog.cs b/Assets/Gameplay/Network Scripts/LobbyLog.cs
index dc5241782..71d468f03 100644
--- a/Assets/Gameplay/Network Scripts/LobbyLog.cs
+++ b/Assets/Gameplay/Network Scripts/LobbyLog.cs
@@ -86,7 +86,11 @@ IEnumerator HideChat()
public void ChatEditEnd()
{
- if(field.text.Length>0&& field.text.Length < 101) GameObject.Find("/Network Client").SendMessage("SendChatMessage", field.text);
+ if (field.text.Length > 0 && field.text.Length < 101)
+ {
+ GameObject networkClient = GameObject.Find("/Network Client");
+ if (networkClient != null) networkClient.SendMessage("SendChatMessage", field.text);
+ }
field.text = "";
scroll.value = 0f;
}
diff --git a/Assets/Gameplay/Network Scripts/LobbyStats.cs b/Assets/Gameplay/Network Scripts/LobbyStats.cs
index 54d9273a1..0eeb62c6e 100644
--- a/Assets/Gameplay/Network Scripts/LobbyStats.cs
+++ b/Assets/Gameplay/Network Scripts/LobbyStats.cs
@@ -25,13 +25,15 @@ public class LobbyStats : MonoBehaviour
void Start()
{
client = transform.parent.parent.gameObject.GetComponent();
+ if (client == null) return;
localName = client.localName;
// default servername
if (client.host == "127.0.0.1") serverNameText.text = "[FI] Debug";
else serverNameText.text = client.host;
- globalResources = GameObject.Find("/Global Resources").GetComponent();
+ GameObject globalResourcesObject = GameObject.Find("/Global Resources");
+ if (globalResourcesObject != null) globalResources = globalResourcesObject.GetComponent();
}
void OnEnable()
@@ -44,6 +46,8 @@ void OnEnable()
void Update()
{
+ if (client == null) return;
+
//get new datas
playerDatas = client.playerDatas;
@@ -63,7 +67,7 @@ void Update()
t.GetChild(4).gameObject.GetComponent().text = client.deaths + ""; //deaths
t.GetChild(5).gameObject.GetComponent().text = KDR(client.kills / client.deaths); //kdr
if(!client.isAlive) t.GetChild(6).gameObject.GetComponent().color = Color.white;
- else
+ else if (globalResources != null && client.localWeaponId >= 0 && client.localWeaponId < globalResources.weapons.Count)
{
t.GetChild(1).gameObject.SetActive(true);
t.GetChild(2).gameObject.SetActive(true);
@@ -76,7 +80,7 @@ void Update()
//others
foreach (object o in playerDatas.Values)
{
- PlayerData p = (PlayerData)o;
+ PlayerDataOriginal p = (PlayerDataOriginal)o;
GameObject statItemClone = Instantiate(statListItemPrefab);
Transform t2 = statItemClone.transform;
@@ -86,7 +90,7 @@ void Update()
t2.GetChild(4).gameObject.GetComponent().text = p.deaths+""; //deaths
t2.GetChild(5).gameObject.GetComponent().text = KDR(p.kills / p.deaths); //kdr
if (!p.isAlive) t2.GetChild(6).gameObject.GetComponent().color = Color.white;
- else
+ else if (globalResources != null && p.weapon >= 0 && p.weapon < globalResources.weapons.Count)
{
t2.GetChild(1).gameObject.SetActive(true);
t2.GetChild(2).gameObject.SetActive(true);
diff --git a/Assets/Gameplay/Network Scripts/NetworkAvatar.cs b/Assets/Gameplay/Network Scripts/NetworkAvatar.cs
index a37d763a6..c5d5bfcc5 100644
--- a/Assets/Gameplay/Network Scripts/NetworkAvatar.cs
+++ b/Assets/Gameplay/Network Scripts/NetworkAvatar.cs
@@ -30,7 +30,10 @@ public class NetworkAvatar : MonoBehaviour
void Start()
{
player = GetComponent();
- globalResources = GameObject.Find("/Global Resources").GetComponent();
+ GameObject globalResourcesObject = GameObject.Find("/Global Resources");
+ if (globalResourcesObject != null) globalResources = globalResourcesObject.GetComponent();
+ if (globalResources == null) return;
+
appereances = globalResources.appereancesPrefab;
lutzDefaultHat = globalResources.lutzDefaultHatPrefab;
}
diff --git a/Assets/Gameplay/Network Scripts/NetworkPlayer.cs b/Assets/Gameplay/Network Scripts/NetworkPlayer.cs
index 743043199..cc0df2bd7 100644
--- a/Assets/Gameplay/Network Scripts/NetworkPlayer.cs
+++ b/Assets/Gameplay/Network Scripts/NetworkPlayer.cs
@@ -15,7 +15,7 @@ public class NetworkPlayer : MonoBehaviour
private GlobalResources globalResources;
private GameObject enemyRagdoll;
- private PlayerData latestPlayerData;
+ private PlayerDataOriginal latestPlayerData;
public Transform groundRayOrigin;
public Transform raycastPivot;
@@ -38,19 +38,27 @@ void Start()
nameTag.GetChild(0).gameObject.GetComponent().text = networkName;
// get client
- client = GameObject.Find("/Network Client").GetComponent();
+ GameObject networkClientObject = GameObject.Find("/Network Client");
+ if (networkClientObject != null) client = networkClientObject.GetComponent();
// get global resources
- globalResources = GameObject.Find("/Global Resources").GetComponent();
+ GameObject globalResourcesObject = GameObject.Find("/Global Resources");
+ if (globalResourcesObject != null) globalResources = globalResourcesObject.GetComponent();
// log message
- client.log.LogMessage(networkName, " joined the game", "", false, false);
+ if (client != null && client.log != null)
+ {
+ client.log.LogMessage(networkName, " joined the game", "", false, false);
+ }
// set obj link
- ((PlayerData)client.playerDatas[networkId]).playerObject = gameObject;
+ if (client != null && client.playerDatas[networkId] != null)
+ {
+ ((PlayerDataOriginal)client.playerDatas[networkId]).playerObject = gameObject;
+ }
//ragdoll
- enemyRagdoll = globalResources.enemyRagdoll;
+ if (globalResources != null) enemyRagdoll = globalResources.enemyRagdoll;
//audio
playerAudio = GetComponent();
@@ -58,9 +66,11 @@ void Start()
void Update()
{
+ if (client == null) return;
+
// Disconnect player
if (latestPlayerData!=null&&latestPlayerData.destroy){
- client.log.LogMessage(networkName, " left the game", "", false, false);
+ if (client.log != null) client.log.LogMessage(networkName, " left the game", "", false, false);
Destroy(gameObject);
return;}
@@ -71,6 +81,7 @@ void Update()
// Get latest data ///////////////////////////////////
latestPlayerData = client.GetLatestDatas(networkId);//
//////////////////////////////////////////////////////
+ if (latestPlayerData == null) return;
// appereances & weapons
if (latestPlayerData.appereancesChanged) LoadAppereances();
@@ -81,8 +92,8 @@ void Update()
if (latestPlayerData.pendingFinalWord) FinalWord();
// death
- if (latestPlayerData.position.y!=-666) ((PlayerData)client.playerDatas[networkId]).isAlive = true;
- else ((PlayerData)client.playerDatas[networkId]).isAlive = false;
+ if (latestPlayerData.position.y!=-666) ((PlayerDataOriginal)client.playerDatas[networkId]).isAlive = true;
+ else ((PlayerDataOriginal)client.playerDatas[networkId]).isAlive = false;
// position
transform.position = Vector3.Lerp(transform.position, latestPlayerData.position, 0.3f);
@@ -97,7 +108,8 @@ void Update()
raycastPivot.localRotation = Quaternion.Euler(latestPlayerData.subRotation);
// nameTag
- nameTag.LookAt(2 * nameTag.position - client.playerCamera.position);
+ if (client.playerCamera != null)
+ nameTag.LookAt(2 * nameTag.position - client.playerCamera.position);
nameTag.gameObject.SetActive(client.isAlive);
// ground
@@ -115,10 +127,10 @@ public void TakeDamage(float amount, int criticalDmgCode, Vector3 position, stri
void Die()
{
- ((PlayerData)client.playerDatas[networkId]).die = false;
+ ((PlayerDataOriginal)client.playerDatas[networkId]).die = false;
// drop weapon
- GameObject wPrefab = globalResources.weapons[((PlayerData)client.playerDatas[networkId]).weapon];
+ GameObject wPrefab = globalResources.weapons[((PlayerDataOriginal)client.playerDatas[networkId]).weapon];
PickupWeapon w = Instantiate(drop, latestPlayerData.position+(Vector3.up*2), Quaternion.identity);
w.weaponPrefab = wPrefab;
Destroy(w.gameObject, 8f);
@@ -137,10 +149,10 @@ void Die()
Destroy(cc,8f);
//force
- if (((PlayerData)client.playerDatas[networkId]).lastKiller > 0)
+ if (((PlayerDataOriginal)client.playerDatas[networkId]).lastKiller > 0)
{
Vector3 pos;
- if (client.GetLatestDatas(((PlayerData)client.playerDatas[networkId]).lastKiller) != null) pos = client.GetLatestDatas(((PlayerData)client.playerDatas[networkId]).lastKiller).position;
+ if (client.GetLatestDatas(((PlayerDataOriginal)client.playerDatas[networkId]).lastKiller) != null) pos = client.GetLatestDatas(((PlayerDataOriginal)client.playerDatas[networkId]).lastKiller).position;
else if (GameObject.Find("/Player")) pos = GameObject.Find("/Player").transform.position;
else pos = transform.position;
@@ -152,7 +164,7 @@ void Die()
void LoadAppereances()
{
- ((PlayerData)client.playerDatas[networkId]).appereancesChanged = false;
+ ((PlayerDataOriginal)client.playerDatas[networkId]).appereancesChanged = false;
// get appereances
GameObject holo = (latestPlayerData.holo<=0) ? null : globalResources.appereances[latestPlayerData.holo];
@@ -181,14 +193,14 @@ void LoadAppereances()
void EquipWeapon()
{
- ((PlayerData)client.playerDatas[networkId]).weaponChanged = false;
+ ((PlayerDataOriginal)client.playerDatas[networkId]).weaponChanged = false;
// clear all
for (int i = 0; i < weaponHand.childCount; i++)
Destroy(weaponHand.GetChild(i).gameObject);
// add current
- GameObject newWeapon = Instantiate(FixedAudio(globalResources.weapons[((PlayerData)client.playerDatas[networkId]).weapon]), weaponHand.position,weaponHand.rotation);
+ GameObject newWeapon = Instantiate(FixedAudio(globalResources.weapons[((PlayerDataOriginal)client.playerDatas[networkId]).weapon]), weaponHand.position,weaponHand.rotation);
Destroy(newWeapon.GetComponent());
newWeapon.transform.parent = weaponHand;
newWeapon.transform.localRotation = Quaternion.Euler(0f, 90f, 90f);
@@ -201,7 +213,7 @@ void FireWeapon()
//get hit point
RaycastHit t = GetFireHitPoint();
- ((PlayerData)client.playerDatas[networkId]).pendingPrimaryFire = false;
+ ((PlayerDataOriginal)client.playerDatas[networkId]).pendingPrimaryFire = false;
// sound
if(weaponHand.childCount>0)
@@ -270,7 +282,7 @@ float getDistanceToGround()
//detonate final word/kiss grenades
internal void FinalWord()
{
- ((PlayerData)client.playerDatas[networkId]).pendingFinalWord = false;
+ ((PlayerDataOriginal)client.playerDatas[networkId]).pendingFinalWord = false;
if (weaponHand.childCount > 0)
if (weaponHand.GetChild(0).gameObject.GetComponent())
if (weaponHand.GetChild(0).gameObject.name.ToLower().Contains("final"))
diff --git a/Assets/Gameplay/Network Scripts/TcpEngine.cs b/Assets/Gameplay/Network Scripts/TcpEngine.cs
index c936b7b02..654a9c101 100644
--- a/Assets/Gameplay/Network Scripts/TcpEngine.cs
+++ b/Assets/Gameplay/Network Scripts/TcpEngine.cs
@@ -12,6 +12,11 @@ public class TcpEngine : MonoBehaviour
private string tcpHost;
private int tcpPort;
+ protected bool IsConnected()
+ {
+ return client != null && client.Connected;
+ }
+
internal bool ConnectBlocking(string host, int port)
{
try
@@ -39,17 +44,17 @@ internal void ConnectNotBlocking(string host, int port)
}
private void connect()
{
- /*try
- {*/
- client = new TcpClient();
- client.Connect(new System.Net.IPEndPoint(System.Net.IPAddress.Parse(tcpHost), tcpPort));
- ConnectionResolve(true);
- /* }
-
- catch //(Exception ex)
+ try
+ {
+ client = new TcpClient();
+ client.Connect(new System.Net.IPEndPoint(System.Net.IPAddress.Parse(tcpHost), tcpPort));
+ ConnectionResolve(true);
+ }
+ catch (Exception ex)
{
+ Debug.LogWarning("TCP connect failed: " + ex.Message);
ConnectionResolve(false);
- }*/
+ }
}
@@ -80,8 +85,16 @@ internal void Disconnect()
{
if (client != null)
{
- client.GetStream().Close();
- client.Close();
+ try
+ {
+ if (client.Connected)
+ client.GetStream().Close();
+ client.Close();
+ }
+ catch (Exception ex)
+ {
+ Debug.LogWarning("TCP disconnect: " + ex.Message);
+ }
print("Disconnected");
}
}
@@ -103,28 +116,22 @@ public virtual void ConnectionResolve(bool success)
internal void Send(byte[] data)
{
-
- if (client == null)
+ if (!IsConnected())
{
return;
}
- else
+ try
{
- try
- {
- NetworkStream ns = client.GetStream();
-
- if (ns.CanWrite)
- {
- ns.Write(data, 0, data.Length);
- }
-
- }
- catch (SocketException se)
+ NetworkStream ns = client.GetStream();
+ if (ns.CanWrite)
{
- Debug.LogError("SE:" + se);
+ ns.Write(data, 0, data.Length);
}
}
+ catch (Exception ex)
+ {
+ Debug.LogWarning("TCP send failed: " + ex.Message);
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Assets/Gameplay/Player Scrips/BodyBuilder.cs b/Assets/Gameplay/Player Scrips/BodyBuilder.cs
index 20226a24a..c0de36b3c 100644
--- a/Assets/Gameplay/Player Scrips/BodyBuilder.cs
+++ b/Assets/Gameplay/Player Scrips/BodyBuilder.cs
@@ -22,7 +22,10 @@ public class BodyBuilder : MonoBehaviour
public void BuildAppereances(GameObject holo, GameObject head, GameObject face, GameObject upperBody, GameObject gloves, GameObject lowerBody, GameObject boots)
{
- globalResources = GameObject.Find("/Global Resources").GetComponent();
+ GameObject globalResourcesObject = GameObject.Find("/Global Resources");
+ if (globalResourcesObject != null) globalResources = globalResourcesObject.GetComponent();
+ if (globalResources == null) return;
+
appereances = globalResources.appereancesPrefab;
lutzDefaultHat = globalResources.lutzDefaultHatPrefab;
diff --git a/Assets/Gameplay/Player Scrips/DeadPlayer.cs b/Assets/Gameplay/Player Scrips/DeadPlayer.cs
index f18e8c994..02be8f699 100644
--- a/Assets/Gameplay/Player Scrips/DeadPlayer.cs
+++ b/Assets/Gameplay/Player Scrips/DeadPlayer.cs
@@ -40,7 +40,11 @@ void SetAppereances()
void SetWeapon(int weaponId)
{
- GameObject wPrefab = GameObject.Find("/Global Resources").GetComponent().weapons[weaponId];
+ GameObject globalResourcesObject = GameObject.Find("/Global Resources");
+ GlobalResources globalResources = globalResourcesObject != null ? globalResourcesObject.GetComponent() : null;
+ if (globalResources == null || weaponId < 0 || weaponId >= globalResources.weapons.Count) return;
+
+ GameObject wPrefab = globalResources.weapons[weaponId];
GameObject w = Instantiate(wPrefab, weapon.position, weapon.rotation);
Destroy(w.GetComponent());
Destroy(w.GetComponent());
diff --git a/Assets/Gameplay/Player Scrips/PlayerAudio.cs b/Assets/Gameplay/Player Scrips/PlayerAudio.cs
index 5075c2f1d..af0de18c4 100644
--- a/Assets/Gameplay/Player Scrips/PlayerAudio.cs
+++ b/Assets/Gameplay/Player Scrips/PlayerAudio.cs
@@ -49,7 +49,10 @@ public class PlayerAudio : MonoBehaviour
void Start()
{
audioSource = GetComponent();
- audioSource.PlayOneShot(narrator[0], volume);
+ if (narrator != null && narrator.Length > 0 && narrator[0] != null)
+ {
+ audioSource.PlayOneShot(narrator[0], volume);
+ }
// build footStep map
foreach(AudioClip a in footSteps)
@@ -58,13 +61,18 @@ void Start()
}
// Custom narrator
- if (GameObject.Find("/Custom Narrator")) Destroy(GameObject.Find("/Custom Narrator"));
+ GameObject customNarrator = GameObject.Find("/Custom Narrator");
+ if (customNarrator != null) Destroy(customNarrator);
if (PlayerPrefs.HasKey("equipped_head"))
{
+ GameObject globalResourcesObject = GameObject.Find("/Global Resources");
+ GlobalResources globalResources = globalResourcesObject != null ? globalResourcesObject.GetComponent() : null;
+ if (globalResources == null) return;
+
//laitela
if (PlayerPrefs.GetString("equipped_head") == "Paperbag laitela")
{
- CustomNarrator c=Instantiate(GameObject.Find("/Global Resources").GetComponent().laitelaNarrator);
+ CustomNarrator c = Instantiate(globalResources.laitelaNarrator);
c.gameObject.name = "Custom Narrator";
}
@@ -72,7 +80,7 @@ void Start()
//taalasmaa
if (PlayerPrefs.GetString("equipped_head") == "Paperbag taalasmaa")
{
- CustomNarrator c = Instantiate(GameObject.Find("/Global Resources").GetComponent().taalasmaaNarrator);
+ CustomNarrator c = Instantiate(globalResources.taalasmaaNarrator);
c.gameObject.name = "Custom Narrator";
}
@@ -82,7 +90,7 @@ void Start()
// Call this to play sounds elsewhere
public void Play(AudioClip clip)
{
- if(audioSource.enabled)
+ if(audioSource != null && audioSource.enabled && clip != null)
audioSource.PlayOneShot(clip, volume);
}
@@ -110,37 +118,45 @@ public void PlayWalk(string groundMaterial)
string foundType = "rock"; // default is rock
// find type
- foreach (string s in gTypes) if (groundMaterial.Contains(s)) { foundType = s; break; }
+ if (!string.IsNullOrEmpty(groundMaterial))
+ foreach (string s in gTypes) if (groundMaterial.Contains(s)) { foundType = s; break; }
// get clip count
int i = 1;
while (steps.Contains(foundType + i)) i++;
i--;
- int randomIndex = Random.Range(1, i);
- if (steps.Contains(foundType + randomIndex)) Play((AudioClip)steps[foundType + randomIndex]);
+ if (i <= 0) return;
+
+ int randomIndex = Random.Range(1, i + 1);
+ AudioClip clip = steps[foundType + randomIndex] as AudioClip;
+ if (clip != null) Play(clip);
else Debug.LogWarning("footstep sound index out of bounds");
}
// footsteps landing
public void PlayLanding(string groundMaterial)
{
- if (audioSource.isPlaying) return;
+ if (audioSource == null || audioSource.isPlaying) return;
if (canWalk != null) StopCoroutine(canWalk);
canWalk = StartCoroutine(CanWalk());
string foundType = "rock"; // default is rock
// find type
- foreach (string s in gTypes) if (groundMaterial.Contains(s)) { foundType = s; break; }
+ if (!string.IsNullOrEmpty(groundMaterial))
+ foreach (string s in gTypes) if (groundMaterial.Contains(s)) { foundType = s; break; }
// get clip count
int i = 1;
while(steps.Contains(foundType + i)) i++;
i--;
- int randomIndex = Random.Range(1,i);
- if (steps.Contains(foundType+randomIndex)) Play((AudioClip)steps[foundType + randomIndex]);
+ if (i <= 0) return;
+
+ int randomIndex = Random.Range(1, i + 1);
+ AudioClip clip = steps[foundType + randomIndex] as AudioClip;
+ if (clip != null) Play(clip);
else Debug.LogWarning("footstep sound index out of bounds");
}
diff --git a/Assets/Gameplay/Player Scrips/PlayerHand.cs b/Assets/Gameplay/Player Scrips/PlayerHand.cs
index 1290450cd..0dce63971 100644
--- a/Assets/Gameplay/Player Scrips/PlayerHand.cs
+++ b/Assets/Gameplay/Player Scrips/PlayerHand.cs
@@ -26,11 +26,16 @@ public class PlayerHand : MonoBehaviour
// Init
void Start()
{
- try {
- networkClient = GameObject.Find("/Network Client");
- globalResources = GameObject.Find("/Global Resources").GetComponent();
+ networkClient = GameObject.Find("/Network Client");
+ GameObject globalResourcesObject = GameObject.Find("/Global Resources");
+ if (globalResourcesObject != null)
+ {
+ globalResources = globalResourcesObject.GetComponent();
+ }
+ if (networkClient == null || globalResources == null)
+ {
+ Debug.LogWarning("PlayerHand did not find one or more network objects.");
}
- catch{Debug.LogWarning("Playerhand did not find network objects");}
// Get weapons
diff --git a/Assets/Gameplay/Player Scrips/PlayerInput.cs b/Assets/Gameplay/Player Scrips/PlayerInput.cs
index 91703cee3..ea44f9453 100644
--- a/Assets/Gameplay/Player Scrips/PlayerInput.cs
+++ b/Assets/Gameplay/Player Scrips/PlayerInput.cs
@@ -21,9 +21,9 @@ private void Start()
// This method reads player input every frame
private void Update()
{
- // Get WASD
- float x = Input.GetAxis("Vertical");
- float z = Input.GetAxis("Horizontal");
+ // Get WASD — use GetAxisRaw for instant response (no Unity smoothing)
+ float x = Input.GetAxisRaw("Vertical");
+ float z = Input.GetAxisRaw("Horizontal");
playerMotor.Move(x, z);
// Get mouse
@@ -39,8 +39,11 @@ private void Update()
if (Input.GetButtonDown("Fire1")) { playerMotor.Shoot(true); }
if (Input.GetButtonUp("Fire1")) { playerMotor.Shoot(false); }
- // Get spacebar
- if (Input.GetButtonDown("Jump")) { playerMotor.Jump(); }
+ // Track jump key state continuously — original UberStrike checks held state
+ // every physics frame, not just button-down events. This enables bunny hopping:
+ // press space mid-air → lands → instant jump on next physics frame.
+ playerMotor.jumpHeld = Input.GetButton("Jump");
+ if (Input.GetButtonUp("Jump")) { playerMotor.JumpReleased(); }
// Get mouse scroll wheel
float scroll = Input.GetAxis("Mouse ScrollWheel");
@@ -52,11 +55,12 @@ private void Update()
// Get E key
if (Input.GetKeyDown(KeyCode.E)) { playerMotor.UseItem(1); }
- // Weapon switch shorcuts
- if (Input.GetKeyDown(KeyCode.Alpha1)) { playerMotor.Aim(true); playerMotor.Aim(false); playerMotor.SetWeapon(1); }
- if (Input.GetKeyDown(KeyCode.Alpha2)) { playerMotor.Aim(true); playerMotor.Aim(false); playerMotor.SetWeapon(4); }
- if (Input.GetKeyDown(KeyCode.Alpha3)) { playerMotor.Aim(true); playerMotor.Aim(false); playerMotor.SetWeapon(3); }
- if (Input.GetKeyDown(KeyCode.Alpha4)) { playerMotor.Aim(true); playerMotor.Aim(false); playerMotor.SetWeapon(2); }
+ // Weapon switch: 1=Melee, 2=Primary, 3=Secondary, 4=Tertiary
+ // Hand hierarchy: child 0=Primary, child 1=Melee, child 2=Secondary, child 3=Tertiary
+ if (Input.GetKeyDown(KeyCode.Alpha1)) { playerMotor.Aim(true); playerMotor.Aim(false); playerMotor.SetWeapon(2); } // Melee = index 1
+ if (Input.GetKeyDown(KeyCode.Alpha2)) { playerMotor.Aim(true); playerMotor.Aim(false); playerMotor.SetWeapon(1); } // Primary = index 0
+ if (Input.GetKeyDown(KeyCode.Alpha3)) { playerMotor.Aim(true); playerMotor.Aim(false); playerMotor.SetWeapon(3); } // Secondary = index 2
+ if (Input.GetKeyDown(KeyCode.Alpha4)) { playerMotor.Aim(true); playerMotor.Aim(false); playerMotor.SetWeapon(4); } // Tertiary = index 3
// Pause
// This Input is hardcoded. We should make input axis for this later
@@ -67,10 +71,9 @@ private void Update()
if (Input.GetKeyDown(KeyCode.P)) { playerUI.ToggleHUD(); }
- // Get ctrl key for crouch
- // This Input is hardcoded. We should make input axis for this later
- if (Input.GetKeyDown(KeyCode.LeftControl)) { playerMotor.Crouch(true); }
- if (Input.GetKeyUp(KeyCode.LeftControl)) { playerMotor.Crouch(false); }
+ // Get shift key for crouch
+ if (Input.GetKeyDown(KeyCode.LeftShift)) { playerMotor.Crouch(true); }
+ if (Input.GetKeyUp(KeyCode.LeftShift)) { playerMotor.Crouch(false); }
}
diff --git a/Assets/Gameplay/Player Scrips/PlayerManager.cs b/Assets/Gameplay/Player Scrips/PlayerManager.cs
index f7c668a22..76d928113 100644
--- a/Assets/Gameplay/Player Scrips/PlayerManager.cs
+++ b/Assets/Gameplay/Player Scrips/PlayerManager.cs
@@ -35,22 +35,39 @@ public class PlayerManager : MonoBehaviour
void Start()
{
inTheMenus = SceneManager.GetActiveScene().name == "MainMenu";
- if(!inTheMenus)respawnUI = GameObject.Find("/MenuSystem/Respawn UI").transform.GetChild(0).gameObject;
+ if (!inTheMenus)
+ {
+ var respawnUiRoot = GameObject.Find("/MenuSystem/Respawn UI");
+ if (respawnUiRoot != null && respawnUiRoot.transform.childCount > 0)
+ {
+ respawnUI = respawnUiRoot.transform.GetChild(0).gameObject;
+ }
+ }
playerUI = GetComponent();
playerAudio = GetComponent();
- if ((Resources.Load(PlayerPrefs.GetString("equipped_primary_quickitem"), typeof(GameObject)) as GameObject) != null)
+ var primaryPrefab = Resources.Load(PlayerPrefs.GetString("equipped_primary_quickitem"), typeof(GameObject)) as GameObject;
+ if (primaryPrefab != null)
{
- float ff = (Resources.Load(PlayerPrefs.GetString("equipped_primary_quickitem"), typeof(GameObject)) as GameObject).GetComponent().stockCount;
- playerUI.UpdateItemCount(0, ff, false);
- primaryItems = ff;
+ var primaryQuickItem = primaryPrefab.GetComponent();
+ if (primaryQuickItem != null)
+ {
+ float ff = primaryQuickItem.stockCount;
+ playerUI.UpdateItemCount(0, ff, false);
+ primaryItems = ff;
+ }
}
-
- if ((Resources.Load(PlayerPrefs.GetString("equipped_secondary_quickitem"), typeof(GameObject)) as GameObject) != null)
+
+ var secondaryPrefab = Resources.Load(PlayerPrefs.GetString("equipped_secondary_quickitem"), typeof(GameObject)) as GameObject;
+ if (secondaryPrefab != null)
{
- float f = (Resources.Load(PlayerPrefs.GetString("equipped_secondary_quickitem"), typeof(GameObject)) as GameObject).GetComponent().stockCount;
- playerUI.UpdateItemCount(1, f, false);
- secondaryItems = f;
+ var secondaryQuickItem = secondaryPrefab.GetComponent();
+ if (secondaryQuickItem != null)
+ {
+ float f = secondaryQuickItem.stockCount;
+ playerUI.UpdateItemCount(1, f, false);
+ secondaryItems = f;
+ }
}
playerHand = playerUI.playerHand;
@@ -58,12 +75,19 @@ void Start()
SetDefaultValues();
// Skybox
- if(GameObject.Find("/Environment").GetComponent().skybox!=null)RenderSettings.skybox = GameObject.Find("/Environment").GetComponent().skybox;
+ var envObj = GameObject.Find("/Environment");
+ var environment = envObj != null ? envObj.GetComponent() : null;
+ if (environment != null && environment.skybox != null)
+ RenderSettings.skybox = environment.skybox;
- if (GameObject.Find("/Network Client"))
+ var networkClientObject = GameObject.Find("/Network Client");
+ if (networkClientObject != null)
{
- client = GameObject.Find("/Network Client").GetComponent();
- client.AssignLocalPlayer(transform);
+ client = networkClientObject.GetComponent();
+ if (client != null)
+ {
+ client.AssignLocalPlayer(transform);
+ }
}
}
@@ -80,7 +104,10 @@ void SetDefaultValues()
public void GotKill(int killedID, int criticalCode)
{
- playerUI.ShowKillName("You killed "+ client.GetLatestDatas(killedID).name);
+ if (playerUI == null || playerAudio == null || client == null) return;
+
+ PlayerDataOriginal killedPlayer = client.GetLatestDatas(killedID);
+ playerUI.ShowKillName("You killed " + ((killedPlayer != null) ? killedPlayer.name : "Unknown"));
killCombo++;
if (killCombo > 6) killCombo = 6;
@@ -115,6 +142,12 @@ private IEnumerator ClearCombos()
internal void Die(int dealerPlayerID, int criticalCode)
{
if (inTheMenus) { PauseGame(); return; }
+ if (client == null)
+ {
+ Debug.LogWarning("PlayerManager.Die skipped network death handling because no Client was found.");
+ PauseGame();
+ return;
+ }
if (!client.isAlive) return;
client.isAlive = false;
deaths++;
@@ -128,11 +161,12 @@ internal void Die(int dealerPlayerID, int criticalCode)
//cause messages
client.LocalPlayerDied(dealerPlayerID, criticalCode); // to others
string causeMsg = ""; // self
+ PlayerDataOriginal dealerData = dealerPlayerID >= 0 ? client.GetLatestDatas(dealerPlayerID) : null;
if (dealerPlayerID < 0) causeMsg = "Congratulations, you killed yourself.";
- else if (criticalCode == 0) causeMsg = "Killed by " + client.GetLatestDatas(dealerPlayerID).name;
- else if (criticalCode == 1) causeMsg = "Headshot from " + client.GetLatestDatas(dealerPlayerID).name;
- else if (criticalCode == 2) causeMsg = "Nutshot from " + client.GetLatestDatas(dealerPlayerID).name;
- else if (criticalCode == 3) causeMsg = "Smackdown from " + client.GetLatestDatas(dealerPlayerID).name;
+ else if (criticalCode == 0) causeMsg = "Killed by " + ((dealerData != null) ? dealerData.name : "Unknown");
+ else if (criticalCode == 1) causeMsg = "Headshot from " + ((dealerData != null) ? dealerData.name : "Unknown");
+ else if (criticalCode == 2) causeMsg = "Nutshot from " + ((dealerData != null) ? dealerData.name : "Unknown");
+ else if (criticalCode == 3) causeMsg = "Smackdown from " + ((dealerData != null) ? dealerData.name : "Unknown");
playerUI.ShowKillName("");
@@ -142,16 +176,35 @@ internal void Die(int dealerPlayerID, int criticalCode)
CustomNarrator("Die");
// hide pause
- GameObject.Find("/MenuSystem/Pause UI").transform.GetChild(0).gameObject.SetActive(false);
+ GameObject pauseUi = GameObject.Find("/MenuSystem/Pause UI");
+ if (pauseUi != null && pauseUi.transform.childCount > 0)
+ {
+ pauseUi.transform.GetChild(0).gameObject.SetActive(false);
+ }
client.AssignLocalPlayer(null);
- respawnUI.SetActive(true);
- respawnUI.SendMessage("SetDeathCause", causeMsg);
+ if (respawnUI != null)
+ {
+ respawnUI.SetActive(true);
+ respawnUI.SendMessage("SetDeathCause", causeMsg);
+ }
GameObject death = Instantiate(deathViewPrefab, transform.position, transform.rotation);
death.SendMessage("SetWeapon", client.localWeaponId);
- if(dealerPlayerID>0) death.SendMessage("SetKiller", client.GetLatestDatas(dealerPlayerID).playerObject);
- death.SendMessage("StartVelocity",GetComponent().linearVelocity);
+ if (dealerPlayerID > 0)
+ {
+ PlayerDataOriginal killerData = client.GetLatestDatas(dealerPlayerID);
+ if (killerData != null && killerData.playerObject != null)
+ {
+ death.SendMessage("SetKiller", killerData.playerObject);
+ }
+ }
+
+ Rigidbody rb = GetComponent();
+ if (rb != null)
+ {
+ death.SendMessage("StartVelocity", rb.linearVelocity);
+ }
Destroy(gameObject);
@@ -330,9 +383,15 @@ public float GetCollectedAmmoFor(string weaponType)
internal void PauseGame()
{
- GetComponent().enabled = false; // Stop inputs
- GetComponent().Move(0f, 0f); // Stop player
- GetComponent().MouseLook(0f, 0f);
+ PlayerInput playerInput = GetComponent();
+ if (playerInput != null) playerInput.enabled = false; // Stop inputs
+
+ PlayerMotor playerMotor = GetComponent();
+ if (playerMotor != null)
+ {
+ playerMotor.Move(0f, 0f); // Stop player
+ playerMotor.MouseLook(0f, 0f);
+ }
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
@@ -344,14 +403,22 @@ internal void PauseGame()
foreach(GameObject g in rootObjs)
{
if (g.name == "Player Avatar" || g.name == "MenuSystem") g.SetActive(true);
- if(g.name == "Environment") g.GetComponent().volume = 1f;
+ if (g.name == "Environment")
+ {
+ AudioSource environmentAudio = g.GetComponent();
+ if (environmentAudio != null) environmentAudio.volume = 1f;
+ }
}
Destroy(gameObject);
//shop tab
- GameObject.Find("/MenuSystem/Top Bar UI").SendMessage("NavigationBar", 3);
- GameObject.Find("/MenuSystem/Top Bar UI").SendMessage("NavigationBar", 2);
+ GameObject topBarUi = GameObject.Find("/MenuSystem/Top Bar UI");
+ if (topBarUi != null)
+ {
+ topBarUi.SendMessage("NavigationBar", 3);
+ topBarUi.SendMessage("NavigationBar", 2);
+ }
}
// Other maps
else
@@ -359,13 +426,21 @@ internal void PauseGame()
playerUI.TogglePauseScreen(true);
gamePaused = true;
- GameObject g = GameObject.Find("/MenuSystem").transform.GetChild(0).gameObject;
- g.SetActive(true);
+ GameObject menuSystem = GameObject.Find("/MenuSystem");
+ if (menuSystem != null && menuSystem.transform.childCount > 0)
+ {
+ GameObject g = menuSystem.transform.GetChild(0).gameObject;
+ g.SetActive(true);
+ }
}
- if (GameObject.Find("/Player"))
- GameObject.Find("/Player").GetComponent().movement = Vector3.zero;
+ GameObject player = GameObject.Find("/Player");
+ if (player != null)
+ {
+ PlayerMotor localPlayerMotor = player.GetComponent();
+ if (localPlayerMotor != null) localPlayerMotor.movement = Vector3.zero;
+ }
}
// call after game is paused
@@ -375,8 +450,11 @@ public void ContinueGame()
Cursor.visible = false;
playerUI.TogglePauseScreen(false);
gamePaused = false;
- GetComponent().enabled = true;
- GetComponent().UpdateOptions();
+ PlayerInput playerInput = GetComponent();
+ if (playerInput != null) playerInput.enabled = true;
+
+ PlayerMotor playerMotor = GetComponent();
+ if (playerMotor != null) playerMotor.UpdateOptions();
}
// Pass weapon pickup to hand
diff --git a/Assets/Gameplay/Player Scrips/PlayerMotor.cs b/Assets/Gameplay/Player Scrips/PlayerMotor.cs
index 4f515742e..81553b843 100644
--- a/Assets/Gameplay/Player Scrips/PlayerMotor.cs
+++ b/Assets/Gameplay/Player Scrips/PlayerMotor.cs
@@ -30,15 +30,32 @@ public class PlayerMotor : MonoBehaviour
private bool climbing = false;
private bool swim = false;
+ // Manual vertical velocity — decoupled from Rigidbody to match CharacterController behavior
+ private float verticalVelocity = 0f;
+
+ // Accumulated mouse input between frames for smooth camera
+ private float accumulatedMouseX = 0f;
+ private float accumulatedMouseY = 0f;
+
public ParticleSystem distortion;
private float moveSpeed = 0f;
private bool sideways = false;
- public float groundMoveSpeed = 6f;
- internal float rotationSpeed = 75f; //45
+ public float groundMoveSpeed = 7.6f; // Authentic: CharacterMoveController.PlayerWalkSpeed = 7.6
+ internal float rotationSpeed = 75f;
internal float originalRotationSpeed = 75f;
- public float jumpForce = 33f;
+ [Header("Movement — authentic UberStrike 4.7.1 (CharacterMoveController) constants")]
+ public float jumpForce = 15f; // PlayerJumpSpeed = 15
+ public float uberGravity = 50f; // EnviromentSettings.Gravity = 50
+ public float groundAccel = 15f; // GroundAcceleration
+ public float airAccel = 3f; // AirAcceleration — low value enables strafe-jump / bunny-hop
+ public float groundFriction = 8f; // GroundFriction
+ public float stopSpeed = 8f; // StopSpeed
+ public float maxHorizontalSpeed = 22.8f; // ClampHorizontally (3x walk = StrafeJumpMultiplier)
+ private Vector3 horizVel = Vector3.zero; // persistent horizontal velocity (carries momentum)
+ [Header("Pad Settings")]
+ public float maxPadVerticalVel = 45f; // Cap to prevent ceiling clipping on enclosed maps
private Rigidbody primaryQuickItem;
private Rigidbody secondaryQuickItem;
public Transform playerCamera;
@@ -55,6 +72,7 @@ public class PlayerMotor : MonoBehaviour
private Animator handAnimator;
private float rbDrag;
private bool canJump = true;
+ internal bool jumpHeld = false; // Set by PlayerInput every frame (continuous state)
private bool crouching = false;
private Animator cameraAnimator;
@@ -64,6 +82,13 @@ public class PlayerMotor : MonoBehaviour
// Runs before first frame
void Start()
{
+ // Enforce physics values on every spawn — prevents prefab serialized values
+ // from overriding tuned values on death/respawn. Remove once prefab is updated.
+ groundMoveSpeed = 7.6f; // authentic PlayerWalkSpeed
+ jumpForce = 15f; // authentic PlayerJumpSpeed
+ uberGravity = 50f; // authentic EnviromentSettings.Gravity
+ maxPadVerticalVel = 45f;
+
capsule = GetComponent();
// Init array
@@ -74,16 +99,15 @@ void Start()
groundRayChecks[4] = new Vector3(-groundCheckRadius / 2, 0f, groundCheckRadius / 2);
groundRayChecks[5] = new Vector3(groundCheckRadius / 2, 0f, -groundCheckRadius / 2);
groundRayChecks[6] = new Vector3(-groundCheckRadius / 2, 0f, -groundCheckRadius / 2);
- groundRayChecks[7] = new Vector3(groundCheckRadius / 2, 0f, groundCheckRadius / 2);
groundRayChecks[7] = new Vector3(0f, 0f, 0f);
// Init
playerAudio = GetComponent();
- cameraAnimator = playerCamera.gameObject.GetComponent();
playerManager = GetComponent();
playerUI = GetComponent();
rigidBody = GetComponent();
playerCamera = transform.Find("Player Camera");
+ cameraAnimator = playerCamera.gameObject.GetComponent();
hand = playerCamera.GetChild(0).gameObject;
handCamera = playerCamera.Find("Camera Mask").gameObject.GetComponent();
@@ -91,8 +115,18 @@ void Start()
lastRotation = rot.x;
handAnimator = handCamera.GetComponent();
+ // Ensure Rigidbody interpolation is on for smooth visual movement
+ rigidBody.interpolation = RigidbodyInterpolation.Interpolate;
+
+ // Disable Unity's built-in gravity — we apply it manually to match
+ // original UberStrike's CharacterController (gravity=50, not Unity's 9.81)
+ rigidBody.useGravity = false;
+ // Prevent fast-moving player from clipping through geometry
+ rigidBody.collisionDetectionMode = CollisionDetectionMode.Continuous;
+
// Water
- mapHasWater = GameObject.Find("/Environment").GetComponent().mapHasWater;
+ var envObj = GameObject.Find("/Environment");
+ mapHasWater = envObj != null && envObj.GetComponent() != null && envObj.GetComponent().mapHasWater;
rbDrag = rigidBody.linearDamping;
UpdateOptions();
@@ -173,7 +207,7 @@ void Update()
if (mapHasWater)
{
swim = rigidBody.position.y < 0;
- rigidBody.useGravity = !swim;
+ // useGravity is always false — manual gravity handles swim vs air
if (swim) rigidBody.linearDamping = 1f;
else rigidBody.linearDamping = rbDrag;
@@ -210,42 +244,100 @@ bool GetTransformDirectionCollision()
// Do all movement in FixedUpdate method
void FixedUpdate()
{
+ // Refresh ground distance at physics rate
+ getDistanceToGround();
+ float dt = Time.fixedDeltaTime;
+
+ bool isGrounded = distanceToGround >= 0 && distanceToGround < groundLimit;
+
+ // --- Jump check every physics frame (matches original CheckJump) ---
+ // Original: checks if jump key is HELD + canJump + grounded → jumps instantly.
+ // This enables bunny hopping: press space mid-air, land, instant jump next frame.
+ if (isGrounded && jumpHeld && canJump && !crouching && !climbing && !swim)
+ {
+ canJump = false;
+ verticalVelocity = jumpForce;
+ pendingHandEffect = true;
+ }
+
+ // --- Vertical velocity (manual, like CharacterController) ---
+ // Apply gravity: _currentVelocity[1] -= Gravity * dt (original CharacterMoveController)
+ if (!isGrounded && !climbing)
+ {
+ if (swim)
+ verticalVelocity -= uberGravity * 0.1f * dt;
+ else
+ verticalVelocity -= uberGravity * dt;
+ }
+ else if (isGrounded && verticalVelocity < 0)
+ {
+ verticalVelocity = 0f; // Stop falling when grounded
+ }
+ // Clamp vertical velocity — original: Mathf.Clamp(_currentVelocity[1], -150, 150)
+ verticalVelocity = Mathf.Clamp(verticalVelocity, -150f, 150f);
+
+ // Swim up with spacebar
+ if (swim && Input.GetKey(KeyCode.Space))
+ verticalVelocity += uberGravity * 0.3f * dt;
+
+ // Ladder climbing — W=up, S=down. Use raw vertical input directly.
+ // Don't use walk velocity (it pushes INTO ladder, collision cancels movement).
+ if (climbing)
+ {
+ float climbInput = Input.GetAxisRaw("Vertical"); // W=1, S=-1
+ if (Mathf.Abs(climbInput) > 0.1f)
+ verticalVelocity = climbInput * moveSpeed * 1.5f;
+ else
+ verticalVelocity = 0f; // Hang on ladder when not pressing W/S
+ // Gentle push toward ladder to maintain OnCollisionStay contact
+ padPush = transform.forward * 1.5f;
+ }
+
//physics material
- if (distanceToGround < groundLimit && !GetTransformDirectionCollision()) capsule.material = null;
- else
- if(climbing) capsule.material = null;
+ if (isGrounded && !GetTransformDirectionCollision()) capsule.material = null;
+ else if (climbing) capsule.material = null;
else capsule.material = pMaterial;
// Player movement
SetMoveSpeed();
- if (rigidBody.linearVelocity.magnitude>0.3f|| movement.magnitude > 0.3f) Crouch(false);
- // If ladder collision
- if (climbing && movement!=Vector3.zero) rigidBody.MovePosition(rigidBody.position + transform.TransformDirection(Vector3.up) * moveSpeed*1.5f * Time.deltaTime);
+ // --- Authentic 4.7.1 horizontal movement: Quake accel + friction (CharacterMoveController) ---
+ // horizVel carries momentum across frames. Ground friction decelerates you; the low
+ // air-acceleration (3) with NO air friction is exactly what builds speed when strafe-jumping.
+ Vector3 wishDir = transform.TransformDirection(movement);
+ wishDir.y = 0f;
+ if (wishDir.sqrMagnitude > 1f) wishDir.Normalize();
- // If swim
- if (swim && GetComponent().isActiveAndEnabled&&distanceToGround>groundLimit&&!Input.GetKey(KeyCode.Space)) rigidBody.AddForce(-Vector3.up, ForceMode.Acceleration);
- else if(Input.GetKey(KeyCode.Space)) rigidBody.AddForce(Vector3.up, ForceMode.Acceleration);
+ if (isGrounded && !climbing) ApplyFriction(dt);
+ ApplyAcceleration(wishDir, moveSpeed, isGrounded ? groundAccel : airAccel, dt);
- Vector3 useTheForce = movement;
- // Jump speed gain
- if (sideways && distanceToGround > groundLimit
- && !swim && !climbing && distanceToGround < groundLimit + 2
- && Mathf.Abs(rigidBody.linearVelocity.z) < 6.6f && Mathf.Abs(rigidBody.linearVelocity.x) < 6.6f)
-
- if(sideways) rigidBody.AddForce(transform.TransformDirection(useTheForce) * moveSpeed * 1.8f,ForceMode.Acceleration);
- //else rigidBody.AddForce(transform.TransformDirection(useTheForce) * moveSpeed * 5f);
+ // Clamp horizontal speed (original ClampHorizontally = 22.8)
+ if (horizVel.sqrMagnitude > maxHorizontalSpeed * maxHorizontalSpeed)
+ horizVel = horizVel.normalized * maxHorizontalSpeed;
+
+ // --- Apply: Quake horizontal + manual vertical + external push (pads / explosions / ladder) ---
+ // linearVelocity is set fresh each frame; the physics engine resolves wall/ceiling collisions.
+ rigidBody.linearVelocity = new Vector3(horizVel.x, verticalVelocity, horizVel.z) + padPush;
- rigidBody.MovePosition(rigidBody.position + transform.TransformDirection(movement) * moveSpeed * Time.deltaTime);
+ // Decay external push only (pads/explosions/ladder). Walk deceleration is ApplyFriction above.
+ if (isGrounded)
+ padPush = Vector3.Lerp(padPush, Vector3.zero, 8f * dt);
+ else
+ padPush = Vector3.Lerp(padPush, Vector3.zero, 1.5f * dt);
+
+ // Player body rotation (uses accumulated mouse input)
+ Quaternion deltaRotation = Quaternion.Euler(new Vector3(0f, accumulatedMouseX, 0f) * rotationSpeed);
+ rigidBody.MoveRotation(rigidBody.rotation * deltaRotation);
+ accumulatedMouseX = 0f;
// Walk anim
if (movement.magnitude > 0.3f)
{
if (!handAnimator.enabled) handAnimator.Play("defaultHand");
-
+
// Enable animator
handAnimator.enabled = true;
- handAnimator.SetBool("walk", true);
+ handAnimator.SetBool("walk", true);
}
else
{
@@ -253,10 +345,10 @@ void FixedUpdate()
handAnimator.enabled = false;
handAnimator.SetBool("walk", false);
- float rectW = 1f; //1.2f
+ float rectW = 1f;
handCamera.rect = new Rect(handCamera.rect.x + -1f * playerRotationY * 0.001f, 0f, rectW, rectW);
handCamera.rect = new Rect(Mathf.SmoothDamp(handCamera.rect.x, 0f, ref handVelocityY, handTime * Time.deltaTime), 0f, rectW, rectW);
- if (handCamera.rect.x > -0.001f && handCamera.rect.x < 0.001f) handCamera.rect = new Rect(0f,0f,1f,1f);
+ if (handCamera.rect.x > -0.001f && handCamera.rect.x < 0.001f) handCamera.rect = new Rect(0f,0f,1f,1f);
}
// Hand Y
@@ -270,16 +362,41 @@ void FixedUpdate()
hand.transform.localPosition = new Vector3(0.263f, hand.transform.localPosition.y + -1f * playerRotationX * 0.001f,0.573f);
hand.transform.localPosition = Vector3.SmoothDamp(hand.transform.localPosition, new Vector3(0.263f, handPositionY, 0.573f), ref handVelocity, handTime * Time.deltaTime);
+ }
- // Player rotation
- Quaternion deltaRotation = Quaternion.Euler(new Vector3(0f, playerRotationY, 0f) * rotationSpeed * Time.deltaTime);
- rigidBody.MoveRotation(rigidBody.rotation * deltaRotation);
+ // --- Authentic Quake-style helpers (ported from CharacterMoveController 4.7.1) ---
+
+ // Ground friction: bleed off speed toward zero. No friction in air → momentum for bunny-hop.
+ private void ApplyFriction(float dt)
+ {
+ float speed = horizVel.magnitude;
+ if (speed < 0.0001f) { horizVel = Vector3.zero; return; }
+ float control = Mathf.Max(stopSpeed, speed);
+ float drop = control * groundFriction * dt;
+ float newSpeed = Mathf.Max(speed - drop, 0f) / speed;
+ horizVel *= newSpeed;
+ }
- // Player camera rotation
+ // Accelerate toward wishDir up to wishSpeed along that axis (classic Quake ground/air accel).
+ private void ApplyAcceleration(Vector3 wishDir, float wishSpeed, float accel, float dt)
+ {
+ float current = Vector3.Dot(horizVel, wishDir);
+ float add = wishSpeed - current;
+ if (add <= 0f) return;
+ float accelSpeed = accel * wishSpeed * dt;
+ if (accelSpeed > add) accelSpeed = add;
+ horizVel += wishDir * accelSpeed;
+ }
+
+ // Camera rotation in LateUpdate for smooth mouse look (runs every render frame, not fixed timestep)
+ void LateUpdate()
+ {
+ // Player camera vertical rotation
float clampAngle = 89f;
- lastRotation += playerRotationX * rotationSpeed * Time.deltaTime;
+ lastRotation += accumulatedMouseY * rotationSpeed;
lastRotation = Mathf.Clamp(lastRotation, -clampAngle, clampAngle);
playerCamera.localRotation = Quaternion.Euler(lastRotation, 0f, 0.0f);
+ accumulatedMouseY = 0f;
}
private void SetMoveSpeed()
@@ -290,15 +407,16 @@ private void SetMoveSpeed()
if (aiming)
{
- // Slow down when aim
+ // Slow down when aim — original UberStrike: PLAYER_ZOOM_SLOWDOWN = 1.8f
if(hand.GetComponent().currentWeapon.GetComponent() != null
|| hand.GetComponent().currentWeapon.GetComponent() != null)
{
- moveSpeed = groundMoveSpeed / 2.5f;
- }
+ moveSpeed = groundMoveSpeed - 1.8f;
+ }
}
- if(swim) moveSpeed = groundMoveSpeed / 4f;
+ if (crouching) moveSpeed = groundMoveSpeed * 0.23f; // Original UberStrike: PLAYER_DUCK_SCALE
+ if (swim) moveSpeed = groundMoveSpeed * 0.4f; // Original UberStrike: PLAYER_SWIM_SCALE
}
internal void MouseScroll(float scroll)
@@ -311,23 +429,16 @@ internal void MouseScroll(float scroll)
else if(scroll != 0) hand.SendMessage("SetWeaponIndex", scroll);
}
+ // Jump is now handled in FixedUpdate via jumpHeld state (continuous check).
+ // This method kept for any direct callers but FixedUpdate is the primary path.
internal void Jump()
{
Crouch(false);
- if (!canJump) return;
- else StartCoroutine(CanJumpAgain());
-
- if (distanceToGround < groundLimit+0.06 && distanceToGround > 0)
- {
- pendingHandEffect = true;
- rigidBody.AddForce(transform.up * jumpForce, ForceMode.Impulse);
- }
}
- IEnumerator CanJumpAgain()
+ // Called from PlayerInput when jump key is released
+ internal void JumpReleased()
{
- canJump = false;
- yield return new WaitForSeconds(0.3f);
canJump = true;
}
@@ -378,14 +489,18 @@ internal void MouseLook(float x, float y)
{
playerRotationY = x;
playerRotationX = y;
+ // Accumulate for physics (FixedUpdate) and camera (LateUpdate)
+ accumulatedMouseX += x * Time.deltaTime;
+ accumulatedMouseY += y * Time.deltaTime;
}
internal void Move(float x, float z)
{
if (distanceToGround < groundLimit)
- movement = Vector3.ClampMagnitude(new Vector3(z, 0f, x), 0.8f);
+ movement = Vector3.ClampMagnitude(new Vector3(z, 0f, x), 1f);
else
- movement = Vector3.Lerp(movement, Vector3.ClampMagnitude(new Vector3(z, 0f, x), 0.7f), 1.9f*Time.deltaTime);
+ // Air control: allow direction changes in air but slightly damped
+ movement = Vector3.Lerp(movement, Vector3.ClampMagnitude(new Vector3(z, 0f, x), 1f), 6f * Time.deltaTime);
}
// Spring grenade
@@ -416,11 +531,22 @@ internal void UseItem(int itemId)
}
- public void PowerUp(Vector3 forceDirection)
+ // Temporary horizontal push from jump pads (decays over time)
+ private Vector3 padPush = Vector3.zero;
+
+ ///
+ /// Called by ForceField/JumpPad. Accepts FINAL velocity vector (already scaled).
+ /// ForceField applies * 0.035 before calling. JumpPad applies its own multiplier.
+ /// Replaces velocity entirely (original ForceType.Exclusive behavior).
+ ///
+ public void PowerUp(Vector3 finalVelocity)
{
if (canUsePowerUp)
{
- rigidBody.AddForce(forceDirection * jumpForce, ForceMode.Impulse);
+ // Cap vertical — maxPadVerticalVel prevents extreme ceiling launches
+ verticalVelocity = Mathf.Clamp(finalVelocity.y, -maxPadVerticalVel, maxPadVerticalVel);
+ // Horizontal: let physics engine handle collision (no artificial cap needed)
+ padPush = new Vector3(finalVelocity.x, 0f, finalVelocity.z);
canUsePowerUp = false;
}
}
@@ -430,6 +556,21 @@ public void SetCanUsePowerUp(bool state)
canUsePowerUp = state;
}
+ ///
+ /// Apply explosion/rocket force to player. Additive — adds to current velocity
+ /// instead of replacing it (unlike PowerUp which is Exclusive).
+ /// Use this for rocket jumps, splash damage knockback, spring grenades, etc.
+ /// Original: ForceType.Additive → _currentVelocity = Scale(vel, (1, 0.5, 1)) + force * 0.035
+ ///
+ public void ApplyExplosionForce(Vector3 force)
+ {
+ // Original additive: halves existing vertical velocity, adds scaled force
+ verticalVelocity = verticalVelocity * 0.5f + force.y;
+ // Always apply horizontal — ground friction in padPush decay handles sliding.
+ // Rocket jumping at your feet while grounded needs the horizontal push to work.
+ padPush += new Vector3(force.x, 0f, force.z);
+ }
+
void getDistanceToGround()
{
// Get closest ground around player
@@ -501,10 +642,15 @@ internal void SetWeapon(int position)
internal void Crouch(bool crouch)
{
- if (climbing || swim || rigidBody.linearVelocity != Vector3.zero) crouch = false;
- if(crouch==crouching) return;
- cameraAnimator.SetBool("down",crouch);
+ // Original UberStrike: can crouch while moving (duck walk at 23% speed)
+ // Only prevent crouch when climbing, swimming, or in air
+ if (climbing || swim) crouch = false;
+ bool isGrounded = distanceToGround >= 0 && distanceToGround < groundLimit;
+ if (!isGrounded && crouch) crouch = false; // Can't start crouching mid-air
+ if (crouch == crouching) return;
+ cameraAnimator.SetBool("down", crouch);
crouching = crouch;
- if (GameObject.Find("/Network Client")) GameObject.Find("/Network Client").SendMessage("LocalPlayerCrouch", crouching);
+ GameObject networkClient = GameObject.Find("/Network Client");
+ if (networkClient != null) networkClient.SendMessage("LocalPlayerCrouch", crouching);
}
}
diff --git a/Assets/Gameplay/Player Scrips/PlayerUI.cs b/Assets/Gameplay/Player Scrips/PlayerUI.cs
index b3a94adb0..95dbf8e53 100644
--- a/Assets/Gameplay/Player Scrips/PlayerUI.cs
+++ b/Assets/Gameplay/Player Scrips/PlayerUI.cs
@@ -143,7 +143,12 @@ public void ToggleSniperScope(bool show)
internal void SetIcon(int itemId, GameObject item)
{
- ((itemId == 0) ? primaryIcon : secondaryIcon).GetComponent().sprite = item.GetComponent().icon;
+ if (item == null) return;
+ var quickItem = item.GetComponent();
+ if (quickItem != null && quickItem.icon != null)
+ {
+ ((itemId == 0) ? primaryIcon : secondaryIcon).GetComponent().sprite = quickItem.icon;
+ }
}
public void Zoom(float input)
diff --git a/Assets/LibraryAssets/_MK/MKGlassFree/Shader/Inc/Forward/MKGlassForward.cginc b/Assets/LibraryAssets/_MK/MKGlassFree/Shader/Inc/Forward/MKGlassForward.cginc
index 973e9c6d7..88199eeeb 100644
--- a/Assets/LibraryAssets/_MK/MKGlassFree/Shader/Inc/Forward/MKGlassForward.cginc
+++ b/Assets/LibraryAssets/_MK/MKGlassFree/Shader/Inc/Forward/MKGlassForward.cginc
@@ -65,12 +65,11 @@
UNITY_TRANSFER_LIGHTING(o,v.texcoord0.xy);
#endif
- //vertex fog
+ //vertex fog (fogCoord only declared on Unity < 2018; Unity 6 struct uses UNITY_LIGHTING_COORDS, no fogCoord)
+ #if UNITY_VERSION < 201800
UNITY_TRANSFER_FOG(o,o.pos);
#endif
-
- //vertex fog
- UNITY_TRANSFER_FOG(o,o.pos);
+ #endif
#if UNITY_UV_STARTS_AT_TOP
float scale = -1.0;
@@ -114,8 +113,10 @@
mkts.Color_Out.a = lerp(0.625, 0.95, _MainTint);
- //if enabled add some fog - forward rendering only
+ //if enabled add some fog - forward rendering only (fogCoord only on Unity < 2018)
+ #if UNITY_VERSION < 201800
UNITY_APPLY_FOG(o.fogCoord, mkts.Color_Out);
+ #endif
return mkts.Color_Out;
}
#endif
\ No newline at end of file
diff --git a/Assets/Menus/Scripts/CreateGamePopup.cs b/Assets/Menus/Scripts/CreateGamePopup.cs
index d9e7a2032..ce47a8e50 100644
--- a/Assets/Menus/Scripts/CreateGamePopup.cs
+++ b/Assets/Menus/Scripts/CreateGamePopup.cs
@@ -56,11 +56,9 @@ void Awake()
public void CreateGame()
{
- if (gameMode == 2)
- {
- container.SetActive(false);
- StartCoroutine(LoadAsync(map+2));
- }
+ container.SetActive(false);
+ // Scene indices: 0=GlobalScene, 1=MainMenu, 2=Intro, 3+=Maps
+ StartCoroutine(LoadAsync(map+3));
}
public void CancelGame()
diff --git a/Assets/Menus/Scripts/MouseOrbitImproved.cs b/Assets/Menus/Scripts/MouseOrbitImproved.cs
index 84e7da854..abb62a906 100644
--- a/Assets/Menus/Scripts/MouseOrbitImproved.cs
+++ b/Assets/Menus/Scripts/MouseOrbitImproved.cs
@@ -23,9 +23,15 @@ public class MouseOrbitImproved : MonoBehaviour
void Start()
{
// Skybox
- RenderSettings.skybox = GameObject.Find("/Environment").GetComponent().skybox;
+ GameObject environmentObject = GameObject.Find("/Environment");
+ Environment environment = environmentObject != null ? environmentObject.GetComponent() : null;
+ if (environment != null) RenderSettings.skybox = environment.skybox;
- target = GameObject.Find("/Player Avatar").transform.GetChild(2);
+ GameObject playerAvatar = GameObject.Find("/Player Avatar");
+ if (playerAvatar != null && playerAvatar.transform.childCount > 2)
+ {
+ target = playerAvatar.transform.GetChild(2);
+ }
Vector3 angles = transform.eulerAngles;
x = angles.y;
@@ -48,6 +54,8 @@ void LateUpdate()
private void Run()
{
+ if (target == null) return;
+
x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
@@ -78,4 +86,4 @@ public static float ClampAngle(float angle, float min, float max)
return Mathf.Clamp(angle, min, max);
}
-}
\ No newline at end of file
+}
diff --git a/Assets/Menus/Scripts/TopBarUI.cs b/Assets/Menus/Scripts/TopBarUI.cs
index f134b6198..cf63547c4 100644
--- a/Assets/Menus/Scripts/TopBarUI.cs
+++ b/Assets/Menus/Scripts/TopBarUI.cs
@@ -54,8 +54,9 @@ public class TopBarUI : MonoBehaviour
void Start()
{
// Skybox
- if(GameObject.Find("/Environment"))
- if(GameObject.Find("/Environment").GetComponent().skybox!=null)RenderSettings.skybox = GameObject.Find("/Environment").GetComponent().skybox;
+ GameObject environmentObject = GameObject.Find("/Environment");
+ Environment environment = environmentObject != null ? environmentObject.GetComponent() : null;
+ if (environment != null && environment.skybox != null) RenderSettings.skybox = environment.skybox;
//audio
@@ -313,7 +314,8 @@ private void UpdateUsername()
{
string newName = PlayerPrefs.GetString("username");
topBarUsername.GetComponent().text = newName;
- if (GameObject.Find("/Player Avatar")) GameObject.Find("/Player Avatar").SendMessage("UpdateNameTag");
+ GameObject playerAvatar = GameObject.Find("/Player Avatar");
+ if (playerAvatar != null) playerAvatar.SendMessage("UpdateNameTag");
}
// clears all local data
@@ -325,16 +327,28 @@ public void ClearLocalData()
public void SpawnPlayerInGame()
{
- if (inTheMenus|| respawnCanvas.GetChild(0).gameObject.GetComponent().currentTime>0) return;
+ if (inTheMenus || respawnCanvas == null || respawnCanvas.childCount == 0) return;
+
+ GameObject respawnPanel = respawnCanvas.GetChild(0).gameObject;
+ RespawnManager respawnManager = respawnPanel.GetComponent();
+ if (respawnManager != null && respawnManager.currentTime > 0) return;
spawnActions.SetActive(false);
// hide player avatar
if(GameObject.Find("/Player Avatar")) GameObject.Find("/Player Avatar").SetActive(false);
- respawnCanvas.GetChild(0).gameObject.SetActive(false);
+ respawnPanel.SetActive(false);
// create player
- GameObject.Find("/Network Client").GetComponent().LocalPlayerSpawn();
+ GameObject networkClientObject = GameObject.Find("/Network Client");
+ Client networkClient = networkClientObject != null ? networkClientObject.GetComponent() : null;
+ if (networkClient == null)
+ {
+ Debug.LogWarning("SpawnPlayerInGame skipped because /Network Client was not found.");
+ return;
+ }
+
+ networkClient.LocalPlayerSpawn();
HideMenuSystemForGame();
}
@@ -353,13 +367,15 @@ public void EditLoadoutInGame()
{
gameObject.SetActive(true);
NavigationBar(2);
- respawnCanvas.GetChild(0).gameObject.SetActive(false);
+ if (respawnCanvas != null && respawnCanvas.childCount > 0)
+ respawnCanvas.GetChild(0).gameObject.SetActive(false);
//if(GameObject.Find("/Dead Player")) GameObject.Find("/Dead Player").GetComponentInChildren().rect = new Rect(-0.33f, 0f, 1f, 1f);
}
public void ResumeGame()
{
- GameObject.Find("/Player").SendMessage("ContinueGame");
+ GameObject player = GameObject.Find("/Player");
+ if (player != null) player.SendMessage("ContinueGame");
HideMenuSystemForGame();
}
@@ -377,12 +393,23 @@ void HideMenuSystemForGame()
public void LeaveServer()
{
- GameObject.Find("/Network Client").GetComponent().Quit();
+ GameObject networkClientObject = GameObject.Find("/Network Client");
+ Client networkClient = networkClientObject != null ? networkClientObject.GetComponent() : null;
+ if (networkClient == null)
+ {
+ Debug.LogWarning("LeaveServer skipped Client.Quit because /Network Client was not found.");
+ }
+ else
+ {
+ networkClient.Quit();
+ }
+
SceneManager.LoadScene("MainMenu");
}
public void KillYourself()
{
- if (GameObject.Find("/Player")) GameObject.Find("/Player").SendMessage("KillYourself");
+ GameObject player = GameObject.Find("/Player");
+ if (player != null) player.SendMessage("KillYourself");
}
}
diff --git a/Assets/Menus/Shop/QuickItemShopItem.cs b/Assets/Menus/Shop/QuickItemShopItem.cs
index ac1ca2ba4..6766244db 100644
--- a/Assets/Menus/Shop/QuickItemShopItem.cs
+++ b/Assets/Menus/Shop/QuickItemShopItem.cs
@@ -10,12 +10,12 @@ public class QuickItemShopItem : ShopItem, IShopItem
internal override string GetName()
{
- return prefab.GetComponent().itemName;
+ return prefab.GetComponent().itemName;
}
internal override Sprite GetThumb()
{
- return prefab.GetComponent().thumbnail;
+ return prefab.GetComponent().thumbnail;
}
// quickitems are not created dynamically,
diff --git a/Assets/Menus/Shop/ShopKeeper.cs b/Assets/Menus/Shop/ShopKeeper.cs
index 49be37a2f..c80e62dc4 100644
--- a/Assets/Menus/Shop/ShopKeeper.cs
+++ b/Assets/Menus/Shop/ShopKeeper.cs
@@ -42,14 +42,19 @@ public class ShopKeeper : MonoBehaviour
void Start()
{
// get global resources
- GlobalResources r = GameObject.Find("/Global Resources").GetComponent();
- weaponPrefabs = r.weapons.ToArray();
- appereancePrefabs = r.appereances.ToArray();
+ GameObject globalResourcesObject = GameObject.Find("/Global Resources");
+ GlobalResources r = globalResourcesObject != null ? globalResourcesObject.GetComponent() : null;
+ if (r != null)
+ {
+ weaponPrefabs = r.weapons.ToArray();
+ appereancePrefabs = r.appereances.ToArray();
+ }
InitItemSlots();
audioSource = transform.parent.gameObject.GetComponent();
- playerAvatar = GameObject.Find("/Player Avatar").GetComponent();
- UpdateAvatar();
+ GameObject playerAvatarObject = GameObject.Find("/Player Avatar");
+ if (playerAvatarObject != null) playerAvatar = playerAvatarObject.GetComponent();
+ if (playerAvatar != null) UpdateAvatar();
}
// show only appereances of one class
@@ -144,7 +149,7 @@ public void Drag(GameObject prefab, Sprite sprite, bool slotToSlot)
// show right tab for draggable item
// for springs
- if (prefab.GetComponent() != null)
+ if (prefab.GetComponent() != null)
{
transform.parent.gameObject.GetComponent().LoadoutTabs(2);
}
@@ -204,7 +209,7 @@ public void EndDrag()
if (mouseOnSlot && availableSlots.Contains(mouseOnSlot))
{
// Equip items
- if (prefabInDrag.GetComponent() != null)
+ if (prefabInDrag.GetComponent() != null)
{
audioSource.PlayOneShot(equipSoundQuickitem);
}
@@ -271,9 +276,9 @@ public string GetNameFromPrefab(GameObject prefab)
}
// in case if spring
- else if (prefab.GetComponent() != null)
+ else if (prefab.GetComponent() != null)
{
- return prefab.GetComponent().itemName;
+ return prefab.GetComponent().itemName;
}
// in case of cloth
else if (prefab.GetComponent() != null)
@@ -291,9 +296,9 @@ public string GetTypeFromPrefab(GameObject prefab)
return prefab.GetComponent().GetType().ToString();
}
// in case of spring
- else if (prefab.GetComponent() != null)
+ else if (prefab.GetComponent() != null)
{
- return prefab.GetComponent().type;
+ return prefab.GetComponent().type;
}
// in case of cloth
else if (prefab.GetComponent() != null)
@@ -313,9 +318,9 @@ public Sprite GetSpriteFromPrefab(GameObject prefab)
}
// in case if spring
- else if (prefab.GetComponent() != null)
+ else if (prefab.GetComponent() != null)
{
- return prefab.GetComponent().thumbnail;
+ return prefab.GetComponent().thumbnail;
}
// in case of cloth
else if (prefab.GetComponent() != null)
@@ -435,10 +440,13 @@ public void SpawnToShootingRange()
{
if (GameObject.Find("/MenuSystem"))
{
+ if (playerAvatar == null) return;
playerAvatar.gameObject.SetActive(false);
GameObject clonePlayer = Instantiate(player);
clonePlayer.name = "Player";
- GameObject.Find("/Environment").GetComponent().volume = 0f;
+ GameObject environmentObject = GameObject.Find("/Environment");
+ AudioSource environmentAudio = environmentObject != null ? environmentObject.GetComponent() : null;
+ if (environmentAudio != null) environmentAudio.volume = 0f;
GameObject.Find("/MenuSystem").SetActive(false);
}
diff --git a/Assets/Prefabs/Powerups/Scripts/JumpPad.cs b/Assets/Prefabs/Powerups/Scripts/JumpPad.cs
index 1e025510e..5ded53269 100644
--- a/Assets/Prefabs/Powerups/Scripts/JumpPad.cs
+++ b/Assets/Prefabs/Powerups/Scripts/JumpPad.cs
@@ -11,6 +11,10 @@ public class JumpPad : MonoBehaviour
public bool isAccel = false;
public float accelMultiply = 5f;
+ [Tooltip("Multiplier applied to forceDirection before sending to PlayerMotor. " +
+ "Sends final velocity directly — no extra modifier applied by PlayerMotor.")]
+ public float forceMultiplier = 10f;
+
void Start()
{
audioSource = GetComponent();
@@ -20,9 +24,15 @@ void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
{
- if (isAccel) other.gameObject.SendMessage("PowerUp",(transform.forward*accelMultiply)+new Vector3(0f,forceDirection.y,0f));
- else other.gameObject.SendMessage("PowerUp", forceDirection);
- audioSource.Play(0);
+ Vector3 finalVelocity;
+ if (isAccel)
+ finalVelocity = (transform.forward * accelMultiply + new Vector3(0f, forceDirection.y, 0f)) * forceMultiplier;
+ else
+ finalVelocity = forceDirection * forceMultiplier;
+
+ // PowerUp receives final velocity — sets it directly
+ other.gameObject.SendMessage("PowerUp", finalVelocity);
+ if (audioSource != null) audioSource.Play(0);
}
}
diff --git a/Assets/Prefabs/Powerups/Scripts/SpringGrenade.cs b/Assets/Prefabs/Powerups/Scripts/SpringGrenade.cs
index 539c9d3c0..f90eb178f 100644
--- a/Assets/Prefabs/Powerups/Scripts/SpringGrenade.cs
+++ b/Assets/Prefabs/Powerups/Scripts/SpringGrenade.cs
@@ -24,11 +24,11 @@ void OnTriggerStay(Collider other)
{
if (other.tag == "Player" && isArmed)
{
- // Explode grenade
- Vector3 forceVector = new Vector3(0f, jumpForce, 0f);
- other.gameObject.SendMessage("PowerUp", forceVector);
+ // Spring grenade — launches player upward (additive)
+ // Original: ForceType.Additive with force=1250 → 1250*0.035 = 43.75 vel
+ Vector3 springForce = new Vector3(0f, jumpForce * 15f, 0f);
+ other.gameObject.SendMessage("ApplyExplosionForce", springForce, SendMessageOptions.DontRequireReceiver);
Destroy(gameObject);
- other.gameObject.SendMessage("SetCanUsePowerUp", true);
// Sound
PlayerAudio audio = other.gameObject.GetComponent();
diff --git a/Assets/Prefabs/Powerups/Scripts/StickyMine.cs b/Assets/Prefabs/Powerups/Scripts/StickyMine.cs
index f575618c1..ca0557960 100644
--- a/Assets/Prefabs/Powerups/Scripts/StickyMine.cs
+++ b/Assets/Prefabs/Powerups/Scripts/StickyMine.cs
@@ -95,9 +95,15 @@ private void Explosion()
transform.position,
-1, -1);
- // Jump
- hitColliders[i].SendMessage("PowerUp", (hitColliders[i].transform.position - transform.position) / 2 * selfJumpPower);
- hitColliders[i].SendMessage("SetCanUsePowerUp", true);
+ // Explosion jump — additive force
+ float dist = Vector3.Distance(hitColliders[i].transform.position, transform.position);
+ if (dist < smallDmgRadius)
+ {
+ Vector3 blastDir = (hitColliders[i].transform.position - transform.position).normalized;
+ float proximityScale = 1f - (dist / smallDmgRadius);
+ Vector3 rocketForce = blastDir * selfJumpPower * proximityScale * 12f;
+ hitColliders[i].SendMessage("ApplyExplosionForce", rocketForce, SendMessageOptions.DontRequireReceiver);
+ }
}
i++;
diff --git a/Assets/Prefabs/Weapons/Cannons/Cannon/cannon_projectile/CannonBullet.cs b/Assets/Prefabs/Weapons/Cannons/Cannon/cannon_projectile/CannonBullet.cs
index fcde5920f..aafe8e46f 100644
--- a/Assets/Prefabs/Weapons/Cannons/Cannon/cannon_projectile/CannonBullet.cs
+++ b/Assets/Prefabs/Weapons/Cannons/Cannon/cannon_projectile/CannonBullet.cs
@@ -112,12 +112,17 @@ private void Explosion()
transform.position,
-1, -1);
- // Jump
+ // Rocket jump — use ApplyExplosionForce (additive, doesn't replace velocity)
+ // Direction: away from explosion, scaled by selfJumpPower
float dist = Vector3.Distance(hitColliders[i].transform.position, transform.position);
-
- if(dist<2) hitColliders[i].SendMessage("PowerUp", Vector3.Normalize((hitColliders[i].transform.position - transform.position)) * selfJumpPower);
-
- hitColliders[i].SendMessage("SetCanUsePowerUp", true);
+ if (dist < smallDmgRadius)
+ {
+ Vector3 blastDir = (hitColliders[i].transform.position - transform.position).normalized;
+ // Scale force by proximity (closer = stronger) and selfJumpPower
+ float proximityScale = 1f - (dist / smallDmgRadius);
+ Vector3 rocketForce = blastDir * selfJumpPower * proximityScale * 12f;
+ hitColliders[i].SendMessage("ApplyExplosionForce", rocketForce, SendMessageOptions.DontRequireReceiver);
+ }
}
i++;
diff --git a/Assets/Prefabs/Weapons/Launchers/Launcher/grenade/LauncherGrenade.cs b/Assets/Prefabs/Weapons/Launchers/Launcher/grenade/LauncherGrenade.cs
index cc9a860f2..fd97912c7 100644
--- a/Assets/Prefabs/Weapons/Launchers/Launcher/grenade/LauncherGrenade.cs
+++ b/Assets/Prefabs/Weapons/Launchers/Launcher/grenade/LauncherGrenade.cs
@@ -109,13 +109,19 @@ private void Explosion()
// Send damage
if (GameObject.Find("/Player"))
GameObject.Find("/Player").GetComponent().TakeDamage(
- Mathf.Floor(GetDmg(Vector3.Distance(hitColliders[i].transform.position, transform.position)) / reduceDmgToSelfBy),
- transform.position,
+ Mathf.Floor(GetDmg(Vector3.Distance(hitColliders[i].transform.position, transform.position)) / reduceDmgToSelfBy),
+ transform.position,
-1,-1);
-
- // Jump
- hitColliders[i].SendMessage("PowerUp", (hitColliders[i].transform.position - transform.position) / 2 * selfJumpPower);
- hitColliders[i].SendMessage("SetCanUsePowerUp", true);
+
+ // Rocket jump — use ApplyExplosionForce (additive, doesn't replace velocity)
+ float dist = Vector3.Distance(hitColliders[i].transform.position, transform.position);
+ if (dist < smallDmgRadius)
+ {
+ Vector3 blastDir = (hitColliders[i].transform.position - transform.position).normalized;
+ float proximityScale = 1f - (dist / smallDmgRadius);
+ Vector3 rocketForce = blastDir * selfJumpPower * proximityScale * 12f;
+ hitColliders[i].SendMessage("ApplyExplosionForce", rocketForce, SendMessageOptions.DontRequireReceiver);
+ }
}
diff --git a/Assets/Prefabs/Weapons/Shotgun.cs b/Assets/Prefabs/Weapons/Shotgun.cs
index 6a22d42a4..aa7e38c4c 100644
--- a/Assets/Prefabs/Weapons/Shotgun.cs
+++ b/Assets/Prefabs/Weapons/Shotgun.cs
@@ -40,6 +40,7 @@ public override void FiringActions()
if (shellIndex) SpitShell(shellIndex, shellSpeed, 2);
FireMuzzle();
+ if (bulletTrail == null) return;
List hitData = GetRaycastHitObject(maxRange, spread, shotCount);
@@ -116,6 +117,8 @@ public override void FireMuzzle()
internal override void NetworkFire(RaycastHit target)
{
+ if (bulletTrail == null) return;
+
List hitData = GetRaycastHitObject(muzzleIndex, target.point, spread, shotCount);
if (hitData.Count > 0)
diff --git a/Assets/Prefabs/Weapons/Weapon.cs b/Assets/Prefabs/Weapons/Weapon.cs
index af98988c5..c09462e60 100644
--- a/Assets/Prefabs/Weapons/Weapon.cs
+++ b/Assets/Prefabs/Weapons/Weapon.cs
@@ -296,10 +296,12 @@ internal Vector3 GetSpread(Vector2 spread)
// same with sound option
public void BulletTrail(Transform pos, Vector3 targetPoint, bool hasSound)
{
+ if (bulletTrail == null) return;
Transform clonet = Instantiate(bulletTrail, pos.position, pos.rotation);
clonet.LookAt(targetPoint);
- clonet.gameObject.GetComponent().sound = hasSound;
- Destroy(clonet.gameObject, 1f);
+ var trail = clonet.gameObject.GetComponent();
+ if (trail != null) trail.sound = hasSound;
+ Destroy(clonet.gameObject, 1f);
}
//custom narrator
diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset
index bb11a5530..e930e9ed5 100644
--- a/ProjectSettings/EditorBuildSettings.asset
+++ b/ProjectSettings/EditorBuildSettings.asset
@@ -6,11 +6,14 @@ EditorBuildSettings:
serializedVersion: 2
m_Scenes:
- enabled: 1
- path: Assets/Menus/Intro.unity
- guid: f7b286020c378264982286603976c541
+ path: Assets/Scenes/GlobalScene.unity
+ guid: 1f05f0a7b71d0f948aa23c64e11f1d87
- enabled: 1
path: Assets/Menus/MainMenu.unity
guid: 850382a7f8c81ea47a2504469e81789a
+ - enabled: 1
+ path: Assets/Menus/Intro.unity
+ guid: f7b286020c378264982286603976c541
- enabled: 1
path: Assets/Maps/Apex_Twin/Apex_Twin.unity
guid: c3fdb28bd94380940b61db76ac6dac05
@@ -56,5 +59,14 @@ EditorBuildSettings:
- enabled: 1
path: Assets/Maps/The_Hangar/The_Hangar.unity
guid: 4d951c4843244e845983843c4a3122d9
+ - enabled: 0
+ path: Assets/Maps/CuberStrike/CuberStrike.unity
+ guid: 91b2e7bed92e18c4a8ad5564553783ac
+ - enabled: 0
+ path: Assets/Maps/GhostIsland/GhostIsland.unity
+ guid: 1dcd903f1950d7f4da9fef161c9524c6
+ - enabled: 0
+ path: Assets/Maps/Volley/Volley.unity
+ guid: ca5011381629bf14da393b88ade88224
m_configObjects: {}
m_UseUCBPForAssetBundles: 0