【问题标题】:Movement, Mouselook, and Gravity work but Jumping does not运动、Mouselook 和 Gravity 有效,但跳跃无效
【发布时间】:2021-07-14 22:34:12
【问题描述】:

几个月前我开始使用 unity 创建游戏,刚刚切换到新的 Unity 输入系统,我的 Unity 编辑器版本是 2019.4.22f。我正在使用教程并为鼠标外观和运动、跳跃和重力编写脚本。我编写了 mouselook 脚本,它运行良好。然后我也完成了 Player Controller Script 的编写并对其进行了测试,移动、鼠标外观和 Gravity 就像一个魅力,但跳跃却不是,我尝试了其他教程并重复了同样的事情。现在,我尝试仅使用输入系统来执行此操作,因为在我使用项目设置的播放器选项中的“两者”选项之前。我也没有任何控制台警告或错误。有没有人有解决方案或这个问题?

using UnityEngine;
 
public class Movement : MonoBehaviour {
 
    [SerializeField] CharacterController controller;
    [SerializeField] float speed = 11f;
    Vector2 horizontalInput;
 
    [SerializeField] float jumpHeight = 3.5f;
    bool jump;
 
    [SerializeField] float gravity = -30f; // -9.81
    Vector3 verticalVelocity = Vector3.zero;
    [SerializeField] LayerMask groundMask;
    bool isGrounded;
 
    private void Update ()
    {
        isGrounded = Physics.CheckSphere(transform.position, 0.1f, groundMask);
        if (isGrounded) {
            verticalVelocity.y = 0;
        }
 
        Vector3 horizontalVelocity = (transform.right * horizontalInput.x + transform.forward * horizontalInput.y) * speed;
        controller.Move(horizontalVelocity * Time.deltaTime);
 
        // Jump: v = sqrt(-2 * jumpHeight * gravity)
        if (jump) {
            if (isGrounded) {
                verticalVelocity.y = Mathf.Sqrt(-2f * jumpHeight * gravity);
                Debug.Log("isGrounded");
            }
            jump = false;
        }
 
        verticalVelocity.y += gravity * Time.deltaTime;
        controller.Move(verticalVelocity * Time.deltaTime);
    }
 
    public void ReceiveInput (Vector2 _horizontalInput)
    {
        horizontalInput = _horizontalInput;
    }
 
    public void OnJumpPressed ()
    {
        jump = true;
    }
 
}

【问题讨论】:

  • 我已经提出过这样的问题,但我已经删除了。
  • 一般来说,与其有两个单独的Move 调用,我宁愿等到所有运动都计算完毕,然后每帧传入一个运动矢量
  • 我不明白你的意思。

标签: c# unity3d controller gravity


【解决方案1】:

您在跳转时遇到的问题是这里的这一部分: 代码逻辑:

  1. if (jump) == true (意思是它在询问,如果玩家当前处于跳跃状态并且当玩家不处于跳跃状态时它不能被调用,因为 if(jump) 将返回 false 而不是激活你的功能。

  2. 如果 (isGrounded) == true 然后将 JumpHeight * 重力设置为您的 verticalVelocity.y,则下一部分是正确完成的地方

问题在于,您已经为游戏对象(玩家)定义了多个向量,例如verticalVelecoity 和horizo​​ntalVelocity 考虑只使用一个向量,因为Vector3 为我们提供了(x,y,z)

我们在 Jump 中使用 .y 轴 -1 或 1;对于水平移动,我们使用 .x 和垂直 .z 这意味着我们正在尝试编辑两个不同的向量,并且只使用您从“输入系统”获得的 _Horizo​​ntal 之一,尽管从未将这些值正确设置回“输入系统”。

        // Jump: v = sqrt(-2 * jumpHeight * gravity)
        if (jump) {
            if (isGrounded) {
                verticalVelocity.y = Mathf.Sqrt(-2f * jumpHeight * gravity);
                Debug.Log("isGrounded");
            }
            jump = false;
        }

看到问题我会建议进行此类更改,在此更改中我没有使用“输入系统(包)”,但这些是建议的更改,前提是没有(此问题中提供了输入系统变量或调用.

using UnityEngine;

public class MovementTest2 : MonoBehaviour
{
    /* THINGS TO KNOW */
    // Private - Only members of this class have access.
    // Public -Can be accessed outside of the script.
    // Public Static - Can be accessed in other scripts by using  ( nameOfTheScript.VariableFromThatScript ) Which are called Pointers.
    // Protected - Protected means it's only available in the class itself and any child-class.
    // [SerializeField] private - Means that the variable is no longer publicly accessible, but can still be accessed inside the Editor of Unity
    // Giving you the chance to Drag / Drop your Character controller and modify values of other variables (While not overwriting your values outside of your other scripts)
    // Always define, if your variable is Public / Private or Protected
    // By default variables are set to Public, if not defined otherwise.  

    
    // [SerializeField] makes your private variable shown within the inspector where the script is attached to.
    [SerializeField] private CharacterController controller;
    [SerializeField] private float gravity = -9.81f; // Set gravity to be the same as on Earth.
    [SerializeField] private float playerSpeed = 11f;
    [SerializeField] private float jumpForce = 3.5f;  // Tells us the force applied to the "Player" with Jump
    [SerializeField] private Transform groundCheck;
    [SerializeField] private float groundRadius = 0.4f; // groundRadius ( defines the size of The Sphere made From GroundCheck GameObject)
    [SerializeField] private LayerMask groundMask;
    
    [SerializeField] private bool isGrounded; // Tells us if We are currently touching the ground of groundMask;
    [SerializeField] private bool isjump = false; // Default value of isJump to be False;

    // As we have one element / GameObject which moves (Player), we only need one Vector3  called velocity which offers us 3 Axis of (x,y,z).
    private Vector3 velocity;
    
    

    private void Update()
    {
        /* Explanation of what it does */
        /* Check Ground position with a circle radius from GroundObjects */

        /* transform.positon  And CheckSpehre */
        // transform.position Generally means that it will Look for the position of the Player (Since the position is at the centre of the Player)
        // It will make a Sphere with a radius of ... and check if groundMask is found from that radius to define "Grounded" .

        /* Make A new GameObject Called GroundCheck Inside of Player GameObject, Move GroundCheck Under the Player*/
        // Define a seperate GameObject for position (checked) such as groundCheck.position (Which has to be a Child of the Player GameObject)
        // For the groundCheck object to follow the position of the "Player GameObject".
        isGrounded = Physics.CheckSphere(groundCheck.position, groundRadius, groundMask);
        if (isGrounded)
        {
            isjump = false; // The player Is grounded set jumping to be False
        }

        Move();  // Check for movement on vertical and horizontal Movement   ( See -> private void Move() )
        Jump();  // Check if the Player is pressing "Jump" and then make it Jump.  ( See -> private void Jump() )


        velocity.y += gravity * Time.deltaTime; // Player getting applied gravity (falling) 
        controller.Move(velocity * Time.deltaTime);
    }


    private void Move()
    {
        // Get Horizontal And Vertical Axis From Unity Default Inputs
        // Set Horizontal Values of Either (-1 or 1) to x
        // Set Vertical Values of Either (-1 or 1) to z
        float x = Input.GetAxis("Horizontal");  // <-- In Unity Click  ( Edit -> Project Settings -> Input Manager -> Horizontal / Vertical 
                                                // Where you can Change Buttons on Which you Move with and Set Keys Used for them.
        float z = Input.GetAxis("Vertical");

        Vector3 move = (transform.right * x + transform.forward * z);  // Move Player Speed Under controller.Move function.
        controller.Move(move * playerSpeed * Time.deltaTime); // Update All of Velocity To be Associated with deltaTime.
    }

    private void Jump()
    {
        if (Input.GetButtonDown("Jump") && isGrounded) // if jump Button pressed == true And isGrounded == true
        {
            isjump = true; // When Spacebar is pressed or other keys set under Jump, then set its state to true
            velocity.y = Mathf.Sqrt(-2f * jumpForce * gravity);
        }
    }


    /* Remove these function as they are not used or called anywhere within this code. */

    //public void ReceiveInput(Vector2 _horizontalInput)
    //{  
    //    horizontalInput = _horizontalInput;
    //}

    //public void OnJumpPressed()
    //{
    //    jump = true;
    //}
}
  1. GroundCheck 对象

Player requires a new GameObject such as this (Which is used to define "GroundCheck" from under the player instead of from the middle of the Player)

  1. 游戏对象“地板”

Add another "New GameObject" -> "Floor", and use a LayerMask called "Ground", which you have to make

可以在此处找到添加新 LayerMask 的参考说明: https://answers.unity.com/questions/8715/how-do-i-use-layermasks.html

  1. 播放器组件

In order for it all to successfully work, make sure that these elements are as shown within this picture "Player GameObject" of the inspector

希望对你有帮助,如果有任何问题,请告诉我!

(请提供有关下载的“输入系统包”的信息,链接到您一直遵循的教程链接,以便对您遇到的问题进行最佳评估,谢谢!)

【讨论】:

  • @GeneralGrievance Post 现已更新,标题大小写敏感性降低,拼写问题已得到修复。我希望它能让阅读变得更简单。 - 谢谢你的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多