using System; using System.Collections.Generic; using System.Linq; using _PROJECT.Scripts.Bow; using FishNet.Object; using FishNet.Object.Synchronizing; using TMPro; using UnityEngine; using Random = UnityEngine.Random; public class ArcheryRange : NetworkBehaviour { public TMP_Text highScoreText; public TMP_Text timeLeftText; public TMP_Text scoreText; public Transform targetStartPosition; public Transform targetEndPosition; public GameObject targetPrefab; public StartTarget startTarget; public Vector3 minRandomOffset = new Vector3(0f, -2f, -5f); public Vector3 maxRandomOffset = new Vector3(0f, 2f, 5f); public float roundLength = 60f; public float targetSpawnTime = 3f; private List _targets; [SyncVar] private float _score; private float _maxScore; private float _roundEndTime; private float _nextTargetTime; private bool _roundActive; public override void OnStartServer() { base.OnStartServer(); _roundActive = false; _targets = new List(); _score = 0; _maxScore = 0; _roundEndTime = 0f; SetHighScoreText("High Score: 0"); } // Update is called once per frame void Update() { if (!IsServer) return; if (!_roundActive) return; if (Time.time >= _roundEndTime) { ResetRange(); } else { SetTimeLeftText($"Time Left: {Math.Ceiling((_roundEndTime - Time.time) % 60)}"); if (Time.time >= _nextTargetTime) { _nextTargetTime = Time.time + targetSpawnTime; SpawnTarget(); } } } private void SpawnTarget() { if (!IsServer) return; var randomPos = targetStartPosition.position + new Vector3( Random.Range(minRandomOffset.x, maxRandomOffset.x), (float)Math.Round(Random.Range(minRandomOffset.y, maxRandomOffset.y)), Random.Range(minRandomOffset.z, maxRandomOffset.z)); var target = SpawnTarget(randomPos); _targets.Add(target); } private ArcheryTarget SpawnTarget(Vector3 randomPos) { var prefab = Instantiate(targetPrefab, randomPos, Quaternion.identity, null); ArcheryTarget target = prefab.GetComponent(); target.endPosition = targetEndPosition.position; target.addScore = AddScore; Spawn(prefab); return target; } public void ResetRange() { if (!IsServer) return; foreach (var target in _targets.Where(target => target != null)) { Despawn(target.gameObject, DespawnType.Pool); } _targets = new List(); if (_maxScore < _score) _maxScore = _score; _score = 0; SetHighScoreText($"High Score: {_maxScore}"); startTarget.ShowTarget(); _roundActive = false; SetTimeLeftText(""); } public void StartRound() { if (!IsServer) return; _roundEndTime = Time.time + roundLength; _nextTargetTime = Time.time; _roundActive = true; } public void AddScore(float distance) { if (!IsServer) return; _score += distance; SetScoreText($"Score: {_score}"); } [ObserversRpc] public void SetHighScoreText(string text) { highScoreText.text = text; } [ObserversRpc] public void SetScoreText(string text) { scoreText.text = text; } [ObserversRpc] public void SetTimeLeftText(string text) { timeLeftText.text = text; } }