Instantiated Prefab no Rigidbody2D on Update function
Hey there,
I have the following situation:
I got a GameplayManager script like this:
public class GameplayManager : MonoBehaviour
{
public Transform spawnPoint1;
public Rigidbody2D player;
void Start()
{
Instantiate (player, spawnPoint1.position, spawnPoint1.rotation);
}
....
}
There is a prefab assigned to the "player" variable there is an empty gameobject assigned to the spawnPoint1 variable.
This script-component(GameplayManager) is attached to the camera component.
On my "player" prefab i assigned a new script component "PlayerManager":
public class PlayerManager : MonoBehaviour
{
Rigidbody2D rb2d;
void Start()
{
rb2d = GetComponent<Rigidbody2D> ();
}
void Update()
{
}
public void Jump()
{
rb2d.AddForce (new Vector2 (rb2d.velocity.x, 500f));
}
...
}
Next i added a Button to my canvas and assigned a Event Trigger: Value: "Player" Prefab Select: PlayerManager.Jump()
When i press the button in the game, no force is applied to the rigidbody of the player prefab.
I simply dont know why..any help or advices?
Thansks and Greetings
Answer by incorrect · May 04, 2016 at 02:18 PM
You should understand the difference between a prefab and it's instance. A prefab is just a prototype that exists in a memory but not in a scene. An instance is a copy built from this prototype and placed into the scene.
So if you are calling a method on a prefab you are not calling a method on an actual instance you've created using Instantiate().
To call a method on the instance of the prefab you need to store a reference to this copy an use it like reference.method();
Try saving a reference when you instantiate the prefab in GameplayManager and assign it's method to the button:
[SerializeField]
private UnityEngine.UI.Button button;
void Start()
{
//saving reference to a copy created
GameObject instance = Instantiate (player, spawnPoint1.position, spawnPoint1.rotation) as GameObject;
//getting PlayerManager on this copy
PlayerManager pManager = instance.GetComponent<PlayerManager>();
//if there is a PlayerManager on this copy
if(pManager != null)
//assign instance's method to the button onClick delegate
button.onClick.AddListener(pManager.Jump);
}
thanks this was my mistake, i will still have to deal with some game logics in the future:)
But i still have a question... when i call Jump method, the rigidbody still needs to be created in "Player$$anonymous$$anager" right, and in this case its unassigned... any advices?
Between: Shouldnt you change
button.onClick.AddListener(instance.Jump);
to:
button.onClick.AddListener(p$$anonymous$$anager.Jump);
?
Yes, my bad. button.onClick.AddListener(p$$anonymous$$anager.Jump);
is the right one. I'll edit my answer, thnx.
You don't need to create RigidBody2D if your prefab GameObject has this component. As I understand, you also have Player$$anonymous$$anager component on this prefab.
Your Player$$anonymous$$anager has Start() method that is executed once object is created. This code actually find a reference to the Rigidbody2D and saves it into rb2d variable.
rb2d = GetComponent<Rigidbody2D> ();
So when Jump() is called, you already have a reference to rigidbody.
do i need this line:
button.onClick.AddListener(p$$anonymous$$anager.Jump);
or can i just apply an "event trigger" to the button in the canvas?