Search Unity

Can Use Same Script?

Discussion in 'Scripting' started by Impervion, Oct 11, 2015.

  1. Impervion

    Impervion

    Joined:
    Oct 1, 2015
    Posts:
    44
    If I made a script for "teleporting" a player from point A to point B. Can the same script be attached to multiple game objects with different point A and B variables? Or would I have to make a new one for each? Thanks.
     
  2. Ian094

    Ian094

    Joined:
    Jun 20, 2013
    Posts:
    1,548
    The same script can be used. Simply assign different point A & B vars.
     
    Kiwasi likes this.
  3. Impervion

    Impervion

    Joined:
    Oct 1, 2015
    Posts:
    44
    Thanks!
     
  4. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    This. It's typically easy to do this by making the variables public so they can be set by other scripts. Or you can use [SerialiseField] to expose them in the inspector.
     
  5. Impervion

    Impervion

    Joined:
    Oct 1, 2015
    Posts:
    44
    I did something like this :
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Teleport : MonoBehaviour {
    5.  
    6.     GameObject endPos;
    7.     GameObject endPos2;
    8.     public Vector3 endPoss;
    9.     public Vector3 endPoss2;
    10.     // Use this for initialization
    11.     void Start () {
    12.         endPos = GameObject.Find ("Tele2");
    13.         endPoss = endPos.transform.position;
    14.         endPos2 = GameObject.Find ("Tele1");
    15.         endPoss2 = endPos2.transform.position;
    16.     }
    17.  
    18.     // Update is called once per frame
    19.     void Update () {
    20.  
    21.     }
    22. }
    23.  
    Then when Player collides, I access the variables accordingly.
    It seems to work, hope this isn't a bad way of doing it, new to programming.
     
  6. manpower13

    manpower13

    Joined:
    Dec 22, 2013
    Posts:
    140
    Hey there,

    I think you should try something else. It looks the same but works better I think:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class Teleport : MonoBehaviour {
    4.    Public  Transform endPos;
    5.     Public Transform endPos2;
    6.     // Use this for initialization
    7.     void Start () {
    8. If(!endPos)
    9. {
    10. Debug.LogError("Assign a start Transform to the teleport object.");
    11. }
    12. if(!endPos2)
    13. {
    14. Debug.LogError("Assign a end Transform to the teleport object.");
    15. }
    16.     }
    17.  
    Simply put this script on your object. Then assign a transform of your start teleport object in the endPos (in the inspector) and assign a transform of your end teleport object in the endPos2 (in the inspector).
    I do not know how you use this object, but you might add something like this:

    Code (CSharp):
    1. Public Vector3 GetEndTeleport()
    2. {
    3.        Return Endpos2.Position;
    4. }
    To get the end position you simply call this function and it will return the end position.
    I did not completely understand why you would need to have the start position too, because I guess that would be just the transform of the object the script is attached too?
    Hope you understand it, if you need some more help I will happily provide some more help.

    ~Floris Weers
     
  7. Impervion

    Impervion

    Joined:
    Oct 1, 2015
    Posts:
    44
    Hello, this is how I set it up, but soon realized it's a bad way of doing it, since I would have to make a "if statement" every time I wanted to check - what object was collided with and know the variable assigned to it.

    In PlayerMove Script :
    Code (CSharp):
    1. void OnTriggerEnter2D(Collider2D coll){
    2.         if (this.GetComponent<BoxCollider2D>().IsTouching(coll)   &&   coll.tag == "Teleport" && coll.gameObject.name== "Tele1") {
    3.             isMoving = false;
    4.             transform.position = new Vector3(coll.GetComponent<Teleport>().endPoss.x,coll.GetComponent<Teleport>().endPoss.y-0.32f,coll.GetComponent<Teleport>().endPoss.z);
    5.          
    6.         }
    7.         if (this.GetComponent<BoxCollider2D>().IsTouching(coll)   &&   coll.tag == "Teleport" && coll.gameObject.name== "Tele2") {
    8.             isMoving = false;
    9.             transform.position = new Vector3(coll.GetComponent<Teleport>().endPoss2.x,coll.GetComponent<Teleport>().endPoss2.y-0.32f,coll.GetComponent<Teleport>().endPoss2.z);
    10.          
    11.         }
    12.  
    13.     }

    Teleport Script :
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Teleport : MonoBehaviour {
    5.  
    6.     GameObject endPos;
    7.     GameObject endPos2;
    8.     public Vector3 endPoss;
    9.     public Vector3 endPoss2;
    10.     // Use this for initialization
    11.     void Start () {
    12.         endPos = GameObject.Find ("Tele2");
    13.         endPoss = endPos.transform.position;
    14.         endPos2 = GameObject.Find ("Tele1");
    15.         endPoss2 = endPos2.transform.position;
    16.     }
    17.  
    18.     // Update is called once per frame
    19.     void Update () {
    20.  
    21.     }
    22. }
    23.  

    I will try and use what you guys have mentioned. My thought was to cut out the " && coll.gameObject.name== "Tele1")", still have the "coll.tag == "Teleport"", and somehow after the collision, get what "object" I collided with, and then use that to check a Switch Statement possibly in Teleport Script?

    Ex - Did you collide with a Teleport, if so get the objects name, check in Teleport according to objects name the assigned value, then teleport. Unless this is what is being mentioned above.

    Also - I see a lot of people mentioning assigning values in the Inspector when making a variable public, is this the best way to do things? or how I was trying to assign things by finding the object via code a good idea/viable?

    Thanks again!
     
  8. manpower13

    manpower13

    Joined:
    Dec 22, 2013
    Posts:
    140
    Well, assigning variable with the inspector is very fast and nice.
    Searching for tags is not so fast and ,in my opinion, not very good. If you want to make multiple teleporters you need multiple tags. Simply assigning the variables in the inspector is faster to manage.
     
  9. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    There's so much to improve on those scripts!
    Let's start with PlayerMove:

    1.
    You're in a collision event handler. Don't you already know that it's touching?

    2.
    Comparing the object name is a surefire way to ensure that you will never be able to re-use this script anywhere else, and is also redundant.

    This is a case where using a tag is the wrong way to go, as well. What if you accidentally tag an object as Teleport but don't add the Teleport script? Or what if you do the inverse? The first case will cause NullReferenceExceptions; the second will cause it to fail silently.

    It's far better to simply check to see if the Teleport component is attached! And since we know we're going to be using values from the Teleport component later, we also want to store this reference.
    Code (csharp):
    1.  
    2. void OnTriggerEnter2D(Collider2D coll){
    3.        Teleport colliderTeleport = coll.GetComponent<Teleport>();
    4.         if (colliderTeleport != null){
    3.
    Oh god, all the GetComponent calls! You should be aware that GetComponent is a pretty slow function. If you ever plan to use a particular component more than once (especially more than once on the same frame), you always want to cache the reference and use it, rather than calling it 3 times in one line.

    4.
    Why is this there? Why not just change the value of endPoss? And if it has particular meaning (such as, this is how you compensate for the location of the character's feet), this value should be stored somewhere (e.g. as a public characterHeightOffset member variable).

    Now Teleport:
    As the other comments have mentioned, you should make those GameObject member variables public - this will allow you to drag references into the Teleport's inspector view, and that is the key to making this script reusable. Better yet, you can make the variables Transforms. Better yet, you only need one - since you're not hard-coding any of the object names, all that needs to be done is to drag the object for the target into the single slot in the inspector.

    And you don't need to get the position in Start, either - just use the position directly when you need it.

    This is all that needs to be in the body of your Teleport script:
    Code (csharp):
    1. public Transform endPoss;
    Yes, that's all it needs. No functions, no name-checking, no nothing. The PlayerMove script is doing all the work - all it needs is to know what position the teleporter is sending it to. And it'd look like this:
    Code (csharp):
    1. transform.position = colliderTeleport.endPoss.position + new Vector3(0f, characterHeightOffset, 0f);

    ~~~~

    If you do these things, you will drastically reduce the size of your code, improve is reliability, speed it up by a factor of about 5, and best of all, make it 100% reusable.

    Extra Credit:
    There's one more improvement you could make to this, and that would be to move the teleportation function to the Teleport script instead of the PlayerMove script. It makes more sense there, and if you eventually want to teleport things other than the player, it'll be a lot easier to update it. I'll leave this as an exercise for the reader though. ;)
     
  10. Impervion

    Impervion

    Joined:
    Oct 1, 2015
    Posts:
    44
    Wow, so much info. As mentioned before I am new, so functions was something I was currently looking into. The reason for :

    void OnTriggerEnter2D(Collider2D coll){
    if (this.GetComponent<BoxCollider2D>().IsTouching(coll)

    Is that my player has 8 Child colliders, this was to try and fix my previous movement problems, and it seemed to work. So that line was to try and make sure it was the Players collider itself that collided?

    Here is the video -


    PlayerMove Script :
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlayerMove : MonoBehaviour {
    5.     public Vector3 East;
    6.     public Vector3 West;
    7.     public Vector3 North;
    8.     public Vector3 South;
    9.     public Vector3 SouthEast;
    10.     public Vector3 SouthWest;
    11.     public Vector3 NorthEast;
    12.     public Vector3 NorthWest;
    13.     public Vector3 PlayerPos;
    14.  
    15.     public GameObject EastObj;
    16.     public GameObject WestObj;
    17.     public GameObject NorthObj;
    18.     public GameObject SouthObj;
    19.     public GameObject NorthEastObj;
    20.     public GameObject NorthWestObj;
    21.     public GameObject SouthEastObj;
    22.     public GameObject SouthWestObj;
    23.  
    24.  
    25.     public bool canWest;
    26.     public bool canNorth;
    27.     public bool canEast;
    28.     public bool canSouth;
    29.  
    30.  
    31.  
    32.  
    33.     float speed = 3.0f;
    34.  
    35.     public Vector3 startPos;
    36.     public Vector3 endPos;
    37.     float increment;
    38.     public bool isMoving;
    39.  
    40.  
    41.  
    42.     // Use this for initialization
    43.     void Start () {
    44.         EastObj=GameObject.Find("ColEast");
    45.         WestObj=GameObject.Find("ColWest");
    46.         NorthObj=GameObject.Find("ColNorth");
    47.         SouthObj=GameObject.Find("ColSouth");
    48.         NorthEastObj =GameObject.Find("ColNorthEast");
    49.         NorthWestObj =GameObject.Find("ColNorthWest");
    50.         SouthWestObj =GameObject.Find("ColSouthWest");
    51.         SouthEastObj =GameObject.Find("ColSouthEast");
    52.  
    53.         startPos = transform.position;
    54.         isMoving = false;
    55.     }
    56.    
    57.     // Update is called once per frame
    58.     void Update () {
    59.  
    60.         if (increment <= 1 ) {
    61.             increment += speed / 100;
    62.         } else {
    63.             isMoving = false;
    64.             PlayerPos = transform.position;
    65.         }
    66.  
    67.  
    68.         if (isMoving) {
    69.             transform.position = Vector3.Lerp (startPos,endPos,increment);
    70.  
    71.         }
    72.  
    73.  
    74.         if (Input.GetKey (KeyCode.D) && isMoving == false && canEast==true) {
    75.  
    76.             isMoving = true;
    77.             increment = 0;
    78.             startPos = transform.position;
    79.             endPos = new Vector3 (East.x,East.y,East.z);
    80.    
    81.  
    82.         }
    83.         if (Input.GetKey (KeyCode.W)&& isMoving == false && canNorth==true) {
    84.  
    85.             isMoving = true;
    86.             increment = 0;
    87.             startPos = transform.position;
    88.             endPos = new Vector3 (North.x,North.y,North.z);
    89.  
    90.            
    91.         }
    92.         if (Input.GetKey (KeyCode.S)&& isMoving == false && canSouth==true) {
    93.  
    94.             isMoving = true;
    95.             increment = 0;
    96.             startPos = transform.position;
    97.             endPos = new Vector3 (South.x,South.y,South.z);
    98.  
    99.  
    100.         }
    101.         if (Input.GetKey (KeyCode.A)&&isMoving == false && canWest==true) {
    102.  
    103.             isMoving = true;
    104.             increment = 0;
    105.             startPos = transform.position;
    106.             endPos = new Vector3 (West.x,West.y,West.z);
    107.  
    108.            
    109.         }
    110.     }
    111.  
    112.  
    113.     void OnTriggerStay2D(Collider2D col){
    114.  
    115.  
    116.             if (EastObj.GetComponent<BoxCollider2D> ().IsTouching (col) && col.tag == "Empty") {
    117.        
    118.             East = col.transform.position;
    119.             canEast = true;
    120.  
    121.         } else if (EastObj.GetComponent<BoxCollider2D> ().IsTouching (col) && col.tag == "Occupied") {
    122.             East = transform.position;
    123.             canEast = false;
    124.         }
    125.        
    126.  
    127.             if (WestObj.GetComponent<BoxCollider2D> ().IsTouching (col) && col.tag == "Empty") {
    128.             West = col.transform.position;
    129.             canWest = true;
    130.        
    131.         } else if (WestObj.GetComponent<BoxCollider2D> ().IsTouching (col) && col.tag == "Occupied") {
    132.             West = transform.position;
    133.             canWest = false;
    134.         }
    135.  
    136.        
    137.             if (NorthObj.GetComponent<BoxCollider2D> ().IsTouching (col) && col.tag == "Empty") {
    138.             North = col.transform.position;
    139.             canNorth = true;
    140.            
    141.         } else if (NorthObj.GetComponent<BoxCollider2D> ().IsTouching (col) && col.tag == "Occupied") {
    142.             North = transform.position;
    143.             canNorth = false;
    144.         }
    145.             if (SouthObj.GetComponent<BoxCollider2D> ().IsTouching (col) && col.tag == "Empty") {
    146.             South = col.transform.position;
    147.             canSouth = true;
    148.            
    149.         } else if (SouthObj.GetComponent<BoxCollider2D> ().IsTouching (col) && col.tag == "Occupied") {
    150.             South = transform.position;
    151.             canSouth = false;
    152.         }
    153.  
    154.  
    155.  
    156.  
    157.  
    158.  
    159.             if (NorthEastObj.GetComponent<BoxCollider2D> ().IsTouching (col)) {
    160.                 NorthEast = col.transform.position;
    161.            
    162.             }
    163.             if (NorthWestObj.GetComponent<BoxCollider2D> ().IsTouching (col)) {
    164.                 NorthWest = col.transform.position;
    165.            
    166.             }
    167.             if (SouthEastObj.GetComponent<BoxCollider2D> ().IsTouching (col)) {
    168.                 SouthEast = col.transform.position;
    169.            
    170.             }
    171.             if (SouthWestObj.GetComponent<BoxCollider2D> ().IsTouching (col)) {
    172.                 SouthWest = col.transform.position;
    173.            
    174.  
    175.        
    176.             }
    177.        
    178.     }
    179.     void OnTriggerEnter2D(Collider2D coll){
    180.         if (this.GetComponent<BoxCollider2D>().IsTouching(coll)   &&   coll.tag == "Teleport" && coll.gameObject.name== "Tele1") {
    181.             isMoving = false;
    182.             transform.position = new Vector3(coll.GetComponent<Teleport>().endPoss.x,coll.GetComponent<Teleport>().endPoss.y-0.32f,coll.GetComponent<Teleport>().endPoss.z);
    183.            
    184.         }
    185.         if (this.GetComponent<BoxCollider2D>().IsTouching(coll)   &&   coll.tag == "Teleport" && coll.gameObject.name== "Tele2") {
    186.             isMoving = false;
    187.             transform.position = new Vector3(coll.GetComponent<Teleport>().endPoss2.x,coll.GetComponent<Teleport>().endPoss2.y-0.32f,coll.GetComponent<Teleport>().endPoss2.z);
    188.            
    189.         }
    190.  
    191.     }
    192.  
    193.  
    194. }
    195.  
    Teleport Script :
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Teleport : MonoBehaviour {
    5.  
    6.     GameObject endPos;
    7.     GameObject endPos2;
    8.     public Vector3 endPoss;
    9.     public Vector3 endPoss2;
    10.     // Use this for initialization
    11.     void Start () {
    12.         endPos = GameObject.Find ("Tele2");
    13.         endPoss = endPos.transform.position;
    14.         endPos2 = GameObject.Find ("Tele1");
    15.         endPoss2 = endPos2.transform.position;
    16.     }
    17.    
    18.     // Update is called once per frame
    19.     void Update () {
    20.    
    21.     }
    22. }
    23.  

    Right now I'm just blindly putting together code how I "think" it would work, I know most, if not all is bad quality. My knowledge is basic and maybe I should try and read up on more tutorials/Unity made tutorials. Since I know you guys have been trying to help, but half the stuff you say I do not know how to use. Sorry if you feel like it was a waste of time, I will definitely try and figure out the specifics of what you all have said, Thanks.
     
  11. Impervion

    Impervion

    Joined:
    Oct 1, 2015
    Posts:
    44
    I made a new project to test this teleporting and I think this is what you meant?:

    Teleport Script :

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Teleport : MonoBehaviour {
    5.     public Transform endPos;
    6.  
    7. }
    8.  
    Player Script :
    Code (CSharp):
    1. void OnTriggerEnter2D(Collider2D col){
    2.  
    3.         if (col.tag == "Teleport") {
    4.             Transform end;
    5.             end = col.GetComponent<Teleport>().endPos;
    6.             transform.position = end.position-new Vector3(0,pSize,0);
    7.         }
    8.  
    9.     }
    I have 2 objects called Teleport1 and Teleport2.
    Applied the script to both and assigned Teleport2 to Teleport1, and Teleport1 to Teleport2.

    It does work... but is it right?