c# - 空气曲棍球比赛 - 如果移动太快,玩家球棒会穿过冰球

标签 c# unity3d

我目前正在使用 Unity3d 开发一款空气曲棍球游戏。我遇到的问题是,当玩家试图过快地击打冰球时,玩家最终会穿过冰球,因此不会发生碰撞。如果玩家保持静止并且冰球击中玩家,或者如果玩家以较慢的速度击中冰球,则游戏将按预期完美运行。

玩家有一个刚体,使用胶囊对撞机进行连续碰撞检测。 Puck 还具有带连续动态碰撞检测的刚体和带凸面的网格碰撞器。

我尝试将固定时间步长设置为 0.01,但这没有效果。这是玩家移动的脚本:

void ObjectFollowCursor()
{
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    Vector3 point = ray.origin + (ray.direction * distance);

    Vector3 temp = point;
    temp.y = 0.2f; // limits player on y axis

    cursorObject.position = temp;
}

下面是冰球与玩家碰撞时的代码:

// If puck hits player
if(collision.gameObject.tag == "Player")
{
    Vector3 forceVec = this.GetComponent<Rigidbody>().velocity.normalized * hitForce;
    rb.AddForce(forceVec, ForceMode.Impulse);
    Debug.Log ("Player Hit");
}

任何帮助将不胜感激。谢谢。

最佳答案

您遇到的问题称为“隧道”。

发生这种情况是因为您的对象正在高速移动,并且在该特定帧中未检测到碰撞。在 n 帧中,球刚好在球棒前面,但是在计算帧 n+1 时,球已经移动到球棒后面,因此完全“错过”了碰撞.

这是一个常见问题,但有解决方案。

我建议您研究这个脚本并尝试在您的游戏中实现。

这不是我的代码: 来源:http://wiki.unity3d.com/index.php?title=DontGoThroughThings

using UnityEngine;
using System.Collections;

public class DontGoThroughThings : MonoBehaviour
{
       // Careful when setting this to true - it might cause double
       // events to be fired - but it won't pass through the trigger
       public bool sendTriggerMessage = false;  

    public LayerMask layerMask = -1; //make sure we aren't in this layer 
    public float skinWidth = 0.1f; //probably doesn't need to be changed 

    private float minimumExtent; 
    private float partialExtent; 
    private float sqrMinimumExtent; 
    private Vector3 previousPosition; 
    private Rigidbody myRigidbody;
    private Collider myCollider;

    //initialize values 
    void Start() 
    { 
       myRigidbody = GetComponent<Rigidbody>();
       myCollider = GetComponent<Collider>();
       previousPosition = myRigidbody.position; 
       minimumExtent = Mathf.Min(Mathf.Min(myCollider.bounds.extents.x, myCollider.bounds.extents.y), myCollider.bounds.extents.z); 
       partialExtent = minimumExtent * (1.0f - skinWidth); 
       sqrMinimumExtent = minimumExtent * minimumExtent; 
    } 

    void FixedUpdate() 
    { 
       //have we moved more than our minimum extent? 
       Vector3 movementThisStep = myRigidbody.position - previousPosition; 
       float movementSqrMagnitude = movementThisStep.sqrMagnitude;

       if (movementSqrMagnitude > sqrMinimumExtent) 
        { 
          float movementMagnitude = Mathf.Sqrt(movementSqrMagnitude);
          RaycastHit hitInfo; 

          //check for obstructions we might have missed 
          if (Physics.Raycast(previousPosition, movementThisStep, out hitInfo, movementMagnitude, layerMask.value))
              {
                 if (!hitInfo.collider)
                     return;

                 if (hitInfo.collider.isTrigger) 
                     hitInfo.collider.SendMessage("OnTriggerEnter", myCollider);

                 if (!hitInfo.collider.isTrigger)
                     myRigidbody.position = hitInfo.point - (movementThisStep / movementMagnitude) * partialExtent; 

              }
       } 

       previousPosition = myRigidbody.position; 
    }
}

关于c# - 空气曲棍球比赛 - 如果移动太快,玩家球棒会穿过冰球,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33830285/

相关文章:

c# - XML版本程序

c# - Outlook 功能区加载检查器。CurrentItem 为 null

unity3d - 如何在 Unity 的协程函数中使用 await 调用异步函数?

c# - 在unity 3D编辑器中获取右键单击的路径

android - 创建 GameServices 对象时出错

c# - 根据内容调整Unity 4.6 UI Text的高度

c# - 如何减少提取文件所需的时间?

c# - WebApi 代理为具有无效字符的 URL 抛出 404

c# - ASP.NET MVC ActionResult View() 不改变 url

c# - 如何使用 C# 将点击监听器分配给在运行时在 Unity 中创建的游戏对象?