Hello everyone
i Have created multiplayer game and used ready Player me for the character change . But while changing the character the texture change is not working for other players . Please help me in this problem . Fell free to contact me with a reply for any additional information you need
https://playcanvas.com/project/982877/overview/finalmeta2
Hey @Tr_andreson ,
I see you got the models/textures working. I was actually taking a look at your previous forum post just now. What scripts and functions would be responsible for loading other people’s models? Do you get any errors in the Chrome Web Dev Console when someone else attempts to set their own model?
Thank You for replying back . This is the script i am using for the character change . Please Check
var CustomAvatarLoader = pc.createScript('customAvatarLoader');
CustomAvatarLoader.attributes.add('css', { type: 'asset', assetType: 'css', title: 'CSS Asset' });
CustomAvatarLoader.attributes.add('html', { type: 'asset', assetType: 'html', title: 'HTML Asset' });
CustomAvatarLoader.attributes.add("LoadAvatarBtn", { type: "entity" });
CustomAvatarLoader.attributes.add("LoadingScreen", { type: "entity" });
CustomAvatarLoader.instance = null;
window.addEventListener("message", function (event) {
if (event.origin === "https://rarerooms.readyplayer.me") {
CustomAvatarLoader.instance.LoadNewAvatar(event.data);
}
}, false);
// initialize code called once per entity
CustomAvatarLoader.prototype.initialize = function () {
CustomAvatarLoader.instance = this;
this.GlbURL = null;
this.iframeWidth = window.innerWidth;
this.iframeHeight = window.innerHeight;
this.app.on("BtnManager:LoadAvatarButtonClick", this.customAvatarSelection.bind(this));
this.on('destroy', function () {
this.app.off("BtnManager:LoadAvatarButtonClick", this.customAvatarSelection.bind(this));
}.bind(this));
this.setupIframe();
this.isMobile = false;
if (pc.platform.mobile || pc.platform.android || pc.platform.ios) { // Mobile
let avatarIframe = document.getElementById("avatarIframe");
avatarIframe.style.width = this.iframeWidth + "px";
avatarIframe.style.height = this.iframeHeight + "px";
avatarIframe.style.border = "none";
this.isMobile = true;
} else { // Desktop
let avatarIframe = document.getElementById("avatarIframe");
avatarIframe.style.width = "900px";
avatarIframe.style.height = "650px";
avatarIframe.style.border = "none";
this.isMobile = false;
}
};
CustomAvatarLoader.prototype.LoadNewAvatar = function (data) {
let iframe = document.getElementById('avatarIframe');
let avatarDiv = document.getElementById('avatarDiv');
iframe.style.display = "none";
avatarDiv.style.display = "none";
this.loadGLBModelFromURL(data);
};
// CustomAvatarLoader.prototype.loadGLBModelFromURL = function (modelURL) {
// var self = this;
// this.GlbURL = modelURL;
// this.app.fire("LoadingMenu:SetLoading", true, "Loading Avatar..");
// let name = "model_" + (Math.floor(Math.random() * 10000));
// let cacheURL = modelURL + "?cacheBuster=" + (Math.floor(Math.random() * 10000));
// this.LoadingScreen.enabled = true;
// utils.loadGlbContainerFromUrl(cacheURL, null, name, function (err, asset) {
// if (asset.resources[0].model)
// this.app.root.findByName("ModelTPC").model.asset = asset.resources[0].model.id;
// else {
// console.log(asset.resources);
// }
// this.LoadAvatarBtn.enabled = true;
// this.LoadingScreen.enabled = false;
// }.bind(this));
// };
CustomAvatarLoader.prototype.setupIframe = function () {
// create STYLE element
var style = document.createElement('style');
// append to head
document.head.appendChild(style);
style.innerHTML = this.css.resource || '';
// Add the HTML
this.div = document.createElement('div');
this.div.id = "avatarDiv";
this.div.classList.add('avatarContrainer');
this.div.innerHTML = this.html.resource || '';
this.div.style.display = "none";
// append to body
// can be appended somewhere else
// it is recommended to have some container element
// to prevent iOS problems of overfloating elements off the screen
var canvas = document.getElementById("application-canvas");
// canvas.style.pointerEvents = "none";
//document.body.insertBefore(this.div,canvas);
document.body.appendChild(this.div);
};
CustomAvatarLoader.prototype.customAvatarSelection = function () {
this.LoadAvatarBtn.enabled = false;
let iframe = document.getElementById('avatarIframe');
let avatarDiv = document.getElementById('avatarDiv');
iframe.src = 'https://rarerooms.readyplayer.me/avatar'; // Change this to your custom subdomain
iframe.style.display = "block";
avatarDiv.style.display = "block";
};
// update code called every frame
CustomAvatarLoader.prototype.update = function () {
CustomAvatarLoader.prototype.loadGLBModelFromURL = function (modelURL) {
var self = this;
this.GlbURL = modelURL;
this.app.fire("LoadingMenu:SetLoading", true, "Loading Avatar..");
let name = "model_" + (Math.floor(Math.random() * 10000));
let cacheURL = modelURL + "?cacheBuster=" + (Math.floor(Math.random() * 10000));
this.LoadingScreen.enabled = true;
utils.loadGlbContainerFromUrl(cacheURL, null, name, function (err, asset) {
if (asset.resources[0].model)
this.app.root.findByName("ModelTPC").model.asset = asset.resources[0].model.id;
else {
console.log(asset.resources);
}
this.LoadAvatarBtn.enabled = true;
this.LoadingScreen.enabled = false;
}.bind(this));
};
};
1 Like
and i cannot see any error in console regarding character change
Is there any way to send character textures through network ?
As this is a fairly large script, let’s take a step back and look at it step by step what’s going on.
What function within your script is responsible for loading other people’s model? Is it loadNewAvatar
?
How is this function called? Do we have an event that we’re subscribing the function to? Where do we subscribe to it?
Also, I should note that it might be useful to ask on the Ready Player Me Discord ? It seems like the issue is more so how to correctly use their API than a problem with PlayCanvas itself?
1 .The function is right below the new avatar load glb model from url
the function is called after the load new avatar function
And i have also asked the ready player me in gmail . And they don’t have any particular documentation for PlayCanvas
is there any way to update textures over a socket network
CustomAvatarLoader.prototype.loadGLBModelFromURL = function (modelURL) {
var self = this;
this.GlbURL = modelURL;
this.app.fire("LoadingMenu:SetLoading", true, "Loading Avatar..");
let name = "model_" + (Math.floor(Math.random() * 10000));
let cacheURL = modelURL + "?cacheBuster=" + (Math.floor(Math.random() * 10000));
this.LoadingScreen.enabled = true;
utils.loadGlbContainerFromUrl(cacheURL, null, name, function (err, asset) {
if (asset.resources[0].model)
this.app.root.findByName("ModelTPC").model.asset = asset.resources[0].model.id;
else {
console.log(asset.resources);
}
this.LoadAvatarBtn.enabled = true;
this.LoadingScreen.enabled = false;
}.bind(this));
};
I will send you the full code properly
var CustomAvatarLoader = pc.createScript('customAvatarLoader');
CustomAvatarLoader.attributes.add('css', { type: 'asset', assetType: 'css', title: 'CSS Asset' });
CustomAvatarLoader.attributes.add('html', { type: 'asset', assetType: 'html', title: 'HTML Asset' });
CustomAvatarLoader.attributes.add("LoadAvatarBtn", { type: "entity" });
CustomAvatarLoader.attributes.add("LoadingScreen", { type: "entity" });
CustomAvatarLoader.instance = null;
window.addEventListener("message", function (event) {
if (event.origin === "https://rarerooms.readyplayer.me") {
CustomAvatarLoader.instance.LoadNewAvatar(event.data);
}
}, false);
// initialize code called once per entity
CustomAvatarLoader.prototype.initialize = function () {
CustomAvatarLoader.instance = this;
this.GlbURL = null;
this.iframeWidth = window.innerWidth;
this.iframeHeight = window.innerHeight;
this.app.on("BtnManager:LoadAvatarButtonClick", this.customAvatarSelection.bind(this));
this.on('destroy', function () {
this.app.off("BtnManager:LoadAvatarButtonClick", this.customAvatarSelection.bind(this));
}.bind(this));
this.setupIframe();
this.isMobile = false;
if (pc.platform.mobile || pc.platform.android || pc.platform.ios) { // Mobile
let avatarIframe = document.getElementById("avatarIframe");
avatarIframe.style.width = this.iframeWidth + "px";
avatarIframe.style.height = this.iframeHeight + "px";
avatarIframe.style.border = "none";
this.isMobile = true;
} else { // Desktop
let avatarIframe = document.getElementById("avatarIframe");
avatarIframe.style.width = "900px";
avatarIframe.style.height = "650px";
avatarIframe.style.border = "none";
this.isMobile = false;
}
};
CustomAvatarLoader.prototype.LoadNewAvatar = function (data) {
let iframe = document.getElementById('avatarIframe');
let avatarDiv = document.getElementById('avatarDiv');
iframe.style.display = "none";
avatarDiv.style.display = "none";
this.loadGLBModelFromURL(data);
};
CustomAvatarLoader.prototype.loadGLBModelFromURL = function (modelURL) {
var self = this;
this.GlbURL = modelURL;
this.app.fire("LoadingMenu:SetLoading", true, "Loading Avatar..");
let name = "model_" + (Math.floor(Math.random() * 10000));
let cacheURL = modelURL + "?cacheBuster=" + (Math.floor(Math.random() * 10000));
this.LoadingScreen.enabled = true;
utils.loadGlbContainerFromUrl(cacheURL, null, name, function (err, asset) {
if (asset.resources[0].model)
this.app.root.findByName("ModelTPC").model.asset = asset.resources[0].model.id;
else {
console.log(asset.resources);
}
this.LoadAvatarBtn.enabled = true;
this.LoadingScreen.enabled = false;
}.bind(this));
};
CustomAvatarLoader.prototype.setupIframe = function () {
// create STYLE element
var style = document.createElement('style');
// append to head
document.head.appendChild(style);
style.innerHTML = this.css.resource || '';
// Add the HTML
this.div = document.createElement('div');
this.div.id = "avatarDiv";
this.div.classList.add('avatarContrainer');
this.div.innerHTML = this.html.resource || '';
this.div.style.display = "none";
// append to body
// can be appended somewhere else
// it is recommended to have some container element
// to prevent iOS problems of overfloating elements off the screen
var canvas = document.getElementById("application-canvas");
// canvas.style.pointerEvents = "none";
//document.body.insertBefore(this.div,canvas);
document.body.appendChild(this.div);
};
CustomAvatarLoader.prototype.customAvatarSelection = function () {
this.LoadAvatarBtn.enabled = false;
let iframe = document.getElementById('avatarIframe');
let avatarDiv = document.getElementById('avatarDiv');
iframe.src = 'https://rarerooms.readyplayer.me/avatar'; // Change this to your custom subdomain
iframe.style.display = "block";
avatarDiv.style.display = "block";
};
// update code called every frame
CustomAvatarLoader.prototype.update = function () {
};
Hi @Tr_andreson ,
You still haven’t added the proposed correction from this topic, avoid creating new threads for the same topic. Just post on the same.
this is my script for character change as you have told me but nothing seems to work
var CustomAvatarLoader = pc.createScript('customAvatarLoader');
CustomAvatarLoader.attributes.add('css', { type: 'asset', assetType: 'css', title: 'CSS Asset' });
CustomAvatarLoader.attributes.add('html', { type: 'asset', assetType: 'html', title: 'HTML Asset' });
CustomAvatarLoader.attributes.add("LoadAvatarBtn", { type: "entity" });
CustomAvatarLoader.attributes.add("LoadingScreen", { type: "entity" });
…
Actually i have solved that previous problem for the character update . This is the new problem
Got it, try replying to the previous thread as solved and if possible share your solution to the problem for other users.
This is a single player example project, you will have to code multiplayer functionality from scratch
This can be done in a very simple way,
Sending the model trough socket is a no go
You already have ‘modelURL’
Add a new property to player entity that holds model url and broadcast it trought socket
The property itself should be set to something like ‘Default’
When player loads a new avatar set the property to modelURL
if playerModel !== Default
Load a model from that URL
Do some other checks…
You get the idea
1 Like
Thank you so much for your response . I have already made it multiplayer . I got your point thanks for your suggestion