设置刚体.在Unity2d中鼠标方向的速度:更新版本



是的,我知道SuperSonyk之前问过这个问题!这篇文章在这里:设置rigidbody。Unity2d中鼠标对方向的速度

然而,那个帖子的答案中引用的链接现在是遗留材料,我无法让自己在Unity当前版本中理解它。

我的问题:简而言之,我想让玩家朝着光标的方向加速。我的游戏目前是一款2D的自上而下太空射击游戏。我的玩家已经使用cam.ScreenToWorldPoint正确地看着我的鼠标。但对我来说,不断地尝试增加力量似乎是徒劳的,因为我对编码相当陌生。

如果我的代码中有任何其他问题,如果有人能指出来就太好了!下面是我的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
//================= MOVEMENT =====================
private float thrust = 0.5f;
private float maxSpeed = 10f;
public Rigidbody2D rb;
//================= AIMING =======================
public Camera cam;
Vector2 mousePos;
// Update is called once per frame: Good for INPUTS
void Update()
{
//aiming
mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
}
// Called Set amount of times. Good for PHYSICS CALCULATIONS
void FixedUpdate()
{
Move();
speedLimiter();
//aim
Vector2 lookDirection = mousePos - rb.position;
float angle = Mathf.Atan2(lookDirection.y, lookDirection.x) * Mathf.Rad2Deg - 90f;
rb.rotation = angle;
}
//======= MY MOVE FUNCTION DOES NOT WORK. HELP? ======
void Move()
{
if (Input.GetButtonDown("Accelerate"))
{
rb.velocity = new Vector3(0, thrust, 0) * Time.deltaTime;
}
}
void speedLimiter()
{
if (rb.velocity.magnitude > maxSpeed)
{
rb.velocity = Vector3.ClampMagnitude(rb.velocity, maxSpeed);
}
}
}

请清楚总结编辑内容,谢谢!

一般来说,由于这是一个2D刚体速度也是Vector2你可能更应该使用Vector2.ClampMagnitude

,然后在

rb.velocity = new Vector3(0, thrust, 0) * Time.deltaTime; 

您只想在全局Y方向上移动吗?速度已经是每秒了价值→如果你重新分配一个新的速度,乘以Time.deltaTime是没有意义的。既然上面写的是thrust,我猜你更想添加到现有速度


你更愿意做的是保存你已经拥有的鼠标方向,然后执行

public class PlayerController : MonoBehaviour
{
...
void FixedUpdate()
{
// I would update the aim BEFORE moving
// Use a NORMALIZED direction! Makes things easier later
Vector2 moveDirection = (mousePos - rb.position).normalized;
float angle = Mathf.Atan2(moveDirection.y, moveDirection.x) * Mathf.Rad2Deg - 90f;
rb.rotation = angle;
// OPTIONAL: Redirect the existing velocity into the new up direction 
// without this after rotating you would still continue to move into the same global direction    
rb.velocity = rb.velocity.magnitude * moveDirection;
Move(moveDirection);
speedLimiter();
}

void Move(Vector2 moveDirection)
{
if (Input.GetButtonDown("Accelerate"))
{
// Instead of re-assigning you would probably add to the existing velocity
// otherwise remove the "+" again
rb.velocity += moveDirection * thrust * Time.deltaTime;
}
}
void speedLimiter()
{
if (rb.velocity.magnitude > maxSpeed)
{
// You are working with Vector2 so use the correct method right away
rb.velocity = Vector2.ClampMagnitude(rb.velocity, maxSpeed);
}
}
}

让玩家看着鼠标,你已经完成了一半的工作。我们将使用vectorlookDirection作为玩家的移动方向,normalize所以它的长度是1,然后乘以推力。这样,我们就有了一个指向鼠标方向的矢量,长度,推力

void Move()
{
if (Input.GetButtonDown("Accelerate"))
{
Vector2 lookDirection = (mousePos - rb.position);
rb.AddForce(lookDirection.normalized  * thrust);
}
}

请注意,我们在这里与Vector2工作,因为你使用的是Rigidbody2D。

另外,我不认为在这里使用Time.DeltaTime是相关的。当你对一个物理对象施加力时,你不需要使用它,根据定义,函数FixedUpdate()有一个固定的频率。如果你看一下Unity的教程,你会发现他们没有把它乘以Time.DeltaTime

最后一个提示:你可能想要玩你的Rigidbody2D的drag属性,让你的玩家在不加速的时候慢下来,否则,它会滑出控制,玩家将无法阻止它。

如果我的回答对你来说不清楚或不完全让你满意,请不要犹豫告诉我,这是我在这里的第一个答案!编辑:我忘了告诉你,但是正如derHugo提到的,因为你使用的是Rigidbody2D,你必须使用Vector2.ClampMagnitude来限制你在speedLimiter函数中的速度。此外,我不认为你需要你的if,因为函数Vector2.ClampMagnitude只会改变速度的值,如果它超过最大值。

感谢大家的回复!在Brackeys社区的帮助下,我使用以下方法解决了这个问题:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
//================= MOVEMENT =====================
private float thrust = 10f;
private float maxSpeed = 100f;
public Rigidbody2D rb;
//================= AIMING =======================
public Camera cam;
Vector2 mousePos;
// Update is called once per frame: Good for INPUTS
void Update()
{
//aiming
mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
}
// Called Set amount of times. Good for PHYSICS CALCULATIONS
void FixedUpdate()
{
Move();
speedLimiter();
//aim
Vector2 lookDirection = mousePos - rb.position;
float angle = Mathf.Atan2(lookDirection.y, lookDirection.x) * Mathf.Rad2Deg - 90f;
rb.rotation = angle;
}
void Move()
{
if (Input.GetKey("up"))
{
rb.AddRelativeForce(Vector2.up*thrust);
}
}
void speedLimiter()
{
if (rb.velocity.magnitude > maxSpeed)
{
rb.velocity = Vector3.ClampMagnitude(rb.velocity, maxSpeed);
}
}
//rb.AddForce(new Vector3(0, thrust, 0));
}