Particle collision detection on cloned objects not working - unity3d

I want to spawn several circles on the screen as game objects that float around randomly. To do this I have a prefab that I am instantiating x number of times in a script attached to a main game object. Then I have a 2nd script attached to the prefab to control the random movement. I added a Particle System to the prefab, so that each spawned clone has particles emitting from its edges. I want to know if one object's particles collide with anything, be it another cloned object, a wall, etc. But my OnParticleCollision (in the movement script attached to the prefab) is not logging anything to the console, it seems to not detect particle collisions at all. Maybe I'm not understanding the bigger concept and instantiating multiple instances of the same prefab with a particle system is not the best approach? Or am I making a more obvious minor mistake?
Things I have tried based on other questions:
Send collision messages IS checked
I do not have any colliders marked as triggers
I verified the visual bounds look correct in Scene View
Collision between cloned game objects themselves work fine, it's only the Particle Collisions not working.
My script attached to the prefab:
public class BubbleMove : MonoBehaviour
{
public Rigidbody2D rb;
void Start()
{
rb.velocity = new Vector2(min, max);
ParticleSystem ps = GetComponent<ParticleSystem>();
ps.transform.position = new Vector3(transform.position.x, transform.position.y, 0);
ps.Play();
}
// Update is called once per frame
void Update()
{
}
void OnParticleCollision(GameObject col){
Debug.Log("Collision Particle: " + col);
}
}
Images of my prefab inspector settings for Rigidbody2D, Circle Collider, and Particle System:

Hi I see the rigidbody is not defined in the inspector for the BubbleMove script.

Related

Continuous collision detection (CCD) in particle system in Unity, is that possible?

According to this article is possible to solve collision problems with fast moving objects in unity.
If you have particle system firing 1 sphere particle (ball throw for example) with collider and gravity modifier. And another moving collider with rigidbody (baseball bat for example), is there any possibility to make these object to NOT going through when they will collide in "high speed"? You cannot set "collision detection" on particle.
For better understainding I am adding two screenshots bellow.
Feel free for asking any question.
Collider(wall) is not moving, particle will bounce
Collider(wall) is moving towards ball with speed of "swing", particle goes through
The problem is because your objects are moving at a speed that they go through the collider. Say your object would move 10 units a frame, and it was 1 unit away from the collider. If the collider was 5 units long, it wouldn’t stop the moving object. This is because the next update will push it too far ahead of the next object.
First, don’t use a particle system for this. Just use a Rigidbody, because it is easier to handle in these situations.
You could solve this by doing a sweep test. A sweep test checks for colliders, where the object is going. You could just stop it from moving at the point it hit.
Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
Sweep();
}
void Sweep()
{
RaycastHit hit;
if (Physics.SweepTest(rb.velocity, out hit, rb.velocity.magnitude))
{
rb.velocity = rb.velocity.normalized * hit.distance;
}
}
Make sure this script is on your ‘baseball’, and add force somewhere in this script. Make sure that you are not using particle system, but you are using Rigidbody.
This was untested; let me know if it doesn’t work or you get an error.

How to detect a potential collision in Unity?

I have a Unity game I am working on as a hobby and have come across an interesting issue with how to best handle collision detection. My problem here is that my game is a 2D turn-based game, whereby a game object can move a fixed distance each time in a non-grid based world space. I have my game objects currently using BoxCollider2D to handle collision detection, but I need to be able to determine if there will be a collision BEFORE actually making a move, which right now causes the game object to overlap another game object and fire the OnCollisionEnter2D event. The eventual idea here is to allow a player to plan out a move and have a "navigation guide" appear next to the object to show move options based on the game object's move capabilities.
Is it possible to take my game object's collider, transform its position to move or rotate it, see if a collision would occur, but NOT actually move the object itself?
You mean like simply using Rigidbody.SweepTest ? ;)
Tests if a rigidbody would collide with anything, if it was moved through the Scene.
From the example
public class ExampleClass : MonoBehaviour
{
public float collisionCheckDistance;
public bool aboutToCollide;
public float distanceToCollision;
public Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
RaycastHit hit;
if (rb.SweepTest(transform.forward, out hit, collisionCheckDistance))
{
aboutToCollide = true;
distanceToCollision = hit.distance;
}
}
}
Oh just noted that actually this is only for 3D Rigidbody.
For 2D this doesn't exist but can be kind of replicated using instead Collider2D.Cast
Casts the Collider shape into the Scene starting at the Collider position ignoring the Collider itself.

Unity - Tricky Particle Collisions

I am making a prototype for my 2D game. It consists of a ball that launches missiles that are aimed to explode where the user clicks. The explosion of the missile releases particles, which hit the ball and exert a force on the ball. Here is a video.
I used a standard particle system with the Collision module activated. Then attached this script to the particle systems created be each explosion:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class particleInteraction : MonoBehaviour {
//PS Variables
ParticleSystem myPS;
public List<ParticleCollisionEvent> particleCollisions = new List<ParticleCollisionEvent>();
//Physics variables
public float effect;
// Use this for initialization
void Start () {
myPS = GetComponent<ParticleSystem>();
}
void OnParticleCollision (GameObject other)
{
//Checking if the hit object is indeed the ball
if (other.tag.Equals("Player"))
{
Rigidbody2D hitObject = other.GetComponent<Rigidbody2D>();
//Getting the number of particles hat hit the ball
int noOfCollisions = myPS.GetCollisionEvents(other, particleCollisions);
Vector3 particleDirection = new Vector2(0,0); //The overall velocity of all the particles that collided
//Iterating through all the collisions and adding their vectors
for (int i = 0; i < noOfCollisions; i++)
{
particleDirection += particleCollisions[i].velocity;
}
//Applying the resultant force
hitObject.AddForce(particleDirection.normalized * effect * noOfCollisions);
}
}
}
This mostly works, however it causes a problem. The missile are designed to explode when they hit the walls too, so when the ball is on a wall I expect a missile aimed at the wall to push the ball off of it. However, the ball simply jerks away from the wall in the next frame (can be seen in the video). I believe this is because of the colliders on the particles instantiating inside of the ball's collider. This causes the physics engine to immediately move the ball away in the next scene.
So I tried using OnParticleTrigger, however I realized that Unity doesn't provide info on the gameobject affected in particle triggers, so I cannot affect the ball.
Could anyone help me find a way to make this work? I want to avoid the jerky movement caused by the intersecting colliders, or maybe use a better method expressing the missile explosions.
reduce the Radius Scale under the Collision Tab.
you can visually debug this using visualize Bounds checked inside the module.

Unity - Inconsistant speed of object following raycast2D

So im creating a simple game and one component of the game is a greendot following the outside of the level. I got this working using a raycast in the middle which rotates and gives the position of collision the the gameobject.
game overview
The problem is that the speed is inconsistant at the moment since the distance between two collisions can be further distance if i have a slope. I also have the feeling that there should be a easier way to get the same result. What are your thoughts?
public class FollowPath : MonoBehaviour {
Vector3 collisionPos;
public GameObject greenDot;
void Update ()
{
RaycastHit2D hit = Physics2D.Raycast(transform.position, transform.up);
transform.Rotate(0.0f, 0.0f, 3);
if (hit.collider != null)
{
collisionPos = hit.point;
}
greenDot.transform.position = collisionPos;
}
}
I'm not sure if you will like this answer, as it suggests a complete departure from the way you were trying to do it.
A simple way to do this, would be to give your moving dot GameObject a Rigidbody2D component, AND a CircleCollider component.
Then, make your walls, and add to each an EdgeCollider component.
You'll probably also want to add a PhysicsMaterial2d to each GameObject with a Collider and set the friction and bounciness values for each.
Once this is setup, you can apply an initial force to the rigid body ball to get it moving, and it will bounce off the walls just like a ball does, using the Unity physics engine. No code would be needed in you update functions.

unity3d 4.3 bullets coming back down

I am trying to build a 2D space shooter game where the player will remain constant at the bottom of the screen and will move left and right. When the player fires a bullet(projectile), the bullet is going up just fine, but it is coming back again. Also if two bullets collide, they react to the collision.
I have two questions here:
How can I ensure that the bullet does not come back? (One way is to destroy it after a few seconds, but not sure if this is the right way)
How do I avoid collision between the bullets.
Here is my code snippet:
void Update () {
if (Input.GetButtonDown("Fire1"))
{
Rigidbody2D clone = (Rigidbody2D)Instantiate(bullet, transform.position + transform.up, transform.rotation);
clone.velocity = transform.TransformDirection(Vector3.up * 20);
}
}
I am very new to Unity and somehow wrote this code by looking into Unity Forums.Any help will be very much appreciated.
Thanks
More details:
I have created the bullet and added Rigidbody2D and a BoxCollider2D for this object. Made the bullet object a prefab and I dragged it under the Player object. Now bullet is a child of the Player object. Attached the script above to the Player object.
To answer your immediate questions:
1) I am not too sure about how you have the scene setup or about using the Unity 2D tools but usually if your bullets are coming back down then I would assume that you still have gravity applied to the rigidbody -- so make sure that you have that unchecked.
2) With Unity3D for objects to interact with each other they need rigidbodies attached. This is vital, say, if you want your lasers to destroy Monster #1. However, you only need one rigidbody attached to an object to have a desired effect. I would suggest removing the rigidbody from your laser and attach rigidbodies to objects ( Monster #1 ) that you want to be affected by the laser fire. ( That should work, if not there are other options -- one using layers and ignoring particular objects on those layers ).
Tips:
Here are some extra things. When you are creating objects and they fly off screen over time they will build up. Imagine you are in a large battle and you instantiated hundreds of lasers -- it will eventually be an issue for performance. So always consider Destroying objects after a certain amount of time.
Also, after looking at your code, I can't tell whether the velocity of the object is based upon its current position and nothing is being added. What I think is happening is when you instantiate an object it may be moving up, but because there is no incrementer, the object ( as it gets higher ) slows until it is at a rate which it is falling. For example this
clone.velocity = transform.TransformDirection(Vector3.up * 20);
should probably do this:
clone.velocity += transform.TransformDirection(Vector3.up * 20);
Heres http://docs.unity3d.com/Documentation/ScriptReference/Vector3-up.html, to read up on velocity. The problem is is that you need to continuously apply a constant forward motion so things in motion will tend to stay in motion. If not gravity will pull it down.
Also, heres a bit of code that I've used in the past that's created a pretty cool shooting laser effect thing:
public class Laser : MonoBehaviour {
public int fireRate = 70;
void Start(){
InvokeRepeating("FireLaser", 0.01f, 0.009f);
Destroy( gameObject, 2.0f );
}
void FireLaser(){
transform.Translate( Vector3.up * fireRate * Time.deltaTime );
}
}
edit: it's 3 a.m. and I hate proofreading.