Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Jump Teleporting?

Discussion in 'Scripting' started by Studio_Akiba, Mar 30, 2015.

  1. Studio_Akiba

    Studio_Akiba

    Joined:
    Mar 3, 2014
    Posts:
    1,421
    I am looking to create a script that would allow me to "teleport" to the nearest collider along the reticle's path (center of the screen), with a limit of 200 meters.
    I am aware of the basics of "teleporting" a player, but have no idea on how to do this with a path and limit its effects to a distance, I also will have to make sure the player does not end up inside the collider.

    I was wondering if anyone else had attempted something like this.
     
  2. Avalion

    Avalion

    Joined:
    May 2, 2012
    Posts:
    34
    Hello !

    This is quite simple but there is multiple ways to do this.

    First of all, we need to determine the position where the player will be teleported, if he can. For this one, you should use Raycasting from the Physics class. This class have some parameters that allows you to get rid of many of your questions :) In your case, with your pointer at the screen center, this code will look like this (C#) :
    Code (CSharp):
    1. // Get a ray pointing from your main camera at the center of the screen
    2. Ray worldRay = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2f, Screen.height / 2f, Camera.main.farClipPlane));
    3. RaycastHit hit;
    4. // Cast the ray to 200m maxi
    5. if (Physics.Raycast(worldRay, out hit, 200))
    6.     targetPosition = hit.point;
    7. else
    8.     // There's no collider before 200m
    Physics.Raycast can have one more argument that specified the layermask. And so, on which items the ray should collide or pass through, as long as they are or not in these Unity layers. This is a bit complicated to use for a new user ^^

    Then, you can calculate the real position for your player from targetPosition to be teleported at the right place and not into the collider, substracting the Camera.main.transform.forward * [Player_width] for example.
    Or, you could use the CharacterController class of Unity and move your Player considering colliders with the Move function

    This is the easiest way I know to do this with Unity functions :)

    If you want some cool transitions or movements, you will have to implements some inertia to your Player movements

    Sorry for my english, i'm french. Hope I helped you.

    Avalion
     
  3. Studio_Akiba

    Studio_Akiba

    Joined:
    Mar 3, 2014
    Posts:
    1,421
    So far, I have this.
    I can get the location in the form of a Vector3, but am having a little trouble with getting the player.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Teleport : MonoBehaviour {
    5.  
    6.     public int Magica = 100;
    7.     public KeyCode useKey = KeyCode.BackQuote;
    8.     public Vector3 targetPosition;
    9.     public GameObject Player = this;
    10.    
    11.     void Update ()
    12.     {
    13.         Ray worldRay = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2f, Screen.height / 2f, Camera.main.farClipPlane));
    14.         RaycastHit hit;
    15.         //Debug.DrawLine (worldRay.origin, targetPosition, Color.green);
    16.        
    17.             if (Physics.Raycast (worldRay, out hit, 200))
    18.             {
    19.                 targetPosition = hit.point;
    20.             }
    21.  
    22.             else
    23.             {
    24.  
    25.             }
    26.  
    27.             if (Input.GetKeyDown (useKey))
    28.             {
    29.                 Player.position = targetPosition;
    30.             }
    31.         }
    32.     }
     
    Last edited: Mar 30, 2015
  4. Studio_Akiba

    Studio_Akiba

    Joined:
    Mar 3, 2014
    Posts:
    1,421
    Never mind, fixed it, stupid syntax mistake.

    Now I just need to work out how to minus the player radius/size from the equation, I know how to minus it, just not how to get it.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Teleport : MonoBehaviour {
    5.  
    6.     public int Magica = 100;
    7.     public KeyCode useKey = KeyCode.BackQuote;
    8.     public Vector3 targetPosition;
    9.    
    10.     void Update ()
    11.     {
    12.         Ray worldRay = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2f, Screen.height / 2f, Camera.main.farClipPlane));
    13.         RaycastHit hit;
    14.         //Debug.DrawLine (worldRay.origin, targetPosition, Color.green);
    15.        
    16.             if (Physics.Raycast (worldRay, out hit, 200))
    17.             {
    18.                 targetPosition = hit.point;
    19.             }
    20.  
    21.             else
    22.             {
    23.  
    24.             }
    25.  
    26.             if (Input.GetKeyDown (useKey))
    27.             {
    28.                 this.transform.position = targetPosition;
    29.             }
    30.         }
    31.     }
     
  5. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
  6. Avalion

    Avalion

    Joined:
    May 2, 2012
    Posts:
    34
    Little tip : targetPosition is a calculated variable :) it should be private ! it's cleaner :)

    Then, on your script, the ray cast should be in the if(KeyCode) statement. making raycast every frame will break some FPS. Doing it into the if statement, the ray will be cast only when the key is pressed.
    The Player position have to be setted only if the raycast actually hit something.
    Finally, to gets your Player radius, you can use "this.collider.bounds.center"
    Be carfull to optimize your code. You should merge all your movement gestion scripts into one class and test if elements are not null before using it (as this.collider).

    Good luck :)
     
  7. Studio_Akiba

    Studio_Akiba

    Joined:
    Mar 3, 2014
    Posts:
    1,421
    @Avalion This was just set to private to test that it was in fact getting the variable.
    I am now discounting the collider, but it is not changing a thing at all, doesn't seem to have changed anything.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4.  
    5. public class Teleport : MonoBehaviour {
    6.  
    7.     public int Magica = 100;
    8.     //public Text MagicaText;
    9.     public KeyCode useKey = KeyCode.BackQuote;
    10.     public Vector3 targetPosition;
    11.    
    12.     void Update ()
    13.     {
    14.  
    15.         //MagicaText.text = "" + Magica;
    16.  
    17.         if (Input.GetKeyDown (useKey))
    18.         {
    19.             //if (Magica =>10)
    20.             //{
    21.             Ray worldRay = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2f, Screen.height / 2f, Camera.main.farClipPlane));
    22.             RaycastHit hit;
    23.             //Debug.DrawLine (worldRay.origin, targetPosition, Color.green);
    24.  
    25.             if (Physics.Raycast (worldRay, out hit, 200))
    26.             {
    27.                 targetPosition = hit.point;
    28.             }
    29.            
    30.             this.transform.position = targetPosition - this.GetComponent<Collider>().bounds.center;
    31.                 Magica -= 10;
    32.             //}
    33.             }
    34.         }
    35.     }
     
  8. Avalion

    Avalion

    Joined:
    May 2, 2012
    Posts:
    34
    Sorry I was thinking about something else ! you don't have to use center but size / 2f. Be warned that size is a Vector3 and you only wants to move the Player on X & Z axis.
     
  9. Studio_Akiba

    Studio_Akiba

    Joined:
    Mar 3, 2014
    Posts:
    1,421
    This means I would not be able to use this line, or is there another way to do it, I have never had to split a Vector3 into pieces before, and floats cannot be used on Bounds.
     
  10. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    Actually just the extents Bounds.extents
     
  11. Avalion

    Avalion

    Joined:
    May 2, 2012
    Posts:
    34
    Thanks passerbycmc for this precision. I'n not actually using bounds every day :)

    This works for me ;)

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Teleport : MonoBehaviour {
    5.  
    6.     public int Magica = 100;
    7.     //public Text MagicaText;
    8.     public KeyCode useKey = KeyCode.BackQuote;
    9.     public Vector3 targetPosition;
    10.  
    11.     void Update() {
    12.  
    13.         //MagicaText.text = "" + Magica;
    14.  
    15.         if (Input.GetKeyDown(useKey)) {
    16.             //if (Magica =>10)
    17.             //{
    18.             Ray worldRay = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2f, Screen.height / 2f, Camera.main.farClipPlane));
    19.             RaycastHit hit;
    20.             //Debug.DrawLine (worldRay.origin, targetPosition, Color.green);
    21.  
    22.             if (Physics.Raycast(worldRay, out hit, 200)) {
    23.                 Vector3 playerSize = this.collider.bounds.extents;
    24.                 playerSize.y = 0;
    25.  
    26.                 // Substract from the camera angle a distance equal to the extent magnitude (It's possible to add an offset here)
    27.                 targetPosition = hit.point - playerSize.magnitude * Camera.main.transform.forward;
    28.             }
    29.  
    30.             this.transform.position = targetPosition;
    31.             Magica -= 10;
    32.         }
    33.     }
    34. }
    But this simple code is not really enough when you move your mainCamera with this...

    the simple way to look at the ground will result into a Y position too low (alias too much into the ground) You have to think about it or use the CharacterController.
     
  12. Studio_Akiba

    Studio_Akiba

    Joined:
    Mar 3, 2014
    Posts:
    1,421
    Thank you, this works for me too.

    What exactly do you mean by: