注意:需要用到的插件EasyTouch 5.x
下面是我在Unity中关于控制Camera的一些功能进行设计的物件搭建,分为五个层级,每个层级的transform的position都是(0,0,0),最后一个层级是用来显示场景的Camera。这样搭建的好处是为了方便分别控制Camera的移动旋转和距离目标物体的远近。然后我给CameraFollow写一个Camera控制脚本,就叫CameraController。
具体功能需求:相机需要始终跟随目标对象,点住鼠标右键移动,相机盯着目标上下旋转,鼠标中键是控制视野的远近。在移动平台,移动摇杆,水平轴控制左右旋转,垂直轴控制上下旋转,两个手指向内滑动,视野拉近,两个手指向外滑动,视野拉远。上下旋转的时候做一下限制视角,视野也得做下限制。
下图是一个功能测试场景:
相机脚本如下:
using HedgehogTeam.EasyTouch;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class CameraController :MonoBehaviour {
private Transform player;
private Transform upAndDown;
private Transform zoomContainer;
private Transform cameraContainer;
public float rotateYSpeed=400f;
public float rotateXSpeed = 200f;
public float zoomSpeed = 120f;
public Vector3 startPos = new Vector3(0, 1, -2.5f);
public GameObject target = null;
private ETCJoystick cameraJoystic;
private void Start()
{
if (target != null)
{ player = target.transform; }
else
{ player = GameObject.FindGameObjectWithTag("Player").transform; }
upAndDown =this.transform.Find("upAndDown");
zoomContainer =this.transform.Find("upAndDown/zoomContainer");
cameraContainer =this.transform.Find("upAndDown/zoomContainer/cameraContainer");
this.cameraContainer.localPosition = startPos;
cameraJoystic =ETCInput.GetControlJoystick("cameraJoystick");
EasyTouch.On_PinchOut += OnPinchOut;
EasyTouch.On_PinchIn += OnPinchIn;
}
private void OnPinchIn(Gesture gesture)
{
Vector3 pos = this.cameraContainer.localPosition;
pos.z -= gesture.deltaPinch *Time.deltaTime * zoomSpeed;
pos.z =Mathf.Clamp(pos.z, -5f, -2f);
this.cameraContainer.localPosition = pos;
}
private void OnPinchOut(Gesture gesture)
{
Vector3 pos = this.cameraContainer.localPosition;
pos.z += gesture.deltaPinch *Time.deltaTime*zoomSpeed;
pos.z =Mathf.Clamp(pos.z, -5f, -2f);
this.cameraContainer.localPosition = pos;
}
private void Update()
{
//follow
this.transform.position = player.position;
float h = cameraJoystic.axisX.axisValue;
float v = cameraJoystic.axisY.axisValue;
if(h!=0)
{
this.transform.Rotate(new Vector3(0, -rotateYSpeed * Time.deltaTime * h, 0));
}
if(v!=0)
{
upAndDown.Rotate(new Vector3(rotateXSpeed * v * Time.deltaTime, 0, 0));
float x= upAndDown.localEulerAngles.x;
x =Mathf.Clamp(x, 10f, 60f);
upAndDown.localEulerAngles =new Vector3(x, 0, 0);
}
//rotate around player
if (Input.GetMouseButton(1))
{
float mouseX = Input.GetAxis("Mouse X");
if (mouseX != 0)
{
this.transform.Rotate(new Vector3(0, rotateYSpeed * Time.deltaTime * mouseX, 0));
}
}
if (Input.GetMouseButton(1))
{
float mouseY = Input.GetAxis("Mouse Y");
if (mouseY != 0)
{
upAndDown.Rotate(new Vector3(-rotateXSpeed * Time.deltaTime * mouseY, 0, 0));
}
}
//lookAt
zoomContainer.LookAt(player.position);
//zoom
float wheelScroll = Input.GetAxis("Mouse ScrollWheel");
Vector3 pos=this.cameraContainer.localPosition;
pos.z += wheelScroll * zoomSpeed *Time.deltaTime;
pos.z =Mathf.Clamp(pos.z, -5f, -2f);
this.cameraContainer.localPosition = pos;
}
private void OnApplicationQuit()
{
EasyTouch.On_PinchOut -= OnPinchOut;
EasyTouch.On_PinchIn -= OnPinchIn;
}
}