C#学习教程:空中曲棍球游戏-如果你移动太快,玩家的球棒会越过冰球在Unity3d中。我遇到的问题是,当玩家试图过快地击打冰球时,玩家最终会通过冰球,因此不会发生碰撞。如果玩家保持静止并且冰球击中玩家或玩家以较慢的速度击中冰球,则游戏将按预期完美运行。玩家有一个使用胶囊对撞机进行连续碰撞检测的刚体。冰球还有一个带有连续动态碰撞检测的刚体和一个带有凸面的网格碰撞器。我尝试将固定时间步长设置为0.01,但没有效果。这是玩家移动的脚本:voidObjectFollowCursor(){Rayray=Camera.main.ScreenPointToRay(Input.mousePosition);Vector3point=ray.origin+(ray.direction*distance);Vector3温度=点;temp.y=0.2f;//在y轴上限制玩家cursorObject.position=temp;}这是冰球与玩家碰撞时的代码://如果冰球击中玩家if(collision.gameObject.tag=="Player"){Vector3forceVec=this.GetComponent().velocity.normalized*hitForce;rb.AddForce(forceVec,ForceMode.Impulse);Debug.Log("玩家命中");}任何帮助将不胜感激。谢谢。您尝试连续碰撞检测(CCD)是正确的。有一些限制(特别是在这种情况下,您希望将CCD用于两个移动物体,而不是一个移动物体和一个静止物体),但它是为这种情况而设计的。Rigidbody文档参考了这些约束:将碰撞检测模式设置为连续以防止Rigidbody通过任何静态(即非刚体)MeshColliders。将其设置为“ContinuousDynamic”以防止刚体穿过任何其他支撑的刚体,并将碰撞检测模式设置为“Continuous”或“ContinuousDynamic”。Box、Sphere和CapsuleColliders支持连续碰撞检测。总而言之,冰球和球拍都需要设置为连续动态,并且都需要是Box、Sphere或CapsuleColliders。如果您可以使这些约束适用于您的游戏,您应该能够进行连续的碰撞检测而无需编写自己的代码。关于Unity的重复CCD的注释:请注意,连续碰撞检测旨在作为一个安全网,以在物体相互穿过时捕获碰撞,但不会提供物理上准确的碰撞结果,因此您仍可以考虑使用中的固定时间步长值如果您遇到快速移动物体的问题,TimeManager检查器已减少,使模拟更加准确。但由于您是手动指定碰撞反应,这可能不是问题。您遇到的问题称为“隧道”。发生这种情况是因为您的对象正在高速移动并且在该特定帧中未检测到碰撞。在第n帧中,球就在球棒前面,但在计算时间帧n+1时,球已经移动到球棒后面,因此完全“错过”了碰撞。这是一个常见问题,但有一个解决方案。我建议你学习这个脚本并尝试在你的游戏中实现它。这不是我的代码:来源:http://wiki.unity3d.com/index.php?id=1title=DontGoThroughThings以上是C#学习教程:空中曲棍球游戏——如果玩家移动太快,玩家的球棒冰球分享的全部内容将通过,如果对大家有用还需要了解更多的C#学习教程,希望大家多多关注——使用UnityEngine;使用系统集合;publicclassDontGoThroughThings:MonoBehaviour{//将此设置为true时要小心-它可能会导致双重//事件被触发-但它不会通过触发器publicboolsendTriggerMessage=false;publicLayerMasklayerMask=-1;//确保我们不在这一层publicfloatskinWidth=0.1f;//可能不需要改变privatefloatminimumExtent;私人浮动部分范围;私人浮动sqrMinimumExtent;刚体我的刚体;私人对撞机myCollider;//初始化值voidStart(){myRigidbody=GetComponent();myCollider=GetComponent();previousPosition=myRigidbody.position;minimumExtent=Mathf.Min(Mathf.Min(myCollider.bounds.extentsx,myCollider.bounds.extents.y),myCollider.bounds.extents.z);partialExtent=minimumExtent*(1.0f-skinWidth);sqrMinimumExtent=minimumExtent*minimumExtent;}voidFixedUpdate(){//我们移动的范围是否超过了最小范围?Vector3movementThisStep=myRigidbody.position-previousPosition;floatmovementSqrMagnitude=movementThisStep.sqrMagnitude;如果(movementSqrMagnitude>sqrMinimumExtent){floatmovementMagnitude=Mathf.Sqrt(movementSqrMagnitude);RaycastHit命中信息;//检查我们可能错过的障碍物如果(hitInfo.collider.isTrigger)hitInfo.collider.SendMessage("OnTriggerEnter",myCollider);如果(!hitInfo.collider.isTrigger)myRigidbody.position=hitInfo.point-(movementThisStep/movementMagnitude)*partialExtent;}}previousPosition=myRigidbody.position;}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处:
