- Home /
How do I check the distance between multiples objects in an array from the player?
Well im trying to make some teleport between doors and I would like to know how to check the distance between the doors and the player so I just press a button when is close enough and teleport to another door
Here is the script
public Transform teleportTarget;
private GameObject[] teleportTarget_;
private GameObject player;
public float distance;
private void Start()
{
player = GameObject.FindGameObjectWithTag("Player");
teleportTarget_ = GameObject.FindGameObjectsWithTag("Doors");
}
void Update()
{
distance = Vector3.Distance(player.transform.position, teleportTarget_.transform.position);
if (distance < 0.6823619 && Input.GetKeyDown("e"))
{
player.transform.position = teleportTarget.transform.position;
}
}
I'm having problems with these things because the game objects are arrays
private GameObject[] teleportTarget_;
distance = Vector3.Distance(player.transform.position, teleportTarget_.transform.position);
Answer by MrRightclick · Apr 10, 2019 at 09:39 AM
Instead of constant update checks for distance (which can get calculation heavy), you could add 2D trigger colliders to the doors and have a check for when the player enters/leaves a collider area, saving the last door to a variable we access when pressing E.
You could add this functionality to a script found on the player object, with OnTriggerEnter2D and OnTriggerExit2D (or OnTriggerStay2D if you so wish) looking for door colliders entering the player's collision area. Something like this:
public GameObject currentDoor;
// Check for collisions
void OnTriggerEnter2D (Collider2D other)
{
// Check if this collider gameobject is a door using the Doors tag
if (other.tag.Equals("Doors"))
{
// This is a door, make this our current door
currentDoor = other.gameObject;
}
}
// Check for collision exits
void OnTriggerExit2D(Collider2D other)
{
// Check if the gameobject we're exiting a collision with is the current door
if (other.tag.Equals("Doors") && other.gameObject.Equals(currentDoor))
{
currentDoor = null;
}
}
void Update ()
{
if (Input.GetKeyDown("e"))
{
// If we have a door saved, teleport to it
if (currentDoor) {
// NOTE: You can still have checks for distance here if you wish!
player.transform.position = currentDoor.transform.position;
}
}
}
You could also do the collision checking through a script added to the Door object. You would then need to check if the collider entering the Door's collision is the player, get the player's script using GetComponent() and save the door variable, something like this:
void OnTriggerEnter2D (Collider2D other)
{
if (other.tag.Equals("Player"))
{
other.gameObject.GetComponent < *PlayerScriptName *> ().currentDoor = gameObject;
}
}
Answer by Hellium · Apr 10, 2019 at 08:10 AM
public Transform teleportTarget;
private GameObject[] doors;
private GameObject player;
public float teleportTreshold = 0.6823619f ;
private void Start()
{
player = GameObject.FindGameObjectWithTag("Player");
doors = GameObject.FindGameObjectsWithTag("Doors");
}
void Update()
{
if( Input.GetKeyDown("e") )
{
for( int doorIndex = 0 ; doorIndex < doors.Length ; ++doorIndex )
{
float sqrDistance = (player.transform.position - doors[doorIndex].transform.position).sqrMagnitude;
if ( sqrDistance < teleportTreshold * teleportTreshold )
{
player.transform.position = teleportTarget.transform.position;
break;
}
}
}
}
Answer by superjustin5000 · Apr 10, 2019 at 02:55 AM
Yea you'd have to throw that into a loop over all objects of the array.
Im not sure if I understood. I'm a really beginner. Can you just be more clear?
Yes sorry, @Hellium gave you what I was talking about. Although @$$anonymous$$rRightclick 's answer is solid.
Answer by MATCAVERNA · Apr 14, 2019 at 09:11 PM
Well I've tried it and it is recognizing the collision and the "E" button but I'm just teleporting to the same door I am as you can see on this video I've recorded
and here is my player script
public float maxSpeed;
public float jumpForce;
public Transform groundChecker;
private bool grounded = true;
private bool jumping;
private Rigidbody2D rb2d;
private Animator anim;
private SpriteRenderer sprite;
// public Transform teleportTarget;
public GameObject currentDoor;
private GameObject player;
void Awake ()
{
rb2d = GetComponent<Rigidbody2D> ();
sprite = GetComponent<SpriteRenderer> ();
anim = GetComponent<Animator> ();
}
// Use this for initialization
void Start () {
player = GameObject.FindGameObjectWithTag("Player");
}
// Update is called once per frame
void Update () {
grounded = Physics2D.OverlapCircle(groundChecker.position, 0.02f);
if (Input.GetKeyDown(KeyCode.Space) && grounded)
{
jumping = true;
}
if (Input.GetKeyDown("e"))
{
// If we have a door saved, teleport to it
if (currentDoor)
{
// NOTE: You can still have checks for distance here if you wish!
player.transform.position = currentDoor.transform.position;
}
}
}
void OnCollisionEnter2D(Collision2D coll)
{
if (coll.gameObject.tag == "ground")
{
grounded = true;
}
// Check if this collider gameobject is a door using the Doors tag
if (coll.gameObject.tag == ("Doors"))
{
// This is a door, make this our current door
currentDoor = coll.gameObject;
}
}
void OnTriggerExit2D(Collider2D other)
{
// Check if the gameobject we're exiting a collision with is the current door
if (other.tag.Equals("Doors") && other.gameObject.Equals(currentDoor))
{
currentDoor = null;
}
}
void FixedUpdate(){
float move = Input.GetAxis("Horizontal");
anim.SetFloat("Speed", Mathf.Abs(move));
rb2d.velocity = new Vector2(move * maxSpeed, rb2d.velocity.y);
if((move> 0f && sprite.flipX) || (move < 0f && !sprite.flipX))
{
Flip();
}
if (jumping)
{
rb2d.AddForce(new Vector2(1f, jumpForce));
jumping = false;
}
anim.SetBool("jumpFall", rb2d.velocity.y != 0.1f && !grounded);
}
void Flip()
{
sprite.flipX = !sprite.flipX;
}
}
Ah, yeah, because there's a logic error in my example. You're setting the door as the current door and then calling teleport to go to the position of the current door, and not a new door "connected" to this door. You need to set a reference to a teleport target.
You need a script attached to each door object, then when pressing E, do something like
// Set this for each door in the inspector
public Transform teleportTarget;
$$anonymous$$oreover, you need to get this new transform component from the door when player presses E:
// Do this in your player script when your player presses E
if (currentDoor)
{
transform.position = currentDoor.GetComponent < *YourScriptNameHere *> ().teleportTarget.position;
}
that kinda worked but when I step in front of the door, it doesn't recognizes as my current door as you can see here
It only work when I put manually a Door game object in the player game object, in that way its only teleporting to one door only
I'VE FINALLY DID THIS, FINALLY WOR$$anonymous$$ED THAN$$anonymous$$S EVERYBODY FOR YOUR HELP AND YOUR TI$$anonymous$$E
I'VE $$anonymous$$ADE A SCRIPT FOR THE DOOR
public class Doors : $$anonymous$$onoBehaviour
{
public Transform teleportTarget;
public GameObject currentDoor;
public GameObject player;
private void Start()
{
}
// Check for collisions
void OnTriggerEnter2D(Collider2D other)
{
// Check if this collider gameobject is a door using the Doors tag
if (other.tag.Equals("Player"))
{
// This is a door, make this our current door
currentDoor = other.gameObject;
}
}
void Update()
{
if (currentDoor)
{
if (Input.Get$$anonymous$$eyDown("e"))
{
player.transform.localPosition = teleportTarget.transform.position;
}
}
}
void OnTriggerExit2D(Collider2D other)
{
// Check if the gameobject we're exiting a collision with is the current door
if (other.tag.Equals("Player") && other.gameObject.Equals(currentDoor))
{
currentDoor = null;
}
}
}
Your answer
Follow this Question
Related Questions
Instantiate from array into array? 2 Answers
Conceptual Question on Creating Arrays at Runtime 1 Answer
Transform Checking on all Array Objects (JS) 3 Answers