- Home /
Strange results when using Context Menu and Camera
I have a script that creates a mesh from each corner of the view fustrum at a given distance.
When the script is run by playing the scene, the mesh is generated as expected.
When the context menu is used while playing or not playing the scene, the mesh Y values are correct, but the X values appear to be half of what they should be.
Is there a difference when using Camera.main with Context Menu compared to play mode?
Edit 2:
To hopefully Clarify this issue, I am including a Debug.Log.
This is the Debug.Log for all 3 possible ways of calling the function Startup() and calculating each vertex position based on Camera.main .
Why am I getting different results for the same script? , the only difference being the way the function is called.
START
UL (-0.8, 0.6, 1.0) : UR (0.8, 0.6, 1.0)
LL (-0.8, -0.6, 1.0) : LR (0.8, -0.6, 1.0)
Constructing Mesh from ContextMenu
UL (-0.4, 0.6, 1.0) : UR (0.4, 0.6, 1.0)
LL (-0.4, -0.6, 1.0) : LR (0.4, -0.6, 1.0)
UPDATE - mouse-click
UL (-0.8, 0.6, 1.0) : UR (0.8, 0.6, 1.0)
LL (-0.8, -0.6, 1.0) : LR (0.8, -0.6, 1.0)
SO ... hit play ... function called ... calculations are perfect.
Right-Click on the script and use context menu ... whoops all the calculations are giving the wrong results.
Call the function by an input in Update ... wow, the calculations are correct.
Spot the difference : the time the calculations were wrong, the same function was run using Context Menu.
This is the problem, I am looking for an answer as this is actually greatly affecting how I build my scenes. Thankyou.
The direct Debug values of Camera.main fieldofview and aspect, the results are :
START
fieldOfView 60 : aspect 1.333333
Constructing Mesh from ContextMenu
fieldOfView 60 : aspect 0.5744382
UPDATE - mouse-click
fieldOfView 60 : aspect 1.333333
Edit :
I have updated my question with pictures to demonstrate the problem. It is only when using Context Menu that the problem occurs. To me this can only be caused by how Unity sees Camera.main. I need to know why the camera FOV is off when using the context menu.
When the script runs by pressing play :
When the script runs by using Context Menu :
Here is my working script :
#pragma strict
@script RequireComponent(MeshFilter, MeshRenderer)
#if UNITY_EDITOR
@ContextMenu ("Construct Mesh")
function ConstructQuad()
{
Debug.Log("Constructing Mesh from ContextMenu");
Startup();
}
#endif
var theCamera : Camera;
var cameraTransform : Transform;
private var mesh : Mesh;
private var uv : Vector2[];
private var verts : Vector3[];
private var tris : int[];
private var normals : Vector3[];
public var uvSize : Vector2 = Vector2.one;
public var uvOffset : Vector2 = Vector2.zero;
public var distance : float = 1.0;
function Start()
{
Startup();
}
function Update()
{
}
function Startup()
{
if ( theCamera == null )
{
theCamera = Camera.mainCamera;
}
cameraTransform = theCamera.transform;
if ( !mesh )
{
GetComponent(MeshFilter).mesh = mesh = new Mesh();
mesh.name = "ScreenMesh";
}
Construct();
}
function Construct()
{
mesh.Clear();
verts = new Vector3[4];
// calculate verts based on camera FOV
var pos : Vector3 = cameraTransform.position - transform.position;
var halfFOV : float = ( theCamera.fieldOfView * 0.5 ) * Mathf.Deg2Rad;
var aspect : float = theCamera.aspect;
var height : float = distance * Mathf.Tan( halfFOV );
var width : float = height * aspect;
// UpperLeft
verts[0] = pos - (cameraTransform.right * width);
verts[0] += cameraTransform.up * height;
verts[0] += cameraTransform.forward * distance;
// UpperRight
verts[1] = pos + (cameraTransform.right * width);
verts[1] += cameraTransform.up * height;
verts[1] += cameraTransform.forward * distance;
// LowerLeft
verts[2] = pos - (cameraTransform.right * width);
verts[2] -= cameraTransform.up * height;
verts[2] += cameraTransform.forward * distance;
// LowerRight
verts[3] = pos + (cameraTransform.right * width);
verts[3] -= cameraTransform.up * height;
verts[3] += cameraTransform.forward * distance;
// ** usual mesh stuff from here onwards **
}
I read through the code a few times and couldn't spot any glaring issues.
Just curious though, would using something like raycasthit and an invisible plane in front of the camera be easier?
Either way, good luck.
The information that would be received from a raycast would be the same as my vertex calculations. In fact, you would have to do my vertex calculations just to know what direction to cast the ray. I have updated my question with pictures to demonstrate the problem. It is only when using Context $$anonymous$$enu that the problem occurs. This can only be caused by how Unity sees Camera.main. I need to know why the camera FOV is off when using the context menu.
I would really like an answer that explains what is happening and how to fix it.
Edit : Thanks for moving that to a comment. It was a good suggestion, and someone in future may need the suggestion to use a raycast method, but for me the problem is what is happening when the script is run with Context $$anonymous$$enu . Thanks again for your suggestion.
$$anonymous$$ore information on Context $$anonymous$$enu : http://docs.unity3d.com/Documentation/ScriptReference/Context$$anonymous$$enu.html
I believe the issue and answer would derive from how/what does Unity see as Camera.main when running functions from the context menu? I shall Debug the actual camera values for fieldOfView and aspect rather than just the outcome to verify, but am almost certain the problem is the game window as a part of the whole window of the unity editor. The same problem if I maximize on play, or $$anonymous$$r off the inspector window and the game window.
Edit :
the results are :
START
fieldOfView 60 : aspect 1.333333
Constructing $$anonymous$$esh from Context$$anonymous$$enu
fieldOfView 60 : aspect 0.5744382
UPDATE - mouse-click
fieldOfView 60 : aspect 1.333333
The theory is sound, but in my case is not the problem. When you look at my script, each of the 3 ways to build the mesh is done by calling the one and same function :
@Context$$anonymous$$enu ("Construct $$anonymous$$esh")
function ConstructQuad() {
Startup();
}
function Start() {
Startup();
}
function Update() {
if (Input.Get$$anonymous$$ouseButtonDown(0)) {
Startup();
}
}
function Startup() {
// It all happens here ....
}
Answer by Fattie · Nov 02, 2012 at 04:29 PM
Yes - there is a known problem in unity where the cameras (etc) go to hell, if the Play is not actually Playing.
For example, "viewport" -like calculations are messed up. My investigations suggested that certain of the ports would appear to default to squares, when it is not on Play.
I discovered this problem circa Aug 24, 2012 and posted it here, but nobody cared. I would have made a bug report but for this damn idleness.
PS Sorry - for some reason I cannot see your recent comments. We broke the comment system :)
Fair enough. Though my problem with Context $$anonymous$$enu happens when the scene is playing or not.
I was hoping there would be some definitive explanation from a Unity-type person (with diamonds next to their handle eg Graham D), something like when using context menu the camera is redefined as the Unity program window, so all calculations related to the camera are not going to be relative to the scene. You need to use Camera.current or Camera.allCameras[1], or use a specific depth, or ...
So to get an actual answer and a solution to my problem , so I can either : (a) understand what is happening; and (b) know how to fix/stop the problem from happening; I have to submit a bug report? Where has Unity Answers gone this last month.
I gave a thumb straight away as it was good to know I was not seeing things or going (more) loopy. There is obviously something going on with the way Unity sees cameras in the program itself, just look at the functions under the GameObject tab : $$anonymous$$ove to View, Align with View, Align View to Selected. I have used the last selection myself to change the view of the camera in Game view to the position and rotation of the Scene view.
I have been bumping this for a week now, and this is the closest to anyone even recognizing my problem, and relating that it is real and an issue. With my luck for conclusive answers lately this is as close as I am going to get. Thanks.
Sorry, that was a bit of a rant but not your fault. Thanks again for showing you recognized my problem, helping me realize that my suspicions on the problem were correct, and there is no other information around. I shall just make an asset with AssetDatabase.CreateAsset so I can design my layout in edit mode without running scripts.
exactly - here's my jury rig solution
http://answers.unity3d.com/questions/307429/simply-display-or-highlight-empty-game-objects-in.html
cheers!
Answer by SongU · Nov 01, 2012 at 05:49 AM
fix line
var width : float = height * aspect *4/3;
or var width : float = height aspect Screen.width/Screen.height;
in unity3d, Screen world change when transform for do not scale 3dObject
if your camera proportion 4:3, camera display more 4-3
sry about my stupid english, but it will be solved...
Thankyou for trying to help, but unfortunately this is wrong. You do show a good method for manually calculating the aspect ratio (Screen.width/Screen.height), but this value is returned anyway with
var aspect : float = theCamera.aspect;
and then you suggest multiplying the aspect by the aspect, and the height. This is wrong, sorry. I have uploaded a picture to demonstrate. Please convert this answer to a comment, so I have a chance of getting an actual answer to my problem.
To clarify : when I use Context $$anonymous$$enu the values returned are different than when run from Start or Update.
When SongU's suggestion runs by pressing play :
When SongU's suggestion runs by using Context $$anonymous$$enu :
Can you please convert this to a comment, so I get a chance of receiving an actual answer, thanks.