Skip to content

Instantly share code, notes, and snippets.

@ryoojw
Last active January 29, 2018 11:28
Show Gist options
  • Save ryoojw/79a204d19e69f5573ffab0ba8f081ffe to your computer and use it in GitHub Desktop.
Save ryoojw/79a204d19e69f5573ffab0ba8f081ffe to your computer and use it in GitHub Desktop.
Respawn Bug Code
namespace TanksMP
{
public class OutOfBounds : PunBehaviour {
//Server only: check for players colliding with the out of bounds
void OnCollisionEnter(Collision col)
{
if (!PhotonNetwork.isMasterClient) return;
//cache corresponding gameobject that was hit
GameObject obj = col.gameObject;
//try to get a player component out of the collided gameobject
Player player = obj.GetComponent<Player>();
// Player triggered
if (player && !player.isDead)
{
Debug.Log("OOUT OF BOUNDS");
// player.OutOfBounds();
StartCoroutine(DoOutOfBounds(player));
}
}
// A wait is required before out of bounds.
// Otherwise the player spawns beneath the level to other players without it.
// The reason is unknown. This just happens to be the solution.
IEnumerator DoOutOfBounds(Player player)
{
yield return new WaitForSeconds(0.1f);
player.OutOfBounds();
}
}
}
namespace TanksMP
{
/// <summary>
/// Networked player class implementing movement control and shooting.
/// Contains both server and client logic in an authoritative approach.
/// </summary>
public class Player : PunBehaviour
{
// Is dead?
[HideInInspector]
public bool isDead = false;
// Out of bounds
public void OutOfBounds()
{
//the game is already over so don't do anything
if(GameManager.GetInstance().IsGameOver()) return;
//the game is not over yet, reset runtime values
//also tell all clients to despawn this player
GetView().SetHealth(maxHealth);
GetView().SetBullet(0);
this.photonView.RPC("RpcRespawn", PhotonTargets.All);
}
//called on all clients on both player death and respawn
//only difference is that on respawn, the client sends the request
[PunRPC]
protected virtual void RpcRespawn()
{
//toggle visibility for player gameobject (on/off)
gameObject.SetActive(!gameObject.activeInHierarchy);
bool isActive = gameObject.activeInHierarchy;
//the player has been killed
if (!isActive)
{
if (explosionFX)
{
//spawn death particles locally using pooling and colorize them in the player's team color
GameObject particle = PoolManager.Spawn(explosionFX, transform.position, transform.rotation);
ParticleColor pColor = particle.GetComponent<ParticleColor>();
if (pColor) pColor.SetColor(GameManager.GetInstance().teams[GetView().GetTeam()].material.color);
}
//play sound clip on player death
if (explosionClip) AudioManager.Play3D(explosionClip, transform.position);
}
//further changes only affect the local client
if (!photonView.isMine)
return;
//local player got respawned so reset states
if (isActive == true)
{
ResetPosition();
}
else
{
isDead = true;
//local player was killed, set camera to follow the killer
// camFollow.target = killedBy.transform;
//hide input controls and other HUD elements
camFollow.HideMask(true);
//display respawn window (only for local player)
GameManager.GetInstance().DisplayDeath();
}
}
/// <summary>
/// Repositions in team area and resets camera & input variables.
/// This should only be called for the local player.
/// </summary>
public void ResetPosition()
{
//start following the local player again
camFollow.target = turret;
camFollow.HideMask(false);
//get team area and reposition it there
transform.position = GameManager.GetInstance().GetSpawnPosition(GetView().GetTeam());
isDead = false;
//reset forces modified by input
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
transform.rotation = Quaternion.identity;
//reset input left over
GameManager.GetInstance().ui.controls[0].OnEndDrag(null);
GameManager.GetInstance().ui.controls[1].OnEndDrag(null);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment