Reputation: 258
Let me preface this by saying I know this is a commonly asked question, however I have searched for a solution and come up with nothing.
This code is for a grenade instantiated by a grenade launcher. The desired behaviour is that the grenade bounces on the ground, but sticks to players. After 3 seconds the grenade explodes.
I am using transform.parent
to make the grenade stick to a player.
using UnityEngine;
// Grenade shell, spawned in WeaponMaster script.
public class GrenadeLauncherGrenade : MonoBehaviour
{
#region Variables
public float speed;
public Rigidbody2D rb;
public GameObject explosion;
private int damage = 50;
private GameObject col;
#endregion
// When the grenade is created, fly forward + start timer
void Start()
{
rb.velocity = transform.right * speed;
Invoke("Explode", 3f);
}
// Explode
private void Explode()
{
Instantiate(explosion, gameObject.transform.position, Quaternion.identity);
try
{
if (col.tag == "Player")
{
Debug.Log("Hit a player");
col.GetComponent<PlayerHealth>().TakeDamage(damage);
}
}
catch (MissingReferenceException e)
{
Debug.Log("Could no longer find a player, they are probally dead: " + e);
}
Destroy(gameObject);
}
// Check if the shell hits something
private void OnCollisionEnter2D(Collision2D collision)
{
col = collision.gameObject;
if (col.tag == "Player")
{
gameObject.transform.parent = col.transform;
Debug.Log("Stick!");
}
}
}
What's even stranger is that in the inspector it looks like the grenade is parented, but its behavior suggests otherwise. I can move the TestPlayer and the grenade doesn't follow.
Upvotes: 3
Views: 230
Reputation: 20249
Nonkinematic rigidbodies make their attached transform move independently of any ancestor transforms. This is in order to avoid conflicts between the physics engine and the changes in motions of ancestor transforms.
So, in order to make the grenade's transform stay relative to the parent transform, you should make the grenade's Rigidbody2D
kinematic when it collides with a player. Also, zero out its angularVelocity
and velocity
:
// Check if the shell hits something
private void OnCollisionEnter2D(Collision2D collision)
{
col = collision.gameObject;
if (col.tag == "Player")
{
rb.isKinematic = true;
rb.velocity = Vector2.zero;
rb.angularVelocity = 0f;
gameObject.transform.parent = col.transform;
Debug.Log("Stick!");
}
}
Upvotes: 2