I’m trying to add collisions again… So i added basic collisions and logged the value but now i want it to do the real thing. Bascially whenever my player collides with the Enemy i want the player gameobject and enemy prefab to stop moving. I thought use the rigidbody2d constaraints freeze position would be a good idea for this. But, to do that im pretty sure i have to get a reference to my Enemy prefab, when i did this though it gave me an error. Another thing im using gravityScale to just test if its working or not. Also the collisions work this time with the debug.log
Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CollisionController : MonoBehaviour
{
public Rigidbody2D rb2d;
public Enemy EnemyPrefab;
void OnTriggerEnter2D(Collider2D collision)
{
// Use collision paramater to figure out which object I'm colliding with.
if (collision.gameObject.tag == "Enemy")
{
rb2d.gravityScale = 5;
// Enemy rigidbody gravity scale set to 5 here.
}
}
}
Why do you think you need to access the Enemy prefab?
You already know what object instance in your scene you are colliding with (collision.gameObject) so why not just grab the Rigidbody2D from that gameObject and set whatever you need to on that?
If you try to do it on the prefab then that is not the object that you are colliding with.
Think of it like this: the prefab is a blueprint (imagine for a house), if you create a house from that blueprint (which is equivalent to instantiating an instance of the prefab in your scene) then if you need to change something on the house you would alter the gameobject in the scene, not the prefab/blueprint.
You know how to use GetComponent don’t you? You can do something like (not tested as not at my pc): collision.gameObject.GetComponent<Rigidbody2D>() and put that into a variable and set the gravity or whatever you are trying to do.
You don’t access the prefab at all, just the collided gameobject instance.
That will only affect the gameobject that this script is on, which I assume is the player based on how it is checking if the other object is the enemy. I basically gave you the code to get the rigidbody of the other gameobject that you collided with, post has been updated as I had missed the collision bit of the code.
You say you want to affect the enemy that you have collided with, so just get the rigidbody of that collided instance and affect the gravity scale of that at the same time that you affect the player in the collision method.
Yes. Just do collision.gameObject.GetComponent<Rigidbody2D>().gravityScale += 5; or whatever you want to do with any part of the Rigidbody2D from the collided instance. If you are going to affect multiple things on the rb, then put the reference to the Rigidbody2D into a local variable to cache it and then use that variable reference instead of having multiple calls to GetComponent in the collision method.
Okay so i fixed the script and got eveything pretty much working. The one thing i cant figure out though is how to stop all my enemy prefabs. it only stops the ones i collided with.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CollisionController : MonoBehaviour
{
private Rigidbody2D _playerRb2d;
private Rigidbody2D _enemyRb2d;
void Start()
{
_playerRb2d = GetComponent<Rigidbody2D>();
}
void OnTriggerEnter2D(Collider2D collision)
{
// Figure out which object I'm colliding with.
if (collision.gameObject.tag == "Enemy")
{
_playerRb2d.gravityScale = 5;
_playerRb2d.constraints = RigidbodyConstraints2D.None;
_enemyRb2d = collision.gameObject.GetComponent<Rigidbody2D>();
_enemyRb2d.constraints = RigidbodyConstraints2D.FreezePosition;
// Find EnemySpawner GameObject and destroy it so it can't spawn anymore prefabs.
Destroy(GameObject.Find("EnemySpawner"));
Debug.Log("Collided with Enemy");
}
}
}
I thought you only wanted to stop the one you collided with.
If that’s not they case, then just change your collision method so that if you collide with an Enemy (which you already check with the tag) then do something like a FindGameObjectsWithTag and loop through them all and do a GetComponent to get the Rigidbody2D on each of them and then set the necessary rb values that you want to change.
Ye i’ve been trying to work on this but i’m really quite confused. The thing with FindGameObjectsWithTag is that I need a null passed as the tag is what the docs say, I have no expericne and no very little about null values. And looping through all the gameObjects or prefabs is something I would probably need an example of. I’m guessing you want me to use a for loop?
Are you reading the manual for FindGameObjectsWithTag? Because nowhere does it say that you should be passing a null value to it.
It clearly says on that page of the manual that you will receive a UnityException if you pass an invalid tag (one that is not set up in the tags in the IDE) or if you pass a null value instead of a tag. It does not say that you should be passing a null value to it.
So don’t pass a null value, just pass the tag that you already know (Enemy) because you are already using that tag in your collision check so you know that it must exist.
And the manual page (again: https://docs.unity3d.com/ScriptReference/GameObject.FindGameObjectsWithTag.html) has an example of looping through the results of FindGameObjectsWithTag using a foreach loop (the very first example on the pag), so you should really be able to base your code on that and instead of doing the Instantiate that the example does, just use GetComponent to retrieve the Rigidbody2D on that gameobject and set the necessary values on it.