我已经开始一个项目,我在播放器上附加了刚体以对其施加一些力。因此,当我运行项目时,在FixedUpdate()
函数中,我会向播放器施加力以使其向前移动。因此,当我按leftarrow或rightarrow时,执行“倾斜”意味着旋转翅膀。
但是现在我想通过按Uparrow或Downarrow平稳地上下移动播放器,当我同时按下Uparrow和Downarrow时,这一定会对播放器产生影响。
这是我的代码。请帮助我。 :(
void FixedUpdate ()
{
rb.AddForce(transform.forward *1000f);
float movedir = Input.GetAxis ("Horizontal");
Vector3 movement = new Vector3 (movedir, 0.0f, 0.0f);
rb.velocity = movement * movingspeed;
rb.rotation = Quaternion.Euler (0.0f, 0.0f, rb.velocity.x * -3f);//perform tilt
if (Input.GetKeyDown (KeyCode.UpArrow))
{
//code for smoothly move up from current position to = current position + 2f
}
if (Input.GetKeyDown (KeyCode.DownArrow))
{
//code for smoothly move down from current position to = current position - 2f
}
}
答案 0 :(得分:0)
您的问题尚不清楚。移动smoothly
可能意味着很多事情。
通常,您应该使用RigidBody.MovePosition和Rigidbody.MoveRotation来设置Rigidbody
的变换,而不要使用rb.rotation
和rb.position
来获得“平滑”动作:
使用Rigidbody.MovePosition移动Rigidbody,遵守Rigidbody的插值设置。
如果在Rigidbody上启用了Rigidbody插值,则调用Rigidbody.MovePosition会在渲染的任何中间帧中的两个位置之间平滑过渡。如果要在每个FixedUpdate中连续移动刚体,则应使用此方法。
如果要将刚体从一个位置传送到另一个位置,而不会渲染中间位置,请改为设置Rigidbody.position。
如您所见,根据您的设置,使用Rigidbody.MovePosition
可能会导致“平滑”运动。
rb.MovePosition(transform.position + Vector3.up * 2.0f);
还使用Input.GetKeyDown
,所以它像触发器一样工作……它不会像Input.GetKey
那样被连续调用
如果要在按住键的同时连续移动,请使用例如
// set e.g. in the inspector
public float verticalMoveSpeed;
// ...
if (Input.GetKey(KeyCode.UpArrow))
{
rb.MovePosition(transform.position + Vector3.up * verticalMoveSpeed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.DownArrow))
{
rb.MovePosition(transform.position - Vector3.up * verticalMoveSpeed * Time.deltaTime);
}
如果您只想使用GetKeyDown
来触发移动,则也可以执行类似的操作
// set e.g. in the inspector
public float verticalMoveSpeed;
// ...
if (Input.GetKeyDown(KeyCode.UpArrow))
{
StartCoroutine(MoveVertical(2.0f, verticalMoveSpeed));
}
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
StartCoroutine(MoveVertical(-2.0f, verticalMoveSpeed));
}
// ...
private IEnumerator MoveVertical(float distance, float speed)
{
var originalY = transform.position.y;
var targetY = originalY + distance;
var currentY = originalY;
do
{
rb.MovePosition(new Vector 3(transform.position.x, currentY, transform.positiom.z);
// Update currentY to the next Y position
currentY = Mathf.Clamp(currentY + speed * Time.deltaTime, originalY, targetY);
yield return null;
}
while(currentY < originalY);
// make sure you didn't move to much on Y
rb.MovePosition(new Vector3(transform.position.x, targetY, transform.position,z));
}
有两种方法可以防止并发例程:
使用一个标志。这也可以防止例程被中断/两次调用/并发
privtae bool isMovingVertical;
// ...
if (Input.GetKeyDown(KeyCode.UpArrow) && !isMovingVertical )
{
StartCoroutine(MoveVertical(2.0f, verticalMoveSpeed));
}
else if (Input.GetKeyDown(KeyCode.DownArrow) && !isMovingVertical )
{
StartCoroutine(MoveVertical(-2.0f, verticalMoveSpeed));
}
// ...
private IEnumerator MoveVertical(float distance, float speed)
{
isMovingVertical = true;
// ...
isMovingVertical = false;
}
使用StopAllCoroutines
中断正在运行的例程(注意,这可能会导致“无限”向一个方向移动-至少在没有通过附加检查阻止它的情况下)
if (Input.GetKeyDown(KeyCode.UpArrow))
{
StopAllCoroutines();
StartCoroutine(MoveVertical(2.0f, verticalMoveSpeed));
}
if (Input.GetKeyDown(KeyCode.DownArrow))
{
StopAllCoroutines();
StartCoroutine(MoveVertical(-2.0f, verticalMoveSpeed));
}