How can I create an object at the mouse point in scene view by clicking not dragging the object?
Generally, most objects are placed in the scene view by dragging or something. I want to right click the mouse (without dragging an object) to create an object in the scene view. I know this would require some editor coding but I’m not sure how to go about it.
UPDATE
After giving it some thought I realised that using a MenuItem would be quite appropriate for me. Here is my code below:
SLMenuItems:
public class SLMenuItems : MonoBehaviour {
public bool canClickSceneViewToCreatePath = false;
void Start()
{
}
[MenuItem("Component/Create Custom Object")]
static void CreateObject() {
Debug.Log("menu item selected");
canClickSceneViewToCreatePath = true;
}
}
SLMenuItemsEditor:
[CustomEditor(typeof(SLMenuItems))]
public class SLMenuItemsEditor : Editor {
SLMenuItems slMenuItems;
void OnEnable()
{
slMenuItems = (SLMenuItems)target;
}
void OnSceneGUI()
{
if (slMenuItems.canClickSceneViewToCreatePath) {
Vector3 pointsPos = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
{
// create object here at pointsPos
slMenuItems.canClickSceneViewToCreatePath = false;
}
}
}
}
I keep getting the following error:
Assets/SLMenuItems.cs(23,9): error CS0120: An object reference is required to access non-static member `SLMenuItems.canClickSceneViewToCreatePath'
pointing to the line:
canClickSceneViewToCreatePath = true;
in SLMenuItems
.
unity3d unity-editor
|
show 8 more comments
Generally, most objects are placed in the scene view by dragging or something. I want to right click the mouse (without dragging an object) to create an object in the scene view. I know this would require some editor coding but I’m not sure how to go about it.
UPDATE
After giving it some thought I realised that using a MenuItem would be quite appropriate for me. Here is my code below:
SLMenuItems:
public class SLMenuItems : MonoBehaviour {
public bool canClickSceneViewToCreatePath = false;
void Start()
{
}
[MenuItem("Component/Create Custom Object")]
static void CreateObject() {
Debug.Log("menu item selected");
canClickSceneViewToCreatePath = true;
}
}
SLMenuItemsEditor:
[CustomEditor(typeof(SLMenuItems))]
public class SLMenuItemsEditor : Editor {
SLMenuItems slMenuItems;
void OnEnable()
{
slMenuItems = (SLMenuItems)target;
}
void OnSceneGUI()
{
if (slMenuItems.canClickSceneViewToCreatePath) {
Vector3 pointsPos = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
{
// create object here at pointsPos
slMenuItems.canClickSceneViewToCreatePath = false;
}
}
}
}
I keep getting the following error:
Assets/SLMenuItems.cs(23,9): error CS0120: An object reference is required to access non-static member `SLMenuItems.canClickSceneViewToCreatePath'
pointing to the line:
canClickSceneViewToCreatePath = true;
in SLMenuItems
.
unity3d unity-editor
1
1.Detect mouse click. 2. Instantiate GameObject. I have simplified this for you. If you're lost, edit the question with your current code.
– Programmer
Nov 1 '18 at 15:54
@Programmer Okay, I think I get it. This is a small part of what I'm trying to achieve. I asked gamedev.stackexchange.com/questions/164911/… a few days ago but haven't got any assistance. I would be glad if you could take a look at it for me.
– hutfelt
Nov 1 '18 at 16:41
1
I suggest you re-create that question here on SO. There are many Unity users able to help you
– Programmer
Nov 1 '18 at 17:55
Have a look atGetMouseButtonDown
,ScreenToWorldPoint
andScreenPointToRay
depending what fits your needs
– derHugo
Nov 2 '18 at 7:14
@Programmer I just updated the question
– hutfelt
Nov 3 '18 at 14:14
|
show 8 more comments
Generally, most objects are placed in the scene view by dragging or something. I want to right click the mouse (without dragging an object) to create an object in the scene view. I know this would require some editor coding but I’m not sure how to go about it.
UPDATE
After giving it some thought I realised that using a MenuItem would be quite appropriate for me. Here is my code below:
SLMenuItems:
public class SLMenuItems : MonoBehaviour {
public bool canClickSceneViewToCreatePath = false;
void Start()
{
}
[MenuItem("Component/Create Custom Object")]
static void CreateObject() {
Debug.Log("menu item selected");
canClickSceneViewToCreatePath = true;
}
}
SLMenuItemsEditor:
[CustomEditor(typeof(SLMenuItems))]
public class SLMenuItemsEditor : Editor {
SLMenuItems slMenuItems;
void OnEnable()
{
slMenuItems = (SLMenuItems)target;
}
void OnSceneGUI()
{
if (slMenuItems.canClickSceneViewToCreatePath) {
Vector3 pointsPos = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
{
// create object here at pointsPos
slMenuItems.canClickSceneViewToCreatePath = false;
}
}
}
}
I keep getting the following error:
Assets/SLMenuItems.cs(23,9): error CS0120: An object reference is required to access non-static member `SLMenuItems.canClickSceneViewToCreatePath'
pointing to the line:
canClickSceneViewToCreatePath = true;
in SLMenuItems
.
unity3d unity-editor
Generally, most objects are placed in the scene view by dragging or something. I want to right click the mouse (without dragging an object) to create an object in the scene view. I know this would require some editor coding but I’m not sure how to go about it.
UPDATE
After giving it some thought I realised that using a MenuItem would be quite appropriate for me. Here is my code below:
SLMenuItems:
public class SLMenuItems : MonoBehaviour {
public bool canClickSceneViewToCreatePath = false;
void Start()
{
}
[MenuItem("Component/Create Custom Object")]
static void CreateObject() {
Debug.Log("menu item selected");
canClickSceneViewToCreatePath = true;
}
}
SLMenuItemsEditor:
[CustomEditor(typeof(SLMenuItems))]
public class SLMenuItemsEditor : Editor {
SLMenuItems slMenuItems;
void OnEnable()
{
slMenuItems = (SLMenuItems)target;
}
void OnSceneGUI()
{
if (slMenuItems.canClickSceneViewToCreatePath) {
Vector3 pointsPos = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
{
// create object here at pointsPos
slMenuItems.canClickSceneViewToCreatePath = false;
}
}
}
}
I keep getting the following error:
Assets/SLMenuItems.cs(23,9): error CS0120: An object reference is required to access non-static member `SLMenuItems.canClickSceneViewToCreatePath'
pointing to the line:
canClickSceneViewToCreatePath = true;
in SLMenuItems
.
unity3d unity-editor
unity3d unity-editor
edited Nov 3 '18 at 14:14
hutfelt
asked Nov 1 '18 at 15:42
hutfelthutfelt
615
615
1
1.Detect mouse click. 2. Instantiate GameObject. I have simplified this for you. If you're lost, edit the question with your current code.
– Programmer
Nov 1 '18 at 15:54
@Programmer Okay, I think I get it. This is a small part of what I'm trying to achieve. I asked gamedev.stackexchange.com/questions/164911/… a few days ago but haven't got any assistance. I would be glad if you could take a look at it for me.
– hutfelt
Nov 1 '18 at 16:41
1
I suggest you re-create that question here on SO. There are many Unity users able to help you
– Programmer
Nov 1 '18 at 17:55
Have a look atGetMouseButtonDown
,ScreenToWorldPoint
andScreenPointToRay
depending what fits your needs
– derHugo
Nov 2 '18 at 7:14
@Programmer I just updated the question
– hutfelt
Nov 3 '18 at 14:14
|
show 8 more comments
1
1.Detect mouse click. 2. Instantiate GameObject. I have simplified this for you. If you're lost, edit the question with your current code.
– Programmer
Nov 1 '18 at 15:54
@Programmer Okay, I think I get it. This is a small part of what I'm trying to achieve. I asked gamedev.stackexchange.com/questions/164911/… a few days ago but haven't got any assistance. I would be glad if you could take a look at it for me.
– hutfelt
Nov 1 '18 at 16:41
1
I suggest you re-create that question here on SO. There are many Unity users able to help you
– Programmer
Nov 1 '18 at 17:55
Have a look atGetMouseButtonDown
,ScreenToWorldPoint
andScreenPointToRay
depending what fits your needs
– derHugo
Nov 2 '18 at 7:14
@Programmer I just updated the question
– hutfelt
Nov 3 '18 at 14:14
1
1
1.Detect mouse click. 2. Instantiate GameObject. I have simplified this for you. If you're lost, edit the question with your current code.
– Programmer
Nov 1 '18 at 15:54
1.Detect mouse click. 2. Instantiate GameObject. I have simplified this for you. If you're lost, edit the question with your current code.
– Programmer
Nov 1 '18 at 15:54
@Programmer Okay, I think I get it. This is a small part of what I'm trying to achieve. I asked gamedev.stackexchange.com/questions/164911/… a few days ago but haven't got any assistance. I would be glad if you could take a look at it for me.
– hutfelt
Nov 1 '18 at 16:41
@Programmer Okay, I think I get it. This is a small part of what I'm trying to achieve. I asked gamedev.stackexchange.com/questions/164911/… a few days ago but haven't got any assistance. I would be glad if you could take a look at it for me.
– hutfelt
Nov 1 '18 at 16:41
1
1
I suggest you re-create that question here on SO. There are many Unity users able to help you
– Programmer
Nov 1 '18 at 17:55
I suggest you re-create that question here on SO. There are many Unity users able to help you
– Programmer
Nov 1 '18 at 17:55
Have a look at
GetMouseButtonDown
, ScreenToWorldPoint
and ScreenPointToRay
depending what fits your needs– derHugo
Nov 2 '18 at 7:14
Have a look at
GetMouseButtonDown
, ScreenToWorldPoint
and ScreenPointToRay
depending what fits your needs– derHugo
Nov 2 '18 at 7:14
@Programmer I just updated the question
– hutfelt
Nov 3 '18 at 14:14
@Programmer I just updated the question
– hutfelt
Nov 3 '18 at 14:14
|
show 8 more comments
1 Answer
1
active
oldest
votes
Your CreateObject
method is static
but your canClickSceneViewToCreatePath
value is not.
It has nothing to do with the editor script but with your class SlMenuItems
itself.
A static
method is not instanced or with other words it is kind of shared between all instances of that component type while the non-static value might be different for each component.
So how should a static method - which is the same for all instances - "know", which of the instances values it should access?
So either make the method non-static or the variable static. Depending on what your further need is.
Since the MenuItem
needs a static method make the variable static as well.
I would suggest you make that class not inherit from MonoBehaviour
at all since it doesn't have any behaviour for a GameObject. It only brings some editor features so rather make it a static class that can "live" in the Assets without needing to be instanced.
Than you can use SceneView.onSceneGUIDelegate
to register a callback for OnSceneGUI
without implementing an editor script for that:
private static GameObject lastCreated;
private static bool isCreating;
public static class SLMenuItems
{
[MenuItem("Component/Create Custom Object")]
private static void CreateObject()
{
Debug.Log("menu item selected");
isCreating = true;
lastCreated = null;
// Add a callback for SceneView update
SceneView.onSceneGUIDelegate -= UpdateSceneView;
SceneView.onSceneGUIDelegate += UpdateSceneView;
}
private static void UpdateSceneView(SceneView sceneView)
{
if(lastCreated)
{
// Keep lastCreated focused
Selection.activeGameObject = lastCreated;
}
if(isCreating)
{
if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
{
Vector3 pointsPos = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
//Todo create object here at pointsPos
lastCreated = Instantiate(somePrefab);
// Avoid the current event being propagated
// I'm not sure which of both works better here
Event.current.Use();
Event.current = null;
// Keep the created object in focus
Selection.activeGameObject = lastCreated;
// exit creation mode
isCreating = false;
}
}
else
{
// Skip if event is Layout or Repaint
if(e.type == EventType.Layout || e.type == EventType.Repaint)
{
Selection.activeGameObject = lastCreated;
return;
}
// Prevent Propagation
Event.current.Use();
Event.current = null;
Selection.activeGameObject = lastCreated;
lastCreated = null;
// Remove the callback
SceneView.onSceneGUIDelegate -= UpdateSceneView;
}
}
}
But I suggest you change your questions title since this is actually not the solution to the "task" you describe before.
Making the method non-static would mean I can't use it as amenuitem
. After making the variablestatic
a got the following error.error CS0176: Static member 'SLMenuItems.canClickSceneViewToCreatePath' cannot be accessed with an instance reference, qualify it with a type name instead
at the linesif (slMenuItems.canClickSceneViewToCreatePath) {
andslMenuItems.canClickSceneViewToCreatePath = false;
inOnSceneGUI()
– hutfelt
Nov 3 '18 at 23:08
If you make the variable static you don't access it via the instanced target (sLMenuItems
) anymore but via the classSLMenuItems
(note the majusculeS
)
– derHugo
Nov 4 '18 at 14:10
Thanks, this is precisely what I need. One more thing, how can I keep the newly created object selected after the mouse click?
– hutfelt
Nov 5 '18 at 16:26
I would also be grateful if you could take a look at stackoverflow.com/questions/53107167/… for me
– hutfelt
Nov 5 '18 at 16:33
@hutfelt you can useselection.activeGameObject = <your created object>
in order to keep it focused. Please see my update. When you said it worked did you use the quick fix from the comments or already the version without an editor script from my updated answer?
– derHugo
Nov 5 '18 at 17:25
|
show 7 more comments
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53104603%2fhow-can-i-create-an-object-at-the-mouse-point-in-scene-view-by-clicking-not-drag%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your CreateObject
method is static
but your canClickSceneViewToCreatePath
value is not.
It has nothing to do with the editor script but with your class SlMenuItems
itself.
A static
method is not instanced or with other words it is kind of shared between all instances of that component type while the non-static value might be different for each component.
So how should a static method - which is the same for all instances - "know", which of the instances values it should access?
So either make the method non-static or the variable static. Depending on what your further need is.
Since the MenuItem
needs a static method make the variable static as well.
I would suggest you make that class not inherit from MonoBehaviour
at all since it doesn't have any behaviour for a GameObject. It only brings some editor features so rather make it a static class that can "live" in the Assets without needing to be instanced.
Than you can use SceneView.onSceneGUIDelegate
to register a callback for OnSceneGUI
without implementing an editor script for that:
private static GameObject lastCreated;
private static bool isCreating;
public static class SLMenuItems
{
[MenuItem("Component/Create Custom Object")]
private static void CreateObject()
{
Debug.Log("menu item selected");
isCreating = true;
lastCreated = null;
// Add a callback for SceneView update
SceneView.onSceneGUIDelegate -= UpdateSceneView;
SceneView.onSceneGUIDelegate += UpdateSceneView;
}
private static void UpdateSceneView(SceneView sceneView)
{
if(lastCreated)
{
// Keep lastCreated focused
Selection.activeGameObject = lastCreated;
}
if(isCreating)
{
if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
{
Vector3 pointsPos = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
//Todo create object here at pointsPos
lastCreated = Instantiate(somePrefab);
// Avoid the current event being propagated
// I'm not sure which of both works better here
Event.current.Use();
Event.current = null;
// Keep the created object in focus
Selection.activeGameObject = lastCreated;
// exit creation mode
isCreating = false;
}
}
else
{
// Skip if event is Layout or Repaint
if(e.type == EventType.Layout || e.type == EventType.Repaint)
{
Selection.activeGameObject = lastCreated;
return;
}
// Prevent Propagation
Event.current.Use();
Event.current = null;
Selection.activeGameObject = lastCreated;
lastCreated = null;
// Remove the callback
SceneView.onSceneGUIDelegate -= UpdateSceneView;
}
}
}
But I suggest you change your questions title since this is actually not the solution to the "task" you describe before.
Making the method non-static would mean I can't use it as amenuitem
. After making the variablestatic
a got the following error.error CS0176: Static member 'SLMenuItems.canClickSceneViewToCreatePath' cannot be accessed with an instance reference, qualify it with a type name instead
at the linesif (slMenuItems.canClickSceneViewToCreatePath) {
andslMenuItems.canClickSceneViewToCreatePath = false;
inOnSceneGUI()
– hutfelt
Nov 3 '18 at 23:08
If you make the variable static you don't access it via the instanced target (sLMenuItems
) anymore but via the classSLMenuItems
(note the majusculeS
)
– derHugo
Nov 4 '18 at 14:10
Thanks, this is precisely what I need. One more thing, how can I keep the newly created object selected after the mouse click?
– hutfelt
Nov 5 '18 at 16:26
I would also be grateful if you could take a look at stackoverflow.com/questions/53107167/… for me
– hutfelt
Nov 5 '18 at 16:33
@hutfelt you can useselection.activeGameObject = <your created object>
in order to keep it focused. Please see my update. When you said it worked did you use the quick fix from the comments or already the version without an editor script from my updated answer?
– derHugo
Nov 5 '18 at 17:25
|
show 7 more comments
Your CreateObject
method is static
but your canClickSceneViewToCreatePath
value is not.
It has nothing to do with the editor script but with your class SlMenuItems
itself.
A static
method is not instanced or with other words it is kind of shared between all instances of that component type while the non-static value might be different for each component.
So how should a static method - which is the same for all instances - "know", which of the instances values it should access?
So either make the method non-static or the variable static. Depending on what your further need is.
Since the MenuItem
needs a static method make the variable static as well.
I would suggest you make that class not inherit from MonoBehaviour
at all since it doesn't have any behaviour for a GameObject. It only brings some editor features so rather make it a static class that can "live" in the Assets without needing to be instanced.
Than you can use SceneView.onSceneGUIDelegate
to register a callback for OnSceneGUI
without implementing an editor script for that:
private static GameObject lastCreated;
private static bool isCreating;
public static class SLMenuItems
{
[MenuItem("Component/Create Custom Object")]
private static void CreateObject()
{
Debug.Log("menu item selected");
isCreating = true;
lastCreated = null;
// Add a callback for SceneView update
SceneView.onSceneGUIDelegate -= UpdateSceneView;
SceneView.onSceneGUIDelegate += UpdateSceneView;
}
private static void UpdateSceneView(SceneView sceneView)
{
if(lastCreated)
{
// Keep lastCreated focused
Selection.activeGameObject = lastCreated;
}
if(isCreating)
{
if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
{
Vector3 pointsPos = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
//Todo create object here at pointsPos
lastCreated = Instantiate(somePrefab);
// Avoid the current event being propagated
// I'm not sure which of both works better here
Event.current.Use();
Event.current = null;
// Keep the created object in focus
Selection.activeGameObject = lastCreated;
// exit creation mode
isCreating = false;
}
}
else
{
// Skip if event is Layout or Repaint
if(e.type == EventType.Layout || e.type == EventType.Repaint)
{
Selection.activeGameObject = lastCreated;
return;
}
// Prevent Propagation
Event.current.Use();
Event.current = null;
Selection.activeGameObject = lastCreated;
lastCreated = null;
// Remove the callback
SceneView.onSceneGUIDelegate -= UpdateSceneView;
}
}
}
But I suggest you change your questions title since this is actually not the solution to the "task" you describe before.
Making the method non-static would mean I can't use it as amenuitem
. After making the variablestatic
a got the following error.error CS0176: Static member 'SLMenuItems.canClickSceneViewToCreatePath' cannot be accessed with an instance reference, qualify it with a type name instead
at the linesif (slMenuItems.canClickSceneViewToCreatePath) {
andslMenuItems.canClickSceneViewToCreatePath = false;
inOnSceneGUI()
– hutfelt
Nov 3 '18 at 23:08
If you make the variable static you don't access it via the instanced target (sLMenuItems
) anymore but via the classSLMenuItems
(note the majusculeS
)
– derHugo
Nov 4 '18 at 14:10
Thanks, this is precisely what I need. One more thing, how can I keep the newly created object selected after the mouse click?
– hutfelt
Nov 5 '18 at 16:26
I would also be grateful if you could take a look at stackoverflow.com/questions/53107167/… for me
– hutfelt
Nov 5 '18 at 16:33
@hutfelt you can useselection.activeGameObject = <your created object>
in order to keep it focused. Please see my update. When you said it worked did you use the quick fix from the comments or already the version without an editor script from my updated answer?
– derHugo
Nov 5 '18 at 17:25
|
show 7 more comments
Your CreateObject
method is static
but your canClickSceneViewToCreatePath
value is not.
It has nothing to do with the editor script but with your class SlMenuItems
itself.
A static
method is not instanced or with other words it is kind of shared between all instances of that component type while the non-static value might be different for each component.
So how should a static method - which is the same for all instances - "know", which of the instances values it should access?
So either make the method non-static or the variable static. Depending on what your further need is.
Since the MenuItem
needs a static method make the variable static as well.
I would suggest you make that class not inherit from MonoBehaviour
at all since it doesn't have any behaviour for a GameObject. It only brings some editor features so rather make it a static class that can "live" in the Assets without needing to be instanced.
Than you can use SceneView.onSceneGUIDelegate
to register a callback for OnSceneGUI
without implementing an editor script for that:
private static GameObject lastCreated;
private static bool isCreating;
public static class SLMenuItems
{
[MenuItem("Component/Create Custom Object")]
private static void CreateObject()
{
Debug.Log("menu item selected");
isCreating = true;
lastCreated = null;
// Add a callback for SceneView update
SceneView.onSceneGUIDelegate -= UpdateSceneView;
SceneView.onSceneGUIDelegate += UpdateSceneView;
}
private static void UpdateSceneView(SceneView sceneView)
{
if(lastCreated)
{
// Keep lastCreated focused
Selection.activeGameObject = lastCreated;
}
if(isCreating)
{
if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
{
Vector3 pointsPos = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
//Todo create object here at pointsPos
lastCreated = Instantiate(somePrefab);
// Avoid the current event being propagated
// I'm not sure which of both works better here
Event.current.Use();
Event.current = null;
// Keep the created object in focus
Selection.activeGameObject = lastCreated;
// exit creation mode
isCreating = false;
}
}
else
{
// Skip if event is Layout or Repaint
if(e.type == EventType.Layout || e.type == EventType.Repaint)
{
Selection.activeGameObject = lastCreated;
return;
}
// Prevent Propagation
Event.current.Use();
Event.current = null;
Selection.activeGameObject = lastCreated;
lastCreated = null;
// Remove the callback
SceneView.onSceneGUIDelegate -= UpdateSceneView;
}
}
}
But I suggest you change your questions title since this is actually not the solution to the "task" you describe before.
Your CreateObject
method is static
but your canClickSceneViewToCreatePath
value is not.
It has nothing to do with the editor script but with your class SlMenuItems
itself.
A static
method is not instanced or with other words it is kind of shared between all instances of that component type while the non-static value might be different for each component.
So how should a static method - which is the same for all instances - "know", which of the instances values it should access?
So either make the method non-static or the variable static. Depending on what your further need is.
Since the MenuItem
needs a static method make the variable static as well.
I would suggest you make that class not inherit from MonoBehaviour
at all since it doesn't have any behaviour for a GameObject. It only brings some editor features so rather make it a static class that can "live" in the Assets without needing to be instanced.
Than you can use SceneView.onSceneGUIDelegate
to register a callback for OnSceneGUI
without implementing an editor script for that:
private static GameObject lastCreated;
private static bool isCreating;
public static class SLMenuItems
{
[MenuItem("Component/Create Custom Object")]
private static void CreateObject()
{
Debug.Log("menu item selected");
isCreating = true;
lastCreated = null;
// Add a callback for SceneView update
SceneView.onSceneGUIDelegate -= UpdateSceneView;
SceneView.onSceneGUIDelegate += UpdateSceneView;
}
private static void UpdateSceneView(SceneView sceneView)
{
if(lastCreated)
{
// Keep lastCreated focused
Selection.activeGameObject = lastCreated;
}
if(isCreating)
{
if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
{
Vector3 pointsPos = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
//Todo create object here at pointsPos
lastCreated = Instantiate(somePrefab);
// Avoid the current event being propagated
// I'm not sure which of both works better here
Event.current.Use();
Event.current = null;
// Keep the created object in focus
Selection.activeGameObject = lastCreated;
// exit creation mode
isCreating = false;
}
}
else
{
// Skip if event is Layout or Repaint
if(e.type == EventType.Layout || e.type == EventType.Repaint)
{
Selection.activeGameObject = lastCreated;
return;
}
// Prevent Propagation
Event.current.Use();
Event.current = null;
Selection.activeGameObject = lastCreated;
lastCreated = null;
// Remove the callback
SceneView.onSceneGUIDelegate -= UpdateSceneView;
}
}
}
But I suggest you change your questions title since this is actually not the solution to the "task" you describe before.
edited Nov 13 '18 at 17:29
answered Nov 3 '18 at 14:42
derHugoderHugo
5,11421029
5,11421029
Making the method non-static would mean I can't use it as amenuitem
. After making the variablestatic
a got the following error.error CS0176: Static member 'SLMenuItems.canClickSceneViewToCreatePath' cannot be accessed with an instance reference, qualify it with a type name instead
at the linesif (slMenuItems.canClickSceneViewToCreatePath) {
andslMenuItems.canClickSceneViewToCreatePath = false;
inOnSceneGUI()
– hutfelt
Nov 3 '18 at 23:08
If you make the variable static you don't access it via the instanced target (sLMenuItems
) anymore but via the classSLMenuItems
(note the majusculeS
)
– derHugo
Nov 4 '18 at 14:10
Thanks, this is precisely what I need. One more thing, how can I keep the newly created object selected after the mouse click?
– hutfelt
Nov 5 '18 at 16:26
I would also be grateful if you could take a look at stackoverflow.com/questions/53107167/… for me
– hutfelt
Nov 5 '18 at 16:33
@hutfelt you can useselection.activeGameObject = <your created object>
in order to keep it focused. Please see my update. When you said it worked did you use the quick fix from the comments or already the version without an editor script from my updated answer?
– derHugo
Nov 5 '18 at 17:25
|
show 7 more comments
Making the method non-static would mean I can't use it as amenuitem
. After making the variablestatic
a got the following error.error CS0176: Static member 'SLMenuItems.canClickSceneViewToCreatePath' cannot be accessed with an instance reference, qualify it with a type name instead
at the linesif (slMenuItems.canClickSceneViewToCreatePath) {
andslMenuItems.canClickSceneViewToCreatePath = false;
inOnSceneGUI()
– hutfelt
Nov 3 '18 at 23:08
If you make the variable static you don't access it via the instanced target (sLMenuItems
) anymore but via the classSLMenuItems
(note the majusculeS
)
– derHugo
Nov 4 '18 at 14:10
Thanks, this is precisely what I need. One more thing, how can I keep the newly created object selected after the mouse click?
– hutfelt
Nov 5 '18 at 16:26
I would also be grateful if you could take a look at stackoverflow.com/questions/53107167/… for me
– hutfelt
Nov 5 '18 at 16:33
@hutfelt you can useselection.activeGameObject = <your created object>
in order to keep it focused. Please see my update. When you said it worked did you use the quick fix from the comments or already the version without an editor script from my updated answer?
– derHugo
Nov 5 '18 at 17:25
Making the method non-static would mean I can't use it as a
menuitem
. After making the variable static
a got the following error. error CS0176: Static member 'SLMenuItems.canClickSceneViewToCreatePath' cannot be accessed with an instance reference, qualify it with a type name instead
at the lines if (slMenuItems.canClickSceneViewToCreatePath) {
and slMenuItems.canClickSceneViewToCreatePath = false;
in OnSceneGUI()
– hutfelt
Nov 3 '18 at 23:08
Making the method non-static would mean I can't use it as a
menuitem
. After making the variable static
a got the following error. error CS0176: Static member 'SLMenuItems.canClickSceneViewToCreatePath' cannot be accessed with an instance reference, qualify it with a type name instead
at the lines if (slMenuItems.canClickSceneViewToCreatePath) {
and slMenuItems.canClickSceneViewToCreatePath = false;
in OnSceneGUI()
– hutfelt
Nov 3 '18 at 23:08
If you make the variable static you don't access it via the instanced target (
sLMenuItems
) anymore but via the class SLMenuItems
(note the majuscule S
)– derHugo
Nov 4 '18 at 14:10
If you make the variable static you don't access it via the instanced target (
sLMenuItems
) anymore but via the class SLMenuItems
(note the majuscule S
)– derHugo
Nov 4 '18 at 14:10
Thanks, this is precisely what I need. One more thing, how can I keep the newly created object selected after the mouse click?
– hutfelt
Nov 5 '18 at 16:26
Thanks, this is precisely what I need. One more thing, how can I keep the newly created object selected after the mouse click?
– hutfelt
Nov 5 '18 at 16:26
I would also be grateful if you could take a look at stackoverflow.com/questions/53107167/… for me
– hutfelt
Nov 5 '18 at 16:33
I would also be grateful if you could take a look at stackoverflow.com/questions/53107167/… for me
– hutfelt
Nov 5 '18 at 16:33
@hutfelt you can use
selection.activeGameObject = <your created object>
in order to keep it focused. Please see my update. When you said it worked did you use the quick fix from the comments or already the version without an editor script from my updated answer?– derHugo
Nov 5 '18 at 17:25
@hutfelt you can use
selection.activeGameObject = <your created object>
in order to keep it focused. Please see my update. When you said it worked did you use the quick fix from the comments or already the version without an editor script from my updated answer?– derHugo
Nov 5 '18 at 17:25
|
show 7 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53104603%2fhow-can-i-create-an-object-at-the-mouse-point-in-scene-view-by-clicking-not-drag%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
1.Detect mouse click. 2. Instantiate GameObject. I have simplified this for you. If you're lost, edit the question with your current code.
– Programmer
Nov 1 '18 at 15:54
@Programmer Okay, I think I get it. This is a small part of what I'm trying to achieve. I asked gamedev.stackexchange.com/questions/164911/… a few days ago but haven't got any assistance. I would be glad if you could take a look at it for me.
– hutfelt
Nov 1 '18 at 16:41
1
I suggest you re-create that question here on SO. There are many Unity users able to help you
– Programmer
Nov 1 '18 at 17:55
Have a look at
GetMouseButtonDown
,ScreenToWorldPoint
andScreenPointToRay
depending what fits your needs– derHugo
Nov 2 '18 at 7:14
@Programmer I just updated the question
– hutfelt
Nov 3 '18 at 14:14