首頁>Game>source

我建立了一个FPS運動指令碼,该指令碼具有如下所示的跳轉功能

public void Jump()
{
    if (jumpAble && grounded)
    {
        jumpAble = false;
        gameObject.GetComponent<Rigidbody>().velocity = (Vector3.up * jumpForce * Time.deltaTime);
    }
}

由於某些原因,這不会使播放器跳起来.但是,將.velocity = ...替換為

gameObject.GetComponent<Rigidbody>().AddForce(Vector3.up * jumpForce * Time.deltaTime, ForceMode.VelocityChange);

使玩家跳.為什麼是這樣? 我的印象是两者本質上是同一件事,但是有一點區別吗?

此外,不確定是否会影响功能,但這就是整个指令碼

public class Player_Movement : MonoBehaviour

{ 公共變換相機;

public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
public bool grounded;
public GameObject joystick;
public bool isWalking = false;
public bool isRunning = false;
public float walkForce = 12f;
public float runForce = 30f;
public float jumpForce;
public bool jumpAble = true;
public GameObject playerRotationHandler;
public float cameraTouchSensitivity;
public Animator animator;
// Update is called once per frame
void Update()
{
    grounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
    if (grounded)
    {
        jumpAble = true;
    }
    Vector3 direction = joystick.GetComponent<Joystick>().inputDirection.x * transform.right + joystick.GetComponent<Joystick>().inputDirection.y * transform.forward;
    if (isRunning)
    {
        gameObject.GetComponent<Rigidbody>().velocity = (direction * runForce * Time.deltaTime);
    }
    else if (isWalking)
    {
        gameObject.GetComponent<Rigidbody>().velocity = (direction * walkForce * Time.deltaTime);
    }
    else
    {
        gameObject.GetComponent<Rigidbody>().velocity = Vector3.zero;
    }
}
public void Jump()
{
    if (jumpAble && grounded)
    {
        jumpAble = false;
        gameObject.GetComponent<Rigidbody>().velocity = (Vector3.up * jumpForce * Time.deltaTime);
        gameObject.GetComponent<Rigidbody>().AddForce (Vector3.up * jumpForce * Time.deltaTime, ForceMode.VelocityChange);
    }
}
public void Rotate(float xMoveValue, float yMoveValue)
{
    float xRotation = Mathf.Atan2(yMoveValue, cameraTouchSensitivity) * Mathf.Rad2Deg;
    float yRotation = Mathf.Atan2(xMoveValue, cameraTouchSensitivity) * Mathf.Rad2Deg;
    playerRotationHandler.transform.Rotate(xRotation, 0, 0);
    transform.Rotate(0, yRotation, 0, Space.World);
    if (playerRotationHandler.transform.localEulerAngles.x < 300 && playerRotationHandler.transform.localEulerAngles.x > 60)
    {
        if (xRotation < 0)
        {
            playerRotationHandler.transform.localEulerAngles = new Vector3(300, playerRotationHandler.transform.localEulerAngles.y, 0);
        }
        if (xRotation > 0)
        {
            playerRotationHandler.transform.localEulerAngles = new Vector3(60, playerRotationHandler.transform.localEulerAngles.y, 0);
        }
    }
}

}

最新回復
  • 7月前
    1 #

    不同之處在於,而 velocity = value 設置為新值 AddForce(value) 添加到現有速度.刚體將保留它从速度變化中接收到的所有現有動量以及以前接收到的力.但是,在您的情况下却不会,因為您在每次更新時都会覆盖速度,从而匯致刚體"忘記"了以前的作用力和速度變化。

    但是,我有點困惑您的代碼如何允许您的播放器完全跳轉.因為您的Update函式將在每種情况下都用新值替換速度,所以取消了刚體可能从 Jump()接收到的任何速度 方法.但是,不確定在哪裏呼叫该方法,因為您發佈的代碼中没有對该方法的引用.也许玩家在按住跳轉按钮的同時,在每个幀上从不同的指令碼呼叫该方法? 在這種情况下,發生的是名為 Jump的指令碼 和 Update 指令碼的方法將競爭谁可以將速度設置為其首選值.無論執行什麼指令碼,最後获胜.顯然,這是使用 .velocity =時執行更新的指令碼 和使用 .AddForce時執行跳轉的指令碼

    那怎麼可能? 指令碼執行順序不應受此影响.会吗?

    答案是 AddForce 實際上並没有立即改變速度.它的實際作用是命令物理引擎在下一个物理更新期間但在將速度應用於位置之前更改速度.這將在您所有的 Update之後發生 已處理.因此,物理引擎会將力添加到您在 Update中設置的速度之上

    那麼我们可以从中學到什麼?

      Avoid replacing the velocity with velocity = .仅直接增加速度( velocity += value )或通過力量間接實現。

      如果您真的要設置速度,則每个刚體的速度應仅通過一種方法来控製,因此不同的方法不会与谁可以將速度設置為其首選方法競爭 值。

  • unity:在倦怠遊戲的拆卸模式下,如何才能達到撞車或撞車的機製?
  • opengl:着色器闪烁法線贴圖照明