Unity Scripting Problem :(

So I created a script for a football. Whenever the football enters the trigger region of the player and the player presses E then the football will be kicked. But for some reason, the script only works on trigger but when I press E the ball is not kicked. Please Help! The script is below:

using System.Collections;

public class Kicking : MonoBehaviour {

public GameObject football;

void OnTriggerEnter (Collider other)
{
if (other.tag == “football” && (Input.GetKeyDown (KeyCode.E)))
{
KickBall ();
}
}

private void KickBall()
{
{
float power = GetPower ();
if (power > 0)
{
Rigidbody rb = football.GetComponent ();
rb.velocity = GetReflected () * power;
}

}
}

private Vector3 GetReflected()
{
Vector3 footballVector = transform.position - football.transform.position;
Vector3 planeTangent = Vector3.Cross(footballVector, Camera.main.transform.forward);
Vector3 planeNormal = Vector3.Cross(planeTangent, footballVector);
Vector3 reflected = Vector3.Reflect(Camera.main.transform.forward, planeNormal);
return reflected.normalized;
}

private float GetPower()
{
return 100;
}

}

I just saw a very similar post a few minutes ago. :slight_smile:

Please refer to this page for how to post code properly on the forums: Using code tags properly

The problem with your code is that you are attempting to get input on the same frame as when the trigger occurs. - Just 1 frame of opportunity*

Try to re-work your script/logic so that you can determine when inside the trigger is valid, and check for the input in your Update() loop when that’s true. See how that goes :slight_smile:

Firstly, put your code inside the code tag (either manually or by clicking the ‘insert’ button on the toolbar where you type the post then click code). Makes it much easier to read.

Secondly the reason it isnt working as you expect is OnTriggerEnter is only called the first frame the ball enters the trigger. This means your code is only run on one frame - if you press E on that exact frame, then it would work. Otherwise if the ball is sitting in the trigger, that code is not run.

The naive solution short term is use OnTriggerStay instead however this has issues (A lot of unnecessary tag comparisons and tying input to the physics update). You could try this to test out your logic but a more robust solution depends on how you implement the game.

I am assuming that you have a permanent reference to the ball (football variable)? If so then you can use OnTriggerEnter and Exit to set a boolean flag (eg. hasBall) to true (Enter) or false (Exit). Then in your update you can process input if hasBall is true.

edit Ha @methos5k … I must type WAY too slow!

1 Like

Wow Thanks! I found the problem. I used OnTriggerStay instead of OnTriggerEnter and it worked perfectly :slight_smile:

Glad to hear it works.
As per my previous post though, you should look to use alternative logic (such as a flag) as there are issues with input processing etc. Physics updates run at a different rate (slower than update under normal circumstances) so you want to avoid input handling (The OnCollision/OnTrigger events are from the physics system).

eg. This is a similar situation that ran into problems (with the flag based solution as the first answer)
https://gamedev.stackexchange.com/questions/97752/unity-problems-with-ontriggerstay-and-input-getkeydown

I agree, the flag sounds better. Plus, you could still miss an input in OnTriggerStay. Mind you, the chance is much smaller than OnTriggerEnter, but it could happen.