Unity3d: CharacterController不'不可能连续播放脚步声音效

本文关键字:连续 不可能 播放 脚步声 音效 CharacterController Unity3d | 更新日期: 2023-09-27 18:19:14

我需要检查我的角色什么时候接地,这样我就不会在他从什么东西上掉下来(或跳到空中)时继续播放行走的声音。

这是处理跳跃、下落和重力的代码。这个代码块中的cc是CharacterController组件。如果角色已经接地并且没有按下跳跃键,垂直速度将保持为零;如果他没有接地,那么在y方向上施加重力。

if (cc.isGrounded) {
    grounded = true;
    if (Input.GetButton ("Jump") == true) {
        ySpeed = jumpSpeed;
        jumpSound.audio.Play();
    } else {
        ySpeed = 0;
    }
} else {
    grounded = false;
    ySpeed += Physics.gravity.y * Time.deltaTime;
}
Debug.Log (cc.isGrounded == true ? "yes" : "no");

问题是isGrounded值不断波动,Debug.Log线在yesno之间波动,所以当我使用isGrounded条件播放脚步声时,声音随机停止并重新开始,即使我一直只是在简单的光滑平面上直线行走。

有办法解决这个问题吗?

我不关心isGrounded波动的事实,这是不正确的,因为在游戏玩法中,这是不明显的。我只担心如何在角色行走,不跳跃,不下落的情况下持续播放脚步声。就我所关心的而言,这可以通过实际修复波动或其他变通方法来解决;我都很满意。

这些是我播放脚步声的条件:

if((Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0) && grounded == true) {
    if(this.audio.isPlaying != true) {
        this.audio.Play ();
    }
} else if (this.audio.isPlaying) {
    this.audio.Stop ();
}

Unity3d: CharacterController不'不可能连续播放脚步声音效

我在使用PhysX引擎开发角色移动时遇到过类似的情况。更准确地说,我的角色无法下楼。相反,他总是试图跳过台阶,然后自由落体。而他的isGrounded也在看似平坦的表面上波动。

我的运动代码也是基于速度积分dX = V·dt

最后,我添加了简单的解决方法:
  1. 移动dX = V·dt + U其中U是一个常数向量(0,-u,0)
  2. 如果字符在第1步之后没有接地,它将向后(向上)移动(0,u,0)

使用u的恒定值,我发现当小于或等于楼梯台阶的高度时,它提供了合理的行为。

为了解释这个解决方法,有必要明确角色控制器不是人体。即使使用像速度积分这样复杂的方法,你仍然需要使用固体身体,而人体是复杂的机构,你现在,它由腿,脚等组成。

事实上,当我的角色开始向下移动时,重力积累dV = G·dt有点滞后,但这足以让角色在楼梯上自由落体。

我的故事就到此结束了:)

p。我找到了相应的代码:

        // move character
        NxU32 activeGroups = getCharacter()->getScene()->getActiveGroups( cg::protagonist );
        _character->_nxController->move( 
            ( _character->_vy + _character->_vxz ) * timeStep, 
            activeGroups, 0.001f, 
            _character->_collisionFlags, 0.01f 
        );
        // press character to floor
        if( pressDown )
        {
            // press character down on step offset distance
            _character->_nxController->move( 
                NxVec3( 0, -_character->_stepOffset, 0 ),
                activeGroups, 0.001f, 
                _character->_collisionFlags, 0.01f 
            );
            // if press-down actions does not reveal floor under feets
            if( !( _character->_collisionFlags & NXCC_COLLISION_DOWN  ) ) 
            {
                // return character to its presios position
                _character->_nxController->move( 
                    NxVec3( 0, _character->_stepOffset, 0 ),
                    activeGroups, 0.001f, 
                    _character->_collisionFlags, 0.01f 
                );
            }
        }

您的方法可能有点过于复杂。我建议存储所有字符声音的引用(通常在Start或公共属性中),然后简单地将它们交换出来

。这样就不需要跟踪char。是接地。

伪代码:

if ( walking ): audio.clip = audioWalk
if ( jump ): audio.clip = audioJump

编辑

当完全静止在平坦地形上时,每隔几次调用Update(或fixeduupdate)就会显示isGrounded被设置为false。然而,虽然isGrounded在检测真实状态方面并不可靠,但我发现了它可靠的检查假状态。换句话说,当角色在"空中"时isGround可靠地保持假。考虑到这一点,你可以这样计算你的播放时间:

// RequiredFallingTime  is a public class field which I set in the inspector to be a little
// bit higher than my jump time (0.7 seconds in my case)
void Update () {
    fallingCount = ( cc.isGrounded ) ? 0 : fallingCount + 1;
    Debug.Log("Update: fallingCount = " + fallingCount);

    fallTime = fallingCount * Time.deltaTime;
    Debug.Log("Update: falling Duration = " + fallTime );

    falling = ( fallTime >= RequiredFallingTime ) ? true : false;
    // Still Falling: None of my Controls should produce sound while falling so return:
    if( fallTime / 2 >= RequiredFallingTime )
        return;
    // If first time falling, play our fall sound:
    if( falling ){
        audioSource.PlayOneShot(audioClipsOneShot[(int)SoundOneShot.fall]);
    }

    // If we made it this far, we're not falling--although we could be jumping.
    // Do Input checking for approp. sounds


}

如果y移动为0,则字符不会被推到地板上,并且isGrounded将返回false。我建议将y速度设置为接地时的任意负数。这样玩家将与地板碰撞,isGrounded将返回true。我所做的只是在地面上不改变y的速度,我所做的只是停止施加重力。

对不起,如果我来晚了一点,这是给任何碰巧读到这篇文章的新手的,因为它出现在谷歌搜索帮助的顶部。