Игрок случайно меняет позицию после реализации элементов интерфейса - PullRequest
0 голосов
/ 21 сентября 2019

Итак, я следовал руководству по созданию 2D-игры в Unity (я новичок, это мой первый контакт с программированием), и я хотел добавить функцию в игру (жирным шрифтом).«Система сердца», которую я добавил, работает правильно (количество пустых сердец равно урону, полученному игроком), но это заставило моего игрока странным образом изменить свою позицию.Вы можете видеть, что есть установленные границы (maxHeight = 3,2, minHeight = -3,2), а также значение его движения (Yincrement = 3,2), и все же, после нажатия стрелок вверх или вниз он, кажется, изменитсяY позиция около 4,67.Вот скрипт игрока:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class Player : MonoBehaviour
{
    private Vector2 targetPos;
    public float Yincrement;

    public float speed;
    public float maxHeight;
    public float minHeigth;

    public int health = 3;
    public int numOfHearts;

    public Image[] hearts;
    public Sprite heartFull;
    public Sprite heartEmpty;

    public GameObject effect;

    public Image healthDisplay;

    private void Update()
    {
        for (int i = 0; i < hearts.Length; i++)
        {
            if (i < health)
            {
                hearts[i].sprite = heartFull;
            }
            else
            {
                hearts[i].sprite = heartEmpty;

                if (i < numOfHearts)
                {
                    hearts[i].enabled = true;
                }
                else
                {
                    hearts[i].enabled = false;
                }
            }

            if (health <= 0)
            {
                SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
            }

            transform.position = Vector2.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);

            if (Input.GetKeyDown(KeyCode.UpArrow) && transform.position.y < maxHeight)
            {
                Instantiate(effect, transform.position, Quaternion.identity);
                targetPos = new Vector2(transform.position.x, transform.position.y + Yincrement);
            }
            else if (Input.GetKeyDown(KeyCode.DownArrow) && transform.position.y > minHeigth)
            {
                Instantiate(effect, transform.position, Quaternion.identity);

                targetPos = new Vector2(transform.position.x, transform.position.y - Yincrement);
            }
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 22 сентября 2019

Основной выпуск

Основная проблема - ваша for петля.Его следует использовать только для обновления пользовательского интерфейса - , а не для многократного вызова вашего движения и перезагрузки сцены!Вы должны закрыть петлю for раньше.

for (int i = 0; i < hearts.Length; i++)
{
    // you can also reduce these to single lines
    hearts[i].enabled = i < numOfHearts;

    if(i < numOfHearts) hearts[i].sprite = i < health ? heartFull : heartEmpty;    
} // <-- ALREADY CLOSE IT HERE

if(health <= 0) ...

...

Зажим положения

Зажим положения крайне небезопасен!Представьте, что текущая позиция равна 3.1, которая по-прежнему равна < maxHeight, поэтому вы добавляете Yincrement один раз, и в результате получается максимально возможная высота 6.3!Это не то, что вы хотели.

Вы должны фиксировать непосредственно на targetPosition, а не на текущем transform.position.Например, вы можете использовать Mathf.Clamp, чтобы убедиться, что targetPos.y всегда остается в заданном диапазоне.

Также, поскольку оба случая делают что-то очень похожее, я бы сократил это до одного движенияиспользуя просто int переменную для установки направления:

...

transform.position = Vector2.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);

var move = 0;
var targetPosY = targePos.y;

if (Input.GetKeyDown(KeyCode.UpArrow) && targetPosY < maxHeight)
{
    move = 1;
}
else if (Input.GetKeyDown(KeyCode.DownArrow) && targetPosY > minHeigth)
{
    move = -1;
}

// Handle the movement according to the direction
// in one single code block for both directions
if(move != 0)
{
    Instantiate(effect, transform.position, Quaternion.identity);

    // increase/decrease the targetPosY according to the move direction
    targetPosY += move * Yincrement;
    // Now make sure it is within the range
    targetPosY = Mathf.Clamp(targetPosY, minHeight, maxHeight);

    // finally assign the new target position
    targetPos = new Vector2(transform.position.x, targetPosY);
}
0 голосов
/ 21 сентября 2019

Не могли бы вы указать подробно, о чем ваша игра и что вы пытаетесь сделать в каждой части сценария.Я мог бы помочь тебе тогда.Кроме того, если это ваш первый контакт с программированием, это путь к продвинутым.Начните с чего-то более простого и сначала поймите основные понятия программирования, прежде чем двигаться дальше.Вот хорошая серия уроков по программированию на c # для начинающих.

https://www.youtube.com/watch?v=pSiIHe2uZ2w

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

transform.position = Vector2.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);

if (Input.GetKeyDown(KeyCode.UpArrow) && transform.position.y < maxHeight)
{
    Instantiate(effect, transform.position, Quaternion.identity);
    targetPos = new Vector2(transform.position.x, transform.position.y + Yincrement);
}
else if (Input.GetKeyDown(KeyCode.DownArrow) && transform.position.y > minHeigth)
{
    Instantiate(effect, transform.position, Quaternion.identity);

    targetPos = new Vector2(transform.position.x, transform.position.y - Yincrement);
}

Также этот код должен быть после того, как вы проверите, переместился ли игрок.

transform.position = Vector2.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);

Вот совет, чтобы сделать движение немного легче.Используйте transform.translate вместо Vector2.MoveTowards.Transform.translate берет 3 поплавка и меняет позицию вашего игрока на три поплавка, представленные в виде вектора.

Вот пример

transform.translate(0,2,0);

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

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class Player : MonoBehaviour
{
    private Vector2 targetPos;
    public float Yincrement;

    public float speed;
    public float maxHeight;
    public float minHeigth;

    public int health = 3;
    public int numOfHearts;

    public Image[] hearts;
    public Sprite heartFull;
    public Sprite heartEmpty;

    public GameObject effect;

    public Image healthDisplay;

    private void Update()
    {
        for (int i = 0; i < hearts.Length; i++)
        {
            if (i < health)
            {
                hearts[i].sprite = heartFull;
            }
            else
            {
                hearts[i].sprite = heartEmpty;

                if (i < numOfHearts)
                {
                    hearts[i].enabled = true;
                }
                else
                {
                    hearts[i].enabled = false;
                }
            }
        }

        if (health <= 0)
        {
            SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
        }

        if (Input.GetKeyDown(KeyCode.UpArrow) && transform.position.y < maxHeight)
        {
            transform.Translate(0,Yincrement,0)
        }
        else if (Input.GetKeyDown(KeyCode.DownArrow) && transform.position.y > minHeigth)
        {
            Instantiate(effect, transform.position, Quaternion.identity);

            transform.Translate(0,Yincrement,0);
        }
    }
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...