Почему моя переменная с плавающей запятой всегда равна 0, даже если я ее установил - PullRequest
0 голосов
/ 06 августа 2020

Я только начинаю делать игру с Unity и Visual Studio, я немного запутался, почему мое Speed ​​ значение всегда равно нулю, даже если я установил его равным другой переменной.

public class Ballista : MonoBehaviour
{
    public Transform firePoint;
    public GameObject arrowPrefab;
    public float speed = 10f;

    public float startTimeHold;
    public float holdDownTime;
    public float arrowSpeed = 100f;
    public float finalSpeed;


    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.M))
        {
            startTimeHold = Time.time;
        }
        if (Input.GetKeyUp(KeyCode.M))
        {
            holdDownTime = Time.time - startTimeHold;
            Shoot();
            finalSpeed = holdDownTime * arrowSpeed;
        }
        
        Debug.Log("holddowntimeis: " + holdDownTime);
        Debug.Log("final speed is: " + finalSpeed);

    }
    
    public void Shoot()
    {
        GameObject arrowGO = (GameObject)Instantiate(arrowPrefab, firePoint.position, firePoint.rotation);
    }
}

и это сценарий, в котором мое скорость значение всегда равно нулю

{
    Rigidbody2D rgBody2D;
    public GameObject ballista;
    private float speed;

    private void Awake()
    {
        rgBody2D = GetComponent<Rigidbody2D>();
        
    }
    private void Start()
    {
        \\ i though the code below will set my speed equal to my finalSpeed but it still 0
        speed = ballista.GetComponent<Ballista>().finalSpeed;

        Vector2 mousePos = Input.mousePosition;
        Debug.Log("speed: " + speed);
        rgBody2D.AddForce(mousePos * speed * Time.deltaTime);

    }
    void Update()
    {
        
    }
}

Ответы [ 3 ]

1 голос
/ 06 августа 2020

speed = ballista.GetComponent (). FinalSpeed;

должен входить в блок

void Update(){

}

, а не в

void Start() {

}

так как void start запускается только один раз, и в этот момент скорость равна нулю Надеюсь, это помогло :)

1 голос
/ 07 августа 2020

В отличие от того, что здесь говорили другие, вы на самом деле делаете НЕ хотите сделать это в Update.

Ваша цель здесь - один раз дать свой недавно созданный стрелка - начальная скорость, а не постоянная сила.

Я думаю, проблема другого характера:

  1. Вы всегда порождаете новый экземпляр вашего второго скрипта из заданного префаба. Этот префаб, кажется, содержит ссылку на экземпляр Ballista префаба . По крайней мере, вы никогда не присваиваете новое значение ballista! Это может быть просто неправильная ссылка, когда finalSpeed никогда не обновляется.

  2. Сначала вы выполняете Shoot, а после этого устанавливаете finalSpeed ->, даже если бы это было быть правильной ссылкой, вы всегда получаете неправильное finalSpeed значение!

Я бы фактически изменил ваши два сценария, чтобы ваш экземпляр стрелки контролировался Ballista вместо того, чтобы позволять каждому порожденная стрелка опрашивает саму скорость:

public class Ballista : MonoBehaviour
{
    public Transform firePoint;
    // By giving it the correct type here you don't need GetComponent later
    public Rigidbody2D arrowPrefab;

    public float startTimeHold;
    public float arrowSpeed = 100f;

    // I personally would add aax value and clamp since to fast RigidBodies can break collision detection eventually
    public float maxArrowSpeed = 300;

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.M))
        {
            startTimeHold = Time.time;
        }
        if (Input.GetKeyUp(KeyCode.M))
        {
            var holdDownTime = Time.time - startTimeHold;
            // get the speed before you shoot
            // Here personally I would clamp to be sure the arrow is never faster than maxArrowSpeed 
            // regardless of how long the user held the button pressed
            var finalSpeed = Mathf.Min(holdDownTime * arrowSpeed, maxArrowSpeed);

            Debug.Log("holddowntimeis: " + holdDownTime);
            Debug.Log("final speed is: " + finalSpeed);
            // pass in your speed
            Shoot(finalSpeed);         
        }
    }
    
    private void Shoot(float speed)
    {
        // Instantiate anyway returns the type of the given prefab
        // which now is a Rigidbody2D
        var arrow = Instantiate(arrowPrefab, firePoint.position, firePoint.rotation);
        // Directly set the speed from here
        // -> your arrow doesn't even need an extra component
        // Since you already spawned it with the correct rotation you maybe don't even need the mouse position thing
        // AddForceRelative adds a force in the local space of the arrow so if the rotation is correctly
        // this simply adds the force in its forward direction
        // Note that also using Time.deltaTime actually only makes sense if you set something continuously
        // For a one-time force you wouldn't need it, rather adjust your arrowSpeed field
        arrow.AddForceRelative(Vector2.forward * speed);
    }
}

Вместо использования AddForce или AddForceRelative вы также можете просто установить целевую скорость:

arrow.velocity = Vector2.forward * speed; 

Поскольку вы не обновляетесь это нормально, и намного легче предвидеть фактическую скорость цели, так как при добавлении силы вы должны учитывать массу и трение. Вы бы, конечно, должны были отрегулировать arrowSpeed (и evtl maxArrowSpeed) соответственно, чтобы они больше не представляли силу, а действительную скорость в единицах в секунду.

Надеюсь, я достаточно ясно изложил свои мысли, Не стесняюсь спрашивать, если что-то осталось неясным;)

1 голос
/ 06 августа 2020

Start происходит только один раз.

Start вызывается в кадре, когда скрипт активирован непосредственно перед первым вызовом любого из методов Update.

Не обращая внимания на все остальное, я предполагаю, что вы хотите, чтобы он обновлял speed каждый кадр в Update

Обновление вызывается каждый кадр , если MonoBehaviour включен.

private void Update()
{
    \\ i though the code below will set my speed equal to my finalSpeed but it still 0
    speed = ballista.GetComponent<Ballista>().finalSpeed;

    Vector2 mousePos = Input.mousePosition;
    Debug.Log("speed: " + speed);
    rgBody2D.AddForce(mousePos * speed * Time.deltaTime);

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