diff --git a/Assets/RicochetModifier.cs b/Assets/RicochetModifier.cs index f31221db9..7c05f3630 100644 --- a/Assets/RicochetModifier.cs +++ b/Assets/RicochetModifier.cs @@ -2,17 +2,17 @@ public class RicochetModifier : MonoBehaviour, ProjectileModifier { - public void ricochetProjectile(RaycastHit other, ref ProjectileState state) + private void RicochetProjectile(RaycastHit other, ref ProjectileState state) { state.direction = Vector3.Reflect(state.direction, other.normal); } public void Attach(ProjectileController projectile) { - projectile.OnColliderHit += ricochetProjectile; + projectile.OnColliderHit += RicochetProjectile; } public void Detach(ProjectileController projectile) { - projectile.OnColliderHit -= ricochetProjectile; + projectile.OnColliderHit -= RicochetProjectile; } } diff --git a/Assets/Scripts/Augment/AugmentImplementations/Hat/MeshProjectileController.cs b/Assets/Scripts/Augment/AugmentImplementations/Hat/MeshProjectileController.cs index 2a144ec4e..1741b241a 100644 --- a/Assets/Scripts/Augment/AugmentImplementations/Hat/MeshProjectileController.cs +++ b/Assets/Scripts/Augment/AugmentImplementations/Hat/MeshProjectileController.cs @@ -102,6 +102,9 @@ protected override void OnDestroy() base.OnDestroy(); positionActiveBuffer?.Dispose(); rotationBuffer?.Dispose(); + UpdateProjectileMovement -= ProjectileMotions.MoveWithGravity; + if (animator) + animator.OnShotFiredAnimation -= FireProjectile; } protected override void OnInitialize(GunStats gunstats) diff --git a/Assets/Scripts/Augment/AugmentImplementations/RevolverAnimator.cs b/Assets/Scripts/Augment/AugmentImplementations/RevolverAnimator.cs index daa967fed..121402dc9 100644 --- a/Assets/Scripts/Augment/AugmentImplementations/RevolverAnimator.cs +++ b/Assets/Scripts/Augment/AugmentImplementations/RevolverAnimator.cs @@ -1,5 +1,3 @@ -using System.Collections; -using System.Collections.Generic; using System.Linq; using UnityEngine; @@ -12,7 +10,7 @@ public class RevolverAnimator : AugmentAnimator private GunBarrel barrel; private GunExtension extension; - public override void OnFire(GunStats stats){} + public override void OnFire(GunStats stats) { } public override void OnInitialize(GunStats stats) { @@ -36,7 +34,5 @@ public override void OnReload(GunStats stats) if (extension) extension.transform.SetParent(attachmentSite, true); - - animator.SetTrigger("Reload"); } } diff --git a/Assets/Scripts/Augment/BulletModifiers/DecalModifier.cs b/Assets/Scripts/Augment/BulletModifiers/DecalModifier.cs index bd66c33fc..b04198035 100644 --- a/Assets/Scripts/Augment/BulletModifiers/DecalModifier.cs +++ b/Assets/Scripts/Augment/BulletModifiers/DecalModifier.cs @@ -48,8 +48,7 @@ public void Detach(ProjectileController projectile) { projectile.OnRicochet -= OnHit; } - decalPool.Flush(); - decalPool = null; + OnDestroy(); } private void OnHit(RaycastHit target, ref ProjectileState state) @@ -94,9 +93,7 @@ private Quaternion DetermineRotation(Collider target, ProjectileState state) private void OnDestroy() { - if (decalPool == null) - return; - decalPool.Flush(); + decalPool?.Flush(); decalPool = null; } } diff --git a/Assets/Scripts/Augment/BulletModifiers/InheritMomentumModifier.cs b/Assets/Scripts/Augment/BulletModifiers/InheritMomentumModifier.cs index 896bd6973..b121a89a3 100644 --- a/Assets/Scripts/Augment/BulletModifiers/InheritMomentumModifier.cs +++ b/Assets/Scripts/Augment/BulletModifiers/InheritMomentumModifier.cs @@ -47,6 +47,14 @@ public void Attach(ProjectileController projectile) projectile.OnProjectileInit += OnProjectileInit; } + public void Detach(ProjectileController projectile) + { + if (!projectile.GunController.Player) + return; + projectile.OnNetworkInit -= OnNetworkInit; + projectile.OnProjectileInit -= OnProjectileInit; + } + private void OnNetworkInit(ref ProjectileFireData data, GunStats _) { var speed = playerBody.velocity.magnitude; @@ -67,12 +75,4 @@ private void OnProjectileInit(ref ProjectileState state, GunStats stats) state.additionalProperties[ExplosionModifier.AreaDamagePropertyName] = damage * (1 - projectileToAreaDamageRatio); state.speed = Mathf.Max(1f, speed * speedMultiplier); } - - public void Detach(ProjectileController projectile) - { - if (!projectile.GunController.Player) - return; - projectile.OnNetworkInit -= OnNetworkInit; - projectile.OnProjectileInit -= OnProjectileInit; - } } diff --git a/Assets/Scripts/Augment/BulletModifiers/KnockbackOnShotModifier.cs b/Assets/Scripts/Augment/BulletModifiers/KnockbackOnShotModifier.cs index aa85d0b79..2111808cd 100644 --- a/Assets/Scripts/Augment/BulletModifiers/KnockbackOnShotModifier.cs +++ b/Assets/Scripts/Augment/BulletModifiers/KnockbackOnShotModifier.cs @@ -15,14 +15,9 @@ public class KnockbackOnShotModifier : MonoBehaviour, ProjectileModifier private (ProjectileState shot, List colliders) collidersHitWithShot = (null, new()); - private void Awake() - { - gunController = transform.parent.GetComponent(); - if (!gunController) - return; - } public void Attach(ProjectileController projectile) { + gunController = projectile.GunController; projectile.OnHitboxCollision += KnockAwayTargets; bulletAmount = projectile.stats.ProjectilesPerShot; calculatedPushPower = (pushPower / bulletAmount) * (1f + (float)Math.Log10(bulletAmount)); diff --git a/Assets/Scripts/Augment/BulletModifiers/RecoilModifier.cs b/Assets/Scripts/Augment/BulletModifiers/RecoilModifier.cs index da6a3a520..120a8f870 100644 --- a/Assets/Scripts/Augment/BulletModifiers/RecoilModifier.cs +++ b/Assets/Scripts/Augment/BulletModifiers/RecoilModifier.cs @@ -12,14 +12,9 @@ public class RecoilModifier : MonoBehaviour, ProjectileModifier private float calculatedPushPower; - private void Awake() - { - gunController = transform.parent.GetComponent(); - if (!gunController) - return; - } public void Attach(ProjectileController projectile) { + gunController = projectile.GunController; projectile.OnProjectileInit += KnockAwayOnShot; bulletAmount = projectile.stats.ProjectilesPerShot; calculatedPushPower = (pushPower / bulletAmount) * (1f + (float)Math.Log10(bulletAmount)); diff --git a/Assets/Scripts/Augment/BulletModifiers/StickyProjectileModifier.cs b/Assets/Scripts/Augment/BulletModifiers/StickyProjectileModifier.cs index e6f600196..242735362 100644 --- a/Assets/Scripts/Augment/BulletModifiers/StickyProjectileModifier.cs +++ b/Assets/Scripts/Augment/BulletModifiers/StickyProjectileModifier.cs @@ -55,8 +55,7 @@ public void Detach(ProjectileController projectile) { projectile.OnColliderHit -= StickToTarget; OnStuckToTarget = null; - stuckObjects.Flush(); - stuckObjects = null; + OnDestroy(); } public void StickToTarget(RaycastHit hit, ref ProjectileState state) @@ -64,8 +63,8 @@ public void StickToTarget(RaycastHit hit, ref ProjectileState state) if (!(affectedLayers == (affectedLayers | (1 << hit.collider.gameObject.layer)))) return; - var stuck = isDespawnedAfterTime ? - stuckObjects.GetAndReturnLater(stuckLifeTime) + var stuck = isDespawnedAfterTime ? + stuckObjects.GetAndReturnLater(stuckLifeTime) : stuckObjects.Get(); stuck.transform.position = hit.ClosestPoint(state.oldPosition); @@ -91,10 +90,7 @@ public StuckObject InstantiateManual(Vector3 position) private void OnDestroy() { - if (stuckObjects == null) - return; - - stuckObjects.Flush(); + stuckObjects?.Flush(); stuckObjects = null; } } diff --git a/Assets/Scripts/Augment/GunController.cs b/Assets/Scripts/Augment/GunController.cs index 2c7598e3b..f08a4074e 100644 --- a/Assets/Scripts/Augment/GunController.cs +++ b/Assets/Scripts/Augment/GunController.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using Mirror; using UnityEngine; @@ -106,11 +107,31 @@ public void Initialize() private void OnDestroy() { - UnsubscribeDelegates(); + Detach(); } - public void UnsubscribeDelegates() + // TODO perhaps avoid too many duplacte detach calls? + public void Detach() { + // TODO remember these after init? + var body = GetComponentInChildren(); + var barrel = GetComponentInChildren(); + var extension = GetComponentInChildren(); + + if (barrel == null) + { + Debug.LogWarning("Gun already detached!"); + return; + } + + var modifiers = new List(); + if (barrel) + modifiers.AddRange(barrel.GetModifiers()); + if (extension) + modifiers.AddRange(extension.GetModifiers()); + modifiers.ForEach(m => m.Detach(projectile)); + + // TODO the null-ing is hopefully not necessary? onInitializeGun = null; onFire = null; onFireEnd = null; diff --git a/Assets/Scripts/Augment/GunStats.cs b/Assets/Scripts/Augment/GunStats.cs index 18e047de7..0eea17667 100644 --- a/Assets/Scripts/Augment/GunStats.cs +++ b/Assets/Scripts/Augment/GunStats.cs @@ -52,6 +52,7 @@ public enum FireModes /// [HideInInspector] public int Ammo = 0; + public float AmmoPercent => (Ammo < 1 ? 0 : Ammo) / (float)MagazineSize; [SerializeField] [Tooltip("Damage of each projectile")] diff --git a/Assets/Scripts/Augment/ProjectileModifier.cs b/Assets/Scripts/Augment/ProjectileModifier.cs index 88c040ae8..4d7f9f5f2 100644 --- a/Assets/Scripts/Augment/ProjectileModifier.cs +++ b/Assets/Scripts/Augment/ProjectileModifier.cs @@ -8,6 +8,7 @@ public enum Priority EXTENSION, ARBITRARY } + /// /// An interface that can be implemented in order to give additional functional property to any projectile created by any set of parts. /// Why? Because putting a copy of every needed bullet script on every single bullet that is created is very inefficient. @@ -16,12 +17,12 @@ public enum Priority /// /// Note: Behaviour tied to updating the projectile every frame (Update), should be done with ProjectileController delegates instead! /// -public interface ProjectileModifier +public interface ProjectileModifier { public abstract void Attach(ProjectileController projectile); public abstract void Detach(ProjectileController projectile); - public Priority GetPriority() + public Priority GetPriority() { return Priority.ARBITRARY; } diff --git a/Assets/Scripts/Gamestate/PlayerManager.cs b/Assets/Scripts/Gamestate/PlayerManager.cs index f30b53ffd..8b0b09c69 100644 --- a/Assets/Scripts/Gamestate/PlayerManager.cs +++ b/Assets/Scripts/Gamestate/PlayerManager.cs @@ -1,7 +1,6 @@ using Mirror; using System.Collections; using System.Linq; -using Unity.VisualScripting.Antlr3.Runtime.Misc; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.Rendering.Universal; @@ -263,6 +262,8 @@ public void SetPlayerInput(InputManager playerInput) var canvas = hudController.GetComponent(); canvas.worldCamera = inputManager.GetComponentInChildren(); canvas.planeDistance = 0.21f; + // TODO pivot inside HUDController (for respawning) + // and remember -= identity.onChipChange += hudController.OnChipChange; // Disable arena camera so we don't render the entire scene twice @@ -326,12 +327,7 @@ void OnDestroy() } if (gunController) { - gunController.onFireStart -= UpdateAimTarget; - gunController.onFire -= UpdateAimTarget; - gunController.onFireEnd -= UpdateHudFire; - gunController.onReload -= UpdateHudReload; - //Remove the gun - Destroy(gunController.gameObject); + RemoveGun(); } if (TryGetComponent(out PlayerMovement playerMovement)) { @@ -411,26 +407,6 @@ private void PlayLeapAudio(Rigidbody body) leapSounds.Play(audioSource); } - private void UpdateHudFire(GunStats stats) - { - // stats variables must be dereferenced - float ammo = stats.Ammo < 1 ? 0 : stats.Ammo; - float magazine = stats.MagazineSize; - hudController.UpdateOnFire(ammo / magazine); - } - - private void UpdateHudReload(GunStats stats) - { - float ammo = stats.Ammo; - float magazine = stats.MagazineSize; - hudController.UpdateOnReload(ammo / magazine); - } - - private void UpdateHudCrosshair(GunStats stats) - { - HUDController.UpdateOnInitialize(stats); - } - private void TryPlaceBid(InputAction.CallbackContext ctx) { if (!selectedBiddingPlatform) return; @@ -515,13 +491,7 @@ public virtual void SetGun(Transform offset) var hadGunBefore = gunController != null; if (hadGunBefore && inputManager) { - gunController.onFireStart -= UpdateAimTarget; - gunController.onFire -= UpdateAimTarget; - gunController.onFire -= ScreenShake; - gunController.onFireEnd -= UpdateHudFire; - gunController.onReload -= UpdateHudReload; - gunController.projectile.OnHitboxCollision -= hudController.HitAnimation; - GunFactory.UnsubscribeAnimators(gunController.gameObject); + UnsubscribeGun(); } overrideAimTarget = false; var gun = GunFactory.InstantiateGun(identity.Body, identity.Barrel, identity.Extension, this, offset); @@ -535,10 +505,7 @@ public virtual void SetGun(Transform offset) gunController.onFireStart += UpdateAimTarget; gunController.onFire += UpdateAimTarget; gunController.onFire += ScreenShake; - gunController.onFireEnd += UpdateHudFire; - gunController.onReload += UpdateHudReload; - UpdateHudCrosshair(gunController.stats); - gunController.projectile.OnHitboxCollision += hudController.HitAnimation; + hudController.Attach(gunController); } playerIK.LeftHandIKTarget = gunController.LeftHandTarget; if (gunController.RightHandTarget) @@ -549,6 +516,16 @@ public virtual void SetGun(Transform offset) GetComponent().InitializeNetworkBehaviours(); } + private void UnsubscribeGun() + { + gunController.onFireStart -= UpdateAimTarget; + gunController.onFire -= UpdateAimTarget; + gunController.onFire -= ScreenShake; + hudController.Detach(gunController); + gunController.Detach(); + GunOrigin.GetComponent().Detach(); + } + public void SetGunNetwork(Transform offset) { overrideAimTarget = false; @@ -566,17 +543,17 @@ public void SetGunNetwork(Transform offset) public void RemoveGun() { - gunController.UnsubscribeDelegates(); + UnsubscribeGun(); for (int i = gunController.transform.childCount - 1; i >= 0; i--) { Destroy(gunController.transform.GetChild(i).gameObject); } Destroy(gunController.gameObject); - GunOrigin.GetComponent().UnsubscribeDelegates(); for (int i = GunOrigin.transform.childCount - 1; i >= 0; i--) { Destroy(GunOrigin.transform.GetChild(i).gameObject); } + // TODO ok and why don't we destroy the guncontroller for the display gun } private void SetLayerOnSubtree(GameObject node, int layer) diff --git a/Assets/Scripts/Gamestate/PlayerSubscriber.cs b/Assets/Scripts/Gamestate/PlayerSubscriber.cs new file mode 100644 index 000000000..02ca61d68 --- /dev/null +++ b/Assets/Scripts/Gamestate/PlayerSubscriber.cs @@ -0,0 +1,5 @@ +public interface PlayerSubscriber +{ + void Subscribe(PlayerManager player); + void Unsubscribe(PlayerManager player); +} diff --git a/Assets/Scripts/Gamestate/PlayerSubscriber.cs.meta b/Assets/Scripts/Gamestate/PlayerSubscriber.cs.meta new file mode 100644 index 000000000..5c4fdea42 --- /dev/null +++ b/Assets/Scripts/Gamestate/PlayerSubscriber.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8fc29f19163bf446af0038304048a81 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/MainMenu/MainMenuController.cs b/Assets/Scripts/UI/MainMenu/MainMenuController.cs index c742fcfa4..7c498ddb3 100644 --- a/Assets/Scripts/UI/MainMenu/MainMenuController.cs +++ b/Assets/Scripts/UI/MainMenu/MainMenuController.cs @@ -94,7 +94,6 @@ private void Awake() private void Start() { aiButtonOriginalPosition = aIButton.transform.localPosition; - Debug.Log(aiButtonOriginalPosition); PlayerInputManagerController.Singleton.MatchHasAI = false; audioSource = GetComponent(); versionText.text = $"Early Access {Application.version}"; diff --git a/Assets/Scripts/UI/PlayerHUDController.cs b/Assets/Scripts/UI/PlayerHUDController.cs index f7b0d2d24..ff3630725 100644 --- a/Assets/Scripts/UI/PlayerHUDController.cs +++ b/Assets/Scripts/UI/PlayerHUDController.cs @@ -2,7 +2,6 @@ using UnityEngine.UI; using System.Linq; using TMPro; -using UnityEngine.Serialization; using static GunStats; using System; @@ -122,13 +121,11 @@ private void Awake() { crosshairMaterial = Instantiate(crosshair.material); crosshair.material = crosshairMaterial; - } - void Start() - { speedLines.material = Instantiate(speedLines.material); speedLinesMaterial = speedLines.material; speedLines.gameObject.SetActive(true); + var image = GetComponent(); // Prevent material properties from being handled globally damageBorder = Instantiate(image.material); @@ -138,7 +135,10 @@ void Start() ammoCapacityMaterial = Instantiate(ammoBar.material); ammoBar.material = ammoCapacityMaterial; ammoCapacityMaterial.SetFloat("_Arc2", 0); + } + private void Start() + { originalChipY = chipBox.anchoredPosition.y; if (!MatchController.Singleton || PlayerInputManagerController.Singleton.LocalPlayerInputs.Count() == 1) { @@ -237,7 +237,7 @@ private void SetChipBoxPosition(float height) chipBox.anchoredPosition = new Vector2(originalChipX, originalChipY - height * 2 * originalChipY); } - public void UpdateOnFire(float ammoPercent) + public void UpdateOnFire(GunStats stats) { if (LeanTween.isTweening(ammoTween)) { @@ -245,15 +245,15 @@ public void UpdateOnFire(float ammoPercent) ammoBar.gameObject.transform.eulerAngles = new Vector3(ammoBar.gameObject.transform.eulerAngles.x, ammoBar.gameObject.transform.eulerAngles.y, 0); } - ammoCapacityMaterial.SetFloat("_Arc2", (1 - ammoPercent) * availableDegrees); + UpdateAmmoBar(stats); ammoTween = ammoHud.gameObject.LeanRotateAroundLocal(Vector3.forward, ammoSpinDegrees, 0.5f).setEaseSpring() .setOnStart( () => ammoBar.gameObject.transform.Rotate(new Vector3(0, 0, -ammoSpinDegrees))).id; } - public void UpdateOnReload(float ammoPercent) + private void UpdateAmmoBar(GunStats stats) { - ammoCapacityMaterial.SetFloat("_Arc2", (1 - ammoPercent) * availableDegrees); + ammoCapacityMaterial.SetFloat("_Arc2", (1 - stats.AmmoPercent) * availableDegrees); } private void UpdateHealthBar(float currentHealth, float maxHealth) @@ -298,7 +298,7 @@ public void UpdateDamageBorder(float intensity) { // Start of curve, reach the top quickly // Always start at 0 so we get proper damage indication each time we get hit - intensity = intensity * (1 / damageBorderTop); + intensity *= 1 / damageBorderTop; } else { @@ -342,7 +342,26 @@ public void MoveCrosshair(float x, float y) crosshair.rectTransform.anchoredPosition = (new Vector2(halfWidth * x, halfHeight * y)); } - public void HitAnimation(HitboxController other, ref ProjectileState state) + public void Attach(GunController gunController) + { + gunController.projectile.OnHitboxCollision += HitAnimation; + gunController.onFireEnd += UpdateOnFire; + gunController.onReload += UpdateAmmoBar; + + // Ensure ammo correctness at attach time + UpdateAmmoBar(gunController.stats); + + InitializeCrosshair(gunController.stats); + } + + public void Detach(GunController gunController) + { + gunController.projectile.OnHitboxCollision -= HitAnimation; + gunController.onFireEnd -= UpdateOnFire; + gunController.onReload -= UpdateAmmoBar; + } + + private void HitAnimation(HitboxController other, ref ProjectileState state) { if (LeanTween.isTweening(hitTween)) { @@ -400,7 +419,7 @@ public void CrossHairDetonationAnimation() .setOnComplete(() => SetCrosshairRadius(initialCrosshairRadius)).id; } - public void UpdateOnInitialize(GunStats stats) + public void InitializeCrosshair(GunStats stats) { initialCrosshairRadius = stats.CrosshairRadius.Value() == 0f ? 0f : 1f / stats.CrosshairRadius.Value(); crosshairMaterial.SetFloat("_Radius", initialCrosshairRadius); diff --git a/Assets/Scripts/Utils/ObjectPool.cs b/Assets/Scripts/Utils/ObjectPool.cs index e2ee4e5ec..1c83eb908 100644 --- a/Assets/Scripts/Utils/ObjectPool.cs +++ b/Assets/Scripts/Utils/ObjectPool.cs @@ -1,6 +1,5 @@ using System.Collections; using System.Collections.Generic; -using Unity.VisualScripting; using UnityEngine; public class ObjectPool where T : MonoBehaviour @@ -27,7 +26,8 @@ private ObjectPool(int capacity) /// public void Flush() { - pool.ForEach(gameObject => GameObject.Destroy(gameObject)); + pool?.ForEach(gameObject => GameObject.Destroy(gameObject)); + // TODO setting it to null is kinda troublesome, had to add a ?. above... pool = null; if (parent != null) GameObject.Destroy(parent.gameObject); @@ -138,7 +138,7 @@ public void Return(T instance) if (!instance) return; instance.gameObject.SetActive(false); - instance.transform.SetParent(parent.transform,true); + instance.transform.SetParent(parent.transform, true); instance.transform.position = parent.transform.position; instance.transform.rotation = parent.transform.rotation; } @@ -148,7 +148,7 @@ public void Return(T instance) /// public void ReturnAll() { - foreach(var instance in pool) + foreach (var instance in pool) Return(instance); } }