Unity OnMatchList inaccesible due to its protection level - unity3d

I have seen that there are more answers to similar questions, but none of these helped me. I hope you can.
I have a Unity2D shooter game and I try to make a menu for UNET. I watched a youtube tutorial from Brackeys to make the menu (https://youtu.be/V4oRs26vAw8?list=PLPV2KyIb3jR5PhGqsO7G4PsbEC_Al-kPZ&t=896) and when he runs the project it shows me the error: "error CS0122: 'UnityEngine.Networking.Match.ListMatchResponse' is inaccessible due to its protection level. I found out that this might happen when you access for example a private variable from another function, but I access a function from Unity and I can not modify its type (I believe). Any ideas? Thank you.
public void OnMatchList(bool success, string extendedInfo, ListMatchResponse matchList)
{
status.text = "";
if (matchList == null)
{
status.text = "Couldn't get room list.";
return;
}
ClearRoomList();
foreach(MatchDesc match in matchList.matches)
{
GameObject _roomListItemGO = Instantiate(roomListItemPrefab);
_roomListItemGO.transform.SetParent(roomListParent);
// Have a component sit on the gameobject
// that will take care of setting up the name / amount of users.
// as well as setting up a callback function that will join the game.
roomList.Add(_roomListItemGO);
}
}

'MatchDesc' has been renamed to 'MatchInfoSnapshot'.
Just replace it and it should work fine.

Related

Unity3D New Input System: Is it really so hard to stop UI clickthroughs (or figure out if cursor is over a UI object)?

Even the official documentation has borderline insane recommendations to solve what is probably one of the most common UI/3D interaction issues:
If I click while the cursor is over a UI button, both the button (via the graphics raycaster) and the 3D world (via the physics raycaster) will receive the event.
The official manual:
https://docs.unity3d.com/Packages/com.unity.inputsystem#1.2/manual/UISupport.html#handling-ambiguities-for-pointer-type-input essentially says "how about you design your game so you don't need 3D and UI at the same time?".
I cannot believe this is not a solved problem. But everything I've tried failed. EventSystem.current.currentSelectedGameObject is sticky, not hover. PointerData is protected and thus not accessible (and one guy offered a workaround via deriving your own class from Standalone Input Module to get around that, but that workaround apparently doesn't work anymore). The old IsPointerOverGameObject throws a warning if you query it in the callback and is always true if you query it in Update().
That's all just mental. Please someone tell me there's a simple, obvious solution to this common, trivial problem that I'm just missing. The graphics raycaster certainly stores somewhere if it's over a UI element, right? Please?
I've looked into this a fair bit and in the end, the easiest solution seems to be to do what the manual says and put it in the Update function.
bool pointerOverUI = false;
void Update()
{
pointerOverUI = EventSystem.current.IsPointerOverGameObject();
}
Your frustration is well founded: there are NO examples of making UI work with NewInput which I've found. I can share a more robust version of the Raycaster workaround, from Youtube:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.UI;
/* Danndx 2021 (youtube.com/danndx)
From video: youtu.be/7h1cnGggY2M
thanks - delete me! :) */
public class SCR_UiInteraction : MonoBehaviour
{
public GameObject ui_canvas;
GraphicRaycaster ui_raycaster;
PointerEventData click_data;
List<RaycastResult> click_results;
void Start()
{
ui_raycaster = ui_canvas.GetComponent<GraphicRaycaster>();
click_data = new PointerEventData(EventSystem.current);
click_results = new List<RaycastResult>();
}
void Update()
{
// use isPressed if you wish to ray cast every frame:
//if(Mouse.current.leftButton.isPressed)
// use wasReleasedThisFrame if you wish to ray cast just once per click:
if(Mouse.current.leftButton.wasReleasedThisFrame)
{
GetUiElementsClicked();
}
}
void GetUiElementsClicked()
{
/** Get all the UI elements clicked, using the current mouse position and raycasting. **/
click_data.position = Mouse.current.position.ReadValue();
click_results.Clear();
ui_raycaster.Raycast(click_data, click_results);
foreach(RaycastResult result in click_results)
{
GameObject ui_element = result.gameObject;
Debug.Log(ui_element.name);
}
}
}
So, just drop into my "Menusscript.cs"?
But as a pattern, this is terrible for separating UI concerns. I'm currently rewiring EVERY separately-concerned PointerEventData click I had already working, and my question is, Why? I can't even find how it's supposed to work: to your point there IS no official guide at all around clicking UI, and it does NOT just drop-on-top.
Anyway, I haven't found anything yet which makes new input work easily on UI, and definitely not found how I'm going to sensibly separate Menuclicks from Activityclicks while keeping game & ui assemblies separate.
Good luck to us all.
Unity documentation for this issue with regard to Unity.InputSystem can be found at https://docs.unity3d.com/Packages/com.unity.inputsystem#1.3/manual/UISupport.html#handling-ambiguities-for-pointer-type-input.
IsPointerOverGameObject() can always return true if the extent of your canvas covers the camera's entire field of view.
For clarity, here is the solution which I found worked best (accumulated from several other posts across the web).
Attach this script to your UI Canvas object:
public class CanvasHitDetector : MonoBehaviour {
private GraphicRaycaster _graphicRaycaster;
private void Start()
{
// This instance is needed to compare between UI interactions and
// game interactions with the mouse.
_graphicRaycaster = GetComponent<GraphicRaycaster>();
}
public bool IsPointerOverUI()
{
// Obtain the current mouse position.
var mousePosition = Mouse.current.position.ReadValue();
// Create a pointer event data structure with the current mouse position.
var pointerEventData = new PointerEventData(EventSystem.current);
pointerEventData.position = mousePosition;
// Use the GraphicRaycaster instance to determine how many UI items
// the pointer event hits. If this value is greater-than zero, skip
// further processing.
var results = new List<RaycastResult>();
_graphicRaycaster.Raycast(pointerEventData, results);
return results.Count > 0;
}
}
In class containing the method which is handling the mouse clicks, obtain the reference to the Canvas UI either using GameObject.Find() or a public exposed variable, and call IsPointerOverUI() to filter clicks when over UI.
Reply to #Milad Qasemi's answer
From the docs you have attached in your answer, I have tried the following to check if the user clicked on a UI element or not.
// gets called in the Update method
if(Input.GetMouseButton(0) {
int layerMask = 1 << 5;
// raycast in the UI layer
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero, Mathf.Infinity, layerMask);
// if the ray hit any UI element, return
// don't handle player movement
if (hit.collider) { return; }
Debug.Log("Touched not on UI");
playerController.HandlePlayerMovement(x);
}
The raycast doesn't seem to detect collisions on UI elements. Below is a picture of the Graphics Raycaster component of the Canvas:
Reply to #Lowelltech
Your solution worked for me except that instead of Mouse I used Touchscreen
// Obtain the current touch position.
var pointerPosition = Touchscreen.current.position.ReadValue();
An InputSytem is a way to receive new inputs provided by Unity. You can't use existing scripts there, and you'll run into problems like the original questioner. Answers with code like "if(Input.GetMouseButton(0)" are invalid because they use the old system.

UNITY An object reference is required to access non-static member `Outline.OutlineMode'

I'm trying to create an outline when you are near it, but i'm getting all the time the same error.
void Update () {
if (Input.GetKeyDown(KeyCode.E)){
var outline = gameObject.AddComponent<Outline>();
outline.OutlineMode = Outline.Mode.OutlineAll;
outline.OutlineColor = Color.yellow;
outline.OutlineWidth = 5f;
}
}
void OnTriggerStay(Collider other) {
if (Outline.OutlineMode == Outline.Mode.OutlineAll) {
Debug.Log("test");
}
}
If i press E it works, and if i change it to ontriggerstay works too, but im trying that it only applies one time, because im getting some errors if its on. I have to say that im using an asset, called quick outline
Srry for my very bad english and explanation and thank you
add the outline to your object in Awake() then set it to disabled.
then enable it in OnTriggerEnter() and disable it in OnTriggerExit()
this will keep you from making multiple copies, and it will only be active when you are in range of your trigger

Instance object does not work properly with animator in Unity 3d

I am making games using Unity and I have some problems and I will ask questions.
The animator of an object instantiated using a prefab does not work properly, and precisely a specific event is a problem. The object placed in the hierarchy is fine. However, certain events do not work for objects instantiated using a script.
this is code.
public Animator guestmove;
public void Jump_motion()
{
if (tag == "Boy")
{
guestmove.SetTrigger("Jump");
}
}
public void Angry_motion()
{
guestmove.SetTrigger("Angry");
}
Here, we implement the event by pressing a button.
I changed the code to work when the tags match, but the objects I placed in the hierarchy also do not work.
This is the code that creates the instance.
if (currentlyObject > 0){
boyObject = Instantiate(boy, tableObject.transform.position, tableObject.transform.rotation);
boyObject.transform.Translate(new Vector3(0, -3, -11));
girlObject = Instantiate(girl, tableObject.transform.position, tableObject.transform.rotation);
girlObject.transform.Translate(new Vector3(1.5f, -3, -11));
}
I kept searching for the relevant data, but I could not find any cases of similar problems. I do not know where the problem is, please help me.
this is link
(https://drive.google.com/file/d/1SKbSIfFQM4-n8l-ZBBvZb_3SuNx-kd5-/view?usp=sharing)
Use the transition to triggers from Any State, this should work.
And where are your functions called?

Unity3d Issue NGUI UITexture/Facebook www Profile Pic

Having small issue here with Unity and NGUI. NGUI has UITexture as its main texture such as Unity has GUITexture.
I sent a request to facebook to get the users profile image which sends back a perfect url which if I put in the browser works fine.
My issue is taking that Texture2D (Facebook API does it as a Texture2D) and putting it on my UITexture. For some reason it just does not take it correctly. I keep getting a null value for it. I am also using Mobile Social as well from the asset store any help, helps.
Here is my snippet of code.
private void UserDataLoaded(FB_Result result)
{
SPFacebook.OnUserDataRequestCompleteAction -= UserDataLoaded;
if (result.IsSucceeded)
{
Debug.Log("User Data Loaded!");
IsUserInfoLoaded = true;
string FBNametxt = SPFacebook.Instance.userInfo.Name;
UILabel Name = GameObject.Find("FBName").GetComponent<UILabel>();
Name.text = FBNametxt;
Texture2D FBLoadTex = SPFacebook.Instance.userInfo.GetProfileImage(FB_ProfileImageSize.normal);
FBGetProfile.GetComponent<UITexture>().mainTexture = FBLoadTex != null ? FBLoadTex : PlaceHolderImg;
}
else {
Debug.Log("User data load failed, something was wrong");
}
}
The placeholder image is just a already selected image used if the fbprofile pic does is null. Which I keep getting.....
It's possible you're looking for RawImage which exist for this purpose
http://docs.unity3d.com/Manual/script-RawImage.html
Since the Raw Image does not require a sprite texture, you can use it to display any texture available to the Unity player. For example, you might show an image downloaded from a URL using the WWW class or a texture from an object in a game.
Use Unity.UI and use that feature.
Add "Ngui Unity2d Sprite" component instead of UiTexture to your profile picture in editor and use below code in your Fb callback
private void ProfilePicCallBack (FBResult result)
{
if (result.Error != null) {
Debug.Log ("Problem with getting Profile Picture");
return;
}
ProfileImage.GetComponent<UI2DSprite> ().sprite2D = Sprite.Create(result.Texture, new Rect(0,0,128,128), new Vector2(0,0));
}
there might be an another way to do this. but this worked for me

Scripting GUI buttons to trigger an event of changing materials

Apologies if there's a similar question, however, I have probably seen it and it has not fixed my problem.
I am trying to write a JS script for unity in order to achieve an event to be triggered once clicked.
I have searched online on UnityAnswers website and others, the closest I can get is based on these questions
http://answers.unity3d.com/questions/368303/changing-shaders-of-a-gameobject-via-script-1.html
and this one
http://answers.unity3d.com/questions/319875/change-objects-material-using-gui-buttons-via-scri.html
and also looked at this one
http://docs.unity3d.com/ScriptReference/Material-shader.html
So, my code is this so far
var button2_tex : Texture;
var button3_tex : Texture;
var button4_tex : Texture;
var seat_mat1 : Material;
var seat_mat2 : Material;
var veneer1 : Texture;
var veneer2 : Texture;
var rend : Renderer;
var _mouseDown = false;
function Start() {
seat_mat1 = Resources.Load( "seat_mat1" );
seat_mat2 = Resources.Load( "seat_mat2" );
}
function Update(){
if(Input.GetMouseButtonDown(0)){
_mouseDown = true;
}
}
function OnGUI() {
GUI.Box (Rect (10,10,100,200), "Menu");
if (_mouseDown){
if (GUI.Button (Rect (20,40,40,20), button1_tex)){
if(seat_mat1){
rend.material = seat_mat2;
Debug.Log("This button was clicked!");
}
else{
rend.material = seat_mat1;
}
}
}
Please note some variables I haven't used yet, as am still testing bunch of other codes to get it working..
the code snippet I am trying to fix starts with "function OnGUI()" but I maybe wrong and could use some fresh insight.
this is a screenshot of the resulting script. The button on the left side is supposedly to change the colour of the material from seat_mat1 to seat_mat2 by the event of mouse clicking on the button.
I have attached the previous script to the 3D object in unity and had made a folder names "Resources" for the materials to be visible and referenced through the script.
My problem is that upon clicking the GUI button, nothing happens, and it maybe something very simple and I am just missing it .. apologies for being inexperienced in JS much or unity.
Thanks in advance.
EDIT:
So after playing a bit more with the code. I added a Debug.Log() after this line
GetComponent.<Renderer>().material = seat_mat2;
Debug.Log("This button was clicked!");
and seems to be this error that I am getting every time the button is pressed
"MissingComponentException: There is no 'Renderer' attached to the "scene_export3" game object, but a script is trying to access it.
You probably need to add a Renderer to the game object "scene_export3". Or your script needs to check if the component is attached before using it.
materialChanger.OnGUI () (at Assets/materialChanger.js:44)"
So with simple understanding, it seems that the renderer is not attached somehow?
Your code is working fine But still i think once you have loaded The materials in start function you do not need to load them every time. And one thing more is to make sure you have applied the script to the gameobject you want to change the material of. If you just want to change the color not want to change complete material use color property of material and your OnGUI function should look like this.
function OnGUI() {
GUI.Box (Rect (10,10,100,200), "Menu");
if (_mouseDown){
if (GUI.Button (Rect (20,40,40,20), button1_tex)){
if(GetComponent.<Renderer>().material == seat_mat1)
GetComponent.<Renderer>().material.color = seat_mat2.color;
else
GetComponent.<Renderer>().material.color = seat_mat1.color;
}
}
}
But if you do not use color poperty it will work fine just make sure you have applied script to game boject you want to change material i your case may be to your seat1.
Thanks Nain for your guidance, with your help I was able to come up with a partial solution, where I know I can fix from there.
The solution is as follows.
The code:
function OnGUI() {
GUI.Box (Rect (10,10,100,200), "Menu");
if (_mouseDown){
if (GUI.Button (Rect (20,40,40,20), button1_tex)){
var rendArray : Renderer[];
rendArray = GetComponentsInChildren.<Renderer>(true);
for(var rend : Renderer in rendArray){
if(rend.sharedMaterial == seat_mat1){
rend.sharedMaterial = seat_mat2;
Debug.Log("This button was clicked!");
}
else{
rend.sharedMaterial = seat_mat1;
}
}
}
}
}
After saving the script in MonoDevelop, open Unity where you create an empty game object and add all the objects with specific material e.g. seat_mat1 under it as children.
Then click on the empty object, rename it if you like, and add a "Mesh Renderer" component from "Add Component > Mesh > Mesh Renderer".
After that drag the script to the empty object and in the inspector you can find an option which you can choose a renderer called "rend". Choose the empty object as the Mesh Renderer.
Upon testing the outcome, I have managed to change materials of some objects together to seat_mat2, but unrelated materials changed themselves to seat_mat1 and once the button is clicked again, they alternate between seat_mat1 and seat_mat2
and even though it is not perfectly done, I am answering this question as anything else is fixable (I hope).
Thank you again Nain for your help :)