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

Need help with Instantiate and prefabs.

Discussion in 'Scripting' started by aMaGGixZ, Jun 8, 2017.

  1. aMaGGixZ

    aMaGGixZ

    Joined:
    Dec 20, 2016
    Posts:
    20
    Hey guys!
    So I've been trying to make a simple AI for a bat.
    - It moves with an animator, going from X to Y.
    - It has a BoxCollider2D set as trigger to make the range of attack. He won't stop making the animation to go on you. It will just shoot at you whenever you enter the trigger.
    - Each (float CD) seconds, if you are inside the trigger, a bullet prefab will be instantiated.

    I have no problems with this part. All works perfectly. But, when I gotta instantiate the bullets, I got some problems. I've made the bullet to destroy itself in 5 seconds, and if it touches the player, the SpriteRenderer will disable (this is because I have a poison script on it, and if I just destroy the item on collision, the script won't apply propperly, but let's don't focus on that). So, here it comes when problems appear.

    To follow the player position and instantiate the bullet prefab going to that position, I've used Vector2 for the bullet position (just where the bat instantiated it), the player position, and subtracted both, just to get the Vector direction. Alright, all cool, but as the bullet is a prefab, I can only add other prefabs as public GameObjects, and I need the Player gameobject (the one which is in the scene) to get it position. I'll link the code of the bullet behaviour. Please, note that it is a Prefab:

    Code (CSharp):
    1. Rigidbody2D rb;
    2.     Vector2 batPos;
    3.     Vector2 pjPos;
    4.     Vector2 target;
    5.  
    6.     public float TimeUntilDestruction = 5.0f;
    7.     public float speed = 3f;
    8.     public GameObject pj;
    9.  
    10.     void Start()
    11.     {
    12.         rb = GetComponent<Rigidbody2D> ();
    13.         batPos = new Vector2 (transform.position.x, transform.position.y);
    14.         pjPos = new Vector2 (pj.gameObject.transform.position.x,pj.gameObject.transform.position.y);
    15.         target = pjPos - batPos;
    16.         target.Normalize ();
    17.         rb.AddForce (target * speed, ForceMode2D.Impulse);
    18.     }
    19.  
    20.     void Update ()
    21.     {
    22.         TimeUntilDestruction -= Time.deltaTime;
    23.         if (TimeUntilDestruction <= 0)
    24.         {
    25.             Destroy (this.gameObject);
    26.         }
    27.     }
    28.    
    If I set the public GameObject as the player prefab, the bullet will go to its position, but not to my player's position. So, what I need is that the prefab has access to my player gameobject position.
    Thanks for helping!
     
  2. Phorsaken

    Phorsaken

    Joined:
    Dec 12, 2013
    Posts:
    27
    You can do this a couple of ways. If this is a single player game you can have a script on the player that is a singleton and just ask it for the player position. If you want it to be more flexible and have multiple players that it can head towards you can have a game controller that keeps a list of player transforms then make a function to access and get the position of the player you want.

    So something like:

    Code (CSharp):
    1. pjPos = PlayerScript.current.GetPostion();
    -Alexander
     
  3. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    That's no problem. You can send the player's gameobject or transform to the bullet after you create it.
    Like, maybe you create it.. and have a method that you can send the position of the player to get the bullet started.

    Answer given while I was entering my response is also possible. :)
     
  4. aMaGGixZ

    aMaGGixZ

    Joined:
    Dec 20, 2016
    Posts:
    20
    But how can I send the position of the player to a prefab? I'm new on this and I don't get what a "singleton" is or how it works. Could you explain me how could I make that method you were talking about? Thanks!
     
  5. aMaGGixZ

    aMaGGixZ

    Joined:
    Dec 20, 2016
    Posts:
    20
    I've been searching about "singleton" and I don't know how to use it and how could I implement it. Would you give me some more information please? I'm new on scripting. Thanks ^^
     
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    A singleton is something that could be used in this situation, but it's not directly the related, so much.

    Well, I wouldn't say send it to the prefab. I'd say that after you instantiated the object (from the prefab), then you'd send the position at that time. Since your code didn't show any updating of the position, it wouldn't need the transform, even..
     
  7. aMaGGixZ

    aMaGGixZ

    Joined:
    Dec 20, 2016
    Posts:
    20
    Yes that my question, how can I send the position to the instantiated object (from the prefab). I need the player position and the bullet position just to give the bullet the vector2, in order to make it move towards the player position.
     
  8. Phorsaken

    Phorsaken

    Joined:
    Dec 12, 2013
    Posts:
    27
    Well if you used my example above and you make a script called PlayerScript that would be attached to your player:

    Code (CSharp):
    1. public static PlayerScript current;
    2.  
    3. // Basic construct of a singleton
    4. private void Awake()
    5. {
    6.   if(current == null)
    7.     current = this;
    8.   else if(current != this)
    9.     Destroy(this);
    10. }
    11.  
    12. public Vector3 GetPosition()
    13. {
    14.   return transform.position;
    15. }
    16.  
    Now if you call this function like I did in my first comment you would get the transforms position of the object you attached the script to. Hope that helps.

    -Alexander
     
  9. aMaGGixZ

    aMaGGixZ

    Joined:
    Dec 20, 2016
    Posts:
    20
    Oh ok, and that script is giving me the position of the player somehow as a global variable, right? Or did I understand it wrong?
     
  10. Phorsaken

    Phorsaken

    Joined:
    Dec 12, 2013
    Posts:
    27
    It gives you global access to that script which in turn has access to the transform it is attached to. Basically the answer is yes.

    -Alexander
     
  11. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    My example would entail simply instantiating the object, then using 'GetComponent<BulletScript>().playerPosition = // position here.
    Just something like that. :)