流畅的玩家滚动球-Unity 3D

时间:2018-10-19 15:35:15

标签: unity3d

我正在尝试实现这种球员的动作: Catch Up (Ketchapp)

从我的角度出发,我尝试并录制了一个有关当前实施情况的视频: CatchUpBallMovementDemo

我面临两种问题:

  1. 在平地上移动时,球突然跳得很厉害,希望您在我录制的视频中清楚地注意到
  2. 当球到达左边缘或右边缘时,您尝试再次滑动它的跳动,而不是因为已经添加了夹紧相关代码而不受限制

我刚刚创建了一个演示项目,因此在这里为它提供了链接,因此您可以亲自检查并向我提出使球运动完美的建议。

演示项目源链接:CatchUpBallDemo

演示项目SIZE 20MB

我目前无法确定是什么导致球运动突然移动,其后继摄像机是否突然运动,尽管我已经创建了用于检查的简单轨迹,但球是否无法正确移动。

球检查器详细信息: enter image description here

在正在运行的演示项目中添加了完整的代码。与我分享您的建议以解决此问题。

代码脚本: BallController

[RequireComponent (typeof(Rigidbody))]
public class BallController : MonoBehaviour
{
    //
    private Rigidbody myRigidBody;
    private bool isJumper;
    private bool allowSpeedIncrease;
    private BallInputHandler ballInputHandler;
    private float speed;
    private float speedMilestone;
    private float jumpCounter;
    private float scoreElapsedTime;

    [SerializeField]
    private bool isGrounded;

    //
    public float ballHorzRange;
    public float ballStartSpeed;
    public float ballTopSpeed;
    public float smoothnessValue;
    public float smoothnessX;

    private void Awake ()
    {
        DoOnAwake ();
    }

    private void DoOnAwake ()
    {
        ballInputHandler = GetComponent<BallInputHandler> ();
        myRigidBody = GetComponent<Rigidbody> ();
        speed = ballStartSpeed;
        speedMilestone = ballStartSpeed;
    }

    public void Start ()
    {
        DoOnStart ();
    }

    private void DoOnStart ()
    {
        // assinging player transform to camera to follow
        Camera.main.GetComponent<CameraFollow> ().FollowPlayer (transform);
    }

    void Update ()
    {
        // slowly increase ball moving speed
        if (allowSpeedIncrease) {

            speed += Time.deltaTime;

            if (speed >= speedMilestone) {
                allowSpeedIncrease = false;
                speed = speedMilestone;
            }
        }

    }

    void FixedUpdate ()
    {
        // do jumping
        if (isJumper) {
            jumpCounter++;
            if (jumpCounter >= 3) {
                isJumper = false;
                jumpCounter = 0;
            }
            myRigidBody.AddForce (Vector3.up * 700f);
        }


        // applying continuous forward velocity
        Vector3 nextVelocity = myRigidBody.velocity;
        nextVelocity.x = ballInputHandler.horizontalInput * smoothnessX;
        nextVelocity.z = speed;

        if (isGrounded) {
            nextVelocity.y = 0;
        } else if (!isJumper) {
            nextVelocity.y -= speed * 0.1f;
        }

        myRigidBody.velocity = nextVelocity.normalized * speed;

        ClampingBallMovement ();
    }

    // ball horizontal movement limitation
    private void ClampingBallMovement ()
    {
        Vector3 currRigidbodyPos = myRigidBody.position;

        if (currRigidbodyPos.x <= -ballHorzRange || currRigidbodyPos.x >= ballHorzRange) {
            currRigidbodyPos.x = Mathf.Clamp (currRigidbodyPos.x, -ballHorzRange, ballHorzRange);
            myRigidBody.position = currRigidbodyPos;
        }
    }

    void OnTriggerEnter (Collider other)
    {
        if (other.CompareTag (GameConstants.TAG_TRACK_SPAWNER)) {
            GameController.Instance.SpawnPlateform ();
        } else if (other.CompareTag (GameConstants.TAG_TRACK_DESTROYER)) {
            Destroy (other.transform.parent.gameObject);
        }
    }
}

BallMeshRolling

public class BallMeshRolling : MonoBehaviour
{
    private Vector3 ballLastPosition;


    void Start ()
    {
        ballLastPosition = transform.parent.position;
    }

    void Update ()
    {

        // implementation-1
        float speed = Vector3.Distance (transform.parent.position, ballLastPosition) * 30f;
        transform.RotateAround (transform.position, Vector3.right, speed);

        //      float dragDifference = (transform.position.x - ballLastPosition.x) * 30f;
        //      transform.RotateAround (transform.position, Vector3.forward, dragDifference);

        ballLastPosition = transform.parent.position;
    }
}

CameraFollow

public class CameraFollow : MonoBehaviour
{

    //
    private Vector3 newPos;
    private Vector3 initialPosition;

    //
    public Transform player;
    public Vector3 offSet;

    void Awake ()
    {
        initialPosition = transform.position;
    }

    void LateUpdate ()
    {
        if (!player)
            return;

        newPos = player.position + offSet;
        newPos.x = ReMap (newPos.x);
        newPos.y = Mathf.Clamp (newPos.y, initialPosition.y, initialPosition.y + 1f);
        //      transform.position = newPos;
        transform.position = Vector3.Lerp (transform.position, newPos, 10f * Time.deltaTime);

    }

    public void FollowPlayer (Transform target)
    {
        player = target;
        ResetCamera ();
    }

    public float ReMap (float value, float from1 = -4f, float to1 = 4f, float from2 = -2.5f, float to2 = 2.5f)
    {
        return (value - from1) / (to1 - from1) * (to2 - from2) + from2;
    }

    public void ResetCamera ()
    {
        transform.position = initialPosition;
    }
}

1 个答案:

答案 0 :(得分:0)

我可以通过将其添加到BallController.ClampingBallMovement()中来解决第二个问题:

private void ClampingBallMovement ()
{
    Vector3 currRigidbodyPos = myRigidBody.position;

    if (currRigidbodyPos.x <= -ballHorzRange || currRigidbodyPos.x >= ballHorzRange) {
        currRigidbodyPos.x = Mathf.Clamp (currRigidbodyPos.x, -ballHorzRange, ballHorzRange);
        myRigidBody.position = currRigidbodyPos;
    }


    // I ADDED THIS
    // Clamp the velocity as well
    if (currRigidbodyPos.x <= -ballHorzRange && myRigidBody.velocity.x < 0 || currRigidbodyPos.x >= ballHorzRange && myRigidBody.velocity.x > 0)
    {
        myRigidBody.velocity = new Vector3(0, myRigidBody.velocity.y, myRigidBody.velocity.z);
    }

}

您夹紧了位置,但也没有夹紧速度。

我无法在PC上重现第一个jerking