How can I create an object at the mouse point in scene view by clicking not dragging the object?












1















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.










share|improve this question




















  • 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 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
















1















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.










share|improve this question




















  • 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 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














1












1








1


1






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.










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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














  • 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 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








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












1 Answer
1






active

oldest

votes


















2














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.






share|improve this answer


























  • 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













  • 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 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











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
});


}
});














draft saved

draft discarded


















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









2














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.






share|improve this answer


























  • 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













  • 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 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
















2














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.






share|improve this answer


























  • 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













  • 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 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














2












2








2







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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








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 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













  • 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 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



















  • 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













  • 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 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

















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


















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Xamarin.iOS Cant Deploy on Iphone

Glorious Revolution

Dulmage-Mendelsohn matrix decomposition in Python