简体   繁体   中英

I'm trying to make it so the person playing the game can press "E" as much as they want in the trigger | Unity 3d + animator

I am working on this Unity 3D game I have been making were you, the player can click random buttons(Don't ask why). In this game I made it were the player can enter a trigger and press E to make the animation trigger only once while clicking it, which perfectly went well. but the only problem is that the "Player" can only make the animation trigger once and than have to leave the trigger and re-enter it to make the animation trigger and work again when pressing E .

My Goal is to have the animation always work when clicking, not holding E everytime when only in the trigger.

this is the code for the button that I have made.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Fixedpress : MonoBehaviour
{
    public Animator Tributton;

    private Coroutine routine;

    private void OnTriggerEnter(Collider other)
    {
        // in general rather use CompareTag instead of ==
        // it is slightly faster and also shows an error if the tag doesn't exist instead of failing silent
        if (!other.CompareTag("Player")) return;

        // just in case to prevent concurrent routines
        if (routine != null) StopCoroutine(routine);

        // start a new Coroutine
        routine = StartCoroutine(WaitForKeyPress());
    }

    private IEnumerator WaitForKeyPress()
    {
        // check each FRAME if the key goes down
        // This is way more reliable as OnTriggerStay which is called
        // in the physics loop and might skip some frames
        // This also prevents from holding E while entering the trigger, it needs to go newly down 
        yield return new WaitUntil(() => Input.GetKeyDown(KeyCode.E));

        // set the trigger once and finish the routine
        // There is no way to trigger twice except exit the trigger and enter again now
        Tributton.SetTrigger("Fiveyon");
        Debug.Log("Fiveyon!");

        // If you even want to prevent this from getting triggered ever again simply add
        enabled = false;
        // Now this can only be triggered ONCE for the entire lifecycle of this component 
        // (except you enable it from the outside again of course)
    }

    void OnTriggerExit(Collider other)
    {
        if (!other.CompareTag("Player")) return;

        // when exiting the trigger stop the routine so later button press is not handled
        if (routine != null) StopCoroutine(routine);
    }
}

Instead of starting a coroutine inside onTriggerEnter, just have a bool to be set as true when the player enters the trigger and retrieve the input inside the Update with that bool as a condition. PS: you can also add a cooldown timer so that the player cannot spam E inside the trigger. Example:

bool canAnimate;

private void OnTriggerEnter(Collider other)
{
    // in general rather use CompareTag instead of ==
    // it is slightly faster and also shows an error if the tag doesn't exist instead of failing silent
    if (!other.CompareTag("Player")) return;

    // just in case to prevent concurrent routines
    if (routine != null) StopCoroutine(routine);

    canAnimate = true;
}

private void Update()
{
if (Input.GetKeyDown(KeyCode.E) && canAnimate)
 {
         Tributton.SetTrigger("Fiveyon");

 }
}

void OnTriggerExit(Collider other)
{
    if (!other.CompareTag("Player")) return;

    // when exiting the trigger stop the routine so later button press is not handled
    if (routine != null) StopCoroutine(routine);
 canAnimate = false;
}

PS: I am sure that there would be a better way to achieve this. Let me know if it helps :)

You need

OnTriggerStay()

You can refer Unity Docs for more details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM