I need a character to do a teleport between two points. One transform.position is the players location, the other is mouse input. However, there are a few conditions, one is that the length of the said teleport is set and if mouse input is further, it can’t pass a certain point, the other thing is that if there is an object with a certain Tag, for example an unpassable wall, the teleport should only take him to that length. The last condition is that the target should teleport within one or two frames as he clicks the button. I haven’t attached any solution attempt of my own because there are so many that I have I tried, I don’t know which one is most efficient. It’s a 2D game where this calculation will be used in many mechanics, so I’d like to make it an efficient mechanic if possible.
This sounds like a simple raycast and then some actions based on the what is found on the ray collision.
Efficiency seems a very unlikely candidate to suffer. Have you made a simple scene in which you simply 'port your GameObject to whatever point you click on the screen?
No offense, but you have 1 post, this post on the forum and you are asking a quite basic question. Also, it’ considered good form to at least post your attempted solution.
I had a plethora of attempted solutions and didn’t know which one might be the right choice to take, so if I post and someone solves it with the same idea, when there is a way better idea solution, didn’t want to accidentally box someone’s mind. After some time I finally did it. Before it just didn’t know how to use Raycasts and as I finally learned, it works.
using UnityEngine;
public class BlinkTP : MonoBehaviour
{
public int speed;
public float maxBlinkDistance;
public LayerMask unblinkableObjects;
void Update()
{
if (Input.GetKeyDown(“space”))
{
Vector2 ray = Camera.main.ScreenToWorldPoint(Input.mousePosition) - gameObject.transform.position;
RaycastHit2D blinkHit = Physics2D.Raycast(gameObject.transform.position, ray, maxBlinkDistance, unblinkableObjects);
if (blinkHit.collider == null)
{
float coff = Mathf.Abs(ray.x) + Mathf.Abs(ray.y);
coff = maxBlinkDistance / coff;
Vector2 newPlayerPos = new Vector2(ray.x * coff, ray.y * coff);
gameObject.transform.position += (Vector3)newPlayerPos;
}
else
{
gameObject.transform.position = blinkHit.point;
}
gameObject.GetComponent().velocity = new Vector2(0,0);
}
}
}
Glad you figured it out. You can clean that up a little bit though.
using UnityEngine;
public class BlinkTP : MonoBehaviour
{
public int speed;
public float maxBlinkDistance;
public LayerMask unblinkableObjects;
private Rigidbody2D rb2D;
private void Awake()
{
rb2D = GetComponent<Rigidbody2D>();
}
void Update()
{
if (Input.GetKeyDown("space"))
{
// get difference, ignore Z value
Vector3 diff = (Vector2)(Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position);
RaycastHit2D blinkHit = Physics2D.Raycast(transform.position, diff, maxBlinkDistance, unblinkableObjects);
if (blinkHit.collider == null)
{
transform.position += diff.normalized * maxBlinkDistance;
}
else
{
transform.position = blinkHit.point;
}
rb2D.velocity = new Vector2(0, 0);
}
}
}
Alternatively you can linecast if that makes more sense:
Vector3 startPoint = transform.position;
// get difference, ignore Z value
Vector3 diff = (Vector2)(Camera.main.ScreenToWorldPoint(Input.mousePosition) - startPoint);
Vector3 endPoint = startPoint + (diff.normalized * maxBlinkDistance);
RaycastHit2D blinkHit = Physics2D.Linecast(startPoint, endPoint);
if (blinkHit.collider == null)
{
transform.position = endPoint;
}
else
{
transform.position = blinkHit.point;
}