Search code examples
c#unity-game-engineobjectmeshgame-development

I have a problem with objects copy and the objects mesh in unity


So, i have a script, and two objects, one copy of the another, exactly what one does, the other does too, but in other position. The script do the following:

get the actual value of the heat variable of the object and use this for the second part;

the second part is get the heat value and check if it's higher or equal than 850, if it is, check if the player pressed the button to transform the object mesh in another mesh

but, when the button is pressed, only the first object has it mesh changed, i already tried raycast, a lot of additional code, ineficient code and don't worked. I know i can just make two similar scripts, but i have plans to create more objects when the player wants, so, it's not going to work...

the script:

using UnityEngine;
using DG.Tweening;

public class Iron : MonoBehaviour
{

private float Heat;
private bool Heating;

[Header("Game Objects")]
[SerializeField] private GameObject WeaponCanvas;

[Header("Materials")]
[SerializeField] private Material HotIron;
[SerializeField] private Material MediumIron;
[SerializeField] private Material CoolIron;
[Space]
[Header("Meshs")]
[SerializeField] private Mesh SimpleSwordMaterial;
[Space]
[Header("Text Mesh Pro")]
[SerializeField] private TMPro.TMP_Text TemperatureText;

private bool Hot;

void Update()
{

    if (Heating && Heat <= 1500)
    {
        Heat += 1.5f;
    }

    if (Heat >= 850)
    {
        GetComponent<Renderer>().material = HotIron;
        Hot = true;
    }

    if (Heat >= 600 && Heat <= 849)
    {
        GetComponent<Renderer>().material = MediumIron;
        Hot = false;
    }

    if (Heat <= 400)
    {
        GetComponent<Renderer>().material = CoolIron;
        Hot = false;
    }
}
void OnCollisionStay(Collision other)
{
    if (other.gameObject.tag == "HeatSource")
    {
        Heating = true;
    }

    if (!(other.gameObject.tag == "HeatSource"))
    {
        Heating = false;
    }
}

public void SimpleSword()
{
    
    var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    RaycastHit hit;

    if (Physics.Raycast(ray, out hit, 3.5f))
    {

        hit.transform.gameObject.GetComponent<MeshFilter>().mesh = SimpleSwordMaterial; // i have problems from here (i guess ;-;)
        hit.transform.gameObject.GetComponent<MeshCollider>().sharedMesh = SimpleSwordMaterial;
        if (hit.transform.gameObject.GetComponent<BoxCollider>() != null)
        {
            Destroy(hit.transform.gameObject.GetComponent<BoxCollider>());
        }
        if (hit.transform.gameObject.GetComponent<SphereCollider>() != null)
        {
            Destroy(hit.transform.gameObject.GetComponent<SphereCollider>());
        }
        if (hit.transform.gameObject.GetComponent<CapsuleCollider>() != null)
        {
            Destroy(hit.transform.gameObject.GetComponent<CapsuleCollider>());
        }
        transform.localScale = new Vector3(1, 1, 1);
    }
    WeaponCanvas.SetActive(false);
    Player.onMenu = false;
    Cursor.lockState = CursorLockMode.Locked;
}

void OnMouseOver()
{
    if (Input.GetMouseButtonDown(1) && Hot)
    {
        WeaponCanvas.SetActive(true);
        Player.onMenu = true;
        Cursor.lockState = CursorLockMode.None;
    }

    TemperatureText.text = ((int)Heat).ToString() + "°";
    TemperatureText.DOFade(1, 0.4f);
}

void OnMouseExit()
{
    TemperatureText.DOFade(0, 0.4f);
}
}

Solution

  • Similar to sharedMaterial

    sharedMesh is not what you want to use...

    It is recommended to use this function only for reading mesh data and not for writing, since you might modify imported assets and all objects that use this mesh will be affected.

    Also, be aware that is not possible to undo the changes done to this mesh.

    I'm having a bit of trouble understanding the problem... are all objects with the Iron.cs getting a new mesh? if yes, it's the .sharedmesh =.

    Furthermore, it's worth noting that each monobehaviour in Unity has a .GetInstanceId() method. You can compare the id of the instance you hit with your raycast and that of the one with the correct temporature.

    You should also consider simply instantiating a prefab of a sword instead.