Unity中的顺利堕落 - C#

时间:2016-07-07 06:54:27

标签: c# unity3d 3d physics smooth

我正在制作一个角色控制器脚本,一切都运行正常,但问题是,一旦我的玩家开始摔倒,它是如此突然而且猛然下降。我希望玩家逐渐失败,这是我的角色控制器脚本 -

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;
    }

}

我的角色有一个刚体撞击,它使用重力并具有旋转的X,Y,Z约束。

  • 玩家顺利上升并顺利倒下,但两者之间的过渡是非常突然的。

感谢您的帮助。 :)

1 个答案:

答案 0 :(得分:1)

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

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

我已经把这些东西拿出来并稍微改进了你的脚本并进行了测试。将它连接到一个上面有rigidbody的胶囊,下面有一个box collider开启和击中空间,你应该得到一个平滑的跳跃。

你的新(ish)剧本:

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;
    }
}

几点:

  • 在TheThisKindOfFashion(jumpHeightisOnGroundcamelCaseExample)中命名变量,变量以大写字母开头,如GravityJumpHeight可以让人困惑。

  • 正如有人在我的一个问题上回答的那样,除非你知道自己在做什么,否则不要修改刚体的速度!看起来很奇怪,但在遵循了这个建议之后我从来没有遇到任何问题!

  • 在您的脚本中,我使用了OnCollision而不是OnTrigger。如果您在box collider下方放置capsulecolliderrigidbody并打开此脚本,则您的角色将停留在地面上。如果你使用触发器,他将会失败(至少根据我的经验!)

快乐的编码! : - )

修改 回复你的意见:

“你如何建议我移动玩家”

运动可以通过各种不同的方式进行,但我通常会一直使用这种运动,除非我需要做一些不同的事情:

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
}

“如何调整玩家跳跃的速度”

您可以更改jumpHeight变量以获得更高或更小的跳跃。如果速度越快意味着速度越快,请转到编辑&gt;项目设置&gt;物理&gt;并将Y重力改为较小的值,例如-20。

教程可以找到here

他们有各种各样的教程,甚至还有一些示例项目,所以你可以把它放在视频之后。