Isometri c Unity 3D Game. Как выстрелить в снаряд? - PullRequest
0 голосов
/ 29 февраля 2020

Я делаю изометрию c 3D-игру. Я сделал два джойстика, один для перемещения плеера, а другой для стрельбы снарядом, когда джойстик отпущен. Я сделал 3 попытки добиться этого результата, но каждый раз возникает проблема. Первая попытка была с этим:

clone.velocity = transform.TransformDirection(newpos);

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

clone.transform.Translate(dir * (launchForce));

, но у нее нет «скорости», поэтому она просто мгновенно перемещается в позицию, не перемещаясь, а переводя, и то же самое происходит с третьей попыткой:

clone.transform.position=Vector3.MoveTowards(Player.transform.position,newpos,10f);

Это лучшее решение до сих пор, потому что оно дает мне возможность выбрать максимальный диапазон между начальной позицией и новой позицией. Вот полный код:

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;

public class shoot : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler
{
private Image bgImg;
private Image joystickImg;
private Vector3 inputVector;
public GameObject proiettile;
private Vector3 dir = Vector3.zero;
private Vector3 newpos;
public float launchForce;
public Rigidbody Player;
private GameObject clone;

private void Start()
{
    bgImg = GetComponent<Image>();
    joystickImg = transform.GetChild(0).GetComponent<Image>();
}

public virtual void OnDrag(PointerEventData ped)
{
    Vector2 pos;
    if (RectTransformUtility.ScreenPointToLocalPointInRectangle(bgImg.rectTransform, ped.position, ped.pressEventCamera, out pos))
    {
        pos.x = (pos.x / bgImg.rectTransform.sizeDelta.x);
        pos.y = (pos.y / bgImg.rectTransform.sizeDelta.y);

        inputVector = new Vector3(pos.x * 2 +1, 0, pos.y * 2 - 1);
        inputVector = (inputVector.magnitude > 1.0f) ? inputVector.normalized : inputVector;

        // Move joystickImg
        joystickImg.rectTransform.anchoredPosition =
            new Vector3(inputVector.x * bgImg.rectTransform.sizeDelta.x / 3
                , inputVector.z * (bgImg.rectTransform.sizeDelta.y / 3));

    }
}

public virtual void OnPointerDown(PointerEventData ped)
{
    OnDrag(ped);
}

public virtual void OnPointerUp(PointerEventData ped)
{
    dir.x = Horizontal();
    dir.z = Vertical();
    newpos = dir * (launchForce);
    clone = Instantiate(proiettile, Player.transform.position, Player.transform.rotation);


    //third attempt
    //clone.transform.position=Vector3.MoveTowards(Player.transform.position,newpos,10f);
    //second attempt
    //clone.transform.Translate(dir * (launchForce));
    //first attempt
    //clone.velocity = transform.TransformDirection(newpos);


    // joystick come back to start position
    inputVector = Vector3.zero;
    joystickImg.rectTransform.anchoredPosition = Vector3.zero;

    //temporary solution to replace the absence of a max range for projectile
    clone.timeoutDestructor = 5;
}

public float Horizontal()
{
    if (inputVector.x != 0)
        return inputVector.x;
    else
        return Input.GetAxis("Horizontal");
}

public float Vertical()
{
    if (inputVector.z != 0)
        return inputVector.z;
    else
        return Input.GetAxis("Vertical");
}
}

1 Ответ

0 голосов
/ 29 февраля 2020

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

Rigidbody будет обрабатывать интерполяцию для вас из коробки (без нее движение может быть затруднено)

Rigidbody будет обрабатывать столкновения между кадрами с CCD для вас из коробки (без него ваш снаряд может go проходить сквозь стены или даже цели, если он достаточно быстр)

И эти две функции сэкономят вам много времени спустя

Одна из попыток: когда я spawn снаряд Я проверяю с помощью SphereCast (или любой другой формы), сталкивается ли он с чем-то. Если это так, я изменяю isTrigger на true, а затем в «OnTriggerExit» я снова меняю isTrigger на false. Если он не сталкивается ни с чем при вызове, я просто устанавливаю isTrigger в false при запуске, и это должно сработать.

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