Прыгающий мяч в Unity без контроллера персонажа

Я хотел бы знать, как заставить мяч прыгать в Unity без использования контроллера персонажа. Мяч должен иметь твердое тело для гравитации и сценарий, чтобы заставить его прыгать в относительной ориентации мяча. Может кто-нибудь помочь, пожалуйста.


person proticsam    schedule 24.03.2011    source источник


Ответы (1)


Как skovacs1 утверждает в Unity Answers :

Простой ответ заключается в настройке значения inAirControlAcceleration, и это должно дать вам нечто более похожее на то, что вы себе представляете. Для еще большего контроля вы также можете заменить составное назначение movement.inAirVelocity на

movement.inAirVelocity +=
    movement.direction * Time.deltaTime *
    movement.inAirControlAcceleration 

так что значение масштабируется по количеству ввода h.

Если это по-прежнему не дает вам того, что вы хотите, предполагая, что вы используете точный связанный скрипт (потому что вы ничего не публиковали), вот что делает соответствующий функциональный код в обновлении здесь:

//move horizontally as calculated in UpdateSmoothedMovementDirection * speed
//+ vertically by the speed calculated in ApplyGravity or ApplyJumping
//+ horizontally + vertically by the inAirMovement calculated in ApplyJumping
//+ horizontally by the adjustment to inAirMovement calculated in
//UpdateSmoothedMovementDirection 
var currentMovementOffset = movement.direction * movement.speed
                            + Vector3(0,movement.verticalSpeed,0)
                            + movement.inAirVelocity;
currentMovementOffset *= Time.deltaTime;
movement.collisionFlags = controller.Move (currentMovementOffset);

Все, о чем вы, кажется, заботитесь, это горизонтальное движение, поэтому единственные переменные, о которых вам действительно нужно заботиться, это движение.направление, движение.скорость и движение.inAirVelocity.

Часть, которая выполняет работу:

function UpdateSmoothedMovementDirection() { //called by Update every frame
    //...irrelevant stuff
    //move direction is *always* (canControl is never changed in this script)
    //the horizontal input when the absolute horizontal input is greater than 0.1
    if (movement.isMoving) movement.direction = Vector3 (h, 0, 0);

    //calculate the speed change only when on the ground
    if (controller.isGrounded) {
        var curSmooth = movement.speedSmoothing * Time.deltaTime;
        var targetSpeed = Mathf.Min (Mathf.Abs(h), 1.0);
        if(Input.GetButton("Fire2") && canControl)
            targetSpeed *= movement.runSpeed;
        else
            targetSpeed *= movement.walkSpeed;

        movement.speed = Mathf.Lerp (movement.speed, targetSpeed, curSmooth);
        //...irrelevant stuff
    }
    //inAirVelocity is going to be adjusted horizontally by Time.deltaTime
    //in the direction of horizontal input
    else {
        //...irrelevant stuff
        if (movement.isMoving)
            movement.inAirVelocity += Vector3(Mathf.Sign(h),0,0) * Time.deltaTime
                                      * movement.inAirControlAcceleration;
    }
}

Часть, которая устанавливает начальную скорость inAirVelocity:

function ApplyJumping() { //called by Update every frame
    //...irrelevant stuff
    //When on the ground and we can jump, the inAirVelocity will be 
    //the motion of the platform we're on
    if (controller.isGrounded) {
        if (jump.enabled && Time.time < jump.lastButtonTime + jump.timeout) {
            //...irrelevant stuff
            movement.inAirVelocity = lastPlatformVelocity;
            //...irrelevant stuff
        }
    }
}

Что, вероятно, не то, что вы ожидаете, так это то, что вы когда-либо вычисляете скорость, только когда находитесь на земле.

Оказавшись в воздухе, вы двигаетесь со скоростью, с которой вы двигались, когда в последний раз были на земле, в направлении ввода (movement.direction) + некоторая корректировка, зависящая от направления ввода (inAirVelocity).

Я предполагаю, что это должно каким-то образом имитировать инерцию, но на самом деле это так не работает, потому что вы все еще можете изменить направление, и замедления нет.

Чтобы получить правильное направление инерции, вам нужно переместить изменение в traffic.direction в следующий блок if(Controller.isGrounded). Чтобы получить фактическое инерционное замедление, вы должны вычесть скорость в операторе else с некоторой скоростью сглаживания, пока она не станет равной 0, и сохранить lastPlatformVelocity отдельно от inAirVelocity, добавить это как отдельный термин и также замедлить его.

Чтобы дать полный контроль над скоростью в воздухе, я рекомендую вам убрать параметры скорости из этого блока if (в этом случае inAirVelocity может не понадобиться изменять в UpdateSmoothedMovementDirection).

Кроме того, вы можете изменить то, что вы используете для расчета движения при прыжках, выполнив что-то вроде

if(!controller.isGrounded) movement.speed = inAirSpeed;

но это приведет к некоторому неестественному поведению, и вам, вероятно, потребуется выполнить некоторую настройку в эфире.

person Vivek2012    schedule 28.03.2011