【问题标题】:Unity Jumping issue for 3d fps3d fps 的 Unity Jumping 问题
【发布时间】:2021-05-14 16:53:09
【问题描述】:

您好,我正在尝试为 fps 游戏创建运动脚本。我有运动但跳转功能不起作用我不确定问题是代码还是我设置字符的方式。在调试日志中,它正在注册我按下了空格键,在调试中它说:FixedUpdate Jump UnityEngine.Debug:Log (object) PlayerMovement:FixedUpdate () (at Assets/PlayerMovement.cs:94)

代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
     [RequireComponent(typeof(Rigidbody))]
 public class PlayerMovement : MonoBehaviour
{
    private float _speed = 7f;
    private CharacterController _charController;
    private float _mouseSensitivity = 450;
    private Camera _camera;
    private float xRotation = 0f;
    private float _minCameraview = -70f, _maxCameraview = 90f;
    private Vector3 _PlayerVelocity;
    public Vector3 jump;
    
public float jumpForce = 2.0f;
    bool isJumpPressed = false;
    public bool isGrounded = true;
    Rigidbody rb;
    // Start is called before the first frame update
    void Start()
    {
      _charController = GetComponent<CharacterController>();
      _camera = Camera.main;

      Cursor.lockState = CursorLockMode.Locked;

      rb = GetComponent<Rigidbody>();
      jump = new Vector3(0.0f, 2.0f, 0.0f);

      //if(_charController == null)

        //Debug.log("No Character Controller attached to player"); 

    }

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

      //Get WASD input for player
      float horizontal = Input.GetAxis("Horizontal");
      float vertical = Input.GetAxis("Vertical");
      // Move player based on WASD input
      Vector3 movement = transform.forward * vertical + transform.right * horizontal;
      
      _charController.Move(movement * Time.deltaTime * _speed);
    
      //Get mouse position input
      float mouseX = Input.GetAxis("Mouse X") * _mouseSensitivity * Time.deltaTime;
      float mouseY = Input.GetAxis("Mouse Y") * _mouseSensitivity * Time.deltaTime;


      // rotate camera based off Y input from Mouse
      xRotation -= mouseY;

      // Clamp Camera rotation
      xRotation = Mathf.Clamp(xRotation, _minCameraview, _maxCameraview);


      _camera.transform.localRotation = Quaternion.Euler(xRotation, 0, 0);

      // rotate player based off X input from Mouse
       transform.Rotate(Vector3.up * mouseX * 3);
      //Jumping 

      if(Input.GetKeyDown(KeyCode.Space) && isGrounded){
      
        rb.AddForce(jump * jumpForce, ForceMode.Impulse);
        isGrounded = false;
              }
    isJumpPressed = Input.GetKeyDown(KeyCode.Space);
    if (isJumpPressed)
    {            
        Debug.Log("Update Jump");
    }
    }
void FixedUpdate()
       {
      // dectect if player is grounded 
        if (_charController.isGrounded)
        {
          _PlayerVelocity.y = 0f;

        }
          // apply gravity to player
        else
        {
            _PlayerVelocity.y += -9.18f * Time.deltaTime;
            _charController.Move(_PlayerVelocity * Time.deltaTime);
        }
        if (isJumpPressed)
        {
          Debug.Log("FixedUpdate Jump");            
        }
       }

}

Rigidbody 我也在使用刚接触的 Rigidbody3D,所以这里是它的设置方式。

这里是角色控制器Character Controller

这是统一的玩家运动PlayerMovement

那么我做错了什么,所以我的角色不会跳?如果可能的话,你能解释一下吗,因为我也试图理解它背后的概念。 (如果这很重要,我正在使用 unity 2020.2.2f1。)

【问题讨论】:

  • 如果你说你使用的是刚体和 CharacterController,那肯定是问题所在。你永远不应该两者兼得。没有其他方法,总有办法做到这一点。
  • 如果你想用角色控制器跳跃,我有一个简单的脚本给你。如果您愿意,请告诉我。
  • @ken 那么你将如何只使用刚体呢?如果你能把角色控制器的脚本也发给我,那就太好了,因为我也想学习。
  • 字符控制器在这种情况下是更好的选择。我会在答案中解释。

标签: c# visual-studio unity3d


【解决方案1】:

问题是你不应该同时使用 ChracacterController 和 Rigidbody。这样做的原因是它变得杂乱无章,它进行了两种不同的物理计算,您可以自己使用其中任何一种来完成。

什么时候应该使用刚体?

刚体应该在 2d 游戏中使用(截至目前,2d 还没有内置角色控制器)。在 3D 中,您可以选择 Rigidbody 或 CharacterController。刚体应该用于飞机、船等。以及任何涉及物理的玩家。对于非玩家使用,刚体应该用于任何东西,如子弹或球。任何使用物理的对象。

什么时候应该使用 CharacterController?

角色控制器应该用于玩家,而不是像飞机或船只这样与物理相关的物体。 CharacterController 具有特殊的内置功能,允许它爬上具有一定坡度限制的斜坡。它们还具有台阶高度,可以控制玩家在 90° 面(如楼梯)上的高度。


我听说这个动作很好,你只希望跳跃起作用。在这种情况下,我将使用 CharacterController 进行跳跃。

float currentGravity;
Vector3 velocity;
public float jump = 2f;
public float gravity = -9.81f;
public float groundDist = 0.5f;
public LayerMask groundMask;

void Update()
{
   if (Physics.Raycast(transform.position, -transform.up, groundedDist, groundedMask)
   {
       currentGravity = -0.5f; //to go slowly down because the player is not truly grounded.

       if (Input.GetKeyDown(KeyCode.Space))
       {
           velocity.y += Mathf.Sqrt(jump * -2 * gravity);
       }
   }
   else
   {
      currentGravity += gravity;
   }
   velocity.y += currentGravity;
   GetComponent<CharacterController>().Move(velocity);
}

这是我为添加跳转而制作的脚本(未经测试)。基本上,我向下(第 10 行)射线投射,最大距离为 groundDist。如果玩家离地面足够近,它会慢慢下降以撞到地面(第 12 行)。在同一个 if 语句中,我检测玩家是否按下了跳转键(第 14 行),然后使用Brackeys 编写的物理方程向玩家添加跳转(第 16 行)。然后,如果玩家不在地面上(第 19 行:使用 raycast if 语句中的 else),它将逐渐增加重力(第 21 行)。第 23 行:实际将重力应用于跳跃速度(如果玩家跳跃)。最后,第 24 行:我使用 Move 将角色向下移动的速度。


您应该可以将其添加到您的脚本中,但如果您需要帮助,请回复此内容,我会添加它。如果您看到/得到任何错误/错误,请告诉我,我会尽力修复它们。

链接:

【讨论】:

  • 我没有添加的东西,但是在你告诉我你因为这个原因收到错误之前先做:除非你添加 LayerMask 到地面物体即有一定名称。然后确保 groundMask 设置为相同的 LayerMask。
  • 到目前为止,我已经修复了大部分编译错误,但我被困在Component.GetComponent&lt;CharacterController&gt;.Move(velocity); 我不断收到错误Component.GetComponent&lt;T&gt;()' is a method, which is not valid in the given context
  • 我该怎么办@ken?
  • 抱歉,您在 > 末尾和 .Move 之前缺少 ()
  • 好吧,我希望这是最后一件事,在Component.GetComponent&lt;CharacterController()&gt; .Move(velocity); 现在得到Invalid expression term '.' 我虽然我可以删除句号,但是带来了更多的错误,这是什么原因造成的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-17
相关资源
最近更新 更多