Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Changing Instantiated object materials in every new scene

Discussion in 'Editor & General Support' started by juriggs, Jun 7, 2020.

  1. juriggs

    juriggs

    Joined:
    Apr 22, 2020
    Posts:
    4
    I'm looking to see if anyone has a better idea of how to accomplish this, as what I've come up with seems a bit burdensome...

    I have a game where the scene remains the same... same arena, same goal, same ball, etc. In each scene, however, I want the materials on those objects to change. I'm using Photon, so I'm instantiating the objects in my Game Manager like so:


    ball = PhotonNetwork.Instantiate("Ball", ballSpawnTransform.transform.position, ballSpawnTransform.transform.rotation, 0);


    My idea on how to handle this is to create a script called "MaterialHandler", or something of the sort. Then, based on the name of the loaded scene, I'll instantiate the object and assign the materials I need. Does that sound reasonable, or is there a better way of accomplishing this?

    Thanks...
     
  2. path14

    path14

    Joined:
    Apr 9, 2017
    Posts:
    113
    I think the only other way is creating multiple prefabs with those materials already applied. I think changing the materials how you're suggesting at game load (with an rpc call) shouldn't be a problem.

    Why is it 'burdensome'?
     
  3. juriggs

    juriggs

    Joined:
    Apr 22, 2020
    Posts:
    4
    It's burdensome because I'm lazy, mostly. There will likely be upwards of 50 scenes in this game (think of it like mini-golf, where you get a certain score and then move on to the next "hole"). I have 3 separate objects, which means 150 objects to skin. I can write a function to do the actual skinning where I pass in the name of the object and the material, so that's not a big deal, but I'll have to hard code the lines that identify what scene we're at so I can choose the right material.
    I'm interested in how to do the RPC call. I have it working right now so that on my Respawn function, the ball in the window of the person who just played updates and has the proper material, but the person who is currently taking their turn has the material of the prefab.
    I tried putting [PunRPC] above the Respawn function, and then calling it from my BallController like this:

    // the PhotonView of the ball that needs to be Respawned
    ballPhotonView.RPC("Respawn", Photon.Pun.RpcTarget.All);

    but that didn't work. The relevant Respawn code looks like this:
    Code (csharp):
    1. PhotonNetwork.Destroy(ball);
    2.                // create new ball
    3.                 ball = GameManager.Instance.InstantiateBall();
    4.                 //get new ball instance
    5.                 GetBall();
    6.                 ballPhotonView = ball.GetComponent<PhotonView>();
    7.                 ball.GetComponent<Rigidbody> ().useGravity = false;
    8.                 ballPhotonView.TransferOwnership(1);
    9.                 ballPhotonView.RPC("UpdatePlayerTurnText", Photon.Pun.RpcTarget.All, "Player One's Turn");
    10.                 ballPhotonView.RPC("SetSpinners", Photon.Pun.RpcTarget.All);
    InstantiateBall looks like this:
    Code (csharp):
    1.  
    2. if(sceneName == "MummyMadness"){
    3.                 ball = PhotonNetwork.Instantiate("Ball", ballSpawnTransform.transform.position, ballSpawnTransform.transform.rotation, 0);
    4.                 body = GameObject.Find("body");
    5.                 leftPlate = GameObject.Find("left_plate");
    6.                 rightPlate = GameObject.Find("right_plate");
    7.                 rearPlate = GameObject.Find("rear_plate");
    8.                 ballMaterial = Resources.Load("Materials/Mummy_mat", typeof(Material)) as Material;
    9.                 body.GetComponent<Renderer>().material = ballMaterial;
    10.                 leftPlate.GetComponent<Renderer>().material = ballMaterial;
    11.                 rightPlate.GetComponent<Renderer>().material = ballMaterial;
    12.                 rearPlate.GetComponent<Renderer>().material = ballMaterial;
    13.                 ballPhotonView = ball.GetComponent<PhotonView>();
    14.                 ballPhotonView.TransferOwnership(PhotonNetwork.LocalPlayer.ActorNumber);
    15.                 return ball;
    16.  
    Any idea why that wouldn't update both player's screens?
    Thanks for your help... it's much appreciated.
     
    Last edited: Jun 7, 2020