英文:
Unity2D Movement - velocity not working correctly
问题
我已经在这个问题上工作了一段时间,但不知道为什么它不起作用。我希望在鼠标按钮释放时,Rigidbody2D对象能够添加速度,而鼠标按下的时间决定速度的大小。
它在最开始几次按下时工作正常,但当我多次按下时,似乎它记住了之前的速度(即使我将其重置为0)。有人可以帮忙吗?以下是代码和示例:
代码:
public class PlayerControl : MonoBehaviour
{
public UnityEngine.UI.Slider powerBar;
private Rigidbody2D rb;
private float holdDownStartTime;
private float force;
private bool moving = false;
private Vector2 mousePosition;
private Vector2 targetPosition;
private Vector3 growthSize = new Vector3(0.1f, 0.1f, 0);
private void Start()
{
powerBar.gameObject.SetActive(false);
RectTransform rectTransform = powerBar.GetComponent<RectTransform>();
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
//重置RigidBody
rb.velocity = Vector3.zero;
rb.angularVelocity = 0;
rb.position = transform.position;
rb.isKinematic = true;
moving = false;
holdDownStartTime = Time.time;
powerBar.gameObject.SetActive(true);
}
if (Input.GetMouseButton(0))
{
if (!moving)
{
powerBar.value = Time.time - holdDownStartTime;
}
}
if (Input.GetMouseButtonUp(0))
{
powerBar.gameObject.SetActive(false);
float holdDownTime = Time.time - holdDownStartTime;
force = CalculateHoldDownForce(holdDownTime);
Move(force);
}
mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
RotateTowards(mousePosition);
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "Food")
{
Eat();
}
}
private void Eat()
{
this.transform.localScale += growthSize;
}
private void Move(float force)
{
targetPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
rb.velocity = new Vector2(targetPosition.x * force / 100, targetPosition.y * force / 100);
}
private void RotateTowards(Vector2 target)
{
Vector2 direction = (target - (Vector2)transform.position).normalized;
var angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
var offset = 90f;
transform.rotation = Quaternion.Euler(Vector3.forward * (angle + offset));
}
private float CalculateHoldDownForce(float holdTime)
{
holdTime *= 3;
float maxForceHoldTime = 2f;
float holdTimeNormalized = Mathf.Clamp01(holdTime / maxForceHoldTime);
float force = holdTimeNormalized * 100f;
return force;
}
}
视频示例:
https://www.loom.com/share/965cc423e13e4c19a9295f59c5fa896a?sid=8d6e30b2-7f99-4204-a3da-5a720067f292
英文:
I have been working at this for a while and do not know why it doesnt work. I want the rigidbody2D object to add velocity when the mouse button is released and however long the mouse is held down determines the power of the velocity.
It works correctly for the first few pushes but when I begin doing it multiple times it seems like it remembers the velocity from before (even though I reset it to 0). Can anyone help? Code and Example below
Code:
public class PlayerControl : MonoBehaviour
{
public UnityEngine.UI.Slider powerBar;
private Rigidbody2D rb;
private float holdDownStartTime;
private float force;
private bool moving = false;
private Vector2 mousePosition;
private Vector2 targetPosition;
private Vector3 growthSize = new Vector3(0.1f,0.1f,0);
private void Start()
{
powerBar.gameObject.SetActive(false);
RectTransform rectTransform = powerBar.GetComponent<RectTransform>();
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
//reset RigidBody
rb.velocity = Vector3.zero;
rb.angularVelocity = 0;
rb.position = transform.position;
rb.isKinematic = true;
//rb.rotation = transform.rotation;
moving = false;
holdDownStartTime = Time.time;
powerBar.gameObject.SetActive(true);
}
if (Input.GetMouseButton(0))
{
if (!moving)
{
powerBar.value = Time.time - holdDownStartTime;
}
}
if (Input.GetMouseButtonUp(0))
{
powerBar.gameObject.SetActive(false);
float holdDownTime = Time.time - holdDownStartTime;
force = CalculateHoldDownForce(holdDownTime);
Move(force);
}
mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
RotateTowards(mousePosition);
}
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.tag == "Food")
{
Eat();
}
}
private void Eat()
{
this.transform.localScale += growthSize;
}
private void Move(float force)
{
targetPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
rb.velocity = new Vector2(targetPosition.x * force/100, targetPosition.y * force/100);
}
private void RotateTowards(Vector2 target)
{
Vector2 direction = (target - (Vector2)transform.position).normalized;
var angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
var offset = 90f;
transform.rotation = Quaternion.Euler(Vector3.forward * (angle + offset));
}
private float CalculateHoldDownForce(float holdTime)
{
holdTime *= 3;
float maxForceHoldTime = 2f;
float holdTimeNormalized = Mathf.Clamp01(holdTime / maxForceHoldTime);
float force = holdTimeNormalized * 100f;
return force;
}
Video Example:
https://www.loom.com/share/965cc423e13e4c19a9295f59c5fa896a?sid=8d6e30b2-7f99-4204-a3da-5a720067f292
答案1
得分: 2
问题出在Move()函数的计算上。
private void Move(float force)
{
targetPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
rb.velocity = new Vector2(targetPosition.x * force/100, targetPosition.y * force/100);
}
在这段代码中,你将targetPosition向量作为速度输入。正如你在视频中所看到的,物体根据中心点穿过了鼠标位置。你应该像这样修改这个函数:
private void Move(float force)
{
targetPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
var targetDirection = targetPosition - rb.transform.position;
rb.velocity = new Vector2(targetDirection.x * force/100, targetDirection.y * force/100);
}
这样修改后,物体将根据目标方向移动,而不是直接根据鼠标位置移动。
英文:
The problem is calculation in the Move() function.
private void Move(float force)
{
targetPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
rb.velocity = new Vector2(targetPosition.x * force/100, targetPosition.y * force/100);
}
In this code you give targetPosition vector as velocity input. As you can see in the video, object goes through your mouse position according to center. You should edit this function like that:
private void Move(float force)
{
targetPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
var targetDirection = targetPosition - rb.transform.position;
rb.velocity = new Vector2(targetDirection.x * force/100, targetDirection.y * force/100);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论