Unity 中的平滑下降 - C#

Smooth fall in Unity - C#

我正在开发一个角色控制器脚本,一切正常,但问题是一旦我的播放器开始掉落,它就会突然倒下。我想让玩家逐渐倒下,这是我的角色控制器脚本 -

using UnityEngine;
using System.Collections;

public class CharacterController : MonoBehaviour {

    public float inputDelay = 0.1f;
    public float forwardVel = 12;
    public float rotateCel = 12;
    public float JumpHeight = 20;
    public Vector3 Gravity = new Vector3 (0, -180, 0);
    public bool CanPress;
    private float jumpTime;
    public float _initialJumpTime = 0.4f;
    //[HideInInspector]
    public bool isGrounded;
    Quaternion targetRotation;
    Rigidbody rBody;
    Vector3 forwardInput, turnInput;
    public bool HasJumped;

    public Quaternion TargetRotation
    {
        get {return targetRotation;}
    }
    // Use this for initialization
    void Start () {
        Physics.gravity = Gravity;
        targetRotation = transform.rotation;
        if (GetComponent<Rigidbody> ())
            rBody = GetComponent<Rigidbody> ();
        else {
            Debug.LogError("Character Needs Rigidbody");
        }

    //  forwardInput = turnInput = 0;
        forwardInput = turnInput = Vector3.zero;
    }

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

        GetInput ();
        //Turn ();

        if (CanPress == true) {
            if (Input.GetKeyDown (KeyCode.Space)) { 
                HasJumped = true;
                jumpTime = _initialJumpTime;
            }
        }

        if (HasJumped == true) {
            rBody.useGravity = false;
            jumpTime -= 1 * Time.deltaTime;
            if (jumpTime > 0) {
            Jump();
            }
            else {
                HasJumped = false;
                rBody.useGravity = true;
            }
        }
    }


    void GetInput() {
        //forwardInput = Input.GetAxis ("Vertical");
        //turnInput = Input.GetAxis ("Horizontal");
        forwardInput = new Vector3 (Input.GetAxis ("Horizontal") * rotateCel, 0, Input.GetAxis ("Vertical") * forwardVel);
        forwardInput = transform.TransformDirection (forwardInput);
        if (Input.GetKeyUp (KeyCode.Space)) {
            //HasJumped = false;
        }


    }

    void Jump() { 

            Vector3 up = transform.TransformDirection (Vector3.up);
        GetComponent<Rigidbody> ().AddForce (up * 5, ForceMode.Impulse);

    }
    void FixedUpdate() {

        Run ();
    }
    void Run() {
        if (Mathf.Abs (10) > inputDelay) {
            //Move
            //rBody.velocity = transform.forward * forwardInput * forwardVel;
            rBody.velocity = forwardInput;
        } else {
            //zero velocity
            rBody.velocity = Vector3.zero;

        }

    }
    void Turn() {
    //  targetRotation *= Quaternion.AngleAxis (rotateCel * turnInput * Time.deltaTime, Vector3.up);
    //  transform.rotation = targetRotation;
    }

    void OnTriggerEnter(Collider col) {
        isGrounded = true;
        CanPress = true;
    }

    void OnTriggerExit(Collider col) {
        isGrounded = false;
        CanPress = false;
    }

}

我的角色有一个 Rigidbody attactches,它使用重力并具有 X、Y、Z 旋转约束。

感谢您的帮助。 :)

好的,所以我拿了你的代码玩了一把。

我认为问题是在你的 Run() 函数中,你改变了影响你跳跃的 rigidbody 的速度。

我已经删除了那些东西并稍微改进了您的脚本并对其进行了测试。将它连接到上面有 rigidbody 的胶囊上,下面有一个地板,上面有 box collider,然后点击 space,你应该可以顺利跳跃。

你的新脚本:

using UnityEngine;
using System.Collections;

public class CharacterController : MonoBehaviour
{
    public float inputDelay = 0.1f;
    public float forwardVel = 12;
    public float rotateCel = 12;
    public float jumpHeight = 10;
    private float jumpTime;
    public float _initialJumpTime = 0.4f;
    //[HideInInspector]
    public bool isGrounded;
    Quaternion targetRotation;
    Rigidbody rBody;
    Vector3 forwardInput, turnInput;
    public bool canJump;

    public Quaternion TargetRotation
    {
        get { return targetRotation; }
    }

    void Start()
    {
        targetRotation = transform.rotation;
        if (GetComponent<Rigidbody>())
            rBody = GetComponent<Rigidbody>();
        else
        {
            Debug.LogError("Character Needs Rigidbody");
        }

        //  forwardInput = turnInput = 0;
        forwardInput = turnInput = Vector3.zero;
    }

    void Update()
    {
        GetInput();
        //Turn ();

        if (Input.GetKeyDown(KeyCode.Space) && canJump)
        {
            rBody.AddForce(Vector3.up * jumpHeight, ForceMode.Impulse);
        }
    }


    void GetInput()
    {
        //forwardInput = Input.GetAxis ("Vertical");
        //turnInput = Input.GetAxis ("Horizontal");
        forwardInput = new Vector3(Input.GetAxis("Horizontal") * rotateCel, 0, Input.GetAxis("Vertical") * forwardVel);
        forwardInput = transform.TransformDirection(forwardInput);
    }

    void FixedUpdate()
    {
        //Run();
    }

    void Run()
    {
        //HERE YOU SET THE RIGIDBODYS VELOCITY, WHICH IS CAUSING YOUR JUMP TO NOT WORK PROPERLY. DO NOT MODIFY THE VELOCITY
        //OF A RIGIDBODY
        if (Mathf.Abs(10) > inputDelay)
        {
            //Move
            //rBody.velocity = transform.forward * forwardInput * forwardVel;
            rBody.velocity = forwardInput;
        }
        else
        {
            //zero velocity
            rBody.velocity = Vector3.zero;
        }
    }

    void Turn()
    {
        //  targetRotation *= Quaternion.AngleAxis (rotateCel * turnInput * Time.deltaTime, Vector3.up);
        //  transform.rotation = targetRotation;
    }

    void OnCollisionEnter(Collision col)
    {
        isGrounded = true;
        canJump = true;
    }

    void OnCollisionExit(Collision col)
    {
        isGrounded = false;
        canJump = false;
    }
}

几点:

  • 在 ThisKindOfFashion(jumpHeightisOnGroundcamelCaseExample 中命名您的变量,变量以大写字母开头,例如 GravityJumpHeight 可能会令人困惑。

  • 正如有人曾经回答过我的一个问题,除非您知道自己在做什么,否则不要修改刚体的速度!看起来很奇怪,但是在听从了那个建议之后我再也没有遇到过问题!

  • 在你的脚本中我使用了 OnCollision 而不是 OnTrigger。如果您在 capsule 下方放置一个带有 box collider 且带有 colliderrigidbody 的地板并打开此脚本,您的角色将停在地面上。如果你使用触发器,他会掉下来(至少根据我的经验!)

编码愉快! :-)


编辑 回复您的评论:

"How do you suggest I move the player"

移动可以通过多种不同的方式完成,但我通常一直使用这个,除非我需要做一些不同的事情:

void Update()
{
    if (Input.GetKeyDown(KeyCode.LeftArrow))
    {
        transform.position += Vector3.left * speed * Time.deltaTime; //speed could be 5f, for example (f means float);
    }

    // then do the same for other directions, RightArrow -.right, UpArrow - .forward, DownArrow - .back
}

"How do I adjust how fast the player jumps"

您可以更改 jumpHeight 变量以获得更高或更小的跳跃。如果更快你的意思是下降得更快,转到编辑>项目设置>物理>并将Y重力更改为更小的值,例如-20。

可以找到教程 here

他们有各种各样的教程,甚至还有示例项目附带的教程,因此您可以按照视频将它们放在一起。