В отличие от того, что здесь говорили другие, вы на самом деле делаете НЕ хотите сделать это в Update
.
Ваша цель здесь - один раз дать свой недавно созданный стрелка - начальная скорость, а не постоянная сила.
Я думаю, проблема другого характера:
Вы всегда порождаете новый экземпляр вашего второго скрипта из заданного префаба. Этот префаб, кажется, содержит ссылку на экземпляр Ballista
префаба . По крайней мере, вы никогда не присваиваете новое значение ballista
! Это может быть просто неправильная ссылка, когда finalSpeed
никогда не обновляется.
Сначала вы выполняете 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
) соответственно, чтобы они больше не представляли силу, а действительную скорость в единицах в секунду.
Надеюсь, я достаточно ясно изложил свои мысли, Не стесняюсь спрашивать, если что-то осталось неясным;)