first commit

This commit is contained in:
2022-07-08 09:14:55 +08:00
commit 4d6bd72555
1123 changed files with 456307 additions and 0 deletions

View File

@ -0,0 +1,123 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Asteroid.cs" company="Exit Games GmbH">
// Part of: Asteroid Demo
// </copyright>
// <summary>
// Asteroid Component
// </summary>
// <author>developer@exitgames.com</author>
// --------------------------------------------------------------------------------------------------------------------
using UnityEngine;
using Random = UnityEngine.Random;
using Photon.Pun.UtilityScripts;
namespace Photon.Pun.Demo.Asteroids
{
public class Asteroid : MonoBehaviour
{
public bool isLargeAsteroid;
private bool isDestroyed;
private PhotonView photonView;
#pragma warning disable 0109
private new Rigidbody rigidbody;
#pragma warning restore 0109
#region UNITY
public void Awake()
{
photonView = GetComponent<PhotonView>();
rigidbody = GetComponent<Rigidbody>();
if (photonView.InstantiationData != null)
{
rigidbody.AddForce((Vector3) photonView.InstantiationData[0]);
rigidbody.AddTorque((Vector3) photonView.InstantiationData[1]);
isLargeAsteroid = (bool) photonView.InstantiationData[2];
}
}
public void Update()
{
if (!photonView.IsMine)
{
return;
}
if (Mathf.Abs(transform.position.x) > Camera.main.orthographicSize * Camera.main.aspect || Mathf.Abs(transform.position.z) > Camera.main.orthographicSize)
{
// Out of the screen
PhotonNetwork.Destroy(gameObject);
}
}
public void OnCollisionEnter(Collision collision)
{
if (isDestroyed)
{
return;
}
if (collision.gameObject.CompareTag("Bullet"))
{
if (photonView.IsMine)
{
Bullet bullet = collision.gameObject.GetComponent<Bullet>();
bullet.Owner.AddScore(isLargeAsteroid ? 2 : 1);
DestroyAsteroidGlobally();
}
else
{
DestroyAsteroidLocally();
}
}
else if (collision.gameObject.CompareTag("Player"))
{
if (photonView.IsMine)
{
collision.gameObject.GetComponent<PhotonView>().RPC("DestroySpaceship", RpcTarget.All);
DestroyAsteroidGlobally();
}
}
}
#endregion
private void DestroyAsteroidGlobally()
{
isDestroyed = true;
if (isLargeAsteroid)
{
int numberToSpawn = Random.Range(3, 6);
for (int counter = 0; counter < numberToSpawn; ++counter)
{
Vector3 force = Quaternion.Euler(0, counter * 360.0f / numberToSpawn, 0) * Vector3.forward * Random.Range(0.5f, 1.5f) * 300.0f;
Vector3 torque = Random.insideUnitSphere * Random.Range(500.0f, 1500.0f);
object[] instantiationData = {force, torque, false, PhotonNetwork.Time};
PhotonNetwork.InstantiateRoomObject("SmallAsteroid", transform.position + force.normalized * 10.0f, Quaternion.Euler(0, Random.value * 180.0f, 0), 0, instantiationData);
}
}
PhotonNetwork.Destroy(gameObject);
}
private void DestroyAsteroidLocally()
{
isDestroyed = true;
GetComponent<Renderer>().enabled = false;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c852cc8bbc743374083cab6f7df68bb7
timeCreated: 1505219178
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,267 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AsteroidsGameManager.cs" company="Exit Games GmbH">
// Part of: Asteroid demo
// </copyright>
// <summary>
// Game Manager for the Asteroid Demo
// </summary>
// <author>developer@exitgames.com</author>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using Photon.Realtime;
using Photon.Pun.UtilityScripts;
using Hashtable = ExitGames.Client.Photon.Hashtable;
namespace Photon.Pun.Demo.Asteroids
{
public class AsteroidsGameManager : MonoBehaviourPunCallbacks
{
public static AsteroidsGameManager Instance = null;
public Text InfoText;
public GameObject[] AsteroidPrefabs;
#region UNITY
public void Awake()
{
Instance = this;
}
public override void OnEnable()
{
base.OnEnable();
CountdownTimer.OnCountdownTimerHasExpired += OnCountdownTimerIsExpired;
}
public void Start()
{
Hashtable props = new Hashtable
{
{AsteroidsGame.PLAYER_LOADED_LEVEL, true}
};
PhotonNetwork.LocalPlayer.SetCustomProperties(props);
}
public override void OnDisable()
{
base.OnDisable();
CountdownTimer.OnCountdownTimerHasExpired -= OnCountdownTimerIsExpired;
}
#endregion
#region COROUTINES
private IEnumerator SpawnAsteroid()
{
while (true)
{
yield return new WaitForSeconds(Random.Range(AsteroidsGame.ASTEROIDS_MIN_SPAWN_TIME, AsteroidsGame.ASTEROIDS_MAX_SPAWN_TIME));
Vector2 direction = Random.insideUnitCircle;
Vector3 position = Vector3.zero;
if (Mathf.Abs(direction.x) > Mathf.Abs(direction.y))
{
// Make it appear on the left/right side
position = new Vector3(Mathf.Sign(direction.x) * Camera.main.orthographicSize * Camera.main.aspect, 0, direction.y * Camera.main.orthographicSize);
}
else
{
// Make it appear on the top/bottom
position = new Vector3(direction.x * Camera.main.orthographicSize * Camera.main.aspect, 0, Mathf.Sign(direction.y) * Camera.main.orthographicSize);
}
// Offset slightly so we are not out of screen at creation time (as it would destroy the asteroid right away)
position -= position.normalized * 0.1f;
Vector3 force = -position.normalized * 1000.0f;
Vector3 torque = Random.insideUnitSphere * Random.Range(500.0f, 1500.0f);
object[] instantiationData = {force, torque, true};
PhotonNetwork.InstantiateRoomObject("BigAsteroid", position, Quaternion.Euler(Random.value * 360.0f, Random.value * 360.0f, Random.value * 360.0f), 0, instantiationData);
}
}
private IEnumerator EndOfGame(string winner, int score)
{
float timer = 5.0f;
while (timer > 0.0f)
{
InfoText.text = string.Format("Player {0} won with {1} points.\n\n\nReturning to login screen in {2} seconds.", winner, score, timer.ToString("n2"));
yield return new WaitForEndOfFrame();
timer -= Time.deltaTime;
}
PhotonNetwork.LeaveRoom();
}
#endregion
#region PUN CALLBACKS
public override void OnDisconnected(DisconnectCause cause)
{
UnityEngine.SceneManagement.SceneManager.LoadScene("DemoAsteroids-LobbyScene");
}
public override void OnLeftRoom()
{
PhotonNetwork.Disconnect();
}
public override void OnMasterClientSwitched(Player newMasterClient)
{
if (PhotonNetwork.LocalPlayer.ActorNumber == newMasterClient.ActorNumber)
{
StartCoroutine(SpawnAsteroid());
}
}
public override void OnPlayerLeftRoom(Player otherPlayer)
{
CheckEndOfGame();
}
public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
{
if (changedProps.ContainsKey(AsteroidsGame.PLAYER_LIVES))
{
CheckEndOfGame();
return;
}
if (!PhotonNetwork.IsMasterClient)
{
return;
}
// if there was no countdown yet, the master client (this one) waits until everyone loaded the level and sets a timer start
int startTimestamp;
bool startTimeIsSet = CountdownTimer.TryGetStartTime(out startTimestamp);
if (changedProps.ContainsKey(AsteroidsGame.PLAYER_LOADED_LEVEL))
{
if (CheckAllPlayerLoadedLevel())
{
if (!startTimeIsSet)
{
CountdownTimer.SetStartTime();
}
}
else
{
// not all players loaded yet. wait:
Debug.Log("setting text waiting for players! ",this.InfoText);
InfoText.text = "Waiting for other players...";
}
}
}
#endregion
// called by OnCountdownTimerIsExpired() when the timer ended
private void StartGame()
{
Debug.Log("StartGame!");
// on rejoin, we have to figure out if the spaceship exists or not
// if this is a rejoin (the ship is already network instantiated and will be setup via event) we don't need to call PN.Instantiate
float angularStart = (360.0f / PhotonNetwork.CurrentRoom.PlayerCount) * PhotonNetwork.LocalPlayer.GetPlayerNumber();
float x = 20.0f * Mathf.Sin(angularStart * Mathf.Deg2Rad);
float z = 20.0f * Mathf.Cos(angularStart * Mathf.Deg2Rad);
Vector3 position = new Vector3(x, 0.0f, z);
Quaternion rotation = Quaternion.Euler(0.0f, angularStart, 0.0f);
PhotonNetwork.Instantiate("Spaceship", position, rotation, 0); // avoid this call on rejoin (ship was network instantiated before)
if (PhotonNetwork.IsMasterClient)
{
StartCoroutine(SpawnAsteroid());
}
}
private bool CheckAllPlayerLoadedLevel()
{
foreach (Player p in PhotonNetwork.PlayerList)
{
object playerLoadedLevel;
if (p.CustomProperties.TryGetValue(AsteroidsGame.PLAYER_LOADED_LEVEL, out playerLoadedLevel))
{
if ((bool) playerLoadedLevel)
{
continue;
}
}
return false;
}
return true;
}
private void CheckEndOfGame()
{
bool allDestroyed = true;
foreach (Player p in PhotonNetwork.PlayerList)
{
object lives;
if (p.CustomProperties.TryGetValue(AsteroidsGame.PLAYER_LIVES, out lives))
{
if ((int) lives > 0)
{
allDestroyed = false;
break;
}
}
}
if (allDestroyed)
{
if (PhotonNetwork.IsMasterClient)
{
StopAllCoroutines();
}
string winner = "";
int score = -1;
foreach (Player p in PhotonNetwork.PlayerList)
{
if (p.GetScore() > score)
{
winner = p.NickName;
score = p.GetScore();
}
}
StartCoroutine(EndOfGame(winner, score));
}
}
private void OnCountdownTimerIsExpired()
{
StartGame();
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 86aba39379844aa428b0d3c0a3d92534
timeCreated: 1505219187
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,31 @@
using Photon.Realtime;
using UnityEngine;
namespace Photon.Pun.Demo.Asteroids
{
public class Bullet : MonoBehaviour
{
public Player Owner { get; private set; }
public void Start()
{
Destroy(gameObject, 3.0f);
}
public void OnCollisionEnter(Collision collision)
{
Destroy(gameObject);
}
public void InitializeBullet(Player owner, Vector3 originalDirection, float lag)
{
Owner = owner;
transform.forward = originalDirection;
Rigidbody rigidbody = GetComponent<Rigidbody>();
rigidbody.velocity = originalDirection * 200.0f;
rigidbody.position += rigidbody.velocity * lag;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6321a7d9112988841b7223ac6a925bfc
timeCreated: 1505219203
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,71 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PlayerNumbering.cs" company="Exit Games GmbH">
// Part of: Asteroid Demo,
// </copyright>
// <summary>
// Player Overview Panel
// </summary>
// <author>developer@exitgames.com</author>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using ExitGames.Client.Photon;
using Photon.Realtime;
using Photon.Pun.UtilityScripts;
namespace Photon.Pun.Demo.Asteroids
{
public class PlayerOverviewPanel : MonoBehaviourPunCallbacks
{
public GameObject PlayerOverviewEntryPrefab;
private Dictionary<int, GameObject> playerListEntries;
#region UNITY
public void Awake()
{
playerListEntries = new Dictionary<int, GameObject>();
foreach (Player p in PhotonNetwork.PlayerList)
{
GameObject entry = Instantiate(PlayerOverviewEntryPrefab);
entry.transform.SetParent(gameObject.transform);
entry.transform.localScale = Vector3.one;
entry.GetComponent<Text>().color = AsteroidsGame.GetColor(p.GetPlayerNumber());
entry.GetComponent<Text>().text = string.Format("{0}\nScore: {1}\nLives: {2}", p.NickName, p.GetScore(), AsteroidsGame.PLAYER_MAX_LIVES);
playerListEntries.Add(p.ActorNumber, entry);
}
}
#endregion
#region PUN CALLBACKS
public override void OnPlayerLeftRoom(Player otherPlayer)
{
GameObject go = null;
if (this.playerListEntries.TryGetValue(otherPlayer.ActorNumber, out go))
{
Destroy(playerListEntries[otherPlayer.ActorNumber]);
playerListEntries.Remove(otherPlayer.ActorNumber);
}
}
public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
{
GameObject entry;
if (playerListEntries.TryGetValue(targetPlayer.ActorNumber, out entry))
{
entry.GetComponent<Text>().text = string.Format("{0}\nScore: {1}\nLives: {2}", targetPlayer.NickName, targetPlayer.GetScore(), targetPlayer.CustomProperties[AsteroidsGame.PLAYER_LIVES]);
}
}
#endregion
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b579f4077cd5953489882224d803b137
timeCreated: 1505982910
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,220 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Spaceship.cs" company="Exit Games GmbH">
// Part of: Asteroid Demo,
// </copyright>
// <summary>
// Spaceship
// </summary>
// <author>developer@exitgames.com</author>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections;
using UnityEngine;
using Photon.Pun.UtilityScripts;
using Hashtable = ExitGames.Client.Photon.Hashtable;
namespace Photon.Pun.Demo.Asteroids
{
public class Spaceship : MonoBehaviour
{
public float RotationSpeed = 90.0f;
public float MovementSpeed = 2.0f;
public float MaxSpeed = 0.2f;
public ParticleSystem Destruction;
public GameObject EngineTrail;
public GameObject BulletPrefab;
private PhotonView photonView;
#pragma warning disable 0109
private new Rigidbody rigidbody;
private new Collider collider;
private new Renderer renderer;
#pragma warning restore 0109
private float rotation = 0.0f;
private float acceleration = 0.0f;
private float shootingTimer = 0.0f;
private bool controllable = true;
#region UNITY
public void Awake()
{
photonView = GetComponent<PhotonView>();
rigidbody = GetComponent<Rigidbody>();
collider = GetComponent<Collider>();
renderer = GetComponent<Renderer>();
}
public void Start()
{
foreach (Renderer r in GetComponentsInChildren<Renderer>())
{
r.material.color = AsteroidsGame.GetColor(photonView.Owner.GetPlayerNumber());
}
}
public void Update()
{
if (!photonView.AmOwner || !controllable)
{
return;
}
// we don't want the master client to apply input to remote ships while the remote player is inactive
if (this.photonView.CreatorActorNr != PhotonNetwork.LocalPlayer.ActorNumber)
{
return;
}
rotation = Input.GetAxis("Horizontal");
acceleration = Input.GetAxis("Vertical");
if (Input.GetButton("Jump") && shootingTimer <= 0.0)
{
shootingTimer = 0.2f;
photonView.RPC("Fire", RpcTarget.AllViaServer, rigidbody.position, rigidbody.rotation);
}
if (shootingTimer > 0.0f)
{
shootingTimer -= Time.deltaTime;
}
}
public void FixedUpdate()
{
if (!photonView.IsMine)
{
return;
}
if (!controllable)
{
return;
}
Quaternion rot = rigidbody.rotation * Quaternion.Euler(0, rotation * RotationSpeed * Time.fixedDeltaTime, 0);
rigidbody.MoveRotation(rot);
Vector3 force = (rot * Vector3.forward) * acceleration * 1000.0f * MovementSpeed * Time.fixedDeltaTime;
rigidbody.AddForce(force);
if (rigidbody.velocity.magnitude > (MaxSpeed * 1000.0f))
{
rigidbody.velocity = rigidbody.velocity.normalized * MaxSpeed * 1000.0f;
}
CheckExitScreen();
}
#endregion
#region COROUTINES
private IEnumerator WaitForRespawn()
{
yield return new WaitForSeconds(AsteroidsGame.PLAYER_RESPAWN_TIME);
photonView.RPC("RespawnSpaceship", RpcTarget.AllViaServer);
}
#endregion
#region PUN CALLBACKS
[PunRPC]
public void DestroySpaceship()
{
rigidbody.velocity = Vector3.zero;
rigidbody.angularVelocity = Vector3.zero;
collider.enabled = false;
renderer.enabled = false;
controllable = false;
EngineTrail.SetActive(false);
Destruction.Play();
if (photonView.IsMine)
{
object lives;
if (PhotonNetwork.LocalPlayer.CustomProperties.TryGetValue(AsteroidsGame.PLAYER_LIVES, out lives))
{
PhotonNetwork.LocalPlayer.SetCustomProperties(new Hashtable {{AsteroidsGame.PLAYER_LIVES, ((int) lives <= 1) ? 0 : ((int) lives - 1)}});
if (((int) lives) > 1)
{
StartCoroutine("WaitForRespawn");
}
}
}
}
[PunRPC]
public void Fire(Vector3 position, Quaternion rotation, PhotonMessageInfo info)
{
float lag = (float) (PhotonNetwork.Time - info.SentServerTime);
GameObject bullet;
/** Use this if you want to fire one bullet at a time **/
bullet = Instantiate(BulletPrefab, position, Quaternion.identity) as GameObject;
bullet.GetComponent<Bullet>().InitializeBullet(photonView.Owner, (rotation * Vector3.forward), Mathf.Abs(lag));
/** Use this if you want to fire two bullets at once **/
//Vector3 baseX = rotation * Vector3.right;
//Vector3 baseZ = rotation * Vector3.forward;
//Vector3 offsetLeft = -1.5f * baseX - 0.5f * baseZ;
//Vector3 offsetRight = 1.5f * baseX - 0.5f * baseZ;
//bullet = Instantiate(BulletPrefab, rigidbody.position + offsetLeft, Quaternion.identity) as GameObject;
//bullet.GetComponent<Bullet>().InitializeBullet(photonView.Owner, baseZ, Mathf.Abs(lag));
//bullet = Instantiate(BulletPrefab, rigidbody.position + offsetRight, Quaternion.identity) as GameObject;
//bullet.GetComponent<Bullet>().InitializeBullet(photonView.Owner, baseZ, Mathf.Abs(lag));
}
[PunRPC]
public void RespawnSpaceship()
{
collider.enabled = true;
renderer.enabled = true;
controllable = true;
EngineTrail.SetActive(true);
Destruction.Stop();
}
#endregion
private void CheckExitScreen()
{
if (Camera.main == null)
{
return;
}
if (Mathf.Abs(rigidbody.position.x) > (Camera.main.orthographicSize * Camera.main.aspect))
{
rigidbody.position = new Vector3(-Mathf.Sign(rigidbody.position.x) * Camera.main.orthographicSize * Camera.main.aspect, 0, rigidbody.position.z);
rigidbody.position -= rigidbody.position.normalized * 0.1f; // offset a little bit to avoid looping back & forth between the 2 edges
}
if (Mathf.Abs(rigidbody.position.z) > Camera.main.orthographicSize)
{
rigidbody.position = new Vector3(rigidbody.position.x, rigidbody.position.y, -Mathf.Sign(rigidbody.position.z) * Camera.main.orthographicSize);
rigidbody.position -= rigidbody.position.normalized * 0.1f; // offset a little bit to avoid looping back & forth between the 2 edges
}
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c565458f43b8ad4469a2ca341c210318
timeCreated: 1505219195
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: