Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Tizizzails · Mar 26, 2021 at 01:50 PM · imagescreenshotraw

Trying to Apply a screenshot to a raw image, only works on second try...

I’m at the point in my (tabletop simulator) project where I’m doing the team setup system. The player enters a name, type, other unit info in the fields on the unit setup screen. They choose a model by toggling between different units in the scene, and a secondary camera shows the unit in a raw image on that screen. They choose the material they want the unit to have, click create and then this CreateUnitCard() function is called. This will instantiate a new UI prefab which will show the name, type, other info and a screenshot of that unit.I watched a Code Monkey video to learn how to take a screenshot, I have to admit I don’t 100% understand it.

The problem is not in the actual screenshot taking, I don’t think – It pops up in the resources folder and looks fine to me. I have noticed that I need to click off of unity and reselect the program before it becomes visible, but it is there. The screenshot just doesn’t get applied to the raw image on the unit card. That remains white. Texture is: None (Texture).

The Screenshot function saves an image and names it after the unit. I have noticed that if I create a unit with a name that matches an image already saved to the resources folder, it does work. So If I try to make “Bob” his screenshot will be saved to the resources folder, but it will not display the screenshot on his card. If I then exit play mode, get back in and try to make “Bob” again, it will work as intended. If anyone could shine some light on this issue I would greatly appreciate it!

Here's the CreateUnitCard function-

     public void CreateUnitCard()
     {
         
         GameObject newCard = Instantiate(unitCard, TeamPanel.transform.position, transform.rotation);
         newCard.transform.SetParent(TeamPanel.transform);
 
         Text nameLine = newCard.gameObject.transform.Find("NameText").GetComponent<Text>();
         nameLine.text = unitName;
 
         Text typeLine = newCard.gameObject.transform.Find("TypeText").GetComponent<Text>();
         typeLine.text = unitType;
 
         Text otherInfoLine = newCard.gameObject.transform.Find("OtherInfoText").GetComponent<Text>();
         otherInfoLine.text = otherUnitInfo;
 
         ScreenshotHandler.TakeScreenshot(200, 300, unitName);
         
         Texture2D UnitPhoto = Resources.Load<Texture2D>(unitName);
         RawImage unitImageHolder = newCard.gameObject.transform.Find("Thumbnail").GetComponent<RawImage>();
         unitImageHolder.texture = UnitPhoto;
 
         //Reset text variables
     }

AND this is the Code Monkey script I'm using -

 public class ScreenshotHandler : MonoBehaviour
 {
     private static ScreenshotHandler instance;
 
     [SerializeField] 
     Camera myCamera;
     private bool takeScreenshotOnNextFrame;
     static string unitName;
 
 
     private void Awake()
     {
         instance = this;
     }
 
     private void OnPostRender()
     {
         if (takeScreenshotOnNextFrame)
         {
             takeScreenshotOnNextFrame = false;
             RenderTexture renderTexture = myCamera.targetTexture;
 
             Texture2D renderResult = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.RGB24, false);
             Rect rect = new Rect(0, 0, renderTexture.width, renderTexture.height);
             renderResult.ReadPixels(rect, 0, 0);
             
             byte[] byteArray = renderResult.EncodeToPNG();
             System.IO.File.WriteAllBytes(Application.dataPath + "/Resources/" + unitName + ".png", byteArray);
             Debug.Log("Saved Screenshot " + unitName + ".png");
 
             RenderTexture.ReleaseTemporary(renderTexture);
             myCamera.targetTexture = null;
         }
     }
 
     private void TakeScreenshot(int width, int height)
     {
         myCamera.targetTexture = RenderTexture.GetTemporary(width, height, 16);
         takeScreenshotOnNextFrame = true;
     }
     public static void TakeScreenshot(int width, int height, string name)
     {
         unitName = name;
         instance.TakeScreenshot(width, height);
     }
 }

This is the create a unit menu - alt text

And here's the main unity window, showing that the unit card is there, the create unit function has run, the image has saved but it was not applied to the Raw Image on the card-alt text

If you have read this far, you are awesome. Thanks for any help!

createunit.jpg (66.5 kB)
mainwindow.jpg (125.4 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by Vivien_Lynn · Mar 26, 2021 at 04:31 PM

It looks like you try to assign your texture (Screenshot) before the screenshot got taken and saved. If you look at the code in your ScreenshotHandler , you see that the Screenshot gets taken in the next frame. That means that the Texture does not yet exist when you try to assign it. One simple fix should be the following: Put the code that assigns the texture to your card into a Coroutine, like so:

 private IEnumerator AssignTextureToCard()
 {
     yield return 0;
     yield return new WaitForEndOfFrame();
 
     Texture2D UnitPhoto = Resources.Load<Texture2D>(unitName);
     RawImage unitImageHolder = newCard.gameObject.transform.Find("Thumbnail").GetComponent<RawImage>();
     unitImageHolder.texture = UnitPhoto;
 
     //Reset text variables
 }

Call this Coroutine after Line 16 in your first script, like so: StartCoroutine(AssignTextureToCard());

  1. This Coroutine waits one frame ( yield return 0; )

  2. In the next frame, it waits for the frame to end ( yield return new WaitForEndOfFrame(); )

  3. Then it assignes the Texture to your card


This is necessary because of Unity's Execution Order (click here for more information). We do yield return 0 to make sure we are in the same frame as when the Screenshot gets taken. With yield return new WaitForEndOfFrame(); we make sure that the Screenshot is actually taken and saved, before we try to access it (See in the Execution Order how the Screen gets rendered, before yield WaitForEndOfFrame ) alt text

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Tizizzails · Mar 27, 2021 at 03:36 AM 0
Share

@Vivien_Lynn Thank you so much for answering, I feel like I've won the lottery! And such a thoughtful answer too! I really appreciate the time you've taken.

But sadly I have to report that this solution did not fix the situation. I'd say it has improved, since the image in the Thumbnail now says "Missing(Texture)" instead of "None(Texture)". Here's how it looks now (The changed parts):

             ScreenshotHandler.TakeScreenshot(200, 300, unitName);
             StartCoroutine(AssignTextureToCard(newCard));
         }
         private IEnumerator AssignTextureToCard(GameObject newCard)
         {
             yield return 0;
             yield return new WaitForEndOfFrame();
     
             Texture2D UnitPhoto = Resources.Load<Texture2D>(unitName);
             RawImage unitImageHolder = 
             newCard.gameObject.transform.Find("Thumbnail").GetComponent<RawImage>();
             unitImageHolder.texture = UnitPhoto;
         }

I had to do the newCard as a parameter of AssignTextureToCard because it's a local variable I guess.

I had another idea and put a similar script on the actual unit card, so right when it's instantiated it uses the text in the name field to load a .png with the same name from resources after .1 seconds, but the result was the same. Missing texture. I would've thought that if I tried to load an image that didn't exist yet, I'd get an error of some kind, but there is none! Anyway, thanks again for your help, I never expected such a thorough answer. If you have any other ideas I'd love to hear them. If not, no problem!

avatar image Vivien_Lynn Tizizzails · Mar 27, 2021 at 08:22 AM 0
Share

It is correct that you need a parameter, to have a reference to your newCard. Can you confirm that the code still works when you execute it the second time? If so, you could try to add a second yield return 0; right after the first one. You need to see with Debug messages if your code gets executed correctly, and if all the references work.

avatar image Tizizzails · Mar 28, 2021 at 12:17 AM 0
Share

@Vivien_Lynn It still does work when I create another unit with the same name. I tested something else - looking in the file explorer resources folder, I can see the screenshot pop up immediately when the screenshot is taken, but there is no metadata for it right away. It's probably just a coincidence. But the metadata pops up in there when I exit play, click off of unity and click back on it. That's also when the screenshot appears in the resources folder in unity. Could it be a weird project setting or something? It looks like everything's running, it just.... Won't... Load!!!! I'm stumped!

avatar image Vivien_Lynn Tizizzails · Mar 28, 2021 at 10:59 AM 0
Share

I am afraid I have no answer to that particular phenomenon. Maybe you should ask about this specifically; "How to apply screenshot to a raw image in runtime?". Keep it short, but give all the information needed to understand the problem, you wrote a bit much in your original post. This increases the chance that people will actually read and understand the question. That being said, I personally would have done this differently. Instead of saving a screenshot (write file) and then loading it (read file), I would have just taken the Render Texture that gets generated in the ScreenshotHandler, and apply that to the Raw Image.

avatar image Tizizzails · Mar 28, 2021 at 02:10 PM 0
Share

@Vivien_Lynn Well thank you very much for trying to help! This issue has been holding me up for almost a week now, I think I'm just going to skip it (it is a cosmetic issue after all, not really my current priority as you can see from the screenshots) and come back to it later. I still have a long way to go. But when I do come back to it I'll try what you suggested. Have a good day!

avatar image Vivien_Lynn Tizizzails · Mar 30, 2021 at 06:28 PM 0
Share

I just remembered that $$anonymous$$ander Zotov once made a tutorial about showing a screenshot in Unity, during runtime. Maybe that is helpful for you. Here is the link: https://youtu.be/DQeylS0l4S4 Good luck! :)

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

115 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Unity 5.6.4 Canvas RawImage hides all objects 0 Answers

[ANDROID]How to load images from a certain folder after a screenshot? 1 Answer

CaptureScreenshot to Texture 1 Answer

Saving texture as raw 1 Answer

Texture2D saves as PNG correctly but doesn't display properly in RawImage 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges