- Home /
How to make player (sphere) shoot the ball (another sphere)?
Hi, I'm having trouble with trying to be able to shoot the ball when the player collides with it. I tried adding force forward but the problem is that it shoots always in the same direction (which is forward). I want it to shoot at the direction depending on the spot where they collide. I've been thinking about using raycast but I don't know how to do it as the player is constantly rotating and changing direction. What I put in the scene is two players, ball and the "stadium". If there's anyone who once solved this "problem" (I know it's probably easy but I've been using Unity only for one week now, even though I'm not a beginner in programming) or knows how to solve it, I'll be really grateful. If you need any more information or screenshots of a game, just let me know. Thanks in advance.
Answer by robertbu · Jul 18, 2014 at 03:42 PM
Given that both the player and the ball are spheres, you can do something like this:
function OnCollisionEnter(col : Collision) {
var dir = (col.transform.position - transform.position).normalized;
col.rigidbody.AddForce(dir * someForce);
}
'someForce' is a variable you define, and I'd start with a value of at least 500 if you left the mass of each of the spheres at 1.0.
Note if you plan in the future to replace the player sphere with another mesh, then I would suggest you look to the normal in the contact points array in the collision to get a direction, possibly in combination with the incoming velocity of the ball and Vector3.Reflect.
Hi, thanks for your respond. Unfortunately, your code doesn't seem to work for me. When I copy it and paste to the script as a .js (Btw I usually code in C#), change the force to 500 and attach it to Player, nothing happens. I'll have to check contant points, sounds like it could work if I fully study them. I was about to send you the ss of inspector of both player and the ball but sadly I'm not on the computer now but on laptop. Anyway, thanks for the reply, I'll try to think of something. Bye.
First, for this to work:
Both objects must have colliders
One of the objects must have a Rigidbody
The collider cannot be marked as a trigger
The Rigidbody cannot be kinematic
If this is all true, then put a Debug.Log() statement as the first line of the OnCollisionEnter() to verify it is being calls. If it is not being called, explore the many posts where OnCollisionEnter() does not fire. Here is a C# translation of this callback (must be inserted into a class:
void OnCollisionEnter(Collision col) {
Debug.Log("Collision Found");
var dir = (col.transform.position - transform.position).normalized;
col.rigidbody.AddForce(dir * someForce);
}
Just so you are sure, this code must be on the player on the game object that has the collider.
Ok, now it works pretty well, even though I didn't change anything in the inspector of any object, it was already there (rigidbodies, colliders etc). Anyway, it works in teh game but i do get some error: http://i.imgur.com/bAtH$$anonymous$$WV.png. Actually, I think I just fixed it while writing this answer by putting an if statement:
if (col.gameObject.CompareTag ("Ball"))
I put it because it was working even if I collided with another player. And it seems that it also fixed the error. But, now I want just one more thing. I want to be able to shoot only when space is being pressed during the collision as I want to be also able to drible with the ball. I can make it like this:
if (col.gameObject.CompareTag ("Ball") && Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.Space))
But it's not easy to press the space as the player moves it towards when they collide. If I change it to "Get$$anonymous$$ey" then I have to press space and keep it down before the collision to be able to shoot it. Any ideas here? Thanks for all :)
You could consider a 'latching' mechanic where 'Get$$anonymous$$eyDwon()' is run in Update() and set a boolean value that is cleared after a short time. This would give the user a window of opportunity.
Hmm, very nice idea. I'll try it and let you know if I succeed :D Thanks, man ;)
Answer by ChrisSch · Jul 18, 2014 at 03:46 PM
You can add the force based on the contact.point normal, at the contact.point. Here's the contact points reference page. http://docs.unity3d.com/ScriptReference/Collision-contacts.html
This might come in handy too. http://docs.unity3d.com/ScriptReference/Rigidbody.AddForceAtPosition.html
Not to be discouraging, but contact.points aren't really first week of Unity lesson. Its not hard, just not something to start off with. xD
The best way to learn is by doing tutorials. Unity's official tutorials are good place to start. And also the Unitycookie beginner series, and lunar lander series. :)
One thing I wanna add tho is, try sticking with C# when programming. Most code you find online and on the asset store will be C#.
First, thanks for reply. I checked contact points reference page but I didn't really get it, but hope I will after doing a few tutorials. I've already learnt a lot this week and I'm not willing to stop. Well, the more I learn the better my future games will be, right? And, yes, I am sticked with C# as I also code in C and C++.