Apfelbox
Apfelbox

Reputation: 367

Instantiate Object on Raycast2D hit and rotate Instance

I want to move an instance of a gameObject along the outline of another gameobject. Its a 2D Project in Unity.

My current Code:

Vector3 mousePosition = m_camera.ScreenToWorldPoint(Input.mousePosition);
    RaycastHit2D hit = Physics2D.Raycast(new Vector2(mousePosition.x, mousePosition.y), new Vector2(player.transform.position.x, player.transform.position.y));
    if (hit.collider != null &&  hit.collider.gameObject.tag == "Player") {
        if (!pointerInstance) {
            pointerInstance = Instantiate(ghostPointer, new Vector3(hit.point.x, hit.point.y, -1.1f), Quaternion.identity);
        } else if(pointerInstance) {
            pointerInstance.gameObject.transform.position = new Vector3(hit.point.x, hit.point.y, -1.1f);
            pointerInstance.gameObject.transform.eulerAngles = new Vector3(0f, 0f, hit.normal.x);
        }

    }

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: instance of tree is shown on the surface of the player facing towards the mousepointer

Any help is appreciated. Thanks!

Upvotes: 1

Views: 485

Answers (1)

Seyed Morteza Kamali
Seyed Morteza Kamali

Reputation: 846

it's better to use Mathematical way instead of physical way(Raycasting),because in raycasting you have to throw ray several time for checking hit point and rotate your object,it makes lag in your game.

Attach this script to your instantiated object:

using UnityEngine;
using System.Collections;

public class Example : MonoBehaviour
{
    public Transform Player;

    void Update()
    {
        //Rotating Around Circle(circular movement depend on mouse position)
        Vector3 targetScreenPos = Camera.main.WorldToScreenPoint(Player.position);
        targetScreenPos.z = 0;//filtering target axis
        Vector3 targetToMouseDir = Input.mousePosition - targetScreenPos;

        Vector3 targetToMe = transform.position - Player.position;

        targetToMe.z = 0;//filtering targetToMe axis

        Vector3 newTargetToMe = Vector3.RotateTowards(targetToMe, targetToMouseDir,  /* max radians to turn this frame */ 2, 0);

        transform.position = Player.position +  /*distance from target center to stay at*/newTargetToMe.normalized;


        //Look At Mouse position
        var objectPos = Camera.main.WorldToScreenPoint(transform.position);
        var dir = Input.mousePosition - objectPos;
        transform.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg);

    }
}

Useful explanations

Atan2:

atan2(y,x) gives you the angle between the x-axis and the vector (x,y), usually in radians and signed such that for positive y you get an angle between 0 and π, and for negative y the result is between −π and 0. https://math.stackexchange.com/questions/67026/how-to-use-atan2


Returns the angle in radians whose Tan is y/x. Return value is the angle between the x-axis and a 2D vector starting at zero and terminating at (x,y). https://docs.unity3d.com/ScriptReference/Mathf.Atan2.html

Mathf.Rad2Deg:

Radians-to-degrees conversion constant (Read Only).

This is equal to 360 / (PI * 2).

Upvotes: 1

Related Questions