0
\$\begingroup\$

Code:

void OnCollisionEnter()
{
    if (Input.GetMouseButton(0))
       {
            // do something
       }
}

Of course, this code does not work. What I intend to do: "After collision, if the user is pressing down, do something". How can we write this another way? I can't figure it out.

\$\endgroup\$
1
  • \$\begingroup\$ I think you want to open the door from any side panel or standing on any special block? something like that? \$\endgroup\$ Dec 29, 2015 at 21:37

2 Answers 2

2
\$\begingroup\$

Do something like this:

var timeSinceCollision = 999;

void Update() {
    timeSinceCollision += Time.deltaTime;
    if(timeSinceCollision < 0.5 && Input.GetMouseButtonDown(0)) {
        // do something
    }
}

void OnCollisionEnter() {
    timeSinceCollision = 0;
}

The 0.5 makes it so that there's a bit of allowable tolerance for when the player collides with whatever and them being able to perform the action (no one is going to be able to press the button the same frame the collision occurs on: ideally that would be 1/60th of a second!).

Edit: Also use GetMouseButtonDown, which will only be true on the frame that the button is first pressed and false thereafter. It prevents the player from holding down the button, then bumping into something, and getting the effect despite doing things out of order.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ Instead of adding frame time every frame, it would be better to store Time.time on action and do Time.time - storedTime < maxTime. \$\endgroup\$ Dec 29, 2015 at 22:50
  • \$\begingroup\$ Can you please upload an example project? Your code doesn't seem to be working for me... \$\endgroup\$
    – user76659
    Dec 30, 2015 at 8:02
  • \$\begingroup\$ @SamedTarıkÇETİN why is that? \$\endgroup\$ Dec 30, 2015 at 14:47
  • \$\begingroup\$ @Draco18s There may be small delays between frames. It's always better to use exact time, which is independent from deltaTime or delay between frames. \$\endgroup\$ Dec 30, 2015 at 15:58
  • \$\begingroup\$ The small delay between frames is in fact, the Time.deltaTime. docs.unity3d.com/ScriptReference/Time-deltaTime.html Time.time is also "time at the beginning of this frame and returns the same value every time it is polled in a given frame. docs.unity3d.com/ScriptReference/Time-time.html Your method and mine would have exactly identical results in Unity. \$\endgroup\$ Dec 30, 2015 at 16:06
0
\$\begingroup\$

I think you scenario is to stand over a special block then do something or open up the door from side panel. In block type case OnCollision is OK but in door type case I'd recommend OnTrigger, well according to your code, use OnCollisionStay instead of OnCollisionEnter

void OnCollisionStay(Collision col)
{
    if (Input.GetMouseButton(0))
       {
            // do something
       }
}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I considered a trigger volume as well, but immediately thought of wall-jumping, which could not be a trigger. Depending on exact needs, OnCollisionStay may be a better solution. \$\endgroup\$ Dec 29, 2015 at 21:46

You must log in to answer this question.