【问题标题】:Collision Detection and isGrounded checks碰撞检测和 isGrounded 检查
【发布时间】:2015-02-20 14:15:15
【问题描述】:

我目前正在使用 Unity 开发一个项目,由于我对 C# 和编程还很陌生,因此我遇到了一些问题。第一个问题是我的玩家的碰撞检测 - 我有一个带有重力的建模刚体和一个附加的(非凸面)网格碰撞器。对于我的墙,它们是带有盒子碰撞器的导入模型。

如果我让我的盒子碰撞器保持模型的默认大小(大约是玩家的两倍厚),那么玩家有时会通过它并飞出另一边。为了解决这个问题,我只是让对撞机更大,以适应墙壁/环境,但如果我希望玩家能够四处走动或在墙壁的两侧,这并不理想。目前玩家在碰撞时会“爬上”墙的一侧,这不应该发生吗?我想知道我是否配置错误,或者完全通过脚本管理玩家的碰撞是否会更好?我在下面有我的角色和玩家组件的屏幕截图: 墙 - http://i.imgur.com/YRdTgSh.png? 播放器 - http://i.imgur.com/DVKOdG1.png?

我的第二个问题是当我尝试检查我的播放器是否接地以让他们跳跃时。下面的代码是我当前用于管理玩家移动和跳跃的整个移动脚本。目前,玩家可以无限跳高,但是如果我从高处生成玩家,他们只会跳一次,直到达到一定高度,然后他们会再次重复跳跃,直到空间被释放。

using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour {

// Update is called once per frame
void FixedUpdate() {

    // Creating floats to hold the speed of the plater
    float playerSpeedHorizontal = 4f * Input.GetAxis ("Horizontal");
    float playerSpeedVertical = 4f * Input.GetAxis ("Vertical");

    // Transform statements to move the player by the playerSpeed amount.
    transform.Translate (Vector3.forward * playerSpeedVertical * Time.deltaTime);
    transform.Translate (Vector3.right * playerSpeedHorizontal * Time.deltaTime);

    // Calling the playerJump function when the jump key is pressed
    if (Input.GetButton("Jump"))
    {
        playerJump();
        Debug.Log ("Can jump");
    }

}

/// Here we handle anything to do with the jump, including the raycast, any animations, and the force setting it's self.
void playerJump() {

    const float JumpForce = 1.0f;
    Debug.Log ("Should Jump");

    if(Physics.Raycast(rigidbody.position, Vector3.up, collider.bounds.extents.y + 0.1f)) {
    //  Debug.Log ("Can jump");
        rigidbody.AddForce (Vector3.up * JumpForce, ForceMode.VelocityChange);
    }
}
}

如果有人可以提供帮助,我将不胜感激,因为我对此感到非常困惑

【问题讨论】:

    标签: c# unity3d collision


    【解决方案1】:

    移动物理体时,使用刚体的 AddForce 函数。您已经将它与您的跳转代码一起使用,这很好,但您还必须将它与所有其他移动代码一起使用。

    transform.Translate (Vector3.forward * playerSpeedVertical * Time.deltaTime);
    transform.Translate (Vector3.right * playerSpeedHorizontal * Time.deltaTime);
    

    应该是

    rigidBody.AddForce(transform.forward * playerSpeedVertical);
    rigidBody.AddForce(transform.right * playerSpeedHorizontal);
    

    这将允许物理引擎在物理模拟期间正确解析刚体的运动。我省略了 ForceMode 参数,但您可以随意使用它。

    通过使用 transform.Translate,您实际上是将刚体传送到碰撞几何体中,因为 transform.Translate 对物理模拟一无所知。

    另外请注意,不要在 FixedUpdate 函数中使用 Time.deltaTime,而应使用 Time.fixedDeltaTime。但是,由于物理模拟始终以固定速率计算,因此您在施加力时实际上不需要使用 fixedDeltaTime。

    至于跳跃,你是在向上投射光线。你想向下投射光线。

    Vector3 rayOrigin = transform.position;
    rayOrigin.y += collider.bounds.extents.y; //move the ray origin up into the collider, so there's no chance your ray cast will begin inside the ground
    float rayDistance = collider.bounds.extents.y + 0.1f;
    
    Ray ray = new Ray();
    ray.origin = rayOrigin;
    ray.direction = Vector3.down;
    
    if(Physics.Raycast(ray, rayDistance, 1 << 8)) {
        rigidbody.AddForce (Vector3.up * JumpForce, ForceMode.VelocityChange);
    }
    

    请注意光线投射的第三个参数,它是1 排除你的播放器,这就是为什么我相信你之前得到不正确的光线投射结果)

    为了知道这对你来说应该是什么参数,首先你需要创建一个新层(在 Unity 中:编辑 -> 项目设置 -> 标签和层)

    创建一个图层,将其称为地面或地形。注意层数。 (即用户层 8 意味着您的光线投射的第三个参数将是 1

    现在最后一步是将此图层分配给您的地面/地形对撞机。

    现在你的玩家应该向下投射一条射线,从他的中段开始,稍微低于他的脚。此射线将忽略他的碰撞器,仅在射线与地面分层物体碰撞时告诉您。

    【讨论】:

    • 使用rigidbody.addforce 来移动玩家根本无法移动。如果我将它设置为vector3.down,我也无法跳转
    • 对于 AddForce,也许最好使用 ForceMode.VelocityChange,因为 4 * playerSpeedHorizo​​ntal 的力可能不足以移动您当前的刚体。至于 Raycast,我自己对它进行了统一测试,并注意到您需要做一些额外的事情才能使 Raycast 表现良好。我将使用我的解决方案编辑我的答案,稍后再回来查看。
    • 好的,太好了!跳跃现在完美! (非常感谢)不过,当我移动我的玩家时,他会以超快的速度朝一个方向射击,但控件的作用更像是指南针而不是方向。因此,如果我按 W,那么无论我在哪里看,他都会朝同一个方向射击。如果我按 S,无论我在哪里看,他都会向 W 的相反方向射击。您能否解释/评论 raycast 代码,以便我能理解它的作用(如果可能)?
    • 抱歉,我以为你出于某种原因正在制作平台游戏。使用刚体.AddRelativeForce,而不是刚体.AddForce。 AddForce 使用世界作为参考点来增加玩家的速度。因此 AddForce(Vector3.right * speed) 将始终沿着世界的正 x 轴移动您。如果您使用 AddRelativeForce,它将从玩家的角度增加玩家的速度。所以 AddRelativeForce(Vector3.right * speed) 会移动到玩家的右边。此外,如果您的播放器移动得太快,请减小与 Vector3.forward 和 Vector3.right 相乘的速度变量。
    • 我并不是想成为一个更大的问题,但是方向位现在可以工作了,但是它增加了速度,这意味着每次它都会让玩家更快,而不仅仅是每次都改变一个设定的数量.
    猜你喜欢
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-30
    相关资源
    最近更新 更多