{"id":25158298,"url":"https://github.com/playstel/fishing_netcode_matchmaker","last_synced_at":"2025-04-03T12:41:36.816Z","repository":{"id":260651037,"uuid":"881960402","full_name":"playstel/fishing_netcode_matchmaker","owner":"playstel","description":"Fishing for 4 players using Unity Netcode, Multiplay Hosting + Matchmaking","archived":false,"fork":false,"pushed_at":"2025-01-21T16:15:15.000Z","size":123308,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-09T01:49:32.610Z","etag":null,"topics":["matching","netcode"],"latest_commit_sha":null,"homepage":"","language":"ASP.NET","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/playstel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-01T15:25:03.000Z","updated_at":"2025-01-21T16:15:21.000Z","dependencies_parsed_at":"2025-01-21T17:33:11.961Z","dependency_job_id":null,"html_url":"https://github.com/playstel/fishing_netcode_matchmaker","commit_stats":null,"previous_names":["playstel/gunfishing","playstel/fishing_netcode_matchmaker"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playstel%2Ffishing_netcode_matchmaker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playstel%2Ffishing_netcode_matchmaker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playstel%2Ffishing_netcode_matchmaker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playstel%2Ffishing_netcode_matchmaker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/playstel","download_url":"https://codeload.github.com/playstel/fishing_netcode_matchmaker/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247005346,"owners_count":20868018,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["matching","netcode"],"created_at":"2025-02-09T01:49:38.106Z","updated_at":"2025-04-03T12:41:36.753Z","avatar_url":"https://github.com/playstel.png","language":"ASP.NET","readme":"# Gun Fishing\n\nThis small project describes working with a Unity Netcode.\n\nGame process:\n\n![image](https://github.com/user-attachments/assets/600ad8a3-6953-4053-897f-4e065ec8be94)\n\n\nMax shooting rate is 12 bullets per second; manual and auto-fire modes (press \"Space\" to switch modes).\nMultiple fish types with random movement (Rust, Purple, Gold). Each type has its speed, volatility, scale, and image, and can have one of 3 rarities (Common, Rare, Legendary), lower volatility fish gives fewer points and is easier to hit.\nAll bullets move at the same speed and are destroyed upon hitting a fish only; bullets have a ricochet, so they remain on the map until they hit a fish (previous rule).\nRecording and displaying the outcome of the last 12 shots for the local player and the total score. For other players, display only the total score.\n\nLobby as a guest, 4 players maximum per lobby:\n\n![image](https://github.com/user-attachments/assets/b8286d22-f187-477e-a737-915b80da209e)\n\n\nBullets and fish have Network Transform.\n\n![image](https://github.com/user-attachments/assets/36015edc-f51e-4ef6-950c-8b804b35d062)\n\n\nShooting through ServerRPC\n\n        [ServerRpc]\n        private void ShootServerRpc(ulong owner)\n        {\n            var bulletInstance = NetworkManager.Singleton.SpawnManager\n                .InstantiateAndSpawn(bulletObject, ownerClientId: owner, position: _transform.position + Vector3.up, rotation: bulletPrefab.transform.rotation);\n            \n            bulletInstance.TryGetComponent(out GunBullet bullet);\n            {\n                bullet.SetHost(this);\n                SuccessRateCheck();\n            }\n        }\n        \n\nUpdating player position through ServerRPC with Unreliable Delivery + NetworkVariable\u003cVector2\u003e:\n\n\n        private void UpdatePosition(Vector2 worldPosition)\n        {\n            var newPosition = new Vector2(worldPosition.x, PosY);\n            _transform.position = newPosition;\n            UpdatePositionServerRpc(newPosition);\n        }\n        \n        [ServerRpc(Delivery = RpcDelivery.Unreliable)]\n        private void UpdatePositionServerRpc(Vector2 newPosition)\n        {\n            if ((_networkPosition.Value - newPosition).sqrMagnitude \u003e 0.01f)\n            {\n                _networkPosition.Value = newPosition;\n            }\n        }\n        \n        [ServerRpc]\n        private void SetPlayerInfoServerRpc(ulong playerId)\n        {\n            if (RoomPlayersManager.Instance == null)\n            {\n                Debug.LogError(\"Failed to find RoomPlayersManager.Instance\");\n                return;\n            }\n            \n            RoomPlayersManager.Instance.AddPlayer(playerId, this);\n        }\n\n\n\nCatching fish through ServerRPC and ClientRPC with Reliable Delivery and without Ownership requirements:\n\n\n        private void OnTriggerEnter2D(Collider2D other)\n        {\n            if (other == null)\n            {\n                Debug.LogError(\"Failed to find trigger collider\");\n                return;\n            }\n            \n            if (!other.CompareTag(\"Bullet\")) return;\n\n            if (other.TryGetComponent(out GunFishing.Gun.GunBullet bullet))\n            {\n                CatchFishServerRpc(bullet.OwnerClientId);\n            }\n        }\n\n        [ServerRpc(RequireOwnership = false, Delivery = RpcDelivery.Reliable)]\n        private void CatchFishServerRpc(ulong playerId)\n        {\n            if (isCaught.Value) return;\n            \n            isCaught.Value = true;\n            \n            UpdateClientRpc(playerId);\n            \n            RoomInfoUi.Instance.AddTotalScore(points.Value);\n\n            NetworkObject.Destroy(gameObject);\n        }\n\n        [ClientRpc(RequireOwnership = false, Delivery = RpcDelivery.Reliable)]\n        private void UpdateClientRpc(ulong playerId)\n        {\n            Debug.Log($\"Fish caught by player {playerId}\");\n\n            RoomInfoUi.Instance.RegisterShot(points.Value, $\"{volatility.Value} {fishType} fish\", playerId);\n            \n            if (playerId == NetworkManager.Singleton.LocalClientId)\n            {\n                RoomPlayersManager.Instance.RegisterHit(playerId);\n            }\n        }\n\n---\n\nAll network scripts are separated from UI logic. The lobby code with Relay or Dedicated server can be found in the start scene.\n\nYou can find the Dedicated Server build in the \"DedicatedServer_Linux\" folder. \n\nDedicated Server (Multiplay Hosting):\n\n![image](https://github.com/user-attachments/assets/09a3d4ee-194d-4085-b790-50dc956c0ce5)\n![image](https://github.com/user-attachments/assets/7d9a11ce-e6c7-4637-b93e-569c771419db)\n![image](https://github.com/user-attachments/assets/092fbd4a-b57a-42df-8e1f-4a7e8902af54)\n\n        private async void Start()\n        {\n            #if SERVER\n            \n            try\n            {\n                Application.targetFrameRate = 60;\n\n                await UnityServices.InitializeAsync();\n                    \n                _serverQueryHandler = await MultiplayService.Instance\n                    .StartServerQueryHandlerAsync(maxPlayers, serverName, gameType, buildId, map);\n\n                ServerConfig serverConfig = MultiplayService.Instance.ServerConfig;\n                \n                await UniTask.WaitUntil(() =\u003e serverConfig.AllocationId != string.Empty);\n\n                var result = NetworkUnityServices.Instance.StartDedicatedServer(serverConfig.Port);\n\n                if (result)\n                {\n                    Debug.Log(\"--- Server has started | Port: \" + serverConfig.Port + \" | Ip: \" + serverConfig.IpAddress);\n                    await MultiplayService.Instance.ReadyServerForPlayersAsync();\n                    _serverHasStarted = true;\n                }\n                else\n                {\n                    Debug.LogError(\"--- Failed to start dedicated server | Port: \" + serverConfig.Port + \" | Ip: \" + serverConfig.IpAddress);\n                }\n            }\n            catch (Exception e)\n            {\n                Debug.LogError(\"--- Failed to start linux dedicated server: \" + e);\n                throw;\n            }\n            \n            #endif\n        }\n\n\nUnity Cloud Relay:\n\n        \n        public async UniTask\u003cstring\u003e CreateRelay(bool loadGameScene = true)\n        {\n            try\n            {\n                NetworkStatusInfo.Instance.SetInfo(\"Creating Relay\");\n                \n                var allocation = await Unity.Services.Relay.Relay.Instance.CreateAllocationAsync(3);\n            \n                var relayJoinCode = await Unity.Services.Relay.Relay.Instance.GetJoinCodeAsync(allocation.AllocationId);\n\n                var relayServerData = new RelayServerData(allocation, _transportProtocol);\n\n                var result = NetworkUnityServices.Instance.StartRelayHost(relayServerData);\n            \n                NetworkStatusInfo.Instance.SetJoinCode(relayJoinCode);\n                \n                if (result)\n                {\n                    NetworkStatusInfo.Instance.SetInfo($\"You are the host\");\n                    \n                    if (loadGameScene)\n                    {\n                        NetworkSceneLoader.Instance.LoadGameScene();\n                    }\n                }\n                else\n                {\n                    NetworkStatusInfo.Instance.SetInfo($\"Failed to create a host\");\n                    return null;\n                }\n\n                return relayJoinCode;\n            }\n            catch (Exception e)\n            {\n                Debug.LogError($\"Relay error: {e.Message}\");\n                NetworkStatusInfo.Instance.SetInfo($\"Relay error: {e.Message}\");\n                return null;\n            }\n        }\n        \n        \n![image](https://github.com/user-attachments/assets/156db46c-31aa-4183-ae77-f146b5011a0b)\n\n\nYou can enable additional connection variants like direct Relay or Dedicated server connections in the Unity Editor:\n\n![image](https://github.com/user-attachments/assets/ef6bf5c7-043e-46ed-8c67-d469632606a1)\n\n\nLobby dashboard:\n\n![image](https://github.com/user-attachments/assets/a3d55fa1-42c1-4b9f-adf7-05d4769b054b)\n\n\nMatchmaker dashboard:\n\n![image](https://github.com/user-attachments/assets/2a57cd93-70de-4df9-b6cd-233b6888e0e6)\n\n---\n\nYou can learn more by downloading and running the project in Unity (2022.3.31f1). \n\n# Other\n\nMore projects https://playstel.com/\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplaystel%2Ffishing_netcode_matchmaker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplaystel%2Ffishing_netcode_matchmaker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplaystel%2Ffishing_netcode_matchmaker/lists"}