您在跳转时遇到的问题是这里的这一部分:
代码逻辑:
-
if (jump) == true (意思是它在询问,如果玩家当前处于跳跃状态并且当玩家不处于跳跃状态时它不能被调用,因为 if(jump) 将返回 false 而不是激活你的功能。
-
如果 (isGrounded) == true 然后将 JumpHeight * 重力设置为您的 verticalVelocity.y,则下一部分是正确完成的地方
问题在于,您已经为游戏对象(玩家)定义了多个向量,例如verticalVelecoity 和horizontalVelocity 考虑只使用一个向量,因为Vector3 为我们提供了(x,y,z)
我们在 Jump 中使用 .y 轴 -1 或 1;对于水平移动,我们使用 .x 和垂直 .z
这意味着我们正在尝试编辑两个不同的向量,并且只使用您从“输入系统”获得的 _Horizontal 之一,尽管从未将这些值正确设置回“输入系统”。
// 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;
//}
}
- 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)
- 游戏对象“地板”
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
- 播放器组件
In order for it all to successfully work, make sure that these elements are as shown within this picture "Player GameObject" of the inspector
希望对你有帮助,如果有任何问题,请告诉我!
(请提供有关下载的“输入系统包”的信息,链接到您一直遵循的教程链接,以便对您遇到的问题进行最佳评估,谢谢!)