- Home /
RTS like Frame on Minimap for user Camera Position with GL not rendering in Multiplayer (MLAPI)
Hello everybody,
I have been looking for anybody to encounter this problem for a while now and i am kinda stuck myself, probably because i am new to Unity and also Rendering with GL.
The Problem:
I am using MLAPI for Networking and have a Player Prefab which is getting spawned by my Networkmanager that has 2 Cameras. One MainCamera to view the Game and another one to view the Field from top down as a basic Minimap. It is probably not good practise to spawn in a lot of Cameras with each player that joins the game but I disable any Camera which is not on a local player and it worked fine for me so far.
Now I want to display a Frame which represents the borders of the MainCameras view on the Minimap using GL Vertices. The script on the Minimap camera (every Player Prefab has one) is the following:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAPI;
public class MiniMapScreenMarker : NetworkBehaviour
{
public Material material;
public Camera playerCamera;
public Camera minimapCamera;
public List<Collider> floorColliders;
public Vector3 topLeftPosition, topRightPosition, bottomLeftPosition, bottomRightPosition;
public void Start() {
foreach(GameObject gameObject in GameObject.FindGameObjectsWithTag("Floor"))
{
floorColliders.Add(gameObject.GetComponent<Collider>());
}
}
public void Update() {
if(IsLocalPlayer){
Ray topLeftCorner = this.playerCamera.ScreenPointToRay(new Vector3(0f, 0f));
Ray topRightCorner = this.playerCamera.ScreenPointToRay(new Vector3(Screen.width, 0f));
Ray bottomLeftCorner = this.playerCamera.ScreenPointToRay(new Vector3(0, Screen.height));
Ray bottomRightCorner = this.playerCamera.ScreenPointToRay(new Vector3(Screen.width, Screen.height));
RaycastHit[] hits = new RaycastHit[4];
foreach(Collider col in floorColliders)
{
if (col.Raycast(topLeftCorner, out hits[0], 200f)) {
this.topLeftPosition = hits[0].point;
}
if (col.Raycast(topRightCorner, out hits[1], 200f)) {
this.topRightPosition = hits[1].point;
}
if (col.Raycast(bottomLeftCorner, out hits[2], 200f)) {
this.bottomLeftPosition = hits[2].point;
}
if (col.Raycast(bottomRightCorner, out hits[3], 200f)) {
this.bottomRightPosition = hits[3].point;
}
}
this.topLeftPosition = this.minimapCamera.WorldToViewportPoint(this.topLeftPosition);
this.topRightPosition = this.minimapCamera.WorldToViewportPoint(this.topRightPosition);
this.bottomLeftPosition = this.minimapCamera.WorldToViewportPoint(this.bottomLeftPosition);
this.bottomRightPosition = this.minimapCamera.WorldToViewportPoint(this.bottomRightPosition);
this.topLeftPosition.z = -1f;
this.topRightPosition.z = -1f;
this.bottomLeftPosition.z = -1f;
this.bottomRightPosition.z = -1f;
}
}
public void OnPostRender() {
if(IsLocalPlayer){
Debug.Log("Gl Render");
GL.PushMatrix();
material.SetPass(0);
{
GL.LoadOrtho();
GL.Begin(GL.LINES);
{
GL.Color(Color.blue);
GL.Vertex(this.topLeftPosition);
GL.Vertex(this.topRightPosition);
GL.Vertex(this.topRightPosition);
GL.Vertex(this.bottomRightPosition);
GL.Vertex(this.bottomRightPosition);
GL.Vertex(this.bottomLeftPosition);
GL.Vertex(this.bottomLeftPosition);
GL.Vertex(this.topLeftPosition);
}
GL.End();
}
GL.PopMatrix();
}
}
}
When i test this being the only client (and host at the same time) it works wonderfully.
Now, if i spawn in a player myself, it still works fine. Whenever a client joins and is spawned in by the Networkmanager though, it is the only one rendering the frame on the Minimap. So basically the last one who joined can enjoy this feature, the rest has nothing. And as soon as the last joined client leaves, the second but last renders it again.
Now, if you are not familiar with OnPostRender(), the Docu says that the script has to be attached to the camera you want to render something on, which it is. Trying to debug this, i also tryed to make use of OnPostRenderCallback(Camera cam), which i basically copied from the Docu (OnPostRenderCallback Documentation). This registers any camera instead of only the one which the script is attached to. Interestingly, if I do not check for the camera of the Minimap here, I get of course these frames on the Minimap and the Player Camera. For any number of Clients. When i check for the Minimap camera by if(cam == minimapCamera)
, it goes back to only rendering for the latest joined client.
I have cheked for the positions of the Gl.Vertices to not be 0 or all the same, but they are accurate and change their position as the player camera does. I do not know what to do anymore, it seems to me that it has to do with everybody seeing only the latest clients minimap camera view while rendering frames on their own or something like that but im kinda clueless about how I could deal with this, regarding that it reders prefectly, when i render those frames on both cameras for each client.
All help appreciated, have a nice day.
PS: sry for bad Uppercases, german habit.
Your answer
Follow this Question
Related Questions
RTS networking basics 0 Answers
Drag to make box in RTS? 3 Answers
can someone help me with my hud? 1 Answer