在Unity中经常用到第一人称漫游,比较常用的是用Unity Assets中导入的Charaters包,里面包含第一人称控制器和第三人称控制器,将第一人称控制器拖入场景中就可以用AWSD实现前后左右移动,控制器自带脚步声音效,在一些游戏场景中经常使用。
但是如果需要在场景中来回切换位置,第一人称似乎比较难实现,比如我们经常看到的VR看房中的样板间展示,点击房间的缩略图就会进入到该房间进行漫游,要实现这种效果,我采用的是在场景中布置了多个摄像机,放在合适的位置。
接着给这几个摄像机和鼠标添加移动的脚本,实现按AWSD可以前后左右移动,移动鼠标可以实现画面旋转查看。
新建Mouselook脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Mouselook : MonoBehaviour
{
public enum RotationAxes
{
MouseXAndY = 0,
MouseX = 1,
MouseY = 2
}
public RotationAxes axes = RotationAxes.MouseXAndY;
public float sensitivityHor = 1f;
public float sensitivityVert = 1f;
public float minmumVert = -45f;
public float maxmumVert = 45f;
private float _rotationX = 0;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if (axes == RotationAxes.MouseX)
{
transform.Rotate(0, Input.GetAxis("Mouse X") * sensitivityHor, 0);
}
else if (axes == RotationAxes.MouseY)
{
_rotationX = _rotationX - Input.GetAxis("Mouse Y") * sensitivityVert;
_rotationX = Mathf.Clamp(_rotationX, minmumVert, maxmumVert);
float rotationY = transform.localEulerAngles.y;
transform.localEulerAngles = new Vector3(-_rotationX, rotationY, 0);
}
else
{
_rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert;
_rotationX = Mathf.Clamp(_rotationX, minmumVert, maxmumVert);
float delta = Input.GetAxis("Mouse X") * sensitivityHor;
float rotationY = transform.localEulerAngles.y + delta;
transform.localEulerAngles = new Vector3(-_rotationX, rotationY, 0);
}
}
}
新建move脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class move : MonoBehaviour {
public CharacterController controller;
public Rigidbody rigidbody;
public float speed = 1;
// Use this for initialization
void Start()
{
rigidbody = this.GetComponent<Rigidbody>();
controller = this.GetComponent<CharacterController>();
}
//Move
// Update is called once per frame
void Update()
{
//Move
if (Input.GetKey("a"))
controller.SimpleMove(transform.right * -speed);
if (Input.GetKey("d"))
controller.SimpleMove(transform.right * speed);
if (Input.GetKey("w"))
controller.SimpleMove(transform.forward * speed);
if (Input.GetKey("s"))
controller.SimpleMove(transform.forward * -speed);
}
}
把脚本挂在摄像机上,并添加Rigidbody组件和Charcter Controller组件,在move组件中选择对应的摄像机的controller和rigidbody。
接下来是实现各个相机之间的跳转,新建一个空物体来控制切换,我这里是GameObject。将下面两个脚本都挂在空物体从camera_1跳转camera_0
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Camerachange2 : MonoBehaviour
{
public GameObject camera_0;
public GameObject camera_1;
private Vector3 CameraOriginalPosition2;//摄像机2的初始位置
public IEnumerator Start()
{
yield return new WaitForSeconds(0.1F);
camera_1.SetActive(true);
camera_0.SetActive(false);
//记录摄像机2的原始位置
CameraOriginalPosition2 = new Vector3(camera_1.transform.localPosition.x, camera_1.transform.localPosition.y, camera_1.transform.localPosition.z);
print("摄像机2的原始位置的X=" + CameraOriginalPosition2.x);
print("摄像机2的原始位置的Y=" + CameraOriginalPosition2.y);
print("摄像机2的原始位置的Z=" + CameraOriginalPosition2.z);
}
// Update is called once per frame
public void change1()
{
camera_1.SetActive(false);
camera_0.SetActive(true);
camera_1.transform.position = CameraOriginalPosition2;
}
}
新建脚本从camera_0跳转camera_1:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Camerachange : MonoBehaviour {
public GameObject camera_0;//设置成public可以使unity中出现如下图所示的
public GameObject camera_1;
private Vector3 CameraOriginalPosition; //摄像机1的原始位置
public IEnumerator Start()
{
yield return new WaitForSeconds(0.1F);
camera_1.SetActive(false);
camera_0.SetActive(true);
//记录摄像机1的原始位置
CameraOriginalPosition = new Vector3(camera_0.transform.localPosition.x, camera_0.transform.localPosition.y, camera_0.transform.localPosition.z);
print("摄像机1的原始位置的X=" + CameraOriginalPosition.x);
print("摄像机1的原始位置的Y=" + CameraOriginalPosition.y);
print("摄像机1的原始位置的Z=" + CameraOriginalPosition.z);
}
public void change()
{
camera_0.SetActive(false);
camera_1.SetActive(true);
camera_0.transform.position = CameraOriginalPosition;
}
// Update is called once per frame
void Update () {
}
}
上述代码可以实现每次跳转漫游之后都能后相机回到初始位置
然后添加按钮实现点击跳转。为按钮增加点击事件。