using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public GameObject player;
public Rigidbody2D playerRB;
public Transform playerTF;
public float moveForce;
public float rotateForce;
private string currentMoveKey = "";
private string currentRotateKey = "";
void Update()
{
//move
if(Input.GetKey("w") && currentMoveKey == "")
{
currentMoveKey = "w";
playerRB.AddForce(transform.up * moveForce * Time.deltaTime);
}
if (Input.GetKeyUp("w") && currentMoveKey == "w")
{
playerRB.velocity = new Vector2(0, 0);//resets when keyup and not already reset
currentMoveKey = "";
}
if (Input.GetKey("s") && currentMoveKey == "")
{
currentMoveKey = "s";
playerRB.AddForce(transform.up * -moveForce * Time.deltaTime);
}
if (Input.GetKeyUp("s") && currentMoveKey == "s")
{
playerRB.velocity = new Vector2(0, 0);
currentMoveKey = "";
}
//rotate
if (Input.GetKeyDown("a") && currentRotateKey == "")
{
currentRotateKey = "a";
}
if (Input.GetKey("a") && currentRotateKey == "a")
{
playerTF.Rotate(transform.forward * rotateForce * Time.deltaTime);
}
if (Input.GetKeyUp("a") && currentRotateKey == "a")
{
currentRotateKey = "";
}
if (Input.GetKeyDown("d") && currentRotateKey == "")
{
currentRotateKey = "d";
}
if (Input.GetKey("d") && currentRotateKey == "d")
{
playerTF.Rotate(transform.forward * -rotateForce * Time.deltaTime);
}
if (Input.GetKeyUp("d") && currentRotateKey == "d")
{
currentRotateKey = "";
}
}
}
嘿!由于某些原因,在我将力添加到RigidBody2D的行中,如果我在移动玩家的同时旋转播放器-从而改变了transform.up的指向位置-播放器继续朝着原始指向的方向移动。换句话说,他看起来像他在滑动,我必须停止移动并重新开始移动以更新他指向的方向。我该怎么做才能解决此问题,以便在他旋转时,他的移动方向会同时更新?
答案 0 :(得分:0)
加力只是不断增加刚体的动量;您已经知道了这一点,因为您在抬起琴键时已重置速度。当您转身但保持向前移动时,刚体速度不会被重置,而只是进行了相加更改。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public GameObject player;
public Rigidbody2D playerRB;
public Transform playerTF;
public float moveForce;
public float rotateForce;
private Vector3 movement;
private string currentRotateKey = "";
void Update()
{
//move in Local space
if (Input.GetKeyDown(KeyCode.W))
{
movement += Vector3.up;
}
if (Input.GetKeyUp(KeyCode.W))
{
movement -= Vector3.up;
}
if (Input.GetKeyDown(KeyCode.S))
{
movement -= Vector3.up;
}
if (Input.GetKeyUp(KeyCode.S))
{
movement += Vector3.up;
}
//rotate
if (Input.GetKeyDown("a") && currentRotateKey == "")
{
currentRotateKey = "a";
}
if (Input.GetKey("a") && currentRotateKey == "a")
{
playerTF.Rotate(transform.forward * rotateForce * Time.deltaTime);
}
if (Input.GetKeyUp("a") && currentRotateKey == "a")
{
currentRotateKey = "";
}
if (Input.GetKeyDown("d") && currentRotateKey == "")
{
currentRotateKey = "d";
}
if (Input.GetKey("d") && currentRotateKey == "d")
{
playerTF.Rotate(transform.forward * -rotateForce * Time.deltaTime);
}
if (Input.GetKeyUp("d") && currentRotateKey == "d")
{
currentRotateKey = "";
}
// Implicit cast from Vector3 to Vector2, takes X and Ys
ApplyMovement(movement);
}
public void ApplyMovement(Vector2 movement)
{
playerRB.velocity = player.transform.TransformDirection(movement.x, movement.y, 0) * moveForce * Time.deltaTime;
}
}
我发现使用KeyCode
枚举而不是字符串值会更干净一些,而且我想为该类跟踪本地Vector3 movement
而不是检查currentMovementKey
。这样一来,您可以一次按下多个键,并在编译时捕获拼写错误。
将移动“应用”到自己的方法中有助于改变您的行为。
movement
在本地空间中处理,使用Vector3.up
而不是transform.up
以避免旋转时出错,然后将其应用于playerRB.velocity
时,我们可以转换回世界空间使用player.transform.TransformDirection(movement.x, movement.y, 0)
(如果该组件与RigidBody2D组件位于同一GameObject上,则也可以是transform.TransformDirection(movement.x, movement.y, 0)
。
如果您想保持加速度而不是想跳起来而不是减速,但是又不想像真实物体那样漂移,事情会变得有些棘手,这是解决问题的一种方法:>
public void ApplyMovement(Vector3 movement)
{
if (movement.sqrMagnitude > Mathf.Epsilon)
{
playerRB.drag = 0; // or some other small value
if (playerRB.velocity.sqrMagnitude > Mathf.Epsilon)
{
playerRB.velocity = player.transform.TransformDirection(movement.normalized) * playerRB.velocity.magnitude;
}
playerRB.AddRelativeForce(movement * moveForce * Time.deltaTime);
}
else
{
playerRB.drag = 100f; // or some other value larger than the small one
}
}
我们现在正在做的是检查是否有不可忽略的运动量(基本为0),如果要移动,就不施加阻力,因为那样会减慢速度我们的积极加速,这使得难以预测设置游戏时应具有的值。
由于我们现在没有在物体上的阻力,因此它应该根据物理学原理漂移。这就是您目前所看到的。如果我们不希望这样做,可以检查是否有不可忽略的(基本为0)速度,并将其与所需的运动方向对齐。不要忘记movement
仍在本地空间中,playerRB.velocity
仍在世界空间中。
然后,由于我们要应用运动,因此应使用AddRelativeVelocity
将 local 运动应用到身体,以继续沿所需方向加速。目前,这种情况一直持续下去,但是您最终可能希望限制最大速度。
如果我们不应用运动,我们希望物理学应用阻力并降低玩家的速度。如果我们让物理学做功,您应该获得合理的加速或减速速度(取决于阻力值和作用力),但是由于我们忽略了漂移,因此您应该立即转弯。