- Home /
Rocket Jumping Woes
I am having issues making a small network game based around rocket jumping. I am using the usual method of using addExplosionForce to affect rigidbodies attached to my characters. When I started building the controls for single player, I simply made it so my 'bullet' layer would not collide with my 'player' layer. That worked perfectly because the rocket would not hit my character's collider and then would hit the ground and apply an explosion from there. However, I ran into a problem with that strategy when converting the demo to a multiplayer game. Now I need the rocket not to hit the player who spawned it, but DO hit the other players in the arena.
I tried to have the rockets spawn a few units in front of the player, but that didn't work at all angles that i wanted to use. Then I tried to have the rocket take note of which player spawned it, and simply not apply an explosion force to that object and also not delete itself. This solution works sometimes, but introduces a bunch of other issues, and is just poor coding because it forces me to have the rocket be aware of the player and the player aware of the rocket and just bad coupling in general.
The real problem here is figuring out how to make rockets spawn really close to my face, not hit me, but do hit my buddy's face 3 ft in front of me. I have included the script that manages my rocket objects to illustrate what I mean.
using UnityEngine;
using System.Collections;
public class RocketManager : MonoBehaviour {
public float speed = 10.0f;
public float explosionForce = 10.0f; // value used for explosion force
public float radius = 10.0f; // the radius of the explosion after the rocket has hit something.
public GameObject myParent; //Used to reference the player that spawned the rocket, so it wont hit himself hopefully. not sure if this is good coding!
/**
* part of my work around. I have my rocket spawner script hand over a reference to the player
* that spawned the object. this is obviously shitty code and doesn't work anyway.
*/
public void setMyParent(GameObject targetParent)
{
myParent = targetParent;
}
// Update is called once per frame
void Update ()
{
transform.position += transform.forward * speed * Time.deltaTime;
}
void OnCollisionEnter(Collision collision){
Vector3 explosionPosition = transform.position;
Collider[] colliders = Physics.OverlapSphere(explosionPosition, radius);
foreach(Collider hit in colliders)
{
Rigidbody rigidBod = hit.GetComponent<Rigidbody>();
GameObject hitObject = hit.gameObject; //part of my work around
if(rigidBod != null && !hitObject.Equals(myParent))
{
rigidBod.AddExplosionForce(explosionForce, explosionPosition, radius, 3.0f);
GameObject.Destroy(this.gameObject);
}
}
}
}
I can see multiple paths to fixing this and perhaps there is a standard method that people use in multiplayer games to make sure things don't collide with the player that spawned them, but I can't figure it out! Any advice would be greatly appreciated. I can include the scripts that spawn the rockets too if that would help.
Perhaps you could use Physics.IgnoreCollision : https://docs.unity3d.com/ScriptReference/Physics.IgnoreCollision.html
$$anonymous$$aybe you should set the local player's layer to one called "my player" and all the other players to one called "other players" at startup. $$anonymous$$ake is so rockets do not collide with the my player layer but do with other players.
Oh I like this idea. So I could have my usual "player startup" script also change the layer tag the other players? I will give both of these methods a try and post again with the results.
Answer by TobiasAndrion · Jul 19, 2016 at 03:26 AM
Thank you to @alucardj for the simple solution! Obviously, Unity has already thought this problem through for us. Unity API page on Physics.ignoreCollision
Here is the updated code for those who are interested
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class ShootRocket : MonoBehaviour {
public float speed = 10.0f; // how fast rocket shoots
public GameObject rocketPrefab; //prefab of rocket object
//Variables relating to the score ball
public GameObject scoreBallPrefab; //The object that will be spawned when we let go of the right mouse button
public Slider chargeSlider; // the slider that is associated with shooting the basketball.
public float chargeSpeed = 10.0f; //how fast to fill up bar for basketball shot.
public float maxForce = 350.0f;
public Transform bulletSpawn;
public GameObject parentObject;
// Update is called once per frame
void Update ()
{
if( Input.GetButtonDown("Fire1"))
{
GameObject tempRocket = GameObject.Instantiate(rocketPrefab,
bulletSpawn.position,
Quaternion.LookRotation(transform.forward)) as GameObject;
//Simple one line fix! Don't forget to just put in Physics. and trying to find an appropriate function
Physics.IgnoreCollision(tempRocket.GetComponent<Collider>(), parentObject.GetComponent<CapsuleCollider>());
}
/**
* The plan: when right click is held down, we increase the value of the slider based on time
* when the right click is let go, we spawn a ball who will take the value as a parameter for the force
* to go forward from the slider itself.
*/
if(Input.GetButton("Fire2"))
{
chargeSlider.value += (chargeSpeed * Time.deltaTime);
}
if(Input.GetButtonUp("Fire2"))
{
GameObject tempBall = GameObject.Instantiate(scoreBallPrefab,
bulletSpawn.position,
Quaternion.LookRotation(transform.forward)) as GameObject;
Rigidbody tempRigid = tempBall.GetComponent<Rigidbody>();
if(tempRigid != null)
{
tempRigid.AddForce(tempBall.transform.forward * chargeSlider.value * maxForce);
}
chargeSlider.value = 0f;
}
}
}