C# 如何使用脚本准确切换车道?
我正在做一个3车道3d无止境跑步者游戏,我遇到了这个问题 在堆栈溢出的帮助下,我成功地在3条车道上切换角色,几秒钟后,我的角色慢慢离开车道,而不是在每条车道上跑一条直线。切换后,角色将离开车道。真烦人。我怎么修理它 我注意到角色的x轴,点的值一点一点地增加。例如,如果是右车道,则其应为1.0000,但在切换后,其逐渐增加1.0045、1.0345、1.09585,依此类推,反之亦然。有时它也会打断3车道的移动,角色试图不停地向右或向左移动,所以我必须停止播放模式 非常感谢您的帮助 这是我的剧本C# 如何使用脚本准确切换车道?,c#,unity3d,physics,unity5.3,C#,Unity3d,Physics,Unity5.3,我正在做一个3车道3d无止境跑步者游戏,我遇到了这个问题 在堆栈溢出的帮助下,我成功地在3条车道上切换角色,几秒钟后,我的角色慢慢离开车道,而不是在每条车道上跑一条直线。切换后,角色将离开车道。真烦人。我怎么修理它 我注意到角色的x轴,点的值一点一点地增加。例如,如果是右车道,则其应为1.0000,但在切换后,其逐渐增加1.0045、1.0345、1.09585,依此类推,反之亦然。有时它也会打断3车道的移动,角色试图不停地向右或向左移动,所以我必须停止播放模式 非常感谢您的帮助 这是我的剧本
//Variables for Lane switching
private bool isChangingLane = false;
private Vector3 locationAfterChanginLane = Vector3.zero;
private Vector3 sideWayMovementDistance = Vector3.right * 2f; // This might be the case that triggers abnormal movements
private float sideWaySpeed = 6f;
public enum Lane
{
Left,
Right,
Center
}
public enum MoveDirection
{
Left,
Right,
None
}
Lane currentLane = Lane.Center;
void Update()
{
currentBaseState = anim.GetCurrentAnimatorStateInfo(0);
if (controller.isGrounded)
{
verticalVelocity = -0.5f;
if (currentBaseState.fullPathHash == locoState)
{
if (Input.GetButtonDown("Jump"))
{
verticalVelocity = 18f;
anim.SetBool("Jump", true);
}
else if (Input.GetKeyDown(KeyCode.S))
{
anim.SetBool("Slide", true);
}
}
MoveLeftRight(); // This is the method to move right and left.
if (isChangingLane)
{
if (Math.Abs(transform.position.x - locationAfterChanginLane.x) < 0.1f)
{
isChangingLane = false;
moveVector.x = 0;
}
}
}
}
private void MoveLeftRight()
{
MoveDirection requestedMoveDirection = MoveDirection.None;
if (Input.GetKeyDown(KeyCode.A) && !isChangingLane)
{
requestedMoveDirection = MoveDirection.Left;
isChangingLane = true;
}
else if (Input.GetKeyDown(KeyCode.D) && !isChangingLane)
{
requestedMoveDirection = MoveDirection.Right;
isChangingLane = true;
}
switch (requestedMoveDirection)
{
case MoveDirection.Right:
if (currentLane == Lane.Right)
{
Debug.Log("Right Lane");
break; //Do nothing when in right lane.
}
else if (currentLane == Lane.Center)
{
locationAfterChanginLane = transform.position + sideWayMovementDistance;
moveVector.x = +sideWaySpeed;
currentLane = Lane.Right;
Debug.Log("Center --> Right");
}
else if (currentLane == Lane.Left)
{
locationAfterChanginLane = transform.position + sideWayMovementDistance;
moveVector.x = +sideWaySpeed;
currentLane = Lane.Center;
Debug.Log("Left --> Center");
}
break;
case MoveDirection.Left:
if (currentLane == Lane.Left)
{
Debug.Log("Left Lane");
break; //Do nothing when in left lane.
}
else if (currentLane == Lane.Center)
{
locationAfterChanginLane = transform.position - sideWayMovementDistance;
moveVector.x = -sideWaySpeed;
currentLane = Lane.Left;
Debug.Log("Center --> Left");
}
else if (currentLane == Lane.Right)
{
locationAfterChanginLane = transform.position - sideWayMovementDistance;
moveVector.x = -sideWaySpeed;
currentLane = Lane.Center;
Debug.Log("Right --> Center");
}
break;
}
}
//车道切换的变量
private bool isChangingLane=假;
专用矢量3位置AfterChanginLine=矢量3.0;
专用矢量3侧向移动距离=矢量3.right*2f;//这可能是触发异常运动的情况
专用浮子横向速度=6f;
公共枚举巷
{
左边
正确的,
居中
}
公共枚举移动方向
{
左边
正确的,
没有一个
}
车道当前车道=车道中心;
无效更新()
{
currentBaseState=anim.GetCurrentAnimatorStateInfo(0);
if(controller.isground)
{
垂直性=-0.5f;
if(currentBaseState.fullPathHash==locoState)
{
if(Input.GetButtonDown(“跳转”))
{
垂直性=18f;
动画挫折(“跳跃”,真实);
}
else if(Input.GetKeyDown(KeyCode.S))
{
动画设置工具(“幻灯片”,真实);
}
}
MoveLeftRight();//这是左右移动的方法。
国际单项体育联合会(伊斯昌金兰)
{
if(数学绝对值(变换位置x-变换后位置x)<0.1f)
{
isChangingLane=假;
moveVector.x=0;
}
}
}
}
私有void MoveLeftRight()
{
MoveDirection requestedMoveDirection=MoveDirection.None;
if(Input.GetKeyDown(KeyCode.A)&&!isChangingLane)
{
requestedMoveDirection=MoveDirection.Left;
isChangingLane=真;
}
else if(Input.GetKeyDown(KeyCode.D)和&!isChangingLane)
{
requestedMoveDirection=MoveDirection.Right;
isChangingLane=真;
}
开关(请求移动方向)
{
案例移动方向。右:
如果(当前车道==车道右侧)
{
Log(“右车道”);
break;//在正确的车道上什么也不做。
}
else if(当前车道==车道中心)
{
LocationAfterChanginLine=变换位置+侧向移动距离;
moveVector.x=+横向速度;
当前车道=车道。右;
Log(“居中-->右侧”);
}
else if(currentLane==车道左)
{
LocationAfterChanginLine=变换位置+侧向移动距离;
moveVector.x=+横向速度;
当前车道=车道中心;
Log(“左-->中”);
}
打破
案例移动方向。左:
如果(当前车道==车道左侧)
{
Log(“左车道”);
break;//在左车道上什么也不做。
}
else if(当前车道==车道中心)
{
LocationAfterChanginLine=transform.position-侧向移动距离;
moveVector.x=-横向速度;
当前车道=车道。左侧;
Log(“中间-->左”);
}
else if(currentLane==右车道)
{
LocationAfterChanginLine=transform.position-侧向移动距离;
moveVector.x=-横向速度;
当前车道=车道中心;
Log(“右-->中心”);
}
打破
}
}
相当简单,在检查角色当前位置是否接近最终位置的代码部分中,还可以设置最终位置
if (Math.Abs(transform.position.x - locationAfterChanginLane.x) < 0.1f)
{
isChangingLane = false;
moveVector.x = 0;
transform.position = locationAfterChanginLane; //Add this line
}
if(Math.Abs(transform.position.x-locationAfterChanginLine.x)<0.1f)
{
isChangingLane=假;
moveVector.x=0;
transform.position=LocationAfterChanginLine;//添加此行
}
发生这种情况的原因本质上是
Update
函数的工作方式。MonoBehavior的更新不是在固定的时间步长上调用的(我们称之为time.deltaTime
)。因此,在大多数情况下,角色的位置将超过/低于最终值。相当简单,在检查角色当前位置是否接近最终位置的代码部分中,也设置最终位置
if (Math.Abs(transform.position.x - locationAfterChanginLane.x) < 0.1f)
{
isChangingLane = false;
moveVector.x = 0;
transform.position = locationAfterChanginLane; //Add this line
}
if(Math.Abs(transform.position.x-locationAfterChanginLine.x)<0.1f)
{
isChangingLane=假;
moveVector.x=0;
transform.position=LocationAfterChanginLine;//添加此行
}
发生这种情况的原因本质上是Update
函数的工作方式。MonoBehavior的更新不是在固定的时间步长上调用的(我们称之为time.deltaTime
)。因此,在大多数情况下,角色的位置将超过/低于
switch (requestedMoveDirection)
{
case MoveDirection.Right:
if (currentLane == Lane.Right)
{
break; //Do nothing when in right lane.
}
else if (currentLane == Lane.Center)
{
locationAfterChangingLane = transform.position + sideWayMovementDistance;
moveVector.x = +sideWaySpeed;
locationAfterChangingLane.x = Clamp(locationAfterChangingLane.x, RightLaneMin, RightLaneMax);
currentLane = Lane.Right;
}
else if (currentLane == Lane.Left)
{
locationAfterChangingLane = transform.position + sideWayMovementDistance;
moveVector.x = +sideWaySpeed;
locationAfterChangingLane.x = Clamp(locationAfterChangingLane.x, centerLaneMin, centerLaneMax);
currentLane = Lane.Center;
}
break;
case MoveDirection.Left:
if (currentLane == Lane.Left)
{
break; //Do nothing when in left lane.
}
else if (currentLane == Lane.Center)
{
locationAfterChangingLane = transform.position - sideWayMovementDistance;
moveVector.x = -sideWaySpeed;
locationAfterChangingLane.x = Clamp(locationAfterChangingLane.x, leftLaneMin, leftLaneMax);
currentLane = Lane.Left;
}
else if (currentLane == Lane.Right)
{
locationAfterChangingLane = transform.position - sideWayMovementDistance;
moveVector.x = -sideWaySpeed;
locationAfterChangingLane.x = Clamp(locationAfterChangingLane.x, centerLaneMin, centerLaneMax);
currentLane = Lane.Center;
}
break;
}