我正在尝试制作2.5D SHMUP类型的游戏,在这种游戏中,世界不断前进,而玩家的飞船和相机留在原地。这意味着即使世界在移动,如果玩家的飞船在屏幕中间,它也将停留在屏幕中间。
为此,我创建了一个名为Moving World的空游戏对象,并在其中附加了以下脚本:
public class movingWorldController : MonoBehaviour
{
private float movementSpeed = 5f;
void Update()
{
transform.position = transform.position + new Vector3(0, 0, movementSpeed * Time.deltaTime);
}
}
然后我将照相机和宇宙飞船作为孩子添加到该对象中,因此它们确实与移动的世界对象一起移动。但是,我还在飞船上附加了一个脚本,以使其能够根据玩家的输入进行移动,如果启用了该脚本,飞船将停止响应玩家的输入。该船的脚本如下所示:
public class ShipController : MonoBehaviour
{
public Rigidbody rb;
public float moveSpeed = 5f;
private Vector3 movement;
void Update()
{
movement.x = Input.GetAxisRaw("Horizontal");
movement.z = Input.GetAxisRaw("Vertical");
}
private void FixedUpdate()
{
rb.MovePosition(rb.position + movement * moveSpeed * Time.deltaTime);
}
}
当禁用世界移动脚本时,飞船控制器工作正常,因此我怀疑世界脚本以某种方式覆盖了飞船的位置。我该如何解决?
关于POC的示例,请参见以下视频:https://www.youtube.com/watch?v=-fVjWgfUKn4&t=282s(跳至4:00观看正在运行的游戏)。请注意,在视频游戏中,Gamemaker用于实现效果,而我试图仅使用代码来实现类似效果。
通过执行以下操作,达到了我想要的效果。首先,我删除了MovingWorld
对象,而是将以下脚本应用于了相机:
public class movingWorldController : MonoBehaviour
{
public float movementSpeed = 5f;
void FixedUpdate()
{
transform.position = transform.position + new Vector3(0, 0, movementSpeed * Time.deltaTime);
}
}
这将使相机连续向前移动。接下来,为确保玩家的飞船与摄像机保持同步并可以同时操纵,我将以下脚本应用于飞船的对象:
public class ShipController : MonoBehaviour
{
public Rigidbody rb;
private float shipVelocity = 5f;
public float moveSpeed = 10f;
private Vector3 movement;
void Update()
{
movement.x = Input.GetAxisRaw("Horizontal") * moveSpeed;
movement.z = Input.GetAxisRaw("Vertical") * moveSpeed + shipVelocity;
}
private void FixedUpdate()
{
rb.MovePosition(rb.position + movement * Time.deltaTime);
}
}
[两个重要说明:
shipVelocity
变量被引入以确保船舶继续以摄像机速度航行。FixedUpdate
方法期间发生,以确保其与船在同一帧上移动。使用Update
方法更新它会由于去同步而给船舶带来抖动。