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
线在yes
和no
之间波动,所以当我使用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 ();
}
我在使用PhysX引擎开发角色移动时遇到过类似的情况。更准确地说,我的角色无法下楼。相反,他总是试图跳过台阶,然后自由落体。而他的isGrounded也在看似平坦的表面上波动。
我的运动代码也是基于速度积分dX = V·dt。
最后,我添加了简单的解决方法:- 移动dX = V·dt + U其中U是一个常数向量(0,-u,0)。
- 如果字符在第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的速度,我所做的只是停止施加重力。
对不起,如果我来晚了一点,这是给任何碰巧读到这篇文章的新手的,因为它出现在谷歌搜索帮助的顶部。