【Unity3D】无限的横轴背景

在街机类的横轴游戏Arcade Game,我们需要背景,但又不想这个背景浪费我们太多的美工时间,可是又不想给玩家一种偷工减料,粗制滥造的感觉。这时我们需要一个无限的横轴背景。如下图所示:


无限的横轴背景和《【Unity3D】连续滚动的背景》(点击打开链接)的原理差不多,只是这次允许玩家自由操纵游戏主角的移动。因此,我们需要在此的制作上加点东西。


一、场景布置

还是这个经典的,我用画图就能画出来的背景:


首先,将这张图片拖入Unity3D之后,你先需要在Unity3D整三个Plane。这三个Plane皆沿X轴旋转90度,然后将上面导入的图片,作为Plane的材质,同时由于Unity3D中的Plane的默认大小是10x10,因此,三个Plane一字排开,分别需要在(10,0,0)(0,0,0)(-10,0,0)这三个位置。


之后,根据我画的图片背景,调整游戏主角——立方体Cube的位置,我这里放在了(0,-2,0.5)这个位置。灯光Directional light自然是必不可少的,同时需要调整主摄像机Main Camera的位置和焦距,来最终完成游戏场景,这里Main Camera的位置和焦距,我设置如下所示:


放在一个远离场景的位置(0,0,100),同时将焦距设置得接近0的无限近景,这样主要是为了减少各种视觉上的凹凸感。


二、脚本编写

接下来,我们需要完成3个工作,一个是主角需要移动,一个是主摄像机Main Camera需要跟着主角移动,最后一个是,场景跟着主角移动,以让玩家觉得,这个横轴背景是无限的。

1、主角移动,这个其实没什么可以说的,原理在《【Unity3D】键盘鼠标控制视角的移动》(点击打开链接)中已经提到过了,直接对立方体Cube赋予以下PlayerController.cs即可,当然这里由于是横轴游戏,所以我们只实现左右/AD两个键的功能。这里的 public int SENSITIVETY在场景内设置为SENSITIVETY=1,方便后期调节。

using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour
{
    public int SENSITIVETY;
    void Update()
    {
        if (Input.GetAxis("Horizontal") != 0)
        {
            transform.Translate(-Input.GetAxis("Horizontal") * SENSITIVETY, 0, 0);
        }
    }
}

2、Main Camera跟着主角移动,对主摄像机赋予如下的CameraController.cs。这里的public GameObject Player;就是那个立方体Cube。

using UnityEngine;
using System.Collections;

public class CameraController : MonoBehaviour
{

    public GameObject Player;
    private Vector3 offset;

    void Start()
    {
        this.offset = this.transform.position - Player.transform.position;//先求出摄像机和主角的两点距离,也就是我们在当前场景布置的两者距离向量
    }

    void Update()
    {
        this.transform.position = new Vector3(Player.transform.position.x + this.offset.x, this.transform.position.y, this.transform.position.z);
        //在每一帧保证摄像机始终在X轴方向和玩家的距离一直,当然,这要不是横轴游戏,自然其它轴也应该保持一段距离
    }
}

上述脚本的目的如下:


这也类似,实际上电影摄影上,对一些主角跑动场景,拍摄的思想了。


3、场景跟着主角移动

上面的两个脚本只能实现摄像机跟随主角移动,但是,场景还是无法连续,这里需要利用一个补位的思想。

我们要求,一旦Cube去到下图的红色位置,最左边的板,需要立即去到最右边来,反之亦然。这也是为何我在最开始,将摄像机弄得如此之远,焦距如此之近,目的就是为了玩家的可见范围仅想与一块版内,看不到这个板的补位过程,从而视觉上看起来是一个无限的横轴背景。


因此,需要对各个Plane,赋予以下的SceneController.cs:

using UnityEngine;
using System.Collections;

public class SceneController : MonoBehaviour {

    public GameObject MainCamera;//摄像机
    public float SCENE_WIDTH;//板的宽度,即Plane的宽度
    public int SCENE_NUM;//板的数量
    private float total_width;//求现有Plane并排在一起的总宽,用于计算板的补位点
    private Vector3 scene_position;//此板所在的位置

	void Start () {
        total_width = SCENE_WIDTH * SCENE_NUM;
        scene_position = this.transform.position;
	}
	
	void Update () {
        if (scene_position.x + total_width / 2.0f < MainCamera.transform.position.x)
        {
            scene_position.x += total_width;
            this.transform.position = scene_position;
        }

        if (MainCamera.transform.position.x < scene_position.x - total_width / 2.0f)
        {
            scene_position.x -= total_width;
            this.transform.position = scene_position;
        }
	}
}

这里的板宽和板数不在脚本中直接指定,是开一个接口给美工等在场景内便于调节。

每一块板,当检测到当前摄像机,已经离自己有板长的一半之远,立即去到下一个位置补位,以完成上述效果。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值