This article written by Cartzhang, reproduced please indicate the source. All rights reserved.
Article Link: http://blog.csdn.net/cartzhang/article/details/53013843
Author: Cartzhang
Last time we only made a quick implementation and realized an Android version of the Google box with a lovely unity sauce.
Description: Picture number to correspond with GitHub, so keep the original number.
Picture address: https://github.com/cartzhang/UnitySay/tree/master/GooglVR_2/img
It's not bullying to just build and apply simple scenes without any analysis.
Of course it is.
See how the code starts with the start?
Look at the scene first, we only mount a GOOGLEVR preform, then start with it.
Figure 1
This guy has only one script GvrViewer.cs, is that what makes you overjoyed? A script is done, is not very simple, this is not easy to say simple.
A cursory glance at the code, less than 550 lines of code.
Do not care about the following 50 lines, editor operation and game pause, exit and other operations, there are 500 lines, this really many ah.
Well, how about that?
Let's start with Unity's code execution sequence,
Order of execution of code in Unity:
Official address: https://docs.unity3d.com/Manual/ExecutionOrder.html
Our focus:
Figure 9.1
From the awake–>start–>update in turn to tell. First, Awake analysis
Code Analysis
void Awake () {//1.0--if (instance = null) {instance = this;
} if (instance!= this) {debug.logerror ("There must is only one Gvrviewer object in a scene.");
UnityEngine.Object.DestroyImmediate (this);
Return
}//1.1--#if Unity_ios application.targetframerate = 60;
#endif//Prevent the screen from dimming/sleeping//1.2-screen.sleeptimeout = Sleeptimeout.neversleep;
1.3--initdevice ();
Stereoscreen = null; Set up stereo Pre-and Post-render stages A For://-Unity without the GVR native//-Integration In-editor
Or when the current platform is Android or IOS. Since GVR is the "the" valid VR SDK on Android or IOS-prevents it from//interfering with VR SDKs on other PL
Atforms. 1.4--#if! UNITY_HAS_GOOGLEVR | | (Unity_editor && (unity_android | |
Unity_ios)) addprepostrenderstages (); #endif//! UNITY_HAS_GOOGLEVR | | Unity_editor
1.0–
1.0-
if (instance = = null) {
instance = this;
}
If (instance!= this) {
debug.logerror ("There must is only one Gvrviewer object in a scene.");
UnityEngine.Object.DestroyImmediate (this);
return;
}
Initialized, this class is a single column.
1.1–
1.1--
#if unity_ios
application.targetframerate =;
#endif
Macro definition, if there is a Unity_ios, the lock frame is at 60 frames. The lock frame is designed to stabilize the game by stabilizing the number of frames.
1.2–
1.2--
screen.sleeptimeout = Sleeptimeout.neversleep;
is to save power, the screen for a long time did not trigger, it triggers the sleep mode. Now is never enabled Hibernate mode.
1.3–
1.3--
initdevice ();
Initialize the device. This is a function, in the future, Nathan.
1.4–
1.4--
#if! UNITY_HAS_GOOGLEVR | | (Unity_editor && (unity_android | | Unity_ios))
addprepostrenderstages ();
#endif //! UNITY_HAS_GOOGLEVR | | Unity_editor
Without a pre render, you add a pre render. If there is no later rendering, add the render after. Then send the message separately, reset (). Finally set their respective parent nodes.
Sets the current object to its parent node, and the code is just one sentence:
Go.transform.parent = transform;
Figure 2
Figure 3
A little SendMessage this function:
[Excludefromdocs]
public void SendMessage (String methodname);
Its function is to invoke a function that has the name MethodName in all Monobehaviour scripts on the current object.
This method is not efficient. But it can be used, it is better to use less.
You can refer to previous posts in detail:
http://blog.csdn.net/cartzhang/article/details/50686627
The following is a function that initializes the 1.3– initialization device.
Detailed comments are given in the code.
private void Initdevice () {
//Initialize device
if (device!= null) {
device. Destroy ();
}
Get device
device = Basevrdevice.getdevice ();
Device initialization, which is an inherited class in which override Init. Refer to Figure
device below. Init ();
Initialize UI
list<string> diagnostics = new list<string> ();
nativeuilayersupported = device. Supportsnativeuilayer (diagnostics);
if (diagnostics. Count > 0) {
debug.logwarning ("Built-in UI layer disabled.") Causes: ["
+ String.Join ("; ", diagnostics.) ToArray ()) + "]");
}
if (defaultdeviceprofile!= null) {
device. Setdefaultdeviceprofile (Defaultdeviceprofile);
}
Device. Setneckmodelscale (Neckmodelscale);
Sets whether to use binocular rendering. Whether VR mode is used.
#if! UNITY_HAS_GOOGLEVR | | Unity_editor
device. Setvrmodeenabled (vrmodeenabled);
#endif //! UNITY_HAS_GOOGLEVR | | Unity_editor
//Update screen data
device. Updatescreendata ();
}
Device. Init () initializes the inheritance and Basevrdevice class.
Figure 7
Figure 4
Whether to use Binocular VR rendering, this can modify its function in real time.
Figure 5
Figure 62, start code
The code is only one sentence and is available in Unity Editor mode in the current Unity Android mode and iOS mode.
void Start () {
//Set up stereo controller only for:
//-Unity without the GVR native integration
//-In-edi Tor emulator when the "current platform" is Android or IOS. Since GVR is the valid VR SDK on Android or IOS-prevents it from
//interfering with VR SDKs on Other platforms.
#if! UNITY_HAS_GOOGLEVR | | (Unity_editor && (unity_android | | Unity_ios))
Addstereocontrollertocameras ();
#endif //! UNITY_HAS_GOOGLEVR | | Unity_editor
}
What is the concrete realization?
is to add the phone's gyro control, you can use the gyroscope to control the camera.
In the last talk in the meeting after the Android apk bag, in the mobile phone automatically can move around to see the scene of our lovely bull sauce beat, is this to control and realize.
#if! UNITY_HAS_GOOGLEVR | | Unity_editor///Add a stereocontroller to any camera this does not have a Render texture (meaning it is///rendering
to the screen). public static void Addstereocontrollertocameras () {for (int i = 0; i < Camera.allCameras.Length; i++) {came
RA camera = camera.allcameras[i]; if (camera.targettexture = = null && camera.cullingmask!= 0 && camera. getcomponent<stereocontroller> () = = null && camera. getcomponent<gvreye> () = = null && camera. getcomponent<gvrprerender> () = = null && camera.
getcomponent<gvrpostrender> () = = null) {camera.gameobject.addcomponent<stereocontroller> (); }} #endif//! UNITY_HAS_GOOGLEVR | | Unity_editor
Figure 8
There is not much code. By searching, we found that there are 5 cameras in the current scene, as shown above. The function is to traverse all the cameras and then find the camera in the camera without Stereocontroller,gvreye,gvrprerender,gvrpostrender, and then add control Stereocontroller components to it.
This is the only maincamera to meet the adjustment.
Figure 93, where to update the screen.
Have you found in the Gvrviewer file, there is not a common update () function, only a updaetstate () function. That game screen how to update it.
Note is PreRender ()
Key functions to be labeled:
Figure 9.2
Look at the call associated with the Updatestate, remove the demo and UI calls, and discover the correlation to the class mentioned in the above Addstereocontrollertocameras function.
Figure 10
1. See the GvrEye.cs file:
Found inside the rendering hierarchy functions: Onprecull and Onpostrender.
Among them, Onpostrender only one sentence is shder a keyword shield.
Look at the following onprecull call implementation process:
Figure 11
After the call, a rendertexture is eventually generated.
Figure 12
The left and right eyes vary according to the setting, and the matrix parameters vary. But the result is the same, a texture.
This is the final step to render the left and right eye, the rendering of the mesh to set the material to prepare.
2.gvrprerender.cs file
This file, depending on the rendering order, is obviously a pre rendered processing.
Only one onprecull such rendering calls.
void Onprecull () {
//Update device status
GvrViewer.Instance.UpdateState ();
if (GvrViewer.Instance.ProfileChanged) {
//set shader, various matrix
setshaderglobals ();
}
Set Camera type
cam.clearflags = GvrViewer.Instance.VRModeEnabled?
CameraClearFlags.SolidColor:CameraClearFlags.Nothing;
}
Figure 13
3.gvrpostrender.cs file
There are two functions at the rendering level, one is onprecull and the other is onrenderobject.
The onprecull is realized by adjusting the ratio according to the setting of the camera screen and its mobile phone screen, and finally obtains the proportional parameter of a camera perspective projection.
And Onrenderobject is to achieve a split screen rendering, to achieve the key step of GOOLEVR, rendering out the picture.
Figure 14
4. Simply say Stereocontrol.
The main function is to create the left and right eye and set its position.
Figure 15
5. GvrHead.cs
Figure 16
With Sterocontrol under the same camera,
There are not many lines in the code:
void Update () {
updated = false; OK to Recompute head pose.
if (updateearly) {
updatehead ();
}
}
Normally, update head pose now.
void Lateupdate () {
updatehead ();
}
Obviously, all of the calls were made to Updatehead ().
This function is also very easy to see.
See if you want to synchronize the tracking rotation, synchronize the tracking position, and then the last
A delegate event is onheadupdated.
This is to see how players use, Update play status will notify the event.
I don't have to say more. Four or one figure thousand words
Figure 185, Flowchart download
Download Flowchart Address GitHub:
Https://github.com/cartzhang/UnitySay/blob/master/GooglVR_2/CodeAnylis.docx
Here is a picture of the flowchart, if necessary, you can download.
If you have any questions, please feel free to contact.
Thank you so much.. Vi. Reference
[1]
Http://baike.baidu.com/link?url=ZdjIjIyvD_ Mle57zvxe6pddyfhqqbxybshxg9nsi0r92eu8vkzhoyevvefg3zk7tvrd127vybwv-9b3hryylcytg68j3ddmqg4r_ylqpz53
[2]
Https://docs.unity3d.com/Manual/ExecutionOrder.html
————— –the-–end ————————-