Hello,
I have a problem I can’t figure it out how to solve it.
I have a crafting system where the player can chose the mesh he want.
I have a classe playerdata with a list of unlock string wich are the unlock mesh name.
I want to create at runtime Icon of the mesh by instanciate the mesh and “take a picture”.
I have a panel wich instanciate Item for every unlock mesh.
Thoses Item prefab call a icon manager to get a sprite :
public void GetIconSimpleForm(string formName, Material Mat,bool isWeapon, string type , Action<Sprite> callBackSprite)
{
callbackSprite = callBackSprite;
GameObject IconMaker = Instantiate(IconMakerPrefab, this.transform,false) as GameObject;
IconMaker.transform.localPosition = CurrentPOS;
CurrentPOS.y += 100;
iconScript = IconMaker.GetComponent<IconMakerScript>();
iconScript.InstanciateMesh(formName, isWeapon, type, callBackSprite);
iconScript.SetMaterial(Mat);
}
those item call the manager with a callback methode, this methode is call after the camera render.
for each “icon demande” the manager instanciate another prefab ( “IconMakerPrefab”) , wich is a mesh + a camera + a light source.
this prefab instanciate the mesh, move the camera corresponding to the mesh type, an render the camera view on a new texture
public void InstanciateMesh(string meshName, bool isWeapon, string type, Action<Sprite> callbacksprite)
{
meshname = meshName;
CallbackIcon = callbacksprite;
CalbbackLoad = true;
string path = "";
if (isWeapon)
{
path = "PrefabsIcons/Weapons/" + meshName + "_Static";
}
else
{
path = "PrefabsIcons/Gears/" + meshName + "_Static";
}
ObjectDisplay = Instantiate(Resources.Load(path, typeof(GameObject)), this.transform, false) as GameObject;
ObjectDisplay.transform.localEulerAngles = ROT;
switch (type.ToLower())
{
case "head":
ObjectDisplay.transform.localPosition = HeadPOS;
camera.orthographicSize = HeadSIZE/2;
break;
case "torso":
ObjectDisplay.transform.localPosition = TorsoPOS;
camera.orthographicSize = TorsoSIZE / 2;
break;
case "upperright":
ObjectDisplay.transform.localPosition = UpperRightPOS;
camera.orthographicSize = UpperRightSIZE / 2;
break;
case "upperleft":
ObjectDisplay.transform.localPosition = UpperLeftPOS;
camera.orthographicSize = UpperLeftSIZE / 2;
break;
case "lowerright":
ObjectDisplay.transform.localPosition = LowerRightPOS;
camera.orthographicSize = LowerRightSIZE / 2;
break;
case "lowerleft":
ObjectDisplay.transform.localPosition = LowerLeftPOS;
camera.orthographicSize = LowerLeftSIZE / 2;
break;
case "handright":
ObjectDisplay.transform.localPosition = HandRightPOS;
camera.orthographicSize = HandRightSIZE / 2;
break;
case "handleft":
ObjectDisplay.transform.localPosition = HandLeftPOS;
camera.orthographicSize = HandLeftSIZE / 2;
break;
case "legsright":
ObjectDisplay.transform.localPosition = LegsRightPOS;
camera.orthographicSize = LegsRightSIZE / 2;
break;
case "legsleft":
ObjectDisplay.transform.localPosition = LegsLeftPOS;
camera.orthographicSize = LegsLeftSIZE / 2;
break;
case "hips":
ObjectDisplay.transform.localPosition = HipsPOS;
camera.orthographicSize = HipsSIZE / 2;
break;
case "shoulderleft":
ObjectDisplay.transform.localPosition = ShoulderLeftPOS;
camera.orthographicSize = ShoulderLeftSIZE / 2;
break;
case "shoulderright":
ObjectDisplay.transform.localPosition = ShoulderRightPOS;
camera.orthographicSize = ShoulderRightSIZE / 2;
break;
}
associatedTexture = new RenderTexture(OriginaleTexture);
camera.targetTexture = associatedTexture;
associatedTexture.name = meshname;
}
this script also wait the camera to render to execute the call back methode :
void OnEnable()
{
RenderPipelineManager.endCameraRendering += RenderPipelineManager_endCameraRendering;
}
void OnDisable()
{
RenderPipelineManager.endCameraRendering -= RenderPipelineManager_endCameraRendering;
}
private void RenderPipelineManager_endCameraRendering(ScriptableRenderContext context, Camera camera)
{
if (CalbbackLoad && !CallBackDone)
{
CallBackMethode();
}
}
the call back methode create a sprite from the camera targetTexture :
public void CallBackMethode ()
{
//camera.Render();
Texture2D texture = new Texture2D(associatedTexture.width, associatedTexture.height);
Rect rect = new Rect(0, 0, associatedTexture.width, associatedTexture.height);
var oldRt = RenderTexture.active;
RenderTexture.active = associatedTexture;
texture.ReadPixels(rect, 0, 0);
texture.Apply();
RenderTexture.active = oldRt;
Sprite sprite = Sprite.Create(texture, rect, Vector2.zero);
sprite.name = meshname;
CallBackDone = true;
CallbackIcon(sprite);
}
And call back the item with his new sripte.
at the next frame the 'iconmaker" prefab is destroy:
private void Update()
{
if (CallBackDone)
{
Destroy(this.gameObject);
}
}
But at the end the sprite is a blank one.
The textures are good but the sprite are not.
When I uncomment Camera.render(); it’s crash but before that my sprites are good.
I must have miss something with the URP rendering.
Any Iea?
Thanks for your help.