aha
This commit is contained in:
73
Assets/Mirror/Examples/CouchCoop/Scripts/CameraViewForAll.cs
Normal file
73
Assets/Mirror/Examples/CouchCoop/Scripts/CameraViewForAll.cs
Normal file
@ -0,0 +1,73 @@
|
||||
using UnityEngine;
|
||||
namespace Mirror.Examples.CouchCoop
|
||||
{
|
||||
public class CameraViewForAll : MonoBehaviour
|
||||
{
|
||||
public Transform cameraTransform;
|
||||
public float camSpeed = 2.0f;
|
||||
public float orthoSizeSpeed = 2.0f;
|
||||
public Camera mainCamera;
|
||||
public float cameraZ = -5;
|
||||
|
||||
public float cameraBufferX = 0.1f;
|
||||
public float cameraBufferY = 0.1f;
|
||||
public float minOrthographicSize = 0.1f;
|
||||
public float targetYPosition = 4.5f; // Optional Y position if cameras rotated
|
||||
|
||||
private Vector2Int boundsMin;
|
||||
private Vector2Int boundsMax;
|
||||
private Vector3 targetCameraPosition;
|
||||
private float targetOrthographicSize;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (CouchPlayer.playersList.Count > 0)
|
||||
{
|
||||
CalculateBounds();
|
||||
CalculateTargetCameraPosAndSize();
|
||||
MoveCamera();
|
||||
}
|
||||
}
|
||||
|
||||
private void CalculateBounds()
|
||||
{
|
||||
boundsMin = new Vector2Int(int.MaxValue, int.MaxValue);
|
||||
boundsMax = new Vector2Int(int.MinValue, int.MinValue);
|
||||
|
||||
foreach (GameObject player in CouchPlayer.playersList)
|
||||
{
|
||||
Vector3 playerPosition = player.transform.position;
|
||||
boundsMin.x = Mathf.Min(boundsMin.x, Mathf.FloorToInt(playerPosition.x));
|
||||
boundsMin.y = Mathf.Min(boundsMin.y, Mathf.FloorToInt(playerPosition.y));
|
||||
boundsMax.x = Mathf.Max(boundsMax.x, Mathf.CeilToInt(playerPosition.x));
|
||||
boundsMax.y = Mathf.Max(boundsMax.y, Mathf.CeilToInt(playerPosition.y));
|
||||
}
|
||||
|
||||
boundsMin.x -= Mathf.FloorToInt(cameraBufferX);
|
||||
boundsMin.y -= Mathf.FloorToInt(cameraBufferY);
|
||||
boundsMax.x += Mathf.CeilToInt(cameraBufferX);
|
||||
boundsMax.y += Mathf.CeilToInt(cameraBufferY);
|
||||
}
|
||||
|
||||
private void CalculateTargetCameraPosAndSize()
|
||||
{
|
||||
float aspectRatio = (float)Screen.width / Screen.height;
|
||||
|
||||
float requiredOrthographicSizeX = Mathf.Max((boundsMax.x - boundsMin.x) / 2 / aspectRatio, minOrthographicSize / aspectRatio);
|
||||
float requiredOrthographicSizeY = Mathf.Max(boundsMax.y - boundsMin.y / 2, minOrthographicSize);
|
||||
|
||||
targetOrthographicSize = Mathf.Max(requiredOrthographicSizeX, requiredOrthographicSizeY);
|
||||
|
||||
float cameraX = (boundsMax.x + boundsMin.x) / 2;
|
||||
float cameraY = targetYPosition != 0.0f ? targetYPosition : (boundsMax.y + boundsMin.y) / 2;
|
||||
|
||||
targetCameraPosition = new Vector3(cameraX, cameraY, cameraZ);
|
||||
}
|
||||
|
||||
private void MoveCamera()
|
||||
{
|
||||
cameraTransform.position = Vector3.Lerp(cameraTransform.position, targetCameraPosition, camSpeed * Time.deltaTime);
|
||||
mainCamera.orthographicSize = Mathf.Lerp(mainCamera.orthographicSize, targetOrthographicSize, orthoSizeSpeed * Time.deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73edff93783204b298f805477ae30ecd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 129321
|
||||
packageName: Mirror
|
||||
packageVersion: 96.0.1
|
||||
assetPath: Assets/Mirror/Examples/CouchCoop/Scripts/CameraViewForAll.cs
|
||||
uploadId: 736421
|
32
Assets/Mirror/Examples/CouchCoop/Scripts/CanvasScript.cs
Normal file
32
Assets/Mirror/Examples/CouchCoop/Scripts/CanvasScript.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
namespace Mirror.Examples.CouchCoop
|
||||
{
|
||||
public class CanvasScript : MonoBehaviour
|
||||
{
|
||||
public CouchPlayerManager couchPlayerManager; // Sets itself
|
||||
public Button buttonAddPlayer, buttonRemovePlayer; // Make sure to attach these Buttons in the Inspector
|
||||
|
||||
private void Start()
|
||||
{
|
||||
buttonAddPlayer.onClick.AddListener(ButtonAddPlayer);
|
||||
buttonRemovePlayer.onClick.AddListener(ButtonRemovePlayer);
|
||||
}
|
||||
|
||||
private void ButtonAddPlayer()
|
||||
{
|
||||
if (couchPlayerManager == null)
|
||||
{ Debug.Log("Start game first."); return; }
|
||||
|
||||
couchPlayerManager.CmdAddPlayer();
|
||||
}
|
||||
|
||||
private void ButtonRemovePlayer()
|
||||
{
|
||||
if (couchPlayerManager == null)
|
||||
{ Debug.Log("Start game first."); return; }
|
||||
|
||||
couchPlayerManager.CmdRemovePlayer();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b76e63e8ad5c42d59aa6ccdda8cddbf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 129321
|
||||
packageName: Mirror
|
||||
packageVersion: 96.0.1
|
||||
assetPath: Assets/Mirror/Examples/CouchCoop/Scripts/CanvasScript.cs
|
||||
uploadId: 736421
|
129
Assets/Mirror/Examples/CouchCoop/Scripts/CouchPlayer.cs
Normal file
129
Assets/Mirror/Examples/CouchCoop/Scripts/CouchPlayer.cs
Normal file
@ -0,0 +1,129 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Mirror.Examples.CouchCoop
|
||||
{
|
||||
public class CouchPlayer : NetworkBehaviour
|
||||
{
|
||||
public Rigidbody rb;
|
||||
public float movementSpeed = 3;
|
||||
public float jumpSpeed = 6;
|
||||
private float movementVelocity;
|
||||
private bool isGrounded;
|
||||
|
||||
public CouchPlayerManager couchPlayerManager;
|
||||
private KeyCode jumpKey = KeyCode.Space; // Check CouchPlayerManager for controls
|
||||
private KeyCode leftKey = KeyCode.LeftArrow;
|
||||
private KeyCode rightKey = KeyCode.RightArrow;
|
||||
|
||||
[SyncVar(hook = nameof(OnNumberChangedHook))]
|
||||
public int playerNumber = 0;
|
||||
public Text textPlayerNumber;
|
||||
|
||||
// a list of players, is used for camera
|
||||
public readonly static List<GameObject> playersList = new List<GameObject>();
|
||||
|
||||
public void Start()
|
||||
{
|
||||
playersList.Add(this.gameObject);
|
||||
// print("playersList: " + playersList.Count);
|
||||
|
||||
SetPlayerUI();
|
||||
}
|
||||
|
||||
public void OnDestroy()
|
||||
{
|
||||
playersList.Remove(this.gameObject);
|
||||
// print("playersList: " + playersList.Count);
|
||||
}
|
||||
|
||||
public override void OnStartAuthority()
|
||||
{
|
||||
this.enabled = true;
|
||||
|
||||
if (isOwned)
|
||||
{
|
||||
#if UNITY_2022_2_OR_NEWER
|
||||
couchPlayerManager = GameObject.FindAnyObjectByType<CouchPlayerManager>();
|
||||
#else
|
||||
// Deprecated in Unity 2023.1
|
||||
couchPlayerManager = GameObject.FindObjectOfType<CouchPlayerManager>();
|
||||
#endif
|
||||
// setup controls according to the pre-sets on CouchPlayerManager
|
||||
jumpKey = couchPlayerManager.playerKeyJump[playerNumber];
|
||||
leftKey = couchPlayerManager.playerKeyLeft[playerNumber];
|
||||
rightKey = couchPlayerManager.playerKeyRight[playerNumber];
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (!Application.isFocused) return;
|
||||
if (isOwned == false) { return; }
|
||||
|
||||
// you can control all local players via arrow keys and space bar for fun testing
|
||||
// otherwise check and set individual controls in CouchPlayerManager script.
|
||||
if (isGrounded == true)
|
||||
{
|
||||
if (Input.GetKey(KeyCode.Space) || Input.GetKeyDown(jumpKey))
|
||||
{
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
rb.linearVelocity = new Vector2(rb.linearVelocity.x, jumpSpeed);
|
||||
#else
|
||||
rb.velocity = new Vector2(rb.velocity.x, jumpSpeed);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
movementVelocity = 0;
|
||||
|
||||
if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(leftKey))
|
||||
{
|
||||
movementVelocity = -movementSpeed;
|
||||
}
|
||||
if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(rightKey))
|
||||
{
|
||||
movementVelocity = movementSpeed;
|
||||
}
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
rb.linearVelocity = new Vector2(movementVelocity, rb.linearVelocity.y);
|
||||
#else
|
||||
rb.velocity = new Vector2(movementVelocity, rb.velocity.y);
|
||||
#endif
|
||||
}
|
||||
|
||||
[ClientCallback]
|
||||
void OnCollisionExit(Collision col)
|
||||
{
|
||||
if (isOwned == false) { return; }
|
||||
isGrounded = false;
|
||||
}
|
||||
|
||||
[ClientCallback]
|
||||
void OnCollisionStay(Collision col)
|
||||
{
|
||||
if (isOwned == false) { return; }
|
||||
isGrounded = true;
|
||||
}
|
||||
|
||||
void OnNumberChangedHook(int _old, int _new)
|
||||
{
|
||||
//Debug.Log(name + " - OnNumberChangedHook: " + playerNumber);
|
||||
SetPlayerUI();
|
||||
}
|
||||
|
||||
public void SetPlayerUI()
|
||||
{
|
||||
// called from hook and in start, to solve a race condition
|
||||
if (isOwned)
|
||||
{
|
||||
textPlayerNumber.text = "Local: " + playerNumber;
|
||||
}
|
||||
else
|
||||
{
|
||||
textPlayerNumber.text = "Remote: " + playerNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
Assets/Mirror/Examples/CouchCoop/Scripts/CouchPlayer.cs.meta
Normal file
18
Assets/Mirror/Examples/CouchCoop/Scripts/CouchPlayer.cs.meta
Normal file
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1931e6adfa27e41bbbea220a6436c0e9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData: ''
|
||||
assetBundleName: ''
|
||||
assetBundleVariant: ''
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 129321
|
||||
packageName: Mirror
|
||||
packageVersion: 96.0.1
|
||||
assetPath: Assets/Mirror/Examples/CouchCoop/Scripts/CouchPlayer.cs
|
||||
uploadId: 736421
|
@ -0,0 +1,69 @@
|
||||
using UnityEngine;
|
||||
using Mirror;
|
||||
|
||||
namespace Mirror.Examples.CouchCoop
|
||||
{
|
||||
public class CouchPlayerManager : NetworkBehaviour
|
||||
{
|
||||
// reference to UI that should be in the scene
|
||||
public CanvasScript canvasScript;
|
||||
// for multiple player prefabs, currently not implemented, remember to add these into Network Managers Prefab array.
|
||||
public GameObject[] playerPrefabs;
|
||||
public int totalCouchPlayers = 0;
|
||||
|
||||
// ignore key controls 0, we will always start at 1
|
||||
public KeyCode[] playerKeyJump;
|
||||
public KeyCode[] playerKeyLeft;
|
||||
public KeyCode[] playerKeyRight;
|
||||
|
||||
// store a list of players so we know which to remove later
|
||||
// can be non sync-list, but may be useful for future features
|
||||
readonly SyncList<GameObject> couchPlayersList = new SyncList<GameObject>();
|
||||
|
||||
public override void OnStartAuthority()
|
||||
{
|
||||
// hook up UI to local player, for cmd communication
|
||||
#if UNITY_2022_2_OR_NEWER
|
||||
canvasScript = GameObject.FindAnyObjectByType<CanvasScript>();
|
||||
#else
|
||||
// Deprecated in Unity 2023.1
|
||||
canvasScript = GameObject.FindObjectOfType<CanvasScript>();
|
||||
#endif
|
||||
canvasScript.couchPlayerManager = this;
|
||||
}
|
||||
|
||||
[Command]
|
||||
public void CmdAddPlayer()
|
||||
{
|
||||
if (totalCouchPlayers >= playerKeyJump.Length-1)
|
||||
{
|
||||
Debug.Log(name + " - No controls setup for further players.");
|
||||
return;
|
||||
}
|
||||
|
||||
totalCouchPlayers += 1;
|
||||
Transform spawnObj = NetworkManager.startPositions[Random.Range(0, NetworkManager.startPositions.Count)];
|
||||
GameObject playerObj = Instantiate(playerPrefabs[0], spawnObj.position, spawnObj.rotation);
|
||||
CouchPlayer couchPlayer = playerObj.GetComponent<CouchPlayer>();
|
||||
couchPlayer.playerNumber = totalCouchPlayers;
|
||||
NetworkServer.Spawn(playerObj, connectionToClient);
|
||||
couchPlayersList.Add(playerObj);
|
||||
}
|
||||
|
||||
[Command]
|
||||
public void CmdRemovePlayer()
|
||||
{
|
||||
if (totalCouchPlayers <= 0)
|
||||
{
|
||||
Debug.Log(name + " - No players to remove for that connection.");
|
||||
return;
|
||||
}
|
||||
|
||||
totalCouchPlayers -= 1;
|
||||
NetworkServer.Destroy(couchPlayersList[couchPlayersList.Count - 1]);
|
||||
couchPlayersList.RemoveAt(couchPlayersList.Count - 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32f263c662d1e4d33870c9411461bbd0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 129321
|
||||
packageName: Mirror
|
||||
packageVersion: 96.0.1
|
||||
assetPath: Assets/Mirror/Examples/CouchCoop/Scripts/CouchPlayerManager.cs
|
||||
uploadId: 736421
|
79
Assets/Mirror/Examples/CouchCoop/Scripts/MovingPlatform.cs
Normal file
79
Assets/Mirror/Examples/CouchCoop/Scripts/MovingPlatform.cs
Normal file
@ -0,0 +1,79 @@
|
||||
using UnityEngine;
|
||||
using Mirror;
|
||||
|
||||
namespace Mirror.Examples.CouchCoop
|
||||
{
|
||||
public class MovingPlatform : NetworkBehaviour
|
||||
{
|
||||
public Transform endTarget;
|
||||
public float moveSpeed = 0.5f;
|
||||
// allows for on demand syncing of stopping and starting platform movement, change via server
|
||||
// note,sync vars changed via inspector do not sync. This is optional feature, can be removed
|
||||
[SyncVar]
|
||||
public bool moveObj = true;
|
||||
|
||||
// optional fancy features
|
||||
public bool moveStopsUponExit = false;
|
||||
public bool moveStartsUponCollision = false;
|
||||
|
||||
private Vector3 startPosition;
|
||||
private Vector3 endPosition;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
startPosition = transform.position;
|
||||
endPosition = endTarget.position;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (moveObj)
|
||||
{
|
||||
float step = moveSpeed * Time.deltaTime;
|
||||
transform.position = Vector3.MoveTowards(transform.position, endPosition, step);
|
||||
|
||||
if (Vector3.Distance(transform.position, endPosition) < 0.001f)
|
||||
{
|
||||
endPosition = endPosition == startPosition ? endTarget.position : startPosition;
|
||||
if (isServer)
|
||||
{
|
||||
RpcResyncPosition(endPosition == startPosition ? (byte)1 : (byte)0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ClientRpc]
|
||||
void RpcResyncPosition(byte _value)
|
||||
{
|
||||
//print("RpcResyncPosition: " + _value);
|
||||
transform.position = _value == 1 ? endTarget.position : startPosition;
|
||||
}
|
||||
|
||||
// optional
|
||||
[ServerCallback]
|
||||
private void OnCollisionEnter(Collision collision)
|
||||
{
|
||||
if (moveStartsUponCollision)
|
||||
{
|
||||
if (collision.gameObject.tag == "Player")
|
||||
{
|
||||
moveObj = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// optional
|
||||
[ServerCallback]
|
||||
private void OnCollisionExit(Collision collision)
|
||||
{
|
||||
if (moveStopsUponExit)
|
||||
{
|
||||
if (collision.gameObject.tag == "Player")
|
||||
{
|
||||
moveObj = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c2bc1b05e6794a419ce8e1091f59a05
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 129321
|
||||
packageName: Mirror
|
||||
packageVersion: 96.0.1
|
||||
assetPath: Assets/Mirror/Examples/CouchCoop/Scripts/MovingPlatform.cs
|
||||
uploadId: 736421
|
49
Assets/Mirror/Examples/CouchCoop/Scripts/PlatformMovement.cs
Normal file
49
Assets/Mirror/Examples/CouchCoop/Scripts/PlatformMovement.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using UnityEngine;
|
||||
using Mirror;
|
||||
|
||||
namespace Mirror.Examples.CouchCoop
|
||||
{
|
||||
public class PlatformMovement : NetworkBehaviour
|
||||
{
|
||||
// A separate script to handle platform behaviour, see its partner script, MovingPlatform.cs
|
||||
private bool onPlatform;
|
||||
private Transform platformTransform;
|
||||
private Vector3 lastPlatformPosition;
|
||||
|
||||
public override void OnStartAuthority()
|
||||
{
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
void FixedUpdate()
|
||||
{
|
||||
if (onPlatform)
|
||||
{
|
||||
Vector3 deltaPosition = platformTransform.position - lastPlatformPosition;
|
||||
transform.position += deltaPosition;
|
||||
lastPlatformPosition = platformTransform.position;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCollisionEnter(Collision collision)
|
||||
{
|
||||
|
||||
if (collision.gameObject.tag == "Finish")
|
||||
{
|
||||
platformTransform = collision.gameObject.GetComponent<Transform>();
|
||||
lastPlatformPosition = platformTransform.position;
|
||||
onPlatform = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCollisionExit(Collision collision)
|
||||
{
|
||||
// ideally set a Platform tag, but we'l just use a Unity Pre-set.
|
||||
if (collision.gameObject.tag == "Finish")
|
||||
{
|
||||
onPlatform = false;
|
||||
platformTransform = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19882c332836048ada1935c7fb20283b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 129321
|
||||
packageName: Mirror
|
||||
packageVersion: 96.0.1
|
||||
assetPath: Assets/Mirror/Examples/CouchCoop/Scripts/PlatformMovement.cs
|
||||
uploadId: 736421
|
Reference in New Issue
Block a user