0
\$\begingroup\$

In my 2D game, the player is able to teleport to any place on the screen with the click of the mouse button. What I am trying to prevent is the ability to teleport across solid objects. If the point from the player and the mouse click position is across an object then I want the player to teleport next to that object instead of across it.

I am currently trying to achieve this with raycasting. The code I wrote somewhat works but only if the mouse click is on an object, if the mouse click is across another object, it still teleports me accross the object without it registering that there is an object between the player and the mouse position.

My code:

Vector3 player_position = Camera.main.WorldToScreenPoint(transform.position);
Vector3 to_object_vector = transform.position - Camera.main.transform.position;
Vector3 linear_distance_vector = Vector3.Project(to_object_vector, Camera.main.transform.forward);

float distance_to_camera = linear_distance_vector.magnitude;
Vector3 mouse_position = Input.mousePosition;
float dist = Vector2.Distance(player_position, mouse_position);
Vector3 dir = (mouse_position - player_position).normalized;
mouse_position.z = distance_to_camera;

RaycastHit2D hit = Physics2D.Raycast(new Vector2(player_position.x, player_position.y), new Vector2(dir.x, dir.y), dist, 0);
if (hit.collider != null) {
     Debug.Log(hit.point);
     mouse_position = new Vector3(hit.point.x, hit.point.y, mouse_position.z);
}

Is there a better approach to this problem?

\$\endgroup\$
6
  • \$\begingroup\$ sorry I couldn't understand what you actually want yo ask. Can you please post your question with some snaps that what is currently going on and what you want, that'd be very easy to understand for all the community members \$\endgroup\$ Mar 14 '16 at 11:05
  • \$\begingroup\$ my fault it is hard for me to explain. Here is a gyazo of what I am trying to prevent: gyazo.com/2674861c985b6e845a4bb8aed06a4a12 . As you can see I can teleport across this object but when I click on the object itself it prevents me. I want to prevent myself from teleporting across that object. So imagine a line if any collider interrupts that line then teleport next to that object instead of across it. \$\endgroup\$
    – Sol
    Mar 14 '16 at 11:18
  • \$\begingroup\$ So you want if you click on block in middle, but player should teleport as you click in empty space next to block? \$\endgroup\$ Mar 14 '16 at 11:28
  • \$\begingroup\$ I dont want the player to teleport across it at all. What I have so far is stopping the player from teleporting in the wall but I also want to stop them from teleporting across it as well. \$\endgroup\$
    – Sol
    Mar 14 '16 at 11:39
  • \$\begingroup\$ Then I'd suggest to move the player instead of assigning new position. As disable SpriteRenderer then assign velocity to that direction and then check for the collision \$\endgroup\$ Mar 14 '16 at 11:44
0
\$\begingroup\$

One thing you should do, and this is useful for all of your Unity projects, is using Debug.DrawLine (if you have origin and destination) or Debug.DrawRay if you only have the direction vector.

I haven't used 2D mode in Unity, but I guess you can still use 3D in Scene inspector, right? If so, then use the functions above to throw rays from player to the hit.point position. You should do it into Update function, since it could draw a ray just for 1 frame if you don't and you wouldn't see it.

Things to check if working properly:

  1. Check if the ray is drawing always trough the object when you click behind it, if it does, then you're not setting the nearest position properly.
  2. Check that those objects you don't want to go through are not in a Ignore raycast layer.

Now, talking about how to move your character, I would try to use Physics AddForce. Even though it is 3D, you can just use 0 into x/z axis and use Physics to move character. If you multiply the vector for a high thrust, I think you could get a teleport simulation (deactivating MeshRenderer before doing it, for example). Remember you need a Rigidbody to use that physics, and probably need to mark it as Kinetic in order to avoid it bouncing.

Hope this helps you.

\$\endgroup\$
5
  • \$\begingroup\$ Thanks I have tried drawline but I was unable to see the actual line because maybe it was drawn for one frame, but I'll try it again! And yeah using physics addforce is a good idea to simulate teleportation! That's a great idea, but I really want to solve this particular problem since I spent so much time on it. And yes the objects are not on the ignore raycast layer i checked. \$\endgroup\$
    – Sol
    Mar 14 '16 at 10:59
  • \$\begingroup\$ I added force but I am still able to go through solid objects if I run up to it and addforce against the wall, which is very unfortunate \$\endgroup\$
    – Sol
    Mar 14 '16 at 23:14
  • \$\begingroup\$ Did you set Dynamic Continuous inside Rigidbody options? \$\endgroup\$ Mar 14 '16 at 23:53
  • \$\begingroup\$ no i didn't I did not realize there was an option for that! Even if the collider is slim it still doesn't allow me to go through!! That worked thank you so much! \$\endgroup\$
    – Sol
    Mar 15 '16 at 0:46
  • \$\begingroup\$ You're welcome. You have enough information on what this option is made for on the net, it's something we all must know. Good luck with your game \$\endgroup\$ Mar 15 '16 at 11:19
0
\$\begingroup\$

Well since raycasting cannot solve my specific issue which is unfortunate, since it should return the end point of any solid objects that interrupts that line I was forced to expand my colliders far enough to where the player can't click over the object like so: enter image description here

Since my if statement is checking if the player is clicking on a collider I will always teleport to the hit.point preventing the player from going outside the map indefinitely!

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .