Unity - Inconsistant speed of object following raycast2D - unity3d

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.

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.

How to keep the same velocity after bumping into things ? (Unity 2D)

My game (2D Top-Down view) is about a tank that fires bouncing bullets. Those bullets have infinite bounces and keep the same velocity after bouncing. It works fine with static objects, however it doesn't keep the same velocity with moving objects : the bullet can push things, but will slow and I don't know how to remove the slow.
Here is a tweet where you can see the bullets slow down after touching some objects :
https://twitter.com/TurboDevTeam/status/1350751139508215808?s=20
Edit :
Here are the parameters of the bullet :
derHugo's comment is on point: since the cars move when hit, they absorb part of the energy.
I've set up a minimal example to demonstrate.
The ball has a CircleCollider2D and a Rigidbody2D with Linear Drag = 0 and a material with Friction = 0 and Bounciness = 1.
The walls have a BoxCollider2D and a Rigidbody2D. Gravity is disabled.
For the first test, the wall Rigidbody2D is set to Static.
For the second test, the wall Rigidbody2D is set to Dynamic, with Mass = 10 and Linear Drag = 1.
In order to keep it bouncing forever in this case, you must code the bounciness by yourself. First remove the Physics Material or set the bounciness to 0, to make sure the Physics Engine is not simulating it.
Then, create a script for the bullet:
public class Bullet : MonoBehaviour
{
private Vector2 lastVelocity;
void FixedUpdate()
{
lastVelocity = GetComponent<Rigidbody2D>().velocity;
}
void OnCollisionEnter2D(Collision2D collision)
{
GetComponent<Rigidbody2D>().velocity = Vector2.Reflect(lastVelocity, collision.contacts[0].normal);
}
}
(Please note that you should use GetComponent carefully, maybe calling it only once on Start and saving a reference, I didn't do it to keep a minimal sample.)
The idea here is to take the velocity right before the collision and invert it. However, if you take the Rigidbody2D velocity on OnCollisionEnter, it's already the updated value. So you must store the value in FixedUpdate, since the next is only called after the OnCollisionEnter method.
Then, you use Vector2.Reflect to reflect the incoming velocity by the collision normal.
Vector2.Reflect results are valid in 2D:

Unity 3D - Collisions

I have a problem with physics. It is my first time doing in 3D, so it may be just a beginner mistake.
I just wanted to create a simple player controller and make it so that it can not pass trough cubes.
The problem is that when going straight into the cube, part of the player is in the cube itself. When stop moving, it pushes me, so they are not intersecting (that makes sense).
I tried moving the player using .Transalte, .MovePosition and by changing the velocity of rigidbody itself. None of it change anything. The player can always move a part of him into the cube.
Any ideas how to solve this?
My player controller:
(The 2 lines commented out in Move() are just other ways to move the player.)
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField]
private float movementSpeed;
private Vector3 input;
private void Update()
{
GetInput();
}
private void FixedUpdate()
{
Move();
}
private void GetInput()
{
float inputHorizontal = Input.GetAxisRaw("Horizontal");
float intputVertical = Input.GetAxisRaw("Vertical");
input = Vector3.ClampMagnitude(new Vector3(inputHorizontal, 0, intputVertical), 1);
}
private void Move()
{
GetComponent<Rigidbody>().velocity += input * movementSpeed;
//GetComponent<Rigidbody>().MovePosition(GetComponent<Rigidbody>().position + input * movementSpeed * Time.deltaTime);
//transform.Translate(input * movementSpeed * Time.deltaTime, Space.World);
}
}
Player is standing still
Player is moving towards cube
Settings of the Game Objects itself
Now I think I understand your problem.
The collider is a geometric shape that is checked but the outcome wont take place until the collision has actually taken place, this means, one geometric shape being inside the other. By this I mean, that what you are experiencing is the normal behaviour of the collision. If both elemnts are rigid bodies, both will move and your problem wont be perceivable, but if your cube is not a rigid body or is kinematic, will stand still in the same position, and depending on the other object speed, its normal that an invasion/superposition of the elements is perceivable, because that is the frame were the collision took place, and were your element needs to be moved back because it has collided.
Consider that if the speed is high enough, and the position from one frame to another varies enough, the collision might not even take place, because the geometric parts do not interfere between frames, as the position variation might be bigger than the bounds of the collider itself. The collision check at the end of the day, is dicrete, and not continuous (even you can set it as continuous to be as frecuent as possible).
To solve or improve that, you can adjust the speeds to avoid that being perceivable + adjust your collider to make it react before the graphic superposition occurs. This means making the capsule or the cube collider bigger than the graphic element itself. You can even calculate , to make it as bigger as much as your your speed * Time.deltaTime result or speed * FixedTimeStep result, depending on your safety distance needs. I think one of those should be the safety distance you need to take into account before the graphic collision occurs.
Another thing you can do is tight more the times physics calculations are done.
https://docs.unity3d.com/Manual/class-TimeManager.html
But need to be careful with this as this can be a performance devourer and need to be handled with care. You can make some trials with that and check your problem can improve.
Hope that helps
You can increase the scale of your player's collider from the Collider component attached to it. You can check how big the collider is from the editor scene view.
Edit: The issue might be that your movement or collision code is called in Update instead of FixedUpdate. When working with rigidbodies, you want to call the physics calculations inside FixedUpdate.
remove rigidbody from the cube, you can click on 'Gizmos' in the top right of the editor and make sure the colliders are at the edges of the objects.

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.