Search Unity

Can't use script from GameObject to Prefab

Discussion in 'Scripting' started by Username0101, Oct 6, 2015.

  1. Username0101

    Username0101

    Joined:
    Sep 3, 2015
    Posts:
    18
    I'll try to explain it very strictly, it may take time to comprehend.

    (GameObject)AbsoluteObject instantiates (Prefab)Asteroids from time to time.
    (GameObject)AbsoluteObject has script attached (Script)HealthBar which takes the given percentage ((int)100 from start) and then adjusts visual healthbar to match.
    (Prefab)Asteroids has two scripts attached, (Script)asteroidMove and (Script)asteroidCollision.
    (Script)asteroidMove, makes sure that asteroid is moving, and works entirely correctly.

    Here's the problem and toughest part:

    (Script)asteroidCollision should detect collision between (Instantiated GameObject)Asteroid and (GameObject)Player... ... done.
    (Script)asteroidCollision should -=5 from (Script)HealthBar that is attached to (GameObject)AbsoluteObject... ... problem, (GameObject)AbsoluteObject doesn't let it be dropped into the slot of (Script)HealthBar.

    I don't know where to begin, I could post here my entire project, but I don't want to be like "here minions! fix my stupid bugs!". But I'd like to get it fixed, so ask any questions necessary and I'll provide you with data, code, screenshots.

    For a good start:
    (Script)asteroidCollision
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class asteroidCollision : MonoBehaviour {
    5.     public HealthBar HPBar;
    6.  
    7.     void OnTriggerEnter(Collider other) {
    8.         if (other.gameObject.name == "Player") {
    9.             HPBar.HPAmount -= 5;
    10.         }
    11.     }
    12. }
    13.  
    Screenshots of inspector view of (GameObject)AbsoluteObject and (Prefab)Asteroids.
    absolutos.png asteroids.png

    Help.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    You want to drop the object that HealthBar is attached to into that slot, not the actual script. The script is just the code, not anything that can be operated with.

    Also, are you sure you don't have any compiler errors? In the console log it is possible to inadvertently click a red knob in the upper right that is NOT the "close window" red knob, and thereby hide your errors.
     
  3. Username0101

    Username0101

    Joined:
    Sep 3, 2015
    Posts:
    18
    You want to drop the object that HealthBar is attached to into that slot, not the actual script.
    Yes, indeed. I know that. But (GameObject)AbsoluteObject containing (Script)HealthBar doesn't allow to get dropped inside the slot.

    Also, are you sure you don't have any compiler errors? In the console log it is possible to inadvertently click a red knob in the upper right that is NOT the "close window" red knob, and thereby hide your error.
    I know this as well. 0 informations, 0 warnings, 0 errors.
     
  4. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148

    Code (csharp):
    1.  
    2. //public HealthBar HPBar; // don't need this
    3.  
    4. ...
    5.  
    6. other.GetComponent<HPBar>().HPAmount -= 5;
    7.  
    (not the greatest way of doing health management, but it'll work)

    you can't populate a prefab with information from the scene. The prefab doesn't exist in the scene so how is it supposed to relate to it?. You need to get the HP bar from the thing you collided with so you can get the instance of it within the scene so the asteroid instance within the scene can do something to it.


    EDIT;
    actually, just re-read the OP... I had assumed AbsoluteObject was the player, but I don't think it is. I suspect its actually performing the GameManager script role (why its not called something descriptive is up for question :p)

    In which case the HPbar isn't attached to the player object in the collision... you'll need to Find the AbsoluteObject and get a reference to it's HPBar in a Start function so the collision code has a reference to the HPBar in the scene. (same logic as originally, just a different arrangement of objects :p)


    Code (csharp):
    1.  
    2. public HealthBar HPBar; // need this :P
    3.  
    4. void Start()
    5. {
    6. HPBar = GameObject.Find("AbsoluteObject").GetComponent<HealthBar>();
    7. }
    8.  
     
    Last edited: Oct 6, 2015
    Username0101 likes this.
  5. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    Set the HPBar of the asteroid when it's instantiated. It sounds like you have the reference to HPBar set in the prefab in the inspector, but it doesn't maintain the reference at runtime.


    Code (CSharp):
    1. //psuedocode. you get the idea.
    2.  
    3. var asteroidInstance = (GameObject)Instantiate(asteroidPrefab);
    4. var asteroidCollision = asteroidInstance.GetComponent<AsteroidCollision>();
    5.  
    6. asteroidCollision.HPBar = absoluteObject.HPBar;
     
  6. Username0101

    Username0101

    Joined:
    Sep 3, 2015
    Posts:
    18
    other.GetComponent<HealthBar>().HPAmount -= 5;

    Did it, thanks. After I swapped the script.
     
  7. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Everyone here seems to be helping you to make a poorly structured game system functional. It can work, but it's going to make every change you make to your game in the future overly painful. If it's structured correctly, it'll be much easier to bolt new features onto the side of the thing.

    If you don't mind, I'd like to lay out the best way to structure this:

    1) Your HealthBar doesn't store any information. HealthBar contains a reference to the Player script, which has its own health member variable, and it uses that to update the UI. No other script ever needs access to HealthBar, or really ever even needs to know it exists. If your core game objects directly reference your UI elements, odds are good you're going to run into trouble later.

    2) Your asteroid gets a reference to the player in OnTriggerEnter, by using other.GetComponent<Player>(). It subtracts the player's health using that. (Because your HealthBar is watching the player, it will then update.) In the inspector, you never have to assign references in the Asteroid to either the HealthBar or the Player; the asteroid never needs to know that HealthBar exists, and it only gets a reference to the Player when it needs it - in the collision.
     
    LeftyRighty likes this.
  8. Username0101

    Username0101

    Joined:
    Sep 3, 2015
    Posts:
    18
    If you don't mind, I'd like to lay out the best way to structure this:
    You obviously know more than I do when it comes to game development and Unity. I'm full of ears.

    1) Your HealthBar doesn't store any information.

    Wrong. It stores 3 "data's", HP, armor, current percentage. I think it's still information. Without these game is kind of pointless.

    No other script ever needs access to HealthBar, or really ever even needs to know it exists.
    asteroidCollision needs to know about HealthBar and outOfMap needs to know about HealthBar.
    One of them even created the problem. Because it needs to know about HealthBar.

    2) Your asteroid gets a reference to the player in OnTriggerEnter, by using other.GetComponent<Player>(). It subtracts the player's health using that. (Because your HealthBar is watching the player, it will then update.) In the inspector, you never have to assign references in the Asteroid to either the HealthBar or the Player; the asteroid never needs to know that HealthBar exists, and it only gets a reference to the Player when it needs it - in the collision.
    If there was a question, I missed it.
    If there was a hint, I missed it.

    If you have some experience with such systems you could share, please tell me.
     
  9. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    I was describing it as it should be, not as it is.
     
  10. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    He IS sharing his experience with you. He's describing how your system should work, if you'd like it to be less of a pain in the ass to extend and maintain.