3D Top-Down Несколько вопросов по контроллеру персонажа

Программирование на Юнити.

3D Top-Down Несколько вопросов по контроллеру персонажа

Сообщение Ayerche 17 окт 2023, 23:50

Уважаемые друзья, имеется игра с видом сверху, top-down 3D, рпг, но с управление как в шутере (non-target). Пока ещё реализована только моделька игрока с анимациями и некоторым шмотом. Застрял на управлении и никак не могу сдвинуться уже третью неделю. Перепробовал и рутмоушн, и чарактер контроллер. Есть несколько проблем:
Управление WASD, персонаж смотрит на курсор, но двигается по мировым координатам (W -> бежит строго север). Анимации блендятся хорошо.

1) Не могу поменять скорость для движения задним ходом и боковым ходом. Куда писать и что конкретно?
2) Если я хочу сделать дополнительную анимацию удара, прыжка, бега спринтом - лучше это делать через IK?
3) Когда в Update меняю то, что там сейчас на
transform.Translate(Vector3.right * Input.GetAxis("Horizontal") * Time.deltaTime * speed);
transform.Translate(Vector3.forward * Input.GetAxis("Vertical") * Time.deltaTime * speed);

Для игрока перед становится там, где курсор т.е. W -> бежит в сторону курсора, а не "на север". Но почему-то полностью пропадает коллизия с террейном, объектами. Т.е. capsule collider будто перестает существовать, хотя игрок "под землю" не проваливается. Из-за чего так?

4) Персонаж падает вначале очень медленно, но со временем ускоряется. Но сначала будто в воздухе летит несколько секунд. Из-за чего так? Нереалистично.
5) Если я хочу всё же сделать так, чтобы персонаж бежал вперед именно в сторону курсора (что упростило бы анимации) - так было бы правильнее? Удобнее? Как тогда подкорректировать код, чтобы перед для персонажа был там, где курсор? Как сделать так, чтобы анимации блендились уже с учетом этого направления?
6) Анимации ударов, стрельбы при каком управлении будет проще прикрутить, как и саму стрельбу с ударами?

Вот кодик:
Синтаксис:
Используется csharp
public class PlayerControl : MonoBehaviour {

        [Header("Скорость:")]
        public float speed = 4f;
        public float acceleration = 10f;
        public float RunSpeed = 3f;
                       
        [Header("Поворот:")]
        public Transform bodyTransform;
        public float smooth = 3;
        public bool useSmooth;

        //private float gravityForce;

        [Header("Скрипт контроля камеры")]
        public Transform cameraParent;
       
        private Vector3 direction;
        private Rigidbody body;
        public Animator _anim;
        private float vertical;
    private float horizontal;
        Vector3 camForward;
        Vector3 move;
        Vector3 moveInput;
        Transform Cam;

        float forwardAmount;
        float turnAmount;

        void Awake()
        {
                body = GetComponent<Rigidbody>();
                body.freezeRotation = true;
                _anim = GetComponent<Animator>();
               
                Cam = Camera.main.transform;
        }
       
        void FixedUpdate()
        {
        vertical = Input.GetAxis("Vertical");
        horizontal = Input.GetAxis("Horizontal");

                if(Cam != null)
                {
                        camForward = Vector3.Scale(Cam.up, new Vector3(1,0,1)).normalized;
                        move = vertical * camForward + horizontal * Cam.right;
                }
                else
                {
                        move = vertical * Vector3.forward + horizontal * Vector3.right;
                }

                if (move.magnitude > 1)
                {
                        move.Normalize();
                }
                Move(move);

                body.AddForce(direction.normalized * acceleration * body.mass * speed);
                if(Mathf.Abs(body.velocity.x) > speed)
                {
                        body.velocity = new Vector3(Mathf.Sign(body.velocity.x) * speed, body.velocity.y, body.velocity.z);
                }
                if(Mathf.Abs(body.velocity.z) > speed)
                {
                        body.velocity = new Vector3(body.velocity.x, body.velocity.y, Mathf.Sign(body.velocity.z) * speed);
                }
                Rotation();
               
        }
        void Move(Vector3 move)
        {
                if(move.magnitude > 1)
                {
                        move.Normalize();
                }
                this.moveInput = move;
                ConvertMoveInput();
                UpdateAnimator();
        }

        void ConvertMoveInput()
        {
                Vector3 localMove = transform.InverseTransformDirection(moveInput);
                forwardAmount = localMove.z;
                turnAmount = localMove.x;
        }

        void UpdateAnimator()
        {
                _anim.SetFloat("Forward", forwardAmount, 0.1f, Time.deltaTime);
                _anim.SetFloat("Turn", turnAmount, 0.1f, Time.deltaTime);
        }
        void Rotation()
        {
                Vector3 lookPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.position.y)) - body.position;
                lookPos.y = 0;

                if(useSmooth)
                {
                        Quaternion playerRotation = Quaternion.LookRotation(lookPos);
                        bodyTransform.rotation = Quaternion.Lerp(bodyTransform.rotation, playerRotation, smooth * Time.fixedDeltaTime);
                }
                else
                {
                        bodyTransform.rotation = Quaternion.LookRotation(lookPos);
                }
        }

        void Update()
        {
                float h = Input.GetAxis("Horizontal");
                float v = Input.GetAxis("Vertical");
                direction = new Vector3(h, 0, v);
                direction = cameraParent.TransformDirection(direction);
                direction = new Vector3(direction.x, 0, direction.z);
    }
}
 


P.S. Я начинающий кодер с знаниями основ, но в геймдеве больше как моделлер и композитор музыки. Поэтому не всё прям соображаю в коде. Прочитать - могу, а вот написать с нуля - это пока что не досягаемая вершина.
Ayerche
UNец
 
Сообщения: 3
Зарегистрирован: 06 окт 2023, 21:17

Re: 3D Top-Down Несколько вопросов по контроллеру персонажа

Сообщение Ayerche 18 окт 2023, 11:25

Добавил а FixedUpdate

Синтаксис:
Используется csharp
// Вычисляем вектор до курсора
        Vector3 lookPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.position.y)) - body.position;
        lookPos.y = 0;

        // Определяем уменьшение скорости в зависимости от направления
        float dotProduct = Vector3.Dot(lookPos.normalized, direction.normalized);
   
        // Применяем разную скорость в зависимости от направления
        float targetSpeed = speed;
        if (dotProduct < 0) // Двигается в противоположную сторону
        {
        targetSpeed = oppositeDirectionSpeed;
        }
        else if (Mathf.Abs(dotProduct) < 0.5f) // Двигается влево или вправо
        {
        targetSpeed = sideDirectionSpeed;
        }

        currentSpeed = Mathf.SmoothStep(currentSpeed, targetSpeed, speedChangeSmoothness * Time.fixedDeltaTime);
body.AddForce(direction.normalized * acceleration * body.mass * currentSpeed);


Теперь скорость персонажа меняется в зависимости от направления движения относительно положения курсора мыши. Но правильно ли я сделал? Можно ли изменение скорости сделать плавным, с учетом диагоналей и вообще градуса вектора?
Ayerche
UNец
 
Сообщения: 3
Зарегистрирован: 06 окт 2023, 21:17


Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11