How can I access material of a mesh renderer without receiving and instance of it?
I am trying to use the following code to determine whether or not there exists squares on my grid, vertically or horizontally, with the same colour as the current block i rest on.
for (int i = 0; i < GridBlocks.Count; i++) { if (GridBlocks[i].transform.position.z == CurrentGridBlock.transform.position.z && GridBlocks[i].GetComponent<MeshRenderer>().material == CurrentGridBlock.GetComponent<MeshRenderer>().material && CurrentGridBlock != GridBlocks[i]) { HorizontalSameColouredBlocks.Add(GridBlocks[i]); } else if (GridBlocks[i].transform.position.x == CurrentGridBlock.transform.position.x && GridBlocks[i].GetComponent<MeshRenderer>().material == CurrentGridBlock.GetComponent<MeshRenderer>().material && CurrentGridBlock != GridBlocks[i]) { VerticalSameColouredBlocks.Add(GridBlocks[i]); } if (HorizontalSameColouredBlocks.Count == Mathf.Sqrt(GridBlocks.Count) - 2 && VerticalSameColouredBlocks.Count == Mathf.Sqrt(GridBlocks.Count) - 2) { break; } }
However, the following line never returns true in either vertical or horizontal.
GridBlocks[i].GetComponent<MeshRenderer>().material == CurrentGridBlock.GetComponent<MeshRenderer>().material
This is because they both return separate instances of that same material. How can get this to ignore the different instances? I have tried just checking if the names are equivalent, this does not work either.
EDIT: Using sharedMaterial
I used .sharedMaterial to see if the outputs were equivalent of want i was testing. This is the output:
As you can see, the original set Gray blocks are reading without any instance, the current block that the player is standing on, reads a single instance, and any other colour in a row/column will read a doubled instance.
I changed this following line:
GridBlocks[i].GetComponent<MeshRenderer>().material == CurrentGridBlock.GetComponent<MeshRenderer>().material
To this:
GridBlocks[i].GetComponent<MeshRenderer>().sharedMaterial == CurrentGridBlock.GetComponent<MeshRenderer>().sharedMaterial
Please help :/ Edit 2: Displaying my entire code that has to be related to this problem
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CubeMovement : MonoBehaviour { private List<GameObject> Pivots, GridBlocks, AvailableGridBlocks, HorizontalSameColouredBlocks, VerticalSameColouredBlocks, GridBlocksToReset; private GameObject Player, ChosenPivot, CurrentGridBlock; private Vector3 TouchPos, PlayerRotation; private MeshRenderer GridBlockMeshRenderer; private PlayerColourRandomizer ColourRandomizerScript; private float DistanceFromCurrentBlock; void Awake() { Pivots = new List<GameObject>(); GridBlocks = new List<GameObject>(); AvailableGridBlocks = new List<GameObject>(); HorizontalSameColouredBlocks = new List<GameObject>(); VerticalSameColouredBlocks = new List<GameObject>(); GridBlocksToReset = new List<GameObject>(); Pivots.AddRange(GameObject.FindGameObjectsWithTag("PivotPoint")); GridBlocks.AddRange(GameObject.FindGameObjectsWithTag("GridBlock")); Player = this.gameObject; ColourRandomizerScript = this.gameObject.GetComponent<PlayerColourRandomizer>(); } void Update() { if (Input.touchCount > 0) { Touch touch = Input.GetTouch(0); Ray ray = Camera.main.ScreenPointToRay(touch.position); Plane plane = new Plane(Vector3.up, transform.position); float distance = 0; if (touch.phase == TouchPhase.Moved) { if (plane.Raycast(ray, out distance)) { TouchPos = ray.GetPoint(distance); } } if (touch.phase == TouchPhase.Ended) { CheckSelectedGridBlock(); Roll(); } if (touch.phase == TouchPhase.Canceled) { ResetValues(); } } } public void SetInitialPlayerPosition() { int RandomStartingPosition = Random.Range(0, GridBlocks.Count); Player.transform.position = new Vector3(GridBlocks[RandomStartingPosition].transform.position.x, 0.5f, GridBlocks[RandomStartingPosition].transform.position.z); } public void SetInitialGridBlockColour() { for(int i = 0; i < GridBlocks.Count; i++) { if(GridBlocks[i].transform.position.x == Player.transform.position.x && GridBlocks[i].transform.position.z == Player.transform.position.z) { GridBlocks[i].GetComponent<MeshRenderer>().material = Player.GetComponent<MeshRenderer>().material; break; } } } public void SetBlackSquares() { int BlackSquaresInGame = Random.Range(2, 5); for (int i = 0; i < BlackSquaresInGame; i++) { int GridBlockPlacement = Random.Range(0, GridBlocks.Count); while (GridBlocks[GridBlockPlacement].transform.position.x == Player.transform.position.x && GridBlocks[GridBlockPlacement].transform.position.z == Player.transform.position.z || GridBlocks[GridBlockPlacement].transform.position.x == Player.transform.position.x - 1f && GridBlocks[GridBlockPlacement].transform.position.z == Player.transform.position.z || GridBlocks[GridBlockPlacement].transform.position.x == Player.transform.position.x + 1f && GridBlocks[GridBlockPlacement].transform.position.z == Player.transform.position.z || GridBlocks[GridBlockPlacement].transform.position.x == Player.transform.position.x && GridBlocks[GridBlockPlacement].transform.position.z == Player.transform.position.z - 1f || GridBlocks[GridBlockPlacement].transform.position.x == Player.transform.position.x && GridBlocks[GridBlockPlacement].transform.position.z == Player.transform.position.z + 1f) { GridBlockPlacement = Random.Range(0, GridBlocks.Count); } GridBlocks[GridBlockPlacement].GetComponent<MeshRenderer>().material = Resources.Load<Material>("Materials/BlackSquare"); } } public void SetupPivots() { for(int i = 0; i < Pivots.Count; i++) { if (Pivots[i].name.Contains("Up")) { Pivots[i].transform.position = new Vector3(Player.transform.position.x, Player.transform.position.y - 0.5f, Player.transform.position.z + 0.5f); } else if(Pivots[i].name.Contains("Down")) { Pivots[i].transform.position = new Vector3(Player.transform.position.x, Player.transform.position.y - 0.5f, Player.transform.position.z - 0.5f); } else if(Pivots[i].name.Contains("Left")) { Pivots[i].transform.position = new Vector3(Player.transform.position.x - 0.5f, Player.transform.position.y - 0.5f, Player.transform.position.z); } else if (Pivots[i].name.Contains("Right")) { Pivots[i].transform.position = new Vector3(Player.transform.position.x + 0.5f, Player.transform.position.y - 0.5f, Player.transform.position.z); } } } public void CheckAavailableMovements() { if (AvailableGridBlocks.Count > 0) { for(int i = 0; i < AvailableGridBlocks.Count; i++) { GridBlockMeshRenderer = AvailableGridBlocks[i].GetComponent<MeshRenderer>(); if (GridBlockMeshRenderer.material.name.Contains("GrayAvailable")) { GridBlockMeshRenderer.material = Resources.Load<Material>("Materials/GraySquare"); } else if (GridBlockMeshRenderer.material.name.Contains("BlackAvailable")) { GridBlockMeshRenderer.material = Resources.Load<Material>("Materials/BlackSquare"); } } AvailableGridBlocks.Clear(); } for (int i = 0; i < GridBlocks.Count; i++) { GridBlockMeshRenderer = GridBlocks[i].GetComponent<MeshRenderer>(); if (Player.transform.position.x == GridBlocks[i].transform.position.x - 1 && Player.transform.position.z == GridBlocks[i].transform.position.z || Player.transform.position.x == GridBlocks[i].transform.position.x + 1 && Player.transform.position.z == GridBlocks[i].transform.position.z || Player.transform.position.x == GridBlocks[i].transform.position.x && Player.transform.position.z == GridBlocks[i].transform.position.z - 1 || Player.transform.position.x == GridBlocks[i].transform.position.x && Player.transform.position.z == GridBlocks[i].transform.position.z + 1) { if (GridBlockMeshRenderer.material.name.Contains("Gray")) { AvailableGridBlocks.Add(GridBlocks[i]); GridBlockMeshRenderer.material = Resources.Load<Material>("Materials/GrayAvailableSquare"); } else if (GridBlockMeshRenderer.material.name.Contains("Black")) { AvailableGridBlocks.Add(GridBlocks[i]); GridBlockMeshRenderer.material = Resources.Load<Material>("Materials/BlackAvailableSquare"); } } if (AvailableGridBlocks.Count == 4) { break; } } } private void CheckSelectedGridBlock() { for (int i = 0; i < AvailableGridBlocks.Count; i++) { if (TouchPos.x > AvailableGridBlocks[i].transform.position.x - 0.5f && TouchPos.x < AvailableGridBlocks[i].transform.position.x + 0.5f && TouchPos.z > AvailableGridBlocks[i].transform.position.z - 0.5f && TouchPos.z < AvailableGridBlocks[i].transform.position.z + 0.5f) { CurrentGridBlock = AvailableGridBlocks[i]; for(int j = 0; j < Pivots.Count; j++) { if (CurrentGridBlock.transform.position.x < Player.transform.position.x && CurrentGridBlock.transform.position.z == Player.transform.position.z && Pivots[j].transform.position.x < Player.transform.position.x) { ChosenPivot = Pivots[j]; break; } else if (CurrentGridBlock.transform.position.x > Player.transform.position.x && CurrentGridBlock.transform.position.z == Player.transform.position.z && Pivots[j].transform.position.x > Player.transform.position.x) { ChosenPivot = Pivots[j]; break; } else if (CurrentGridBlock.transform.position.z < Player.transform.position.z && CurrentGridBlock.transform.position.x == Player.transform.position.x && Pivots[j].transform.position.z < Player.transform.position.z) { ChosenPivot = Pivots[j]; break; } else if (CurrentGridBlock.transform.position.z > Player.transform.position.z && CurrentGridBlock.transform.position.x == Player.transform.position.x && Pivots[j].transform.position.z > Player.transform.position.z) { ChosenPivot = Pivots[j]; break; } } break; } else if (i == AvailableGridBlocks.Count - 1) { CurrentGridBlock = null; } } } private void Roll() { StartCoroutine(Move()); } private void ChangeCurrentGridBlockColour() { if (!CurrentGridBlock.GetComponent<MeshRenderer>().material.name.Contains("Black")) { CurrentGridBlock.GetComponent<MeshRenderer>().material = Player.GetComponent<MeshRenderer>().material; } else if (CurrentGridBlock.GetComponent<MeshRenderer>().material.name.Contains("Black")) { } } private void ClearLinedBlocks() { if (CurrentGridBlock != null) { for (int i = 0; i < GridBlocks.Count; i++) { if (GridBlocks[i].transform.position.z == CurrentGridBlock.transform.position.z) { Debug.Log("VERTICAL -- GridBlock: " + GridBlocks[i].GetComponent<MeshRenderer>().sharedMaterial); Debug.Log("Current: " + CurrentGridBlock.GetComponent<MeshRenderer>().sharedMaterial); Debug.Log(GridBlocks[i].GetComponent<MeshRenderer>().sharedMaterial == CurrentGridBlock.GetComponent<MeshRenderer>().sharedMaterial); } if (GridBlocks[i].transform.position.x == CurrentGridBlock.transform.position.x) { Debug.Log("HORIZONTAL -- GridBlock: " + GridBlocks[i].GetComponent<MeshRenderer>().sharedMaterial); Debug.Log("Current: " + CurrentGridBlock.GetComponent<MeshRenderer>().sharedMaterial); Debug.Log(GridBlocks[i].GetComponent<MeshRenderer>().sharedMaterial == CurrentGridBlock.GetComponent<MeshRenderer>().sharedMaterial); } if (GridBlocks[i].transform.position.z == CurrentGridBlock.transform.position.z && GridBlocks[i].GetComponent<MeshRenderer>().sharedMaterial == CurrentGridBlock.GetComponent<MeshRenderer>().sharedMaterial && CurrentGridBlock != GridBlocks[i]) { HorizontalSameColouredBlocks.Add(GridBlocks[i]); } else if (GridBlocks[i].transform.position.x == CurrentGridBlock.transform.position.x && GridBlocks[i].GetComponent<MeshRenderer>().sharedMaterial == CurrentGridBlock.GetComponent<MeshRenderer>().sharedMaterial && CurrentGridBlock != GridBlocks[i]) { VerticalSameColouredBlocks.Add(GridBlocks[i]); } if (HorizontalSameColouredBlocks.Count == Mathf.Sqrt(GridBlocks.Count) - 2 && VerticalSameColouredBlocks.Count == Mathf.Sqrt(GridBlocks.Count) - 2) { break; } } if (HorizontalSameColouredBlocks.Count >= 2) { DistanceFromCurrentBlock = 1; GridBlocksToReset.Add(CurrentGridBlock); for (int i = 0; i < HorizontalSameColouredBlocks.Count; i++) { if (CurrentGridBlock.transform.position.x - HorizontalSameColouredBlocks[i].transform.position.x == DistanceFromCurrentBlock) { GridBlocksToReset.Add(HorizontalSameColouredBlocks[i]); HorizontalSameColouredBlocks.RemoveAt(i); DistanceFromCurrentBlock++; i = 0; } else if (i == HorizontalSameColouredBlocks.Count - 1 && DistanceFromCurrentBlock > 0) { DistanceFromCurrentBlock = -1; for (int j = 0; j < HorizontalSameColouredBlocks.Count; j++) { if (CurrentGridBlock.transform.position.x - HorizontalSameColouredBlocks[i].transform.position.x == DistanceFromCurrentBlock) { GridBlocksToReset.Add(HorizontalSameColouredBlocks[i]); DistanceFromCurrentBlock--; j = 0; } } } } if (GridBlocksToReset.Count >= 3) { foreach (GameObject x in GridBlocksToReset) { x.GetComponent<MeshRenderer>().material = Resources.Load<Material>("Materials/GraySquare"); } } GridBlocksToReset.Clear(); } if (VerticalSameColouredBlocks.Count >= 2) { DistanceFromCurrentBlock = 1; GridBlocksToReset.Add(CurrentGridBlock); for (int i = 0; i < VerticalSameColouredBlocks.Count; i++) { if (CurrentGridBlock.transform.position.x - VerticalSameColouredBlocks[i].transform.position.x == DistanceFromCurrentBlock) { GridBlocksToReset.Add(VerticalSameColouredBlocks[i]); VerticalSameColouredBlocks.RemoveAt(i); DistanceFromCurrentBlock++; i = 0; } else if (i == VerticalSameColouredBlocks.Count - 1 && DistanceFromCurrentBlock > 0) { DistanceFromCurrentBlock = -1; for (int j = 0; j < VerticalSameColouredBlocks.Count; j++) { if (CurrentGridBlock.transform.position.x - VerticalSameColouredBlocks[i].transform.position.x == DistanceFromCurrentBlock) { GridBlocksToReset.Add(VerticalSameColouredBlocks[i]); DistanceFromCurrentBlock--; j = 0; } } } } if (GridBlocksToReset.Count >= 3) { foreach (GameObject x in GridBlocksToReset) { x.GetComponent<MeshRenderer>().material = Resources.Load<Material>("Materials/GraySquare"); } } GridBlocksToReset.Clear(); } VerticalSameColouredBlocks.Clear(); HorizontalSameColouredBlocks.Clear(); } } private void FixFloatingPointPrecision() { Player.transform.position = new Vector3(Mathf.Round(Player.transform.position.x), 0.5f, Mathf.Round(Player.transform.position.z)); PlayerRotation = transform.eulerAngles; PlayerRotation.x = Mathf.Round(PlayerRotation.x / 90) * 90; PlayerRotation.y = Mathf.Round(PlayerRotation.y / 90) * 90; PlayerRotation.z = Mathf.Round(PlayerRotation.z / 90) * 90; transform.eulerAngles = PlayerRotation; } private void ResetValues() { TouchPos = Vector3.zero; ChosenPivot = null; CurrentGridBlock = null; GridBlockMeshRenderer = null; } IEnumerator Move() { if (CurrentGridBlock != null) { if (ChosenPivot.name.Contains("Up")) { for (int i = 0; i < 10; i++) { Player.transform.RotateAround(ChosenPivot.transform.position, Vector3.right, 9f); yield return new WaitForSeconds(0.01f); } FixFloatingPointPrecision(); ChangeCurrentGridBlockColour(); } else if (ChosenPivot.name.Contains("Down")) { for (int i = 0; i < 10; i++) { Player.transform.RotateAround(ChosenPivot.transform.position, Vector3.left, 9f); yield return new WaitForSeconds(0.01f); } FixFloatingPointPrecision(); ChangeCurrentGridBlockColour(); } else if (ChosenPivot.name.Contains("Right")) { for (int i = 0; i < 10; i++) { Player.transform.RotateAround(ChosenPivot.transform.position, Vector3.back, 9f); yield return new WaitForSeconds(0.01f); } FixFloatingPointPrecision(); ChangeCurrentGridBlockColour(); } else if (ChosenPivot.name.Contains("Left")) { for (int i = 0; i < 10; i++) { Player.transform.RotateAround(ChosenPivot.transform.position, Vector3.forward, 9f); yield return new WaitForSeconds(0.01f); } FixFloatingPointPrecision(); ChangeCurrentGridBlockColour(); } ClearLinedBlocks(); SetupPivots(); CheckAavailableMovements(); ColourRandomizerScript.RandomizeNextColour(); } ResetValues(); } }
The part that this problem occurs is under the function ClearLinedBlocks(), perhaps the problem is caused elsewhere, I don't know any help would be appreciated, even if I can be suggested a new way to get the right output!
Answer by The_Three_Vs · Mar 31, 2020 at 04:29 PM
Use .sharedMaterial instead of .material. This will return the original material instead of the instance.
Hope this helps!
This still doesn't work, check my edit to see what the output is when i log each object's shared$$anonymous$$aterial, thanks for the reply though!
What Debug.Log statements are you using? The code I used to test this was:
public GameObject referenceObject;
private void Start()
{
Debug.Log(GetComponent<$$anonymous$$eshRenderer>().shared$$anonymous$$aterial);
Debug.Log(referenceObject.GetComponent<$$anonymous$$eshRenderer>().shared$$anonymous$$aterial);
Debug.Log(GetComponent<$$anonymous$$eshRenderer>().shared$$anonymous$$aterial == referenceObject.GetComponent<$$anonymous$$eshRenderer>().shared$$anonymous$$aterial);
}
And my console outputs were:
Grass$$anonymous$$at (UnityEngine.$$anonymous$$aterial)
Grass$$anonymous$$at (UnityEngine.$$anonymous$$aterial)
True
and
Grass$$anonymous$$at (UnityEngine.$$anonymous$$aterial)
Default-$$anonymous$$aterial (UnityEngine.$$anonymous$$aterial)
False
@The_Three_Vs Hey again, I tried to test this out more, no luck I tried using Debug.Log the same way you did you find my outputs.
If you look in the image, you can see 2 blue squares, along with the blue player who is on top of a blue square, making three in row, when this happened i scrolled through the output to see the vertical output, and this returned again that my current block is a single instance of the BlueSquare, and the blue squares above the player returned a doubled instance of the material, thus returning a false output as well in the image for the condition if they were equivalent. Ill post the entirety of my code in another edit. Thanks for your help until now of course!
Alright, so I discovered that when you assign a .material to another .material, it turns both objects' .shared$$anonymous$$aterial into instances. I have no explanation for this. Regardless, I believe you can fix the issue by changing ....GetComponent<$$anonymous$$eshRenderer>().material = ....GetComponent<$$anonymous$$eshRenderer>().material
to ....GetComponent<$$anonymous$$eshRenderer>().material = ....GetComponent<$$anonymous$$eshRenderer>().shared$$anonymous$$aterial
or ....GetComponent<$$anonymous$$eshRenderer>().shared$$anonymous$$aterial = ....GetComponent<$$anonymous$$eshRenderer>().shared$$anonymous$$aterial
It worked for me.