fix: Invaders hit fx not replicated on player & enemy bullets (#113)

* player and enemy bullet send client rpcs to spawn hit FX

* redundant server side checks removed, spawn/despawn method usage parity

* formatting
This commit is contained in:
Fernando Cortez 2023-03-10 11:09:15 -05:00 коммит произвёл GitHub
Родитель 96465ee7ec
Коммит 0600a7360f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 75 добавлений и 33 удалений

Просмотреть файл

@ -1,9 +1,9 @@
using Unity.Mathematics;
using System;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Assertions;
public class EnemyBullet : MonoBehaviour
public class EnemyBullet : NetworkBehaviour
{
private const float k_YBoundary = -4.0f;
@ -12,59 +12,86 @@ public class EnemyBullet : MonoBehaviour
[SerializeField]
[Tooltip("The constant speed at which the Bullet travels")]
private float m_TravelSpeed = 3.0f;
[SerializeField]
ParticleSystem m_ShieldExplosionParticle;
private void Start()
void Awake()
{
Assert.IsTrue(InvadersGame.Singleton);
Assert.IsTrue(NetworkManager.Singleton);
enabled = false;
}
if(InvadersGame.Singleton)
public override void OnNetworkSpawn()
{
enabled = IsServer;
if (!IsServer)
{
return;
}
Assert.IsTrue(InvadersGame.Singleton);
if (InvadersGame.Singleton)
{
InvadersGame.Singleton.isGameOver.OnValueChanged += OnGameOver;
}
}
private void Update()
{
if (!NetworkManager.Singleton.IsServer) return;
transform.Translate(0, -m_TravelSpeed * Time.deltaTime, 0);
if (transform.position.y < k_YBoundary) Destroy(gameObject);
if (transform.position.y < k_YBoundary)
{
NetworkObject.Despawn();
}
}
private void OnDestroy()
public override void OnNetworkDespawn()
{
if (InvadersGame.Singleton) InvadersGame.Singleton.isGameOver.OnValueChanged -= OnGameOver;
if (InvadersGame.Singleton)
{
InvadersGame.Singleton.isGameOver.OnValueChanged -= OnGameOver;
}
}
private void OnTriggerEnter2D(Collider2D collider)
{
if (!NetworkManager.Singleton.IsServer)
// several OnTriggerEnter2D calls may be invoked in the same frame (for different Colliders), so we check if
// we're spawned to make sure we don't trigger hits for already despawned bullets
if (!IsServer || !IsSpawned)
return;
var hitPlayer = collider.gameObject.GetComponent<PlayerControl>();
if (hitPlayer != null)
{
NetworkObject.Despawn();
hitPlayer.HitByBullet();
Destroy(gameObject);
return;
}
var hitShield = collider.gameObject.GetComponent<Shield>();
if (hitShield != null)
{
SpawnExplosionVFXClientRpc(transform.position, Quaternion.identity);
Destroy(hitShield.gameObject);
Destroy(gameObject);
Instantiate(m_ShieldExplosionParticle, transform.position, quaternion.identity);
NetworkObject.Despawn();
}
}
[ClientRpc]
void SpawnExplosionVFXClientRpc(Vector3 spawnPosition, Quaternion spawnRotation)
{
Instantiate(m_ShieldExplosionParticle, spawnPosition, spawnRotation);
}
private void OnGameOver(bool oldValue, bool newValue)
{
enabled = false;
// On game over destroy the bullets
if (NetworkManager.Singleton.IsServer) Destroy(gameObject);
NetworkObject.Despawn();
}
}

Просмотреть файл

@ -1,8 +1,8 @@
using Unity.Mathematics;
using System;
using Unity.Netcode;
using UnityEngine;
public class PlayerBullet : MonoBehaviour
public class PlayerBullet : NetworkBehaviour
{
private const float k_YBoundary = 15.0f;
public PlayerControl owner;
@ -15,20 +15,31 @@ public class PlayerBullet : MonoBehaviour
[SerializeField]
ParticleSystem m_EnemyExplosionParticle;
void Awake()
{
enabled = false;
}
public override void OnNetworkSpawn()
{
enabled = IsServer;
}
private void Update()
{
if (!NetworkManager.Singleton.IsServer) return;
transform.Translate(0, m_TravelSpeed * Time.deltaTime, 0);
if (transform.position.y > k_YBoundary)
if (NetworkManager.Singleton.IsServer)
Destroy(gameObject);
{
NetworkObject.Despawn();
}
}
private void OnTriggerEnter2D(Collider2D collider)
{
if (!NetworkManager.Singleton.IsServer)
// several OnTriggerEnter2D calls may be invoked in the same frame (for different Colliders), so we check if
// we're spawned to make sure we don't trigger hits for already despawned bullets
if (!IsServer || !IsSpawned)
return;
var hitEnemy = collider.gameObject.GetComponent<EnemyAgent>();
@ -36,17 +47,13 @@ public class PlayerBullet : MonoBehaviour
{
owner.IncreasePlayerScore(hitEnemy.score);
if (NetworkManager.Singleton.IsServer)
{
// Only the server can despawn a NetworkObject
hitEnemy.NetworkObject.Despawn();
}
// Only the server can despawn a NetworkObject
hitEnemy.NetworkObject.Despawn();
Destroy(gameObject);
SpawnExplosionVFXClientRPC(transform.position, Quaternion.identity);
NetworkObject.Despawn();
// this instantiates at the position of the bullet, there is an offset in the Y axis on the
// particle systems in the prefab so it looks like it spawns in the middle of the enemy
Instantiate(m_EnemyExplosionParticle, transform.position, quaternion.identity);
return;
}
@ -54,7 +61,15 @@ public class PlayerBullet : MonoBehaviour
if (hitShield != null)
{
Destroy(hitShield.gameObject);
Destroy(gameObject);
NetworkObject.Despawn();
}
}
[ClientRpc]
void SpawnExplosionVFXClientRPC(Vector3 spawnPosition, Quaternion spawnRotation)
{
// this instantiates at the position of the bullet, there is an offset in the Y axis on the
// particle systems in the prefab so it looks like it spawns in the middle of the enemy
Instantiate(m_EnemyExplosionParticle, spawnPosition, spawnRotation);
}
}