How can i give soccer ball a trajectory? - unity3d

I am a beginner and trying to make penalty shooter Game in unity.. I have just setup the scene and just trying to shoot the ball towards the goal post.
When i shoot the ball it goes toward the goal but does not come down, because i am shooting it through the script and its gravity is off and kinematic is on.
Currently i have the following script:
void Start () {
startTime = Time.time;
rb.GetComponent<Rigidbody>();
}
void Update () {
transform.position -= fakevel * Time.deltaTime;
transform.position += fakeGravity * Time.deltaTime;
fakevel *= 0.999f ;
}
void OnTriggerEnter( Collider other ) {
fakevel = new Vector3(0.01f, 0, 0) * 2000f;
fakeGravity = new Vector3 (0 ,0.01f, 0)* 200f;
y = -45.68312f;
}
}
I have tried enabling the gravity and disabling the kinematic at some specific position but i does so the gravity just pull it down at that position and it does not look realistic. Some screen shoots are attached.
Please help me in setting trajectory of the ball and stopping it when it collides with the goalpost,

I would suggest you use a non-kinematic rigidbody on your ball and add a force to it when you shoot it: GetComponent<Rigidbody>().AddForce(forceVector3, ForceMode.Impulse) (this is just an example, you should avoid calling GetComponent on a frequent basis, you are better off calling it for the rigidbody component once on Start and store it in a private variable)
This way Unity's physics engine can handle gravity and the balls' velocity over time. To modify the trajectory you can play around with the properties of the balls' rigidbody component.
If you want to have more control over the velocity, you can also set the rigidbody's velocity directly in the FixedUpdate() (which is called right before each physics update). When doing so, you have to consider that velocity is measured in m/s and the physics engine handles sub-steps for you (I am assuming that FixedUpdate() is called more than once per second), meaning you do not have to multiply your velocity with some delta time (but I am not 100% sure about this right now).

Seeing how it does work, just doesn't give the effect you want, you can either spend several hours fine tuning it, or like xyLe_ stated, use the built in physics. Using the built-in physics isn't a bad thing, you just gotta be smart with it. You can add a bouncy physics material also, which will help give the ball a well, ball feel.

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.

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.

Rigidbody not stopping instantly when setting its velocity to 0

I'm trying to make my player's movement snappy, in a 3D environment, using forces. I tried a couple of things, but judging by how my player reacts in-game, I think I'm missing some piece of information.
public Rigidbody rb;
public float acceleration = 500f;
public UnityEngine.ForceMode forceMode = ForceMode.Impulse;
void Update() {
rb.AddRelativeForce(new Vector3(Input.GetAxis("Horizontal") * acceleration * Time.deltaTime, 0, Input.GetAxis("Vertical") * acceleration * Time.deltaTime), forceMode);
rb.velocity = Vector3.zero;
}
First of all, how come this code still allows me to move my player around? Resetting the velocity to 0 every frame should prevent it from moving, shouldn't it? I guess the force is still being applied on the subsequent frames even if the velocity is constantly set to 0?
How should I use forces to get really snappy movement, where when I stop pressing UP, the force applied on the Z axis is "stopped"?
Something important to note is the Order of Execution of unity scripts and functionality. The way that physics works is actually a bit more nuanced, and is likely causing your issue.
A quick fix to your problem would likely be something like putting your rigidbody to sleep after setting the velocity to 0:
rb.Sleep();
This ensures that the execution of internal physics update does not affect this rigidbody any further. Typically you do not need need to manually handle Sleep() and WakeUp() for rigidbodies as they are automatically called based on collisions or velocity thresholds, but in this case it will prevent the queued AddForce from impacting the RB after its velocity is zeroed out.

Ball is jumping unexpectedly in unity 3d

I'm making a game with unity3D that ball is rolling on the ground.
When I set single large ground block, and using Rigidbody.AddForce() in Unity3D. ball is rolling fine.
But if I set multiple small ground blocks, ball is jumping unexpectly on boundary of blocks. Even block size, positions and intervals are exactly matched.
Can I solve this problem?
(I can't freeze position Y of ball. because ball needs gravity.)
-edited-
Here is my code to move ball by AddForce(). when I clicked.
private void MoveBall(Vector3 pos)
{
Ray HookRay = Camera.main.ScreenPointToRay(pos);
int layerMask = LayerMask.GetMask("Block");
RaycastHit objectHit;
float distance = Mathf.Infinity;
if (Physics.Raycast(HookRay, out objectHit, distance, layerMask))
{
moveTo = objectHit.point;
Vector3 forceValue = moveTo - transform.position;
forceValue.y = 0f;
rb.AddForce( forceValue * charSpeed, ForceMode.Impulse);
}
}
And here is screenshot of Unity3D
I placed 3x1x3 cube blocks and arranged all positions Y to 0.
There are no cracks or gaps on it.
This likely comes from inaccuracies in the physics engine. They are there because the engine tries to cut corners to speed up processing. You can make it cut less counters (at the cost of speed) by following a few steps. First thing to try is to make the rigidbody do collision detection continuous. You can also try turning on interpolation. There are also more advanced ways where you will do physics updates more often than your frame rate. But I would try the simpler options first. They’re often enough.
Go to Edit -> Project Settings -> Physics and play with default contact offset, maybe make it much smaller like 0.00001 and try it. Another way you can freeze the y and then when some condition happens you can unfreeze it again.

Unity collider going through other colliders at times?

I'm trying to create a Pong clone for practice. I setup my project in 2D.
The paddle has the following components:
-Rigidbody2D (set to kinematic)
-BoxCollider2D (is a trigger)
The ball has the following components:
-Rigidbody2D (set to kinematic)
-CircleCollider2D (is a trigger)
The paddle is controlled via dragging (user dragging finger on screen left/right). I used the EasyTouch plugin for this.
Then I move the ball with this script:
void Update () {
transform.position += new Vector3(xSpeed * Time.deltaTime, ySpeed * Time.deltaTime);
}
This is how I detect collisions and redirect the ball once it hits something (Horizontal objects are the top/bottom/paddle while Vertical objects are the left/right screen border):
void OnTriggerEnter2D(Collider2D c)
{
if(c.gameObject.tag.Equals("Horizontal"))
{
ySpeed *= -1;
}
else if(c.gameObject.tag.Equals("Vertical"))
{
xSpeed *= -1;
}
}
The problem is sometimes the ball goes through the paddle which can look glitchy to the end-user. I've searched about this online and I've tried to set the rigidbody's Collision Detection property to Continuous instead of Discrete. But the ball still goes through the paddle at certain times.
Anyone know how to solve this? What am I doing wrong with how I setup/coded my game?
Thanks
You have a very simple concept error.
OnTriggerEnter2D(Collider2D) is to get if the collider has entered other collider. In other words you can go through the object.
you need to use this function instead:
OnCollisionEnter2D(Collision2D coll)
I suggest you to watch this Unity tutorial because it explains all this really good: https://unity3d.com/learn/tutorials/modules/beginner/physics/colliders
Additional info : http://docs.unity3d.com/ScriptReference/Collider2D.html
Thanks.
As the code shows, the transform is controlled by yourself while the continuous detection requires control of physics engine, so try to control the gameObject with physics engine instead give it a position modified by your own code.