Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  4. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  5. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  6. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Placing prefabs on other objects without raycasts?

Discussion in 'Extensions & OnGUI' started by FeastSC2, Jun 25, 2018.

  1. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    366
    Whenever building tools to place prefabs quickly in your scene, it's common to use raycasting on some collider to know where the prefab should be created. For example in 3D, we raycast on a terrain to place the prefab directly on top of the terrain.

    I wanted to use the same concept for 2D: I double click with my mouse and it places the prefab on a pre-existing prefab if there are any, if not it goes to Z:0.

    The problem I have is that I don't want my 2d prefabs to have a 2d colliders as these colliders are not used in my game. So how can I detect if there is a sprite where I'm clicking on without using raycasts (specifically without using colliders on the sprites in my scene).
     
  2. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    132
    Without implementing your own mesh or shader raycasting, the best in-built method to pick objects is the appropriately named HandleUtility.PickGameObject.
     
    FeastSC2 likes this.
  3. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    366
    Since I would like to know about multiple gameobjects in the cursor's direction, as if a line was cast from the mouse cursor towards infinity in the direction of: from the sceneView camera to the cursor. Is there something else I can use that achieves this?

    Here's how I previously did this with raycast:

    Code (CSharp):
    1.         var result = Physics.RaycastAll(worldRay, 100000f);
     
  4. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    132
    If you still want to avoid implementing your own mesh raycasting system, you could add temporary colliders with hideFlags to your objects and raycast against them.

    However for maximum flexibility you'll probably want to be able to raycast against meshes. I've actually implemented this for my own projects. It's not actually that difficult, mainly just porting to C# some algorithms made by way smarter people than I. :)

    This is the algorithm I used for broad-phase collision: http://www.realtimerendering.com/resources/RTNews/html/rtnv21n1.html#art9
    This is the algorithm I used for triangle intersection: https://www.cs.utah.edu/~aek/research/triangle.pdf

    Here's an example of it in action (this mesh has no collider):
     
    FeastSC2 likes this.
  5. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    366
    I ended up succeeding to make it for what I needed with the simple HandleUtility.PickGameObject. The answer simply was using what you suggested and the ignoreObjects argument.


    Code (CSharp):
    1.         List<GameObject> ignoreList = new List<GameObject>();
    2.         var obj = HandleUtility.PickGameObject(Event.current.mousePosition, false);
    3.         if (obj)
    4.         {
    5.             while (LayerHelper.IsLocked(obj.layer)) // Don't place prefab on GameObjects with locked layers
    6.             {
    7.                 ignoreList.Add(obj);
    8.                 obj = HandleUtility.PickGameObject(Event.current.mousePosition, false, ignoreList.ToArray());
    9.             }
    10.         }
    That's a very cool result you got there! I'll make sure to implement this when I create a 3d game myself : )
     
    Madgvox likes this.