Changing a material on a character

The whole answer can be found below.

Please note: The Photon forum is closed permanently. After many dedicated years of service we have made the decision to retire our forum and switch to read-only: we've saved the best to last! And we offer you support through these channels:

Try Our
Documentation

Please check if you can find an answer in our extensive documentation on PUN.

Join Us
on Discord

Meet and talk to our staff and the entire Photon-Community via Discord.

Read More on
Stack Overflow

Find more information on Stack Overflow (for Circle members only).

Write Us
an E-Mail

Feel free to send your question directly to our developers.

Changing a material on a character

ChrisParker
2014-10-11 23:11:09

Sorry if the answer is simple, I am very new to networking.

So far I have my game working well, I am using OnPhotonSerializeView to update the position, rotation and animations of my character. I am using an RPC to make a sword strike animation play. This all works OK across the network. But I am trying to make my character customisable and have started by trying to change the hair colour. I have 5 different hair materials and using a keypress I swap which material is applied to the hair. This works fine on the local player, but over the network it only changes the controllable characters hair, not the network character.

I have tried lots of different ways to do this, but still have had no success. If someone can suggest how I would go about this, I would really appreciate it.

Comments

march87ls
2014-10-12 21:51:23

I'm going to be writing a script that does this for my prototype game.

My plan is to use an RPC call that will basically change the material on the local player and would be seen by others in the game.

photonView.RPC will do it I think.

ChrisParker
2014-10-12 23:33:44

I'd be interested to see how you go, because that is what I am doing and it doesn't change on the networked player, only the local one.

march87ls
2014-10-13 15:46:25

ChrisParker,

re:"This works fine on the local player, but over the network it only changes the controllable characters hair, not the network character. " Just to clarify, your local player is the networked character, correct? And as your local player, you want to change its hair color, yes?

march87ls
2014-10-13 19:43:15

ChrisParker, I just tried a very simple material replace and I got it working. I'm not sure if it's what you're looking for, but it's what I wanted to do for my own little prototype.

Will post in a bit. I'm having major issues with the most recent version of PUN - full of errors. :(

march87ls
2014-10-13 20:00:26

See if this is what you're looking to do: http://www.youtube.com/watch?v=ZMdvECfkfKM

ChrisParker
2014-10-13 20:21:51

Thanks for your help on this. I have been playing with this for ages and still no luck.

Yes, that video is showing exactly what I am trying to do. Sorry, I am a bit confused by the terminology, etc, but I have 2 game instances running. One game is Bob's, the other game is Bill's, Bill joins Bob's game. I then change the colour of Bill's hair. On Bill's screen his hair colour changes. (that is what I was referring to as the local character). Now on Bob's screen, Bob's hair changes colour, Bill's doesn't. And when Bob changes his hair, his changes correctly on his screen, but on Biill's screen Bob's stays the same and Bill's changes. So it is getting mixed up somehow.

I thought it would be the scripts with the error, but I use the same code to run an animation for swinging a sword and the correct character will swing the sword, it's only changing materials that I get a problem.

Some code snippets to show the bits that are relevant.

	void Update () {
		// only gets input from owner
		if(isControllable)
			GetInput();
	}

	void GetInput() {
		if (Input.GetKeyUp(KeyCode.Alpha1)) {
			ChangeHair(1);
		} else if (Input.GetKeyUp(KeyCode.Alpha2)) {
			ChangeHair(2);
		} else if (Input.GetKeyUp(KeyCode.Alpha3)) {
			ChangeHair(3);
		} else if (Input.GetKeyUp(KeyCode.Alpha4)) {
			ChangeHair(4);
		} else if (Input.GetKeyUp(KeyCode.Alpha5)) {
			ChangeHair(5);
		}
	 }

	void ChangeHair(int number) {
		if(number == 1) {
			hair.renderer.material = blackHair;
		} else if(number == 2) {
			hair.renderer.material = brownHair;
		} else if(number == 3) {
			hair.renderer.material = redHair;
		} else if(number == 4) {
			hair.renderer.material = whiteHair;
		} else if(number == 5) {
			hair.renderer.material = yellowHair;
		}
		if(PhotonNetwork.player.ID > 0) {
			photonView.RPC("ChangeHairColour", PhotonTargets.All, number);
		 }
 	}

	[RPC]
	public void ChangeHairColour(int hairNum) {
			if(hairNum == 1) {
				hair.renderer.material = blackHair;
			} else if(hairNum == 2) {
				hair.renderer.material = brownHair;
			} else if(hairNum == 3) {
				hair.renderer.material = redHair;
			} else if(hairNum == 4) {
				hair.renderer.material = whiteHair;
			} else if(hairNum == 5) {
				hair.renderer.material = yellowHair;
			}
	}

I have the materials defined as public variables and have them defined in the prefab to point to the relevant materials. The hair variable is using a tag to get the Hair object from the character model.

Thanks again for your help.

march87ls
2014-10-13 21:42:39

First thing I see is that your local (or player that wants to change their hair) isn't being given ownership of that right to do so. Add a photonView.isMine to allow only that player (the one changing its hair) to change their hair. Once the local player changes their hair, well they want to brag and tell all the other players about how wonderful it looks (lol). That's where it makes the announcement with the photonView.RPC call. Sorta like saying, "Hey check out my new hairstyle!!" This gets everyone's attention via the RPC being triggered.

Here's the code I wrote for that sample:

using UnityEngine;
using System.Collections;

public class ChangeTexture : Photon.MonoBehaviour
{
	
	public Texture blackHair;
	public Texture redHair;
	
	
	void Update ()
	{

		if (photonView.isMine) {
			if (Input.GetKeyDown (KeyCode.E)) {
				photonView.RPC ("ChangeHairColour", PhotonTargets.All, 1);
			}
		
			if (Input.GetKeyDown (KeyCode.P)) {
				photonView.RPC ("ChangeHairColour", PhotonTargets.All, 2);
			}
		}//if (photonView.isMine)
		
	}
	
	
	[RPC]
	void ChangeHairColour(int hairNum){
		
		if(hairNum == 1) {
			gameObject.renderer.material.mainTexture = blackHair;
		} else if(hairNum == 2) {
			gameObject.renderer.material.mainTexture = redHair;
			
		}
		
		
	}
	
}//ChangeTexture

Attach it to the object and add the defined Texture in the inspector.

ChrisParker
2014-10-14 05:28:24

Thanks, I should have tried something like that ages ago. My script was in my main characters script, accessing the hair object from there. That doesn't work. By adding a PhotonView and the script to the hair object itself it now works. Thanks for the help.

Edam05
2021-04-23 23:40:13

please how make like this script for photon 2

dcmrobin
2023-03-28 18:31:25

 I think you might use RpcTarget.All instead of PhotonTargets.All    
Back to top