Skip to content

Commit

Permalink
Implement issue #3 : Game View follows Scene View
Browse files Browse the repository at this point in the history
- Implement issue #3 as experimental functionality.
- Right Click “FoV” button in Scene View and select “Main Camera follows this Scene View”.
  • Loading branch information
Takayuki Matsuoka committed Apr 25, 2017
1 parent a990d15 commit dbd091b
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 37 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ sysinfo.txt
# Unity Test Scene
test.unity
test.unity.meta

.note
200 changes: 163 additions & 37 deletions Assets/SceneViewFovControl/Editor/Status.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using UnityEngine;
// https://github.com/anchan828/unitejapan2014/tree/master/SyncCamera/Assets
using UnityEngine;
using UnityEditor;
using System;
using System.Collections.Generic;

#if !UNITY_EDITOR
#error This script must be placed under "Editor/" directory.
Expand All @@ -8,62 +11,100 @@
namespace UTJ.UnityEditor.Extension.SceneViewFovControl {

class Status {
static WeakReference masterSceneView = new WeakReference(null);
float fov = 0.0f;
bool reset = false;
bool autoFov = true;
float lastOnSceneGuiFov = 0.0f;

static Camera[] activeCameras = new Camera[0];

const string ButtonStringFovAuto = "FoV:Auto";
const string ButtonStringFovUser = "FoV:{0:0.00}";

static readonly GUIContent ButtonContentFovAuto = new GUIContent(ButtonStringFovAuto);
GUIContent ButtonContentFovUser = new GUIContent(ButtonStringFovUser);

public void OnScene(SceneView sceneView) {
if(sceneView == null || sceneView.camera == null) {
return;
}
enum MenuId {
ToggleMainCameraFollowsSceneView
}

if(sceneView.in2DMode || autoFov) {
public void OnScene(SceneView sceneView) {
if(sceneView == null
|| sceneView.camera == null
|| sceneView.in2DMode
) {
return;
}

Camera camera = sceneView.camera;
if(fov == 0.0f || reset) {
fov = camera.fieldOfView;
reset = false;
}

var ev = Event.current;
var settings = Settings.Data;
float deltaFov = 0.0f;

if(ev.modifiers == settings.ModifiersNormal || ev.modifiers == settings.ModifiersQuick) {
if(ev.type == EventType.ScrollWheel) {
// todo : Check compatibility of Event.delta.y.
// e.g. Platform, mice, etc.
// note : In MacOS, ev.delta becomes zero when "Shift" pressed. I don't know the reason.
deltaFov = ev.delta.y;
ev.Use();
} else if(ev.type == EventType.KeyDown && ev.keyCode == settings.KeyCodeIncreaseFov) {
deltaFov = +1.0f;
ev.Use();
} else if(ev.type == EventType.KeyDown && ev.keyCode == settings.KeyCodeDecreaseFov) {
deltaFov = -1.0f;
ev.Use();
if(!autoFov) {
if(fov == 0.0f || reset) {
fov = camera.fieldOfView;
reset = false;
}

var ev = Event.current;
var settings = Settings.Data;
float deltaFov = 0.0f;

if(ev.modifiers == settings.ModifiersNormal || ev.modifiers == settings.ModifiersQuick) {
if(ev.type == EventType.ScrollWheel) {
// todo : Check compatibility of Event.delta.y.
// e.g. Platform, mice, etc.
// note : In MacOS, ev.delta becomes zero when "Shift" pressed. I don't know the reason.
deltaFov = ev.delta.y;
ev.Use();
} else if(ev.type == EventType.KeyDown && ev.keyCode == settings.KeyCodeIncreaseFov) {
deltaFov = +1.0f;
ev.Use();
} else if(ev.type == EventType.KeyDown && ev.keyCode == settings.KeyCodeDecreaseFov) {
deltaFov = -1.0f;
ev.Use();
}
}

if(deltaFov != 0.0f) {
deltaFov *= settings.FovSpeed;
if(ev.modifiers == settings.ModifiersQuick) {
deltaFov *= settings.FovQuickMultiplier;
}
fov += deltaFov;
fov = Mathf.Clamp(fov, settings.MinFov, settings.MaxFov);
}

camera.fieldOfView = fov;
}

if(deltaFov != 0.0f) {
deltaFov *= settings.FovSpeed;
if(ev.modifiers == settings.ModifiersQuick) {
deltaFov *= settings.FovQuickMultiplier;
if(IsMasterSceneView(sceneView)) {
// todo : It should choose a camera which be shown in the "Camera Preview" window in the Scene View.
if(activeCameras.Length == 0) {
var mainCamera = Camera.main;
CopyCameraInfo(from: camera, to: mainCamera);
} else {
foreach(var toCamera in activeCameras) {
CopyCameraInfo(from: camera, to: toCamera);
}
}
fov += deltaFov;
fov = Mathf.Clamp(fov, settings.MinFov, settings.MaxFov);
}
}

camera.fieldOfView = fov;
static void SetMasterSceneView(SceneView sceneView) {
masterSceneView = new WeakReference(sceneView);
}

static bool IsMasterSceneView(SceneView sceneView) {
return sceneView != null && masterSceneView.Target as SceneView == sceneView;
}

public static void CopyCameraInfo(Camera from, Camera to) {
if(from == null || to == null) {
return;
}
to.fieldOfView = from.fieldOfView;
to.gameObject.transform.position = from.transform.position;
to.gameObject.transform.rotation = from.transform.rotation;
}

public void OnSceneGUI(SceneView sceneView) {
Expand All @@ -80,15 +121,100 @@ public void OnSceneGUI(SceneView sceneView) {

GUIStyle style = EditorStyles.toolbarButton;
sceneView.DoToolbarRightSideGUI(content, style, (rect) => {
int btn = -1;
if(Event.current.type == EventType.MouseUp) {
btn = Event.current.button;
}
if (GUI.Button(rect, content, style)) {
autoFov = !autoFov;
if(!autoFov) {
reset = true;
if(btn == 1) {
OnFovButtonRightClicked(sceneView);
} else {
OnFovButtonLeftClicked(sceneView);
}
}
});
}

public void ToggleAutoFov() {
autoFov = !autoFov;
if(!autoFov) {
reset = true;
}
}

public static void ToggleMainCameraFollowsSceneView(SceneView sceneView) {
if(IsMasterSceneView(sceneView)) {
SetMasterSceneView(null);
} else {
SetMasterSceneView(sceneView);
}
}

void OnFovButtonLeftClicked(SceneView sceneView) {
ToggleAutoFov();
}

void OnFovButtonRightClicked(SceneView sceneView) {
var menu = new GenericMenu();
// todo: near/far clip control
// todo: main (active) camera stick with scene view (toast, toggle)
menu.AddItem(
new GUIContent("Main Camera follows this Scene View")
, false
, (obj) => {
ToggleMainCameraFollowsSceneView(sceneView);
}
, MenuId.ToggleMainCameraFollowsSceneView
);
//menu.AddItem(new GUIContent("Item"), false, Callback, 2);
menu.ShowAsContext();
}

[InitializeOnLoadMethod]
static void ActiveCameraCorrector() {
Selection.selectionChanged += () => {
Camera[] newActiveCameras = null;
{
var activeCameraList = new List<Camera>();
var goes = Selection.gameObjects;
if(goes != null) {
foreach(var go in goes) {
var camera = go.GetComponent<Camera>();
if(camera != null) {
activeCameraList.Add(camera);
}
}
}
activeCameraList.Sort(delegate(Camera lhs, Camera rhs) {
return lhs.GetInstanceID() - rhs.GetInstanceID();
});
newActiveCameras = activeCameraList.ToArray();
}

bool activeCamerasAreChanged = false;
if(activeCameras.Length != newActiveCameras.Length) {
activeCamerasAreChanged = true;
} else {
for(int i = 0; i < newActiveCameras.Length; ++i) {
if(!object.Equals(newActiveCameras[i], activeCameras[i])) {
activeCamerasAreChanged = true;
break;
}
}
}

if(activeCamerasAreChanged) {
// When active camera is changed, disable copying scene view transform to game view.
SetMasterSceneView(null);
activeCameras = newActiveCameras;
}
};
}

// void Callback(object obj) {
// var i = (MenuId) obj;
// Debug.LogFormat("Callback = {0}", i);
// }
}

} // namespace

0 comments on commit dbd091b

Please sign in to comment.