Moving scene view camera from editor script--

There are 7 pages of threads somewhat related to this, and I’ve gone through most of them.

Most of them say to grab ‘Camera.current’ and use that-- Well, actually, most people say they think that is what Camera.current does.

However, I have a script in my Editor folder, which otherwise works fine, however Camera.current just gets null reference exceptions.

My editor script goes somewhat like this:

class RobsEditor extends EditorWindow 
{
    @MenuItem ("Window/RobsEditor")
    static function Init () 
    {
	var window : RobsEditor = EditorWindow.GetWindow (RobsEditor);
    }

    function OnGUI () 
    {
	GUILayout.Label ("Rob's Editor", EditorStyles.boldLabel);

	EditorGUILayout.BeginHorizontal();
	
	if (GUILayout.Button("Search"))
	{
                //This Only prints out the camera in the heirarchy view
		var count : int = Camera.allCameras.Length;
		for (var y : int = 0; y < Camera.allCameras.Length; y++)
		{
		    Debug.Log(Camera.allCameras[y].name);
		}

               //nothing ever happens
		if (Camera.current != null)
		{
		    Camera.current.transform.position.x = 0;
		    Camera.current.transform.position.y = 0;
		    Camera.current.transform.position.z = -10;
		}
	}
    }
}

Anyone have any ideas?

1 Like

You should be able to do something like this too.

var sceneCamera:Camera = SceneView.lastActiveSceneView.camera;

sceneCamera.transform.position.z = -10;

Disclaimer: Untested and undocumented, so subject to not work and to change at any point.

4 Likes

You can also use the following to get the cameras for all open scene views.

var sceneCameras:Camera[] = SceneView.GetAllSceneCameras();

Disclaimer: Also undocumented/untested, so use at your own risk.

1 Like

Hey–

That did not work (though, it looks like it would-- ashame that it is undocumented, because I’d love to see what else is in that class).

It did get into the if statement, but I have no idea what camera changed. Any other suggestions?

Ah, you’re right. The position for the scene view camera is generated every frame. Try editing SceneView.lastActiveSceneView.pivot instead.

The following code should work.

using UnityEngine;
using UnityEditor;

public class SceneViewCameraTest : ScriptableObject
{
	[MenuItem("Test/Move Scene View Camera")]
	static public void MoveSceneViewCamera()
	{
		Vector3 position = SceneView.lastActiveSceneView.pivot;
		position.z -= 10.0f;
		SceneView.lastActiveSceneView.pivot = position;
		SceneView.lastActiveSceneView.Repaint();
	}
}

Again, undocumented, so subject to not work/change.

12 Likes

Hey, I’ll give that a shot in a minute-- may I ask where you are getting the undocumented classes?

Source code :slight_smile:

But you can use Reflection to see undocumented class members. Many people use Reflector to do this. Forum search and Google can tell you more.

Hey Shawn, that above code worked out-- thanks for that.

I’ve read up upon Reflection, and my understanding of it is simply put,

if (myClass.HasFunction("Restart"))
{
    myClass.Restart();
}

I’ll keep the above product in mind should I want to check it out :slight_smile:

P.S. Any idea how I would get the above software to run on Mac?

This, of course, would only compile if the class function existed :wink: So the function invocation would have to be done at runtime too, some “like”: Reflector.invokeFunction(myClass, “Restart”);

Hello,

I’ve found this thread when I was looking for a way to switch view via script,
I’m writing a script to switch view so I can switch to Top view, Left, Back, Front and so on via shortcut but as it is all undocumented I’m pretty stuck,
I’ve managed to move the camera via the code above but I’m clueless on how to rotate it, I’ve already tried via rotation and via other SceneView.lastActiveSceneView class members. any hint how to do this ?
by the way it really surprises me there’s no hotkeys for doing that!
at last not on this list
http://blogs.unity3d.com/2011/08/24/unity-hotkeys-keyboard-shortcuts-in-unity/

I want to do something similar to pasoftdev. Except what I want to do is prevent the camera from rotating. Specifically when the camera is in one of the Iso views (Top, Front, Right, Etc.) When I’m in these modes, I’d really likethe camera to stay locked facing that direction, but I can’t seem to find a way to do it. Is this something that could be scripted? Or maybe a feature request? I have tried the “SceneView.lastActiveSceneView.lockRotation” member but to no avail, as well as the rotation member.

I just wrote a script that allows multiple SceneViews to follow a gameobject in edit and play mode. I uploaded it to the Unity3d Wiki: http://wiki.unity3d.com/index.php/SceneViewCameraFollower

I just found out about this tonight while trying to do something similar. I was trying to focus on an object from a top-down view, which I was able to accomplish using this:

sceneView.LookAt(myPosition, Quaternion.Euler(90, 0, 0));

You can adjust the euler angle values to rotate the camera however you want.

5 Likes

Thank @Zaikman @shawn_1 ! This is useful for me !

And my demo : https://www.youtube.com/watch?v=UESaudzhHQI

Here is an asset that helps you save some editor camera angles, it comes with the source code and everything on how it’s done. Hope it helps.

I found this thread from a script reference from another thread (link).

The manual script method to align the scene view to an objects saves me time but there is still a small problem like @Hatsuko also noticed: “The position is slightly different.” - I’m pretty sure, that this offset comes after using the scroll wheel… because after resetting the view you can use the scroll wheel until it snaps in the exact position, like “Align View to selected” would do. But because scroll wheel is often used in the scene view the time saving is gone, because 1. the rotation must be copied from the selected object to 2. correct the offset with the scroll wheel.

Now my question to maybe @shawn_1 : how can we reset/write this scene view position offset, which the scroll wheel influences?

Hi shawn, this changed the position of the pivot, not the position of SceneView.lastActiveSceneView.camera.transform. How to set the position of the camera directly?

Wow, old thread…

Eh, setting the position directly would not work as you want though. The position is internally set every frame, so your changes would get stomped. The position is set to the following every frame: pivot + rotation * new Vector3(0, 0, -cameraDistance). cameraDistance is derived from size.

So if you want to move the camera around you’ll need to manipulation pivot, rotation, and size properties on the scene view.

4 Likes

Thanks Shawn!

This seems to work well:

public static void TeleportSceneCamera(Vector3 cam_position, Vector3 cam_forward)
{
    // Can't set transform of camera :(
    // It internally updates every frame:
    //      cam.position = pivot + rotation * new Vector3(0, 0, -cameraDistance)
    // Info: https://discussions.unity.com/t/426597/19

    var scene_view = UnityEditor.SceneView.lastActiveSceneView;

    // SceneView.lastActiveSceneView.cameraDistance is private, compute it.
    var offset = scene_view.pivot - scene_view.camera.transform.position;
    var cameraDistance = offset.magnitude;

    scene_view.pivot = cam_position + cam_forward * cameraDistance * -1.0f;
    scene_view.rotation = Quaternion.LookRotation(cam_forward);
}

It’s a bit wonky when coming from UI editing (probably doesn’t work well when cameraDistance is an extreme value?)

Edit: there’s also an interesting SceneViewCameraFollower script on Unify that uses a different method!

3 Likes