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,136 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ConnectAndJoinRandom.cs" company="Exit Games GmbH">
// Part of: Photon Unity Utilities,
// </copyright>
// <summary>
// Simple component to call ConnectUsingSettings and to get into a PUN room easily.
// </summary>
// <remarks>
// A custom inspector provides a button to connect in PlayMode, should AutoConnect be false.
// </remarks>
// <author>developer@exitgames.com</author>
// --------------------------------------------------------------------------------------------------------------------
//#if UNITY_EDITOR
//using UnityEditor;
//#endif
using UnityEngine;
//using Photon.Pun;
using Photon.Realtime;
namespace Photon.Pun.UtilityScripts
{
/// <summary>Simple component to call ConnectUsingSettings and to get into a PUN room easily.</summary>
/// <remarks>A custom inspector provides a button to connect in PlayMode, should AutoConnect be false.</remarks>
public class ConnectAndJoinRandom : MonoBehaviourPunCallbacks
{
/// <summary>Connect automatically? If false you can set this to true later on or call ConnectUsingSettings in your own scripts.</summary>
public bool AutoConnect = true;
/// <summary>Used as PhotonNetwork.GameVersion.</summary>
public byte Version = 1;
/// <summary>Max number of players allowed in room. Once full, a new room will be created by the next connection attemping to join.</summary>
[Tooltip("The max number of players allowed in room. Once full, a new room will be created by the next connection attemping to join.")]
public byte MaxPlayers = 4;
public int playerTTL = -1;
public void Start()
{
if (this.AutoConnect)
{
this.ConnectNow();
}
}
public void ConnectNow()
{
Debug.Log("ConnectAndJoinRandom.ConnectNow() will now call: PhotonNetwork.ConnectUsingSettings().");
PhotonNetwork.ConnectUsingSettings();
PhotonNetwork.GameVersion = this.Version + "." + SceneManagerHelper.ActiveSceneBuildIndex;
}
// below, we implement some callbacks of the Photon Realtime API.
// Being a MonoBehaviourPunCallbacks means, we can override the few methods which are needed here.
public override void OnConnectedToMaster()
{
Debug.Log("OnConnectedToMaster() was called by PUN. This client is now connected to Master Server in region [" + PhotonNetwork.CloudRegion +
"] and can join a room. Calling: PhotonNetwork.JoinRandomRoom();");
PhotonNetwork.JoinRandomRoom();
}
public override void OnJoinedLobby()
{
Debug.Log("OnJoinedLobby(). This client is now connected to Relay in region [" + PhotonNetwork.CloudRegion + "]. This script now calls: PhotonNetwork.JoinRandomRoom();");
PhotonNetwork.JoinRandomRoom();
}
public override void OnJoinRandomFailed(short returnCode, string message)
{
Debug.Log("OnJoinRandomFailed() was called by PUN. No random room available in region [" + PhotonNetwork.CloudRegion + "], so we create one. Calling: PhotonNetwork.CreateRoom(null, new RoomOptions() {maxPlayers = 4}, null);");
RoomOptions roomOptions = new RoomOptions() { MaxPlayers = this.MaxPlayers };
if (playerTTL >= 0)
roomOptions.PlayerTtl = playerTTL;
PhotonNetwork.CreateRoom(null, roomOptions, null);
}
// the following methods are implemented to give you some context. re-implement them as needed.
public override void OnDisconnected(DisconnectCause cause)
{
Debug.Log("OnDisconnected(" + cause + ")");
}
public override void OnJoinedRoom()
{
Debug.Log("OnJoinedRoom() called by PUN. Now this client is in a room in region [" + PhotonNetwork.CloudRegion + "]. Game is now running.");
}
}
//#if UNITY_EDITOR
//[CanEditMultipleObjects]
//[CustomEditor(typeof(ConnectAndJoinRandom), true)]
//public class ConnectAndJoinRandomInspector : Editor
//{
// void OnEnable() { EditorApplication.update += Update; }
// void OnDisable() { EditorApplication.update -= Update; }
// bool isConnectedCache = false;
// void Update()
// {
// if (this.isConnectedCache != PhotonNetwork.IsConnected)
// {
// this.Repaint();
// }
// }
// public override void OnInspectorGUI()
// {
// this.isConnectedCache = !PhotonNetwork.IsConnected;
// this.DrawDefaultInspector(); // Draw the normal inspector
// if (Application.isPlaying && !PhotonNetwork.IsConnected)
// {
// if (GUILayout.Button("Connect"))
// {
// ((ConnectAndJoinRandom)this.target).ConnectNow();
// }
// }
// }
//}
//#endif
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5c1b84a427010e0469ce0df07ab64dbc
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}

View File

@ -0,0 +1,111 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="OnJoinedInstantiate.cs" company="Exit Games GmbH">
// Part of: Photon Unity Utilities,
// </copyright>
// <summary>
// Very basic component to move a GameObject by WASD and Space.
// </summary>
// <remarks>
// Requires a PhotonView.
// Disables itself on GameObjects that are not owned on Start.
//
// Speed affects movement-speed.
// JumpForce defines how high the object "jumps".
// JumpTimeout defines after how many seconds you can jump again.
// </remarks>
// <author>developer@exitgames.com</author>
// --------------------------------------------------------------------------------------------------------------------
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
namespace Photon.Pun.UtilityScripts
{
/// <summary>
/// Very basic component to move a GameObject by WASD and Space.
/// </summary>
/// <remarks>
/// Requires a PhotonView.
/// Disables itself on GameObjects that are not owned on Start.
///
/// Speed affects movement-speed.
/// JumpForce defines how high the object "jumps".
/// JumpTimeout defines after how many seconds you can jump again.
/// </remarks>
[RequireComponent(typeof(PhotonView))]
public class MoveByKeys : Photon.Pun.MonoBehaviourPun
{
public float Speed = 10f;
public float JumpForce = 200f;
public float JumpTimeout = 0.5f;
private bool isSprite;
private float jumpingTime;
private Rigidbody body;
private Rigidbody2D body2d;
public void Start()
{
//enabled = photonView.isMine;
this.isSprite = (GetComponent<SpriteRenderer>() != null);
this.body2d = GetComponent<Rigidbody2D>();
this.body = GetComponent<Rigidbody>();
}
// Update is called once per frame
public void FixedUpdate()
{
if (!photonView.IsMine)
{
return;
}
if ((Input.GetAxisRaw("Horizontal") < -0.1f) || (Input.GetAxisRaw("Horizontal") > 0.1f))
{
transform.position += Vector3.right * (Speed * Time.deltaTime) * Input.GetAxisRaw("Horizontal");
}
// jumping has a simple "cooldown" time but you could also jump in the air
if (this.jumpingTime <= 0.0f)
{
if (this.body != null || this.body2d != null)
{
// obj has a Rigidbody and can jump (AddForce)
if (Input.GetKey(KeyCode.Space))
{
this.jumpingTime = this.JumpTimeout;
Vector2 jump = Vector2.up * this.JumpForce;
if (this.body2d != null)
{
this.body2d.AddForce(jump);
}
else if (this.body != null)
{
this.body.AddForce(jump);
}
}
}
}
else
{
this.jumpingTime -= Time.deltaTime;
}
// 2d objects can't be moved in 3d "forward"
if (!this.isSprite)
{
if ((Input.GetAxisRaw("Vertical") < -0.1f) || (Input.GetAxisRaw("Vertical") > 0.1f))
{
transform.position += Vector3.forward * (Speed * Time.deltaTime) * Input.GetAxisRaw("Vertical");
}
}
}
}
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 99b4daedc5e674a429acdf1e77da6a55
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}

View File

@ -0,0 +1,72 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="OnClickDestroy.cs" company="Exit Games GmbH">
// Part of: Photon Unity Utilities
// </copyright>
// <summary>A compact script for prototyping.</summary>
// <author>developer@exitgames.com</author>
// --------------------------------------------------------------------------------------------------------------------
namespace Photon.Pun.UtilityScripts
{
using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
/// <summary>
/// Destroys the networked GameObject either by PhotonNetwork.Destroy or by sending an RPC which calls Object.Destroy().
/// </summary>
/// <remarks>
/// Using an RPC to Destroy a GameObject is typically a bad idea.
/// It allows any player to Destroy a GameObject and may cause errors.
///
/// A client has to clean up the server's event-cache, which contains events for Instantiate and
/// buffered RPCs related to the GO.
///
/// A buffered RPC gets cleaned up when the sending player leaves the room, so players joining later
/// won't get those buffered RPCs. This in turn, may mean they don't destroy the GO due to coming later.
///
/// Vice versa, a GameObject Instantiate might get cleaned up when the creating player leaves a room.
/// This way, the GameObject that a RPC targets might become lost.
///
/// It makes sense to test those cases. Many are not breaking errors and you just have to be aware of them.
///
///
/// Gets OnClick() calls by Unity's IPointerClickHandler. Needs a PhysicsRaycaster on the camera.
/// See: https://docs.unity3d.com/ScriptReference/EventSystems.IPointerClickHandler.html
/// </remarks>
public class OnClickDestroy : MonoBehaviourPun, IPointerClickHandler
{
public PointerEventData.InputButton Button;
public KeyCode ModifierKey;
public bool DestroyByRpc;
void IPointerClickHandler.OnPointerClick(PointerEventData eventData)
{
if (!PhotonNetwork.InRoom || (this.ModifierKey != KeyCode.None && !Input.GetKey(this.ModifierKey)) || eventData.button != this.Button )
{
return;
}
if (this.DestroyByRpc)
{
this.photonView.RPC("DestroyRpc", RpcTarget.AllBuffered);
}
else
{
PhotonNetwork.Destroy(this.gameObject);
}
}
[PunRPC]
public IEnumerator DestroyRpc()
{
Destroy(this.gameObject);
yield return 0; // if you allow 1 frame to pass, the object's OnDestroy() method gets called and cleans up references.
}
}
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9dab7328ba500e944a99d62065fba6c0
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}

View File

@ -0,0 +1,56 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="OnClickInstantiate.cs" company="Exit Games GmbH">
// Part of: Photon Unity Utilities
// </copyright>
// <summary>A compact script for prototyping.</summary>
// <author>developer@exitgames.com</author>
// --------------------------------------------------------------------------------------------------------------------
namespace Photon.Pun.UtilityScripts
{
using UnityEngine;
using UnityEngine.EventSystems;
/// <summary>
/// Instantiates a networked GameObject on click.
/// </summary>
/// <remarks>
/// Gets OnClick() calls by Unity's IPointerClickHandler. Needs a PhysicsRaycaster on the camera.
/// See: https://docs.unity3d.com/ScriptReference/EventSystems.IPointerClickHandler.html
/// </remarks>
public class OnClickInstantiate : MonoBehaviour, IPointerClickHandler
{
public enum InstantiateOption { Mine, Scene }
public PointerEventData.InputButton Button;
public KeyCode ModifierKey;
public GameObject Prefab;
[SerializeField]
private InstantiateOption InstantiateType = InstantiateOption.Mine;
void IPointerClickHandler.OnPointerClick(PointerEventData eventData)
{
if (!PhotonNetwork.InRoom || (this.ModifierKey != KeyCode.None && !Input.GetKey(this.ModifierKey)) || eventData.button != this.Button)
{
return;
}
switch (this.InstantiateType)
{
case InstantiateOption.Mine:
PhotonNetwork.Instantiate(this.Prefab.name, eventData.pointerCurrentRaycast.worldPosition + new Vector3(0, 0.5f, 0), Quaternion.identity, 0);
break;
case InstantiateOption.Scene:
PhotonNetwork.InstantiateRoomObject(this.Prefab.name, eventData.pointerCurrentRaycast.worldPosition + new Vector3(0, 0.5f, 0), Quaternion.identity, 0, null);
break;
}
}
}
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9b79a9b62449de940a073364858c3f9b
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}

View File

@ -0,0 +1,89 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="OnClickInstantiate.cs" company="Exit Games GmbH">
// Part of: Photon Unity Utilities
// </copyright>
// <summary>A compact script for prototyping.</summary>
// <author>developer@exitgames.com</author>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections;
namespace Photon.Pun.UtilityScripts
{
using UnityEngine;
using UnityEngine.EventSystems;
/// <summary>
/// This component will instantiate a network GameObject when in a room and the user click on that component's GameObject.
/// Uses PhysicsRaycaster for positioning.
/// </summary>
public class OnClickRpc : MonoBehaviourPun, IPointerClickHandler
{
public PointerEventData.InputButton Button;
public KeyCode ModifierKey;
public RpcTarget Target;
void IPointerClickHandler.OnPointerClick(PointerEventData eventData)
{
if (!PhotonNetwork.InRoom || (this.ModifierKey != KeyCode.None && !Input.GetKey(this.ModifierKey)) || eventData.button != this.Button)
{
return;
}
this.photonView.RPC("ClickRpc", this.Target);
}
#region RPC Implementation
private Material originalMaterial;
private Color originalColor;
private bool isFlashing;
[PunRPC]
public void ClickRpc()
{
//Debug.Log("ClickRpc Called");
this.StartCoroutine(this.ClickFlash());
}
public IEnumerator ClickFlash()
{
if (isFlashing)
{
yield break;
}
isFlashing = true;
this.originalMaterial = GetComponent<Renderer>().material;
if (!this.originalMaterial.HasProperty("_EmissionColor"))
{
Debug.LogWarning("Doesn't have emission, can't flash " + gameObject);
yield break;
}
bool wasEmissive = this.originalMaterial.IsKeywordEnabled("_EMISSION");
this.originalMaterial.EnableKeyword("_EMISSION");
this.originalColor = this.originalMaterial.GetColor("_EmissionColor");
this.originalMaterial.SetColor("_EmissionColor", Color.white);
for (float f = 0.0f; f <= 1.0f; f += 0.08f)
{
Color lerped = Color.Lerp(Color.white, this.originalColor, f);
this.originalMaterial.SetColor("_EmissionColor", lerped);
yield return null;
}
this.originalMaterial.SetColor("_EmissionColor", this.originalColor);
if (!wasEmissive) this.originalMaterial.DisableKeyword("_EMISSION");
isFlashing = false;
}
#endregion
}
}

View File

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

View File

@ -0,0 +1,32 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="OnJoinedInstantiate.cs" company="Exit Games GmbH">
// Part of: Photon Unity Utilities,
// </copyright>
// <summary>
// This component will quit the application when escape key is pressed
// </summary>
// <author>developer@exitgames.com</author>
// --------------------------------------------------------------------------------------------------------------------
using UnityEngine;
using System.Collections;
using System.Diagnostics;
namespace Photon.Pun.UtilityScripts
{
/// <summary>
/// This component will quit the application when escape key is pressed
/// </summary>
public class OnEscapeQuit : MonoBehaviour
{
[Conditional("UNITY_ANDROID"), Conditional("UNITY_IOS")]
public void Update()
{
// "back" button of phone equals "Escape". quit app if that's pressed
if (Input.GetKeyDown(KeyCode.Escape))
{
Application.Quit();
}
}
}
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1fbabafd914a48f4eb6108d8d8f43d29
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}

View File

@ -0,0 +1,450 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="OnJoinedInstantiate.cs" company="Exit Games GmbH">
// Part of: Photon Unity Utilities,
// </copyright>
// <summary>
// This component will instantiate a network GameObject when a room is joined
// </summary>
// <author>developer@exitgames.com</author>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using Photon.Realtime;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Photon.Pun.UtilityScripts
{
/// <summary>
/// This component will instantiate a network GameObject when a room is joined
/// </summary>
public class OnJoinedInstantiate : MonoBehaviour
, IMatchmakingCallbacks
{
public enum SpawnSequence { Connection, Random, RoundRobin }
#region Inspector Items
// Old field, only here for backwards compat. Value copies over to SpawnPoints in OnValidate
[HideInInspector] private Transform SpawnPosition;
[HideInInspector] public SpawnSequence Sequence = SpawnSequence.Connection;
[HideInInspector] public List<Transform> SpawnPoints = new List<Transform>(1) { null };
[Tooltip("Add a random variance to a spawn point position. GetRandomOffset() can be overridden with your own method for producing offsets.")]
[HideInInspector] public bool UseRandomOffset = true;
[Tooltip("Radius of the RandomOffset.")]
[FormerlySerializedAs("PositionOffset")]
[HideInInspector] public float RandomOffset = 2.0f;
[Tooltip("Disables the Y axis of RandomOffset. The Y value of the spawn point will be used.")]
[HideInInspector] public bool ClampY = true;
[HideInInspector] public List<GameObject> PrefabsToInstantiate = new List<GameObject>(1) { null }; // set in inspector
[FormerlySerializedAs("autoSpawnObjects")]
[HideInInspector] public bool AutoSpawnObjects = true;
#endregion
// Record of spawned objects, used for Despawn All
public Stack<GameObject> SpawnedObjects = new Stack<GameObject>();
protected int spawnedAsActorId;
#if UNITY_EDITOR
protected void OnValidate()
{
/// Check the prefab to make sure it is the actual resource, and not a scene object or other instance.
if (PrefabsToInstantiate != null)
for (int i = 0; i < PrefabsToInstantiate.Count; ++i)
{
var prefab = PrefabsToInstantiate[i];
if (prefab)
PrefabsToInstantiate[i] = ValidatePrefab(prefab);
}
/// Move any values from old SpawnPosition field to new SpawnPoints
if (SpawnPosition)
{
if (SpawnPoints == null)
SpawnPoints = new List<Transform>();
SpawnPoints.Add(SpawnPosition);
SpawnPosition = null;
}
}
/// <summary>
/// Validate, and if valid add this prefab to the first null element of the list, or create a new element. Returns true if the object was added.
/// </summary>
/// <param name="prefab"></param>
public bool AddPrefabToList(GameObject prefab)
{
var validated = ValidatePrefab(prefab);
if (validated)
{
// Don't add to list if this prefab already is on the list
if (PrefabsToInstantiate.Contains(validated))
return false;
// First try to use any null array slots to keep things tidy
if (PrefabsToInstantiate.Contains(null))
PrefabsToInstantiate[PrefabsToInstantiate.IndexOf(null)] = validated;
// Otherwise, just add this prefab.
else
PrefabsToInstantiate.Add(validated);
return true;
}
return false;
}
/// <summary>
/// Determines if the supplied GameObject is an instance of a prefab, or the actual source Asset,
/// and returns a best guess at the actual resource the dev intended to use.
/// </summary>
/// <returns></returns>
protected static GameObject ValidatePrefab(GameObject unvalidated)
{
if (unvalidated == null)
return null;
if (!unvalidated.GetComponent<PhotonView>())
return null;
#if UNITY_2018_3_OR_NEWER
GameObject validated = null;
if (unvalidated != null)
{
if (PrefabUtility.IsPartOfPrefabAsset(unvalidated))
return unvalidated;
var prefabStatus = PrefabUtility.GetPrefabInstanceStatus(unvalidated);
var isValidPrefab = prefabStatus == PrefabInstanceStatus.Connected || prefabStatus == PrefabInstanceStatus.Disconnected;
if (isValidPrefab)
validated = PrefabUtility.GetCorrespondingObjectFromSource(unvalidated) as GameObject;
else
return null;
if (!PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(validated).Contains("/Resources"))
Debug.LogWarning("Player Prefab needs to be a Prefab in a Resource folder.");
}
#else
GameObject validated = unvalidated;
if (unvalidated != null && PrefabUtility.GetPrefabType(unvalidated) != PrefabType.Prefab)
validated = PrefabUtility.GetPrefabParent(unvalidated) as GameObject;
#endif
return validated;
}
#endif
public virtual void OnEnable()
{
PhotonNetwork.AddCallbackTarget(this);
}
public virtual void OnDisable()
{
PhotonNetwork.RemoveCallbackTarget(this);
}
public virtual void OnJoinedRoom()
{
// Only AutoSpawn if we are a new ActorId. Rejoining should reproduce the objects by server instantiation.
if (AutoSpawnObjects && !PhotonNetwork.LocalPlayer.HasRejoined)
{
SpawnObjects();
}
}
public virtual void SpawnObjects()
{
if (this.PrefabsToInstantiate != null)
{
foreach (GameObject o in this.PrefabsToInstantiate)
{
if (o == null)
continue;
#if UNITY_EDITOR
Debug.Log("Auto-Instantiating: " + o.name);
#endif
Vector3 spawnPos; Quaternion spawnRot;
GetSpawnPoint(out spawnPos, out spawnRot);
var newobj = PhotonNetwork.Instantiate(o.name, spawnPos, spawnRot, 0);
SpawnedObjects.Push(newobj);
}
}
}
/// <summary>
/// Destroy all objects that have been spawned by this component for this client.
/// </summary>
/// <param name="localOnly">Use Object.Destroy rather than PhotonNetwork.Destroy.</param>
public virtual void DespawnObjects(bool localOnly)
{
while (SpawnedObjects.Count > 0)
{
var go = SpawnedObjects.Pop();
if (go)
{
if (localOnly)
Object.Destroy(go);
else
PhotonNetwork.Destroy(go);
}
}
}
public virtual void OnFriendListUpdate(List<FriendInfo> friendList) { }
public virtual void OnCreatedRoom() { }
public virtual void OnCreateRoomFailed(short returnCode, string message) { }
public virtual void OnJoinRoomFailed(short returnCode, string message) { }
public virtual void OnJoinRandomFailed(short returnCode, string message) { }
public virtual void OnLeftRoom() { }
protected int lastUsedSpawnPointIndex = -1;
/// <summary>
/// Gets the next SpawnPoint from the list using the SpawnSequence, and applies RandomOffset (if used) to the transform matrix.
/// Override this method with any custom code for coming up with a spawn location. This method is used by AutoSpawn.
/// </summary>
public virtual void GetSpawnPoint(out Vector3 spawnPos, out Quaternion spawnRot)
{
// Fetch a point using the Sequence method indicated
Transform point = GetSpawnPoint();
if (point != null)
{
spawnPos = point.position;
spawnRot = point.rotation;
}
else
{
spawnPos = new Vector3(0, 0, 0);
spawnRot = new Quaternion(0, 0, 0, 1);
}
if (UseRandomOffset)
{
Random.InitState((int)(Time.time * 10000));
spawnPos += GetRandomOffset();
}
}
/// <summary>
/// Get the transform of the next SpawnPoint from the list, selected using the SpawnSequence setting.
/// RandomOffset is not applied, only the transform of the SpawnPoint is returned.
/// Override this method to change how Spawn Point transform is selected. Return the transform you want to use as a spawn point.
/// </summary>
/// <returns></returns>
protected virtual Transform GetSpawnPoint()
{
// Fetch a point using the Sequence method indicated
if (SpawnPoints == null || SpawnPoints.Count == 0)
{
return null;
}
else
{
switch (Sequence)
{
case SpawnSequence.Connection:
{
int id = PhotonNetwork.LocalPlayer.ActorNumber;
return SpawnPoints[(id == -1) ? 0 : id % SpawnPoints.Count];
}
case SpawnSequence.RoundRobin:
{
lastUsedSpawnPointIndex++;
if (lastUsedSpawnPointIndex >= SpawnPoints.Count)
lastUsedSpawnPointIndex = 0;
/// Use Vector.Zero and Quaternion.Identity if we are dealing with no or a null spawnpoint.
return SpawnPoints == null || SpawnPoints.Count == 0 ? null : SpawnPoints[lastUsedSpawnPointIndex];
}
case SpawnSequence.Random:
{
return SpawnPoints[Random.Range(0, SpawnPoints.Count)];
}
default:
return null;
}
}
}
/// <summary>
/// When UseRandomeOffset is enabled, this method is called to produce a Vector3 offset. The default implementation clamps the Y value to zero. You may override this with your own implementation.
/// </summary>
protected virtual Vector3 GetRandomOffset()
{
Vector3 random = Random.insideUnitSphere;
if (ClampY)
random.y = 0;
return RandomOffset * random.normalized;
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(OnJoinedInstantiate), true)]
[CanEditMultipleObjects]
public class OnJoinedInstantiateEditor : Editor
{
SerializedProperty SpawnPoints, PrefabsToInstantiate, UseRandomOffset, ClampY, RandomOffset, Sequence, autoSpawnObjects;
GUIStyle fieldBox;
private void OnEnable()
{
SpawnPoints = serializedObject.FindProperty("SpawnPoints");
PrefabsToInstantiate = serializedObject.FindProperty("PrefabsToInstantiate");
UseRandomOffset = serializedObject.FindProperty("UseRandomOffset");
ClampY = serializedObject.FindProperty("ClampY");
RandomOffset = serializedObject.FindProperty("RandomOffset");
Sequence = serializedObject.FindProperty("Sequence");
autoSpawnObjects = serializedObject.FindProperty("AutoSpawnObjects");
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
const int PAD = 6;
if (fieldBox == null)
fieldBox = new GUIStyle("HelpBox") { padding = new RectOffset(PAD, PAD, PAD, PAD) };
EditorGUI.BeginChangeCheck();
EditableReferenceList(PrefabsToInstantiate, new GUIContent(PrefabsToInstantiate.displayName, PrefabsToInstantiate.tooltip), fieldBox);
EditableReferenceList(SpawnPoints, new GUIContent(SpawnPoints.displayName, SpawnPoints.tooltip), fieldBox);
/// Spawn Pattern
EditorGUILayout.BeginVertical(fieldBox);
EditorGUILayout.PropertyField(Sequence);
EditorGUILayout.PropertyField(UseRandomOffset);
if (UseRandomOffset.boolValue)
{
EditorGUILayout.PropertyField(RandomOffset);
EditorGUILayout.PropertyField(ClampY);
}
EditorGUILayout.EndVertical();
/// Auto/Manual Spawn
EditorGUILayout.BeginVertical(fieldBox);
EditorGUILayout.PropertyField(autoSpawnObjects);
EditorGUILayout.EndVertical();
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
}
/// <summary>
/// Create a basic rendered list of objects from a SerializedProperty list or array, with Add/Destroy buttons.
/// </summary>
/// <param name="list"></param>
/// <param name="gc"></param>
public void EditableReferenceList(SerializedProperty list, GUIContent gc, GUIStyle style = null)
{
EditorGUILayout.LabelField(gc);
if (style == null)
style = new GUIStyle("HelpBox") { padding = new RectOffset(6, 6, 6, 6) };
EditorGUILayout.BeginVertical(style);
int count = list.arraySize;
if (count == 0)
{
if (GUI.Button(EditorGUILayout.GetControlRect(GUILayout.MaxWidth(20)), "+", (GUIStyle)"minibutton"))
{
int newindex = list.arraySize;
list.InsertArrayElementAtIndex(0);
list.GetArrayElementAtIndex(0).objectReferenceValue = null;
}
}
else
{
// List Elements and Delete buttons
for (int i = 0; i < count; ++i)
{
EditorGUILayout.BeginHorizontal();
bool add = (GUI.Button(EditorGUILayout.GetControlRect(GUILayout.MaxWidth(20)), "+", (GUIStyle)"minibutton"));
EditorGUILayout.PropertyField(list.GetArrayElementAtIndex(i), GUIContent.none);
bool remove = (GUI.Button(EditorGUILayout.GetControlRect(GUILayout.MaxWidth(20)), "x", (GUIStyle)"minibutton"));
EditorGUILayout.EndHorizontal();
if (add)
{
Add(list, i);
break;
}
if (remove)
{
list.DeleteArrayElementAtIndex(i);
//EditorGUILayout.EndHorizontal();
break;
}
}
EditorGUILayout.GetControlRect(false, 4);
if (GUI.Button(EditorGUILayout.GetControlRect(), "Add", (GUIStyle)"minibutton"))
Add(list, count);
}
EditorGUILayout.EndVertical();
}
private void Add(SerializedProperty list, int i)
{
{
int newindex = list.arraySize;
list.InsertArrayElementAtIndex(i);
list.GetArrayElementAtIndex(i).objectReferenceValue = null;
}
}
}
#endif
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ed3b5dcba7bf9114cb13fc59e0a71f55
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}

View File

@ -0,0 +1,24 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="OnStartDelete.cs" company="Exit Games GmbH">
// Part of: Photon Unity Utilities,
// </copyright>
// <summary>
// This component will destroy the GameObject it is attached to (in Start()).
// </summary>
// <author>developer@exitgames.com</author>
// --------------------------------------------------------------------------------------------------------------------
using UnityEngine;
namespace Photon.Pun.UtilityScripts
{
/// <summary>This component will destroy the GameObject it is attached to (in Start()).</summary>
public class OnStartDelete : MonoBehaviour
{
// Use this for initialization
private void Start()
{
Destroy(this.gameObject);
}
}
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f8d56a54ae062da4a87516fb994f4e30
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}