Страница 1 из 1

Как убрать распрыжку. [РЕШЕНО]

СообщениеДобавлено: 20 июл 2017, 15:04
Melkor
Здравствуйте, создал скрипт управления , кинул его на персонажа.
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WASD : MonoBehaviour {

        public float speed;
        public Rigidbody2D rgb2d;
        public bool jump;
        public float Jspeed;

        void Start () {
                rgb2d = GetComponent<Rigidbody2D> ();
        }

        void OnCollisionStay2D(Collision2D coll){
                if (coll.transform.tag == "ground"){
                        jump = true;
                }
        }

        void OnCollisionExit2D(Collision2D coll){
                if (coll.transform.tag == "ground"){
                        jump = false;
                }
        }

        void Update () {
                if (Input.GetKey (KeyCode.A)) {
                        transform.Translate (-speed*Time.deltaTime, 0, 0);
                }

                if (Input.GetKey (KeyCode.D)) {
                        transform.Translate (speed*Time.deltaTime, 0, 0);
                }

                if ((Input.GetKey (KeyCode.W) || Input.GetKey (KeyCode.Space)) && jump) {
                        rgb2d.AddForce (new Vector3(0, Jspeed, 0), ForceMode2D.Impulse);
                }
        }
}
 

настройки:
Скрытый текст:


Собственно проблема в том , что появилась распрыжка: обычно персонаж прыгает на определенную высоту, однако если зажать пробел на месте , то прыгать он будет выше.
Как убрать и из-за чего это возникает?
https://vk.com/video132513584_456239062

Re: Как убрать распрыжку.

СообщениеДобавлено: 20 июл 2017, 15:54
Anonymyx
if ((Input.GetKeyDown (KeyCode.W) || Input.GetKeyDown (KeyCode.Space)) && jump) {
rgb2d.AddForce (new Vector3(0, Jspeed, 0), ForceMode2D.Impulse);

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

Re: Как убрать распрыжку.

СообщениеДобавлено: 20 июл 2017, 16:00
Melkor
Anonymyx писал(а):if ((Input.GetKeyDown (KeyCode.W) || Input.GetKeyDown (KeyCode.Space)) && jump) {
rgb2d.AddForce (new Vector3(0, Jspeed, 0), ForceMode2D.Impulse);

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

p.s. Только начинаю вникать в юнити, трансформ поменяю на векторы.

Re: Как убрать распрыжку.

СообщениеДобавлено: 20 июл 2017, 16:02
Anonymyx
Происходит потому что GetKey возвращает true каждый кадр, пока зажата кнопка, и получается сила накладывается тоже каждый кадр, пока зажата кнопка.
Так вам и не надо было чтобы он прыгал если зажать пробел, не?

Re: Как убрать распрыжку.

СообщениеДобавлено: 20 июл 2017, 16:07
Melkor
Anonymyx писал(а):Происходит потому что GetKey возвращает true каждый кадр, пока зажата кнопка, и получается сила накладывается тоже каждый кадр, пока зажата кнопка.
Так вам и не надо было чтобы он прыгал если зажать пробел, не?


Про то что GetKey возврщает true было понятно , такая задумка и была/
Мне надо чтобы он прыгал все время пока зажат пробел , но чтобы прыгал он на одинаковую высоту.

Re: Как убрать распрыжку.

СообщениеДобавлено: 20 июл 2017, 16:19
Anonymyx
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WASD : MonoBehaviour {

    public float speed;
    public Rigidbody2D rgb2d;
    public bool jump;
    public float Jspeed;
    bool jumping;

    void Start ()
    {
        rgb2d = GetComponent<Rigidbody2D> ();
    }

    void OnCollisionEnter2D(Collision2D coll)
    {
        if (coll.transform.tag == "ground"){
            jump = true;
        }
    }

    void OnCollisionExit2D(Collision2D coll){
        if (coll.transform.tag == "ground"){
            jump = false;
        }
    }

    void Update ()
    {
        if (Input.GetKey (KeyCode.A))
        {
            transform.Translate (-speed*Time.deltaTime, 0, 0);
        }

        if (Input.GetKey (KeyCode.D))
        {
            transform.Translate (speed*Time.deltaTime, 0, 0);
        }

        if ((Input.GetKey (KeyCode.W) || Input.GetKey (KeyCode.Space)) && jump) {
            jumping = true;
        }
    }

    void FixedUpdate()
    {
        if (jumping)
        {
            rgb2d.AddForce(new Vector3(0, Jspeed, 0), ForceMode2D.Impulse);
            jumping = false;
        }
    }
}


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

Re: Как убрать распрыжку.

СообщениеДобавлено: 20 июл 2017, 17:24
Melkor
Anonymyx писал(а):
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WASD : MonoBehaviour {

    public float speed;
    public Rigidbody2D rgb2d;
    public bool jump;
    public float Jspeed;
    bool jumping;

    void Start ()
    {
        rgb2d = GetComponent<Rigidbody2D> ();
    }

    void OnCollisionEnter2D(Collision2D coll)
    {
        if (coll.transform.tag == "ground"){
            jump = true;
        }
    }

    void OnCollisionExit2D(Collision2D coll){
        if (coll.transform.tag == "ground"){
            jump = false;
        }
    }

    void Update ()
    {
        if (Input.GetKey (KeyCode.A))
        {
            transform.Translate (-speed*Time.deltaTime, 0, 0);
        }

        if (Input.GetKey (KeyCode.D))
        {
            transform.Translate (speed*Time.deltaTime, 0, 0);
        }

        if ((Input.GetKey (KeyCode.W) || Input.GetKey (KeyCode.Space)) && jump) {
            jumping = true;
        }
    }

    void FixedUpdate()
    {
        if (jumping)
        {
            rgb2d.AddForce(new Vector3(0, Jspeed, 0), ForceMode2D.Impulse);
            jumping = false;
        }
    }
}


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


Спасибо. Переведу все на физику. И последний вопрос касательно вашего кода: зачем мы проверяем нажатия в апдейте , нельзя ли проверку нажатия клавиш встроить в фикседАпдейт?

Re: Как убрать распрыжку.

СообщениеДобавлено: 20 июл 2017, 17:34
Melkor
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WASD : MonoBehaviour {

        public Vector2 speed = new Vector2(50, 50);
        private Vector2 movement;

        public Rigidbody2D rgb2d;
        public bool jump;
        public float Jspeed;
        bool jumping;

        void Start ()
        {
                rgb2d = GetComponent<Rigidbody2D> ();
        }

        void OnCollisionEnter2D(Collision2D coll)
        {
                if (coll.transform.tag == "ground"){
                        jump = true;
                }
        }

        void OnCollisionExit2D(Collision2D coll){
                if (coll.transform.tag == "ground"){
                        jump = false;
                }
        }

        void Update ()
        {
 
                float inputY = Input.GetAxis ("Vertical");
                float inputX = Input.GetAxis ("Horizontal");

                movement = new Vector2 (speed.x * inputX, speed.y * inputY);

        }

        void FixedUpdate()
        {
                rgb2d.velocity = movement;

                if ((Input.GetKey (KeyCode.W) || Input.GetKey (KeyCode.Space)) && jump)
                {
                        rgb2d.AddForce(new Vector3(0, Jspeed, 0), ForceMode2D.Impulse);
                }
        }
}


Собсственно , перевел все на физику. И с вашим вариантом и с этим , продолжает прыгать на разную высоту, единственное различие - теперь иногда на большую из двух высот он прыгает при первом прыжке.

Re: Как убрать распрыжку.

СообщениеДобавлено: 20 июл 2017, 17:56
Anonymyx
Ввод проверяется каждый фрэйм, а FixedUpdate может вызываться несколько раз за фрэйм или вообще не вызываться, в зависимости от ФПС. Отсюда следует что возможны "двойные нажатия" или потеря ввода. Поэтому ввод принято проверять в Update.
С вашим новым кодом он у меня вообще не прыгает, ибо вы каждый FixedUpdate меняете напрямую скорость и сразу добавляете импуль, но в следующий кадр этот импульс уже будет потерян, ибо вы снова явно указываете velocity.
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WASD : MonoBehaviour {

    public float speed;
    private Vector2 movement;

    public Rigidbody2D rgb2d;
    public bool jump;
    public float Jspeed;
    bool jumping;

    void Start ()
    {
        rgb2d = GetComponent<Rigidbody2D> ();
    }

    void OnCollisionEnter2D(Collision2D coll)
    {
        if (coll.transform.tag == "ground"){
            jump = true;
        }
    }

    void OnCollisionExit2D(Collision2D coll){
        if (coll.transform.tag == "ground"){
            jump = false;
        }
    }

    void Update ()
    {

        float inputY = Input.GetAxis ("Vertical");
        float inputX = Input.GetAxis ("Horizontal");

        movement = new Vector2(inputX, inputY);

    }

    void FixedUpdate()
    {
        rgb2d.AddForce(movement * speed);

        if ((Input.GetKey (KeyCode.W) || Input.GetKey (KeyCode.Space)) && jump)
        {
            rgb2d.AddForce(new Vector3(0, Jspeed, 0), ForceMode2D.Impulse);
        }
    }
}

А если так?
У меня нормально прыгает.

Re: Как убрать распрыжку.

СообщениеДобавлено: 20 июл 2017, 17:59
Melkor
[quote="Anonymyx"][/quote]
, Искренне прошу прощения за несколько последних сообщений, просто обожаю монодевелоп, в котором переодически не работает сохранение ctrl+s и скрипт в юнити не меняется, мой вопрос насчет перемещения части кода , отвечающей за нажатие на клавишу остается открытым))

Re: Как убрать распрыжку.

СообщениеДобавлено: 20 июл 2017, 18:03
Anonymyx
Я уже ответил вроде как.
Ввод проверяется каждый фрэйм, а FixedUpdate может вызываться несколько раз за фрэйм или вообще не вызываться, в зависимости от ФПС. Отсюда следует что возможны "двойные нажатия" или потеря ввода. Поэтому ввод принято проверять в Update.


Сохранение не работает если при запуске MonoDevelop'а включена русская раскладка, тогда иногда вообще hotkey'и не работает.

Re: Как убрать распрыжку.

СообщениеДобавлено: 20 июл 2017, 18:05
Melkor
Anonymyx писал(а):Я уже ответил вроде как.
Ввод проверяется каждый фрэйм, а FixedUpdate может вызываться несколько раз за фрэйм или вообще не вызываться, в зависимости от ФПС. Отсюда следует что возможны "двойные нажатия" или потеря ввода. Поэтому ввод принято проверять в Update.


Сохранение не работает если при запуске MonoDevelop'а включена русская раскладка, тогда иногда вообще hotkey'и не работает.


сообщение писал на необновленной странице , извините.

Re: Как убрать распрыжку.

СообщениеДобавлено: 20 июл 2017, 18:11
Anonymyx
Если используете последний вариант что я кидал, в настройках RigidBody Lineаr drag поставьте что-нибудь больше 0, иначе заносить будет.

Re: Как убрать распрыжку.

СообщениеДобавлено: 20 июл 2017, 18:21
Melkor
Anonymyx писал(а):Если используете последний вариант что я кидал, в настройках RigidBody Lineаr drag поставьте что-нибудь больше 0, иначе заносить будет.

спасибо