繁体   English   中英

OnCollisionExit 被调用,但行为奇怪

[英]OnCollisionExit is called, but behaves strangely

我正在 Unity 中开发 3d FPS 游戏。 目前,我正在实施一个穿墙机制。 这背后的逻辑非常简单——如果玩家向前推进,但没有接地,并且接触到墙壁,我会限制 Y/Z 方向(但玩家仍然可以向前跑,因为我忽略了 X 方向)并关闭重力。 它似乎工作正常,有点笨拙,但对我来说还可以。 除非,当墙被抛在身后时,玩家仍然可以在半空中奔跑,直到他失去惯性(这里是示例: https://imgur.com/a/LtbWs9J )。 这是代码:

using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(AudioSource))]
public class WallRunning : MonoBehaviour
{
    public AudioClip audioClip;
    private CharacterMovement cm;
    private Rigidbody rb;
    private bool isJumping;
    public bool isWall;
    private bool playAudio;
    private AudioSource audioSource;
    public float energyLimit = 3.5f;


    private void Start()
    {
        //Get attached components so we can interact with them in our script.
        cm = GetComponent<CharacterMovement>();
        rb = GetComponent<Rigidbody>();
        audioSource = GetComponent<AudioSource>();
    }

    private void FixedUpdate()
    {
        bool jumpPressed = Input.GetButtonDown("Jump");
        float verticalAxis = Input.GetAxis("Vertical");
        //Check if the controller is grounded.
        if (cm.Grounded)
        {
            isJumping = false;
            isWall = false;
        }
        //Has the jump button been pressed.
        if (jumpPressed)
        {
            StartCoroutine(Jumping());
        }
        //If we are pushing forward, and not grounded, and touching a wall.
        if (verticalAxis > 0 && isJumping && isWall)
        {
            StartCoroutine(Energy());
            //We constrain the Y/Z direction to defy gravity and move off the wall.
            //But we can still run forward as we ignore the X direction.
            rb.useGravity = false;
            rb.constraints = RigidbodyConstraints.FreezePositionY | RigidbodyConstraints.FreezePositionX | RigidbodyConstraints.FreezeRotation;
            //We also telegraph to the player by playing a sound effect on contact.
            if (audioClip != null && playAudio == true)
            {
                audioSource.PlayOneShot(audioClip);
                //We block more audio being played while we are on the wall.
                playAudio = false;
            }
        }
        else
        {
            StopCoroutine(Energy());
            //We need to make sure we can play audio again when touching the wall.
            playAudio = true;
            rb.useGravity = true;
            rb.constraints = RigidbodyConstraints.FreezeRotation;
        }
    }

    void OnCollisionEnter(Collision other)
    {
        //Are we touching a wall object?
        if (other.gameObject.CompareTag("Walls"))
        {
            isWall = true;
        }
    }


    void OnCollisionExit(Collision other)
    {
        //Did we stop touching the wall object?
        if (!other.gameObject.CompareTag("Walls"))
        {
            isWall = false;
        }
    }


    IEnumerator Jumping()
    {
        //Check for 5 frames after the jump button is pressed.
        int frameCount = 0;
        while (frameCount < 5)
        {
            frameCount++;
            //Are we airbourne in those 5 frames?
            if (!cm.Grounded)
            {
                isJumping = true;
            }
            yield return null;
        }
    }

    IEnumerator Energy()
    {
        yield return new WaitForSeconds(energyLimit);
        isWall = false;
    }
}

注意:墙壁上有盒子碰撞器(“Is Trigger”复选框未选中),并且玩家连接了非运动刚体和胶囊碰撞器。 墙没有标记为“静态”并分配给默认层,而玩家被分配给玩家层。

我究竟做错了什么? 我确定我搞砸了代码,但无法找出问题所在。

代替


    void OnCollisionExit(Collision other)
    {
        //Did we stop touching the wall object?
        if (!other.gameObject.CompareTag("Walls"))
        {
            isWall = false;
        }
    }


    void OnCollisionExit(Collision other)
    {
        //Did we stop touching the wall object?
        if (other.gameObject.CompareTag("Walls"))
        {
            isWall = false;
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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