I'm making a mulitplayer game using photons, the game has almost all of them, but I have problems in the process of displaying the star rating score, everything runs normally when playing alone, the score ui also appears, but when the player plays more than one person when all have entered the door, the score ui does not appear. What should I fix in my code? help me this for my thesis.
This is code for score star rating
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using Photon.Pun;
public class ScoreManager : MonoBehaviourPunCallbacks, IPunObservable
{
public GameObject scoreUI; // assign your Score UI in the inspector
public GameObject[] stars; // assign your Star UI in the inspector
private Timer timerScript;
private List<PlayerControl> playerScripts = new List<PlayerControl>(); // list to store player scripts
private PhotonView pV;
public string playerTag = "Player";
void Start()
{
// get Timer component from a gameObject in the scene. Ensure that Timer is attached to a gameObject in your scene.
timerScript = FindObjectOfType<Timer>();
// start with the score UI hidden
scoreUI.SetActive(false);
// initialize PhotonView
pV = GetComponent<PhotonView>();
}
void Update()
{
// check if playerScripts list is empty
if (playerScripts.Count == 0)
{
// try to find PlayerControl again
GameObject[] players = GameObject.FindGameObjectsWithTag(playerTag);
foreach (GameObject player in players)
{
PlayerControl playerControl = player.GetComponent<PlayerControl>();
if (playerControl != null)
{
playerScripts.Add(playerControl); // add player script to the list
}
}
}
// if playerScripts list is not empty
if (playerScripts.Count > 0)
{
// flag to check if all players meet the score condition
bool allPlayersMeetCondition = true;
// iterate through all player scripts
foreach (PlayerControl playerScript in playerScripts)
{
// if any player does not meet the condition, set the flag to false and break the loop
if (playerScript == null || playerScript.playersInside != playerScript.totalPlayers)
{
allPlayersMeetCondition = false;
Debug.Log("Condition to show score has NOT been met.");
break;
}
}
// if all players meet the score condition
if (allPlayersMeetCondition)
{
Debug.Log("Condition to show score has been met.");
// stop the timer
timerScript.StopTimer();
// show the score UI
photonView.RPC("ShowScoreUI", RpcTarget.All);
// calculate stars
if (timerScript.timer <= 5) // less than or equal to 1 minute
{
photonView.RPC("ShowStars", RpcTarget.All, 3);
}
else if (timerScript.timer > 5 && timerScript.timer <= 10) // greater than 1 minute but less than or equal to 1.5 minutes
{
photonView.RPC("ShowStars", RpcTarget.All, 2);
}
else if (timerScript.timer > 20) // greater than 1.5 minutes
{
photonView.RPC("ShowStars", RpcTarget.All, 1);
}
}
}
}
[PunRPC]
public void ShowScoreUI()
{
Debug.Log("ShowScoreUI function called.");
scoreUI.SetActive(true);
}
[PunRPC]
public void ShowStars(int starCount)
{
for (int i = 0; i < stars.Length; i++)
{
stars[i].SetActive(i < starCount);
}
}
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.IsWriting)
{
// We own this player: send the others our data
stream.SendNext(timerScript.timer);
stream.SendNext(playerScripts.Count); // Send the number of PlayerControl
foreach (PlayerControl playerScript in playerScripts)
{
// check if playerScript is not null
if (playerScript != null)
{
stream.SendNext(playerScript.playersInside);
stream.SendNext(playerScript.totalPlayers);
// Include the playersInside and totalPlayers values
}
}
}
else
{
// Network player, receive data
timerScript.timer = (float)stream.ReceiveNext();
int playerScriptsCount = (int)stream.ReceiveNext(); // Receive the number of PlayerControl
for (int i = 0; i < playerScriptsCount; i++)
{
if (i < playerScripts.Count && playerScripts[i] != null)
{
playerScripts[i].playersInside = (int)stream.ReceiveNext();
playerScripts[i].totalPlayers = (int)stream.ReceiveNext();
// Receive the playersInside and totalPlayers values
}
else
{
// If there is not enough PlayerControl, just receive the data and do nothing
stream.ReceiveNext();
stream.ReceiveNext();
}
}
}
}
}
This is for Player Control
using System.Collections;
using UnityEngine.InputSystem;
using UnityEngine;
using UnityEngine.InputSystem.Interactions;
using UnityEngine.UI;
using Photon.Pun;
using Cinemachine;
using UnityEngine.SceneManagement; // tambahkan ini di bagian atas script Anda
using TMPro;
public class PlayerControl : MonoBehaviour, IPunObservable
{
// Start is called before the first frame update
public float jumpTime; //time till which we will apply jump force
private float jumpTimeCounter; //time to count how long player has pressed jump key
private bool isJumping; //bool to tell if player is jumping or not
public Rigidbody2D rb;
public bool isOnPlatform;
public bool isOnMovingPlatform = false;
// public float pushForce = 1f;
private BoxCollider2D playerCollider;
public bool isPlayerBelow = false;
public float jumpForce = 10f;
private Animator anim;
private SpriteRenderer characterSprite;
private bool isGrounded;
public PhotonView photonView;
private Vector3 smoothMove;
private Vector2 m_Move;
public bool isKey = false,indoor=false;
public GameObject key;
public PhotonTransformView photonTransformView;
public GameObject playerCamera;
private CinemachineVirtualCamera virtualCamera;
private Transform playerCollided;
public float jumpDown = 2;
Transform playerTransform;
public GameObject player;
public TextMeshProUGUI PlayerNameText;
private bool isPlayerCollid;
private GameObject playerOnTop;
private int coinsCollected;
private bool hasKey;
public bool isPushing = false;
private float pushingDistance = 5f; // Set this to the distance within which other players can help push
public int playersInside = 0; // pemain yang ada di dalam pintu
public int totalPlayers;
public float moveSpeed = 5f;
private Vector3 startPosition;
public GameObject platform; // assign the platform object in Unity Inspector
private ScoreManager scriptScoreManager;
private GameObject scoreManager;
public bool isScoreController = false;
// public GameObject sceneCamera;
// public GameObject playerCamera;
void Awake()
{
/* if (SystemInfo.deviceType == DeviceType.Console)
{
transform.position = GameSetup.LevelCharacterSpawns1S[GameSetup.LevelI];
*
}*/
anim =GetComponent<Animator>();
characterSprite = GetComponent<SpriteRenderer>();
photonView = GetComponent<PhotonView>();
photonTransformView = GetComponent<PhotonTransformView>();
key = GameObject.FindGameObjectWithTag("key");
playerCollider = GetComponent<BoxCollider2D>();
startPosition = transform.position;
totalPlayers = PhotonNetwork.CurrentRoom.PlayerCount;
rb = GetComponent<Rigidbody2D>();
rb.interpolation = RigidbodyInterpolation2D.Interpolate;
rb.collisionDetectionMode = CollisionDetectionMode2D.Continuous;
if(photonView.IsMine){
PlayerNameText.text = PhotonNetwork.LocalPlayer.NickName;
}else {
PlayerNameText.text = photonView.Owner.NickName;
}
if (photonView.IsMine){
GameObject sceneCamera = GameObject.FindGameObjectWithTag("MainCamera");
if (SceneManager.GetActiveScene().name == "Level1Canon")
{
sceneCamera.SetActive(true);
playerCamera.SetActive(false);
}
if (SceneManager.GetActiveScene().name == "Level1Ghost")
{
sceneCamera.SetActive(false);
playerCamera.SetActive(true);
playerCamera.GetComponent<Camera>().fieldOfView = 70f;
}
else
{
sceneCamera.SetActive(false);
playerCamera.SetActive(true);
}
}
}
void Start()
{
if (photonView.IsMine)
{
if (!photonView.IsMine)
{
return;
}
}
}
// Update is called once per frame
void Update()
{
if (playerCollided != null){
playerCollided.position = new Vector2( transform.position.x, playerCollided.position.y);
}
if (GameSetup.DestroyCharacters)
{
Destroy(gameObject);
}
}
[PunRPC]
void UpdatePlayerCounts(int playersInsideCount, int totalPlayersCount)
{
playersInside = playersInsideCount;
totalPlayers = totalPlayersCount;
}
public void AdjustPlayerCounts(bool playerEntered)
{
if (playerEntered)
{
playersInside++;
}
else
{
playersInside--;
}
totalPlayers = PhotonNetwork.CurrentRoom.PlayerCount;
photonView.RPC("UpdatePlayerCounts", RpcTarget.AllBuffered, playersInside, totalPlayers);
}
public void Jump()
{
if(isGrounded && !isPlayerCollid)
{
isJumping = true;
jumpTimeCounter = jumpTime;
// Ubah ini
rb.AddForce(new Vector2(0, jumpForce), ForceMode2D.Impulse);
anim.SetBool("Jumping", true);
}
if (isJumping == true)
{
if (jumpTimeCounter > 0)
{
// Menambahkan kecepatan horizontal saat melompat
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
jumpTimeCounter -= Time.deltaTime;
}
else
{
isJumping = false;
}
}
}
public void StopMoving()
{
rb.velocity = new Vector2(0, rb.velocity.y);
anim.SetBool("Walking",false);
}
// public void OnMove(InputAction.CallbackContext context)
// {
// m_Move = context.ReadValue<Vector2>();
// }
public void OnMove(InputAction.CallbackContext context)
{
m_Move = context.ReadValue<Vector2>();
if (photonView.IsMine)
{
Move(m_Move);
}
}
IEnumerator JumpDene()
{
isGrounded = false;
isJumping = true;
jumpTimeCounter = jumpTime;
// Menambahkan kecepatan horizontal saat melompat
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
anim.SetBool("Jumping", true);
yield return new WaitForSeconds(0.12f);
// Menambahkan kecepatan horizontal saat turun
rb.velocity = new Vector2(rb.velocity.x, -jumpForce / jumpDown);
}
public void OnJump(InputAction.CallbackContext context)
{
switch (context.phase)
{
case InputActionPhase.Performed:
break;
case InputActionPhase.Started:
if (indoor)
{
GameSetup.doorleftCount++;
// pengecekan total pemain dan bintang di sini
playersInside++;
photonView.RPC("HidePlayer", RpcTarget.AllBuffered);
}
else
{
if (isGrounded)
{
StartCoroutine(JumpDene());
}
}
break;
}
}
public void cameraScore(){
GameObject sceneCamera = GameObject.FindGameObjectWithTag("MainCamera");
sceneCamera.SetActive(true); // Nyalakan scene camera
playerCamera.SetActive(false);
}
[PunRPC]
public void Teleport(Vector3 newPosition)
{
transform.position = newPosition;
}
[PunRPC]
void HidePlayer()
{
if (photonView.IsMine || PhotonNetwork.IsMasterClient)
{
Camera childCamera = gameObject.GetComponentInChildren<Camera>();
if(childCamera != null)
{
// Detach the camera from the parent
childCamera.transform.parent = null;
}
// Pindahkan objek ke posisi yang tidak terlihat oleh kamera
gameObject.transform.position = new Vector3(10000, 10000, 10000);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "ground")
{
isGrounded = true;
anim.SetBool("Jumping", false);
}
if (collision.gameObject.CompareTag("FallingPlatform"))
{
isGrounded = true;
anim.SetBool("Jumping", false);
}
if (collision.gameObject.CompareTag("bullet"))
{
// Pemain kembali ke posisi awal setelah terkena bullet
transform.position = startPosition;
// Destroy bullet setelah menabrak pemain
Destroy(collision.gameObject);
Destroy(gameObject);
}
if (collision.gameObject.tag == "button")
{
isGrounded = true;
}
if (collision.gameObject.tag == "platform")
{
isJumping = true;
isGrounded = true;
}
if (collision.gameObject.tag == "Player")
{
isGrounded = true;
isPlayerCollid = true;
Rigidbody2D otherPlayerRb = collision.gameObject.GetComponent<Rigidbody2D>();
otherPlayerRb.velocity = Vector2.zero;
// Atau, Anda dapat mengatur kecepatan pemain Anda menjadi 0 juga
rb.velocity = Vector2.zero;
anim.SetBool("Jumping", false);
isPlayerBelow = true;
var CollidedTransform = collision.gameObject.GetComponent<Transform>();
}
if (collision.gameObject.tag == "pushable")
{
if(collision.gameObject.transform.position.y<transform.position.y)
isGrounded = true;
collision.gameObject.GetComponent<PushableObjectSetup>().playercontact++;
collision.gameObject.GetComponent<PushableObjectSetup>().requiredPlayerCount--;
if (collision.gameObject.transform.position.x < transform.position.x)
{
isGrounded = true;
}
if (collision.gameObject.transform.position.x > transform.position.x)
{
isGrounded = true;
}
}
// if (collision.gameObject.CompareTag("door"))
// {
// scoreManager = GameObject.Find("Score");
// scoreManager.SetActive(true);
// }
}
private void OnTriggerEnter2D(Collider2D other) {
if(other.gameObject.CompareTag("ColliderRope")){
rb.mass = 0.09f;
Debug.Log("Test");
}
}
private void OnTriggerExit2D(Collider2D other) {
if(other.gameObject.CompareTag("ColliderRope")){
rb.mass = 1f;
Debug.Log("Test");
}
}
private void OnCollisionExit2D(Collision2D collision)
{
if (collision.gameObject.tag == "ground")
{
// isGrounded = false;
}
if (collision.gameObject.tag == "Player")
{
if(collision.gameObject.transform.position.y<transform.position.y)
{
isGrounded = false;
Debug.Log("Player is no longer below another player");
}
else
{
Debug.Log("Player is no longer above another player");
}
isPlayerCollid = false;
isPlayerBelow = false;
playerCollided = null;
}
if (collision.gameObject.tag == "pushable")
{
collision.gameObject.GetComponent<PushableObjectSetup>().playercontact--;
collision.gameObject.GetComponent<PushableObjectSetup>().requiredPlayerCount++;
}
}
[PunRPC]
private void IncreasePlayerContact()
{
GetComponent<PushableObjectSetup>().playercontact++;
GetComponent<PushableObjectSetup>().requiredPlayerCount--;
if (transform.position.x < transform.position.x)
{
isGrounded = true;
}
else if (transform.position.x > transform.position.x)
{
isGrounded = true;
}
}
[PunRPC]
private void DecreasePlayerContact()
{
GetComponent<PushableObjectSetup>().playercontact--;
GetComponent<PushableObjectSetup>().requiredPlayerCount++;
}
private void Move(Vector2 direction)
{
if (direction.x == 0)
StopMoving();
// if(direction.y==0)
// isJumping = false;
if (direction.sqrMagnitude < 0.01)
return;
if (direction.x > 0)
{
photonView.RPC("OnDirectionChange_RIGHT", RpcTarget.AllBuffered);
}else if(direction.x < 0)
{
photonView.RPC("OnDirectionChange_LEFT", RpcTarget.AllBuffered);
}
if (!isPlayerCollid)
{
rb.velocity = new Vector2(moveSpeed * direction.x, rb.velocity.y);
}
// jika pemain di bawah, tetap biarkan mereka menggunakan rb.velocity
else if (isPlayerBelow)
{
rb.velocity = new Vector2(moveSpeed * direction.x, rb.velocity.y);
}
//Jika pemain ini berada di bawah pemain lain, ubah posisi pemain yang berada di atas
if (playerOnTop != null)
{
playerOnTop.transform.position = new Vector3(
playerOnTop.transform.position.x + moveSpeed * direction.x * Time.deltaTime,
playerOnTop.transform.position.y,
playerOnTop.transform.position.z
);
}
anim.SetBool("Walking", true);
}
[PunRPC]
void OnDirectionChange_RIGHT()
{
characterSprite.flipX = true;
}
[PunRPC]
void OnDirectionChange_LEFT()
{
characterSprite.flipX = false;
}
private void smoothMovement()
{
transform.position = Vector3.Lerp(transform.position, smoothMove, Time.deltaTime * 10);
}
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.IsWriting)
{
stream.SendNext(transform.position);
stream.SendNext(rb.velocity);
stream.SendNext(anim.GetBool("Walking"));
stream.SendNext(anim.GetBool("Jumping"));
stream.SendNext(characterSprite.flipX);
}
else if (stream.IsReading)
{
smoothMove = (Vector3)stream.ReceiveNext();
rb.velocity = (Vector2)stream.ReceiveNext();
anim.SetBool("Walking", (bool)stream.ReceiveNext());
anim.SetBool("Jumping", (bool)stream.ReceiveNext());
characterSprite.flipX = (bool)stream.ReceiveNext();
}
}
}
This is for Time
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class Timer : MonoBehaviour
{
public float timer = 0.0f;
public bool isTimerRunning = true;
public TextMeshProUGUI timerText;
// Update is called once per frame
void Update()
{
if (isTimerRunning)
{
timer += Time.deltaTime;
int hours = Mathf.FloorToInt(timer / 3600F);
int minutes = Mathf.FloorToInt((timer - hours * 3600) / 60F);
int seconds = Mathf.FloorToInt(timer - hours * 3600 - minutes * 60);
timerText.text = string.Format("{0:0}:{1:00}:{2:00}", hours, minutes, seconds);
}
}
public void StopTimer()
{
isTimerRunning = false;
}
}