Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
  • Help Room /
avatar image
0
Question by JeyP4 · May 15, 2018 at 07:09 PM · cameradelaydisplay

How can I delay play mode environment continuously?

Hey I know it is strange. But can we do something like, delay the play mode environment by some time delay.(say 500msec)

I am simulating a car, which is a sending a realtime windscreen video to a control room. Because of network, a delay is happening say 0.5 sec. I want to see what control room will be seeing.

Comment
Add comment · Show 2
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 JeyP4 · May 15, 2018 at 07:12 PM 0
Share

@Baroque I saw ur answer in similar question. If my problem is similar, can u guide me in little detail in steps. Thanks ...Cheers

avatar image JeyP4 · May 16, 2018 at 08:34 PM 0
Share

Hey @Hellium I followed your answer on the same topic. I tried it also. It takes good processing power and also Unity Crashes after some time. I saw that you mentioned some optimization tips, But I am unable to do so. Can you give the optimized code!! Please.. Thanks..

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Hellium · May 16, 2018 at 09:33 PM

Hello @JeyP4,

I've quickly reworked the code I provided in the answer I gave on StackOverflow, but I haven't profilled the two solutions, so I don't know if you will have better performances.


Here is a new reworked version using an array, a custom struct to save the captured Texture + the time the texture has been captured at, and two indices to manage the captured frame and the rendered frame

 using UnityEngine;
 using System.Collections;
 
 public class DelayedCamera : MonoBehaviour
 {
     public struct Frame
     {
         /// <summary>
         /// The texture representing the frame
         /// </summary>
         private Texture2D texture;
 
         /// <summary>
         /// The time (in seconds) the frame has been captured at
         /// </summary>
         private float recordedTime;
 
         /// <summary>
         /// Captures a new frame using the given render texture
         /// </summary>
         /// <param name="renderTexture">The render texture this frame must be captured from</param>
         public void CaptureFrom( RenderTexture renderTexture )
         {
             RenderTexture.active = renderTexture;
 
             // Create a new texture if none have been created yet in the given array index
             if ( texture == null )
                 texture = new Texture2D( renderTexture.width, renderTexture.height );
 
             // Save what the camera sees into the texture
             texture.ReadPixels( new Rect( 0, 0, renderTexture.width, renderTexture.height ), 0, 0 );
             texture.Apply();
 
             recordedTime = Time.time;
 
             RenderTexture.active = null;
         }
 
         /// <summary>
         /// Indicates whether the frame has been captured before the given time
         /// </summary>
         /// <param name="time">The time</param>
         /// <returns><c>true</c> if the frame has been captured before the given time, <c>false</c> otherwise</returns>
         public bool CapturedBefore( float time )
         {
             return recordedTime < time;
         }
 
         /// <summary>
         /// Operator to convert the frame to a texture
         /// </summary>
         /// <param name="frame"></param>
         public static implicit operator Texture2D( Frame frame ) { return frame.texture; }
     }
 
     /// <summary>
     /// The camera used to capture the frames
     /// </summary>
     [SerializeField]
     private Camera renderCamera;
 
     /// <summary>
     /// The delay
     /// </summary>
     [SerializeField]
     private float delay;
 
     /// <summary>
     /// The size of the buffer containing the recorded images
     /// </summary>
     private int bufferSize = 256;
 
     /// <summary>
     /// The render texture used to record what the camera sees
     /// </summary>
     private RenderTexture renderTexture;
 
     /// <summary>
     /// The recorded frames
     /// </summary>
     private Frame[] frames;
 
     /// <summary>
     /// The index of the captured texture
     /// </summary>
     private int capturedFrameIndex;
 
     /// <summary>
     /// The index of the rendered texture
     /// </summary>
     private int renderedFrameIndex;
 
     /// <summary>
     /// The frame index
     /// </summary>
     private int frameIndex;
     
     private void Awake()
     {
         frames = new Frame[bufferSize];
 
         // Change the depth value from 24 to 16 may improve performances. And try to specify an image format with better compression.
         renderTexture = new RenderTexture( Screen.width, Screen.height, 24 );
         renderCamera.targetTexture = renderTexture;
         StartCoroutine( Render() );
     }
 
     /// <summary>
     /// Makes the camera render with a delay
     /// </summary>
     /// <returns></returns>
     private IEnumerator Render()
     {
         WaitForEndOfFrame wait = new WaitForEndOfFrame();
 
         while ( true )
         {
             yield return wait;
 
             capturedFrameIndex = frameIndex % bufferSize;
 
             frames[capturedFrameIndex].CaptureFrom( renderTexture );
 
             // Find the index of the frame to render
             // The foor loop is **voluntary** empty
             for ( ; frames[renderedFrameIndex].CapturedBefore( Time.time - delay ) ; renderedFrameIndex = ( renderedFrameIndex + 1 ) % bufferSize ) ;
             
             Graphics.Blit( frames[renderedFrameIndex], null as RenderTexture );
 
             frameIndex++;
         }
     }
 }


Original answer

You can play with the size of the buffer to make the delay smaller or bigger, but there is no "notion of time", so an efficient computer will have a smaller delay than a slower one.


Here, I use an array of Textures with a fixed length. In the image below, the grey cells means the cell does not (yet) contain a Texture2D. When the cell is in dark blue, it means the texture has just been recorded. When the cells is in light blue, it means, it has been recorded some frames before.


By maintaining an index to know which texture to replace / instantiate, I know the newest recorded texture and the oldest, which is the next one in the array.

alt text

 using UnityEngine;
 using System.Collections;
 
 public class DelayedCamera : MonoBehaviour
 {
     /// <summary>
     /// The camera used to record the scene
     /// </summary>
     [SerializeField]
     private Camera renderCamera;
 
     /// <summary>
     /// The size of the buffer containing the recorded images
     /// </summary>
     [SerializeField]
     private int bufferSize = 16;
 
     /// <summary>
     /// The render texture used to record what the camera sees
     /// </summary>
     private RenderTexture renderTexture;
 
     /// <summary>
     /// The recorded frames
     /// </summary>
     private Texture2D[] frames;
 
     /// <summary>
     /// The captured texture index
     /// </summary>
     private int capturedFrameIndex;
 
     /// <summary>
     /// The frame index
     /// </summary>
     private int frameIndex;
 
 
     private void Awake()
     {
         frames = new Texture2D[bufferSize];
 
         // Change the depth value from 24 to 16 may improve performances. And try to specify an image format with better compression.
         renderTexture = new RenderTexture( Screen.width, Screen.height, 24 );
         renderCamera.targetTexture = renderTexture;
         StartCoroutine( Render() );
     }
 
     private IEnumerator Render()
     {
         WaitForEndOfFrame wait = new WaitForEndOfFrame();
 
         while ( true )
         {
             yield return wait;    
 
             capturedFrameIndex = frameIndex % bufferSize;
 
             // Create new texture of the current frame
             RenderTexture.active = renderTexture;
 
             // Create a new texture if none have been created yet at the given array index
             if ( frames[capturedFrameIndex] == null )
                 frames[capturedFrameIndex] = new Texture2D( renderTexture.width, renderTexture.height );
 
             // Save what the camera sees into the texture
             frames[capturedFrameIndex].ReadPixels( new Rect( 0, 0, renderTexture.width, renderTexture.height ), 0, 0 );
             frames[capturedFrameIndex].Apply();
             RenderTexture.active = null;
 
             // Render the oldest recorded frame
             if ( frames[( capturedFrameIndex + 1) % bufferSize] != null )
             {
                 Graphics.Blit( frames[( capturedFrameIndex + 1 ) % bufferSize], null as RenderTexture );
             }
 
             frameIndex++;
         }
     }
 }


delayedcamera.png (19.5 kB)
Comment
Add comment · Show 4 · 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 JeyP4 · May 17, 2018 at 02:15 AM 0
Share

First of all Thnx for such a quick reply and this efficient code. Wow, this is highly smooth....superb.

I am facing just two problems with this code

  1. All the time it shows "No camera Rendering". See attached imagealt text.

  2. As there is some movement and calculation in the scene during play, the frame rate flickers from 35 to 60. So giving buffer some value is not effective. Can something be done with 'Time.deltatime' to record the time used in past frames and calculate the buffer size automatically.

nocameraredering.jpg (121.8 kB)
avatar image Hellium JeyP4 · May 17, 2018 at 08:37 AM 1
Share

I've reworked my solution to manage a real delay.

You can disable the warning by clicking on the little menu at the top right of the Game tab and unchecking Warn if no camera rendering

avatar image JeyP4 · May 17, 2018 at 11:13 PM 0
Share

Hey @Hellium Very good work. Thank you so much. It is working perfectly. :D

avatar image Hellium JeyP4 · May 18, 2018 at 07:10 AM 1
Share

Glad it works fine and smoothly for you. Thanks for the feedback, I will update my answer on StackOverflow ! ;D

avatar image
0

Answer by naomi_k · Mar 02, 2020 at 02:30 PM

Does anyone know how to implement this code with a VR headset (Oculus rift s)?

Comment
Add comment · 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

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

194 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 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

Best way to display maps? 0 Answers

How to put a display in the display list? 0 Answers

Make FixedUpdate camera be static like in Update? 0 Answers

Camera Doesn't Show Game In Build 0 Answers

Gameobjects showing in scene but not in game tab 0 Answers


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