Search Unity

[Solved] Instantiate Object on Raycast2D hit and rotate Instance

Discussion in '2D' started by Apfelbox, Apr 22, 2017.

  1. Apfelbox

    Apfelbox

    Joined:
    Apr 28, 2014
    Posts:
    39
    I want to move an instance of a gameObject along the outline of another gameobject. Its a 2D Project in Unity.
    My current Code:
    Code (CSharp):
    1. Vector3 mousePosition = m_camera.ScreenToWorldPoint(Input.mousePosition);
    2.     RaycastHit2D hit = Physics2D.Raycast(new Vector2(mousePosition.x, mousePosition.y), new Vector2(player.transform.position.x, player.transform.position.y));
    3.     if (hit.collider != null &&  hit.collider.gameObject.tag == "Player") {
    4.         if (!pointerInstance) {
    5.             pointerInstance = Instantiate(ghostPointer, new Vector3(hit.point.x, hit.point.y, -1.1f), Quaternion.identity);
    6.         } else if(pointerInstance) {
    7.             pointerInstance.gameObject.transform.position = new Vector3(hit.point.x, hit.point.y, -1.1f);
    8.             pointerInstance.gameObject.transform.eulerAngles = new Vector3(0f, 0f, hit.normal.x);
    9.         }
    10.  
    11.     }
    Unfortunately, the gameObject doesn't rotate towards the mouse and the position on the left side of the playerObject is also sometimes off. I tried to use Instantiate() with Quaternion.LookRotation(hit.normal), but no luck either.

    Here a rough sketch of what I want to achieve:


    Any help is appreciated. Thanks!
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,455
    Have you tried looking at the documentation for Physics2D.Raycast ? That shows you that the second argument is a direction, not a world position which I presume is your problem.

    If you want to perform a cast between two points (line segment) then use Physics2D.Linecast.

    If your player is just a circle of a specific radius then you do not need to use physics queries, just some simple math. From your diagram, calculate a normalized direction from the player position (2D) to the mouse position (2D) and scale that by the player radius. Here's some pseudo code:

    Code (CSharp):
    1. Vector2 mousePos = <blah>;
    2. Vector2 playerPos = <blah>;
    3. float playerRadius = <blah>;
    4. var hitPoint = playerPos + ((mousePos - playerPos).normalized * playerRadius);
     
    Last edited: Apr 23, 2017
  3. Apfelbox

    Apfelbox

    Joined:
    Apr 28, 2014
    Posts:
    39
    Thank you! In the meantime, I found a workaround but this information is definitely helpful for future projects.

    I also learned that it's better to use Mathematical way instead of a physical way(Raycasting) because in raycasting you have to throw ray several time for checking hit point, it could make your game lag.
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,455
    Raycasting is fast, more so if you use the non-allocating ones. You're doing something wrong if they're taking too much time.

    Less code is always faster so yeah, if there's a simple algorithm then use it.