视野操控
- 1 PC版:鼠标控制摄像机围绕物体缩放旋转
- 2 安卓版:手指控制中心物体缩放旋转
- 3 安卓版:手指控制摄像机围绕物体缩放旋转
1 PC版:鼠标控制摄像机围绕物体缩放旋转
左键控制摄像机XY轴移动,滑轮控制与物体远近,右键围绕物体旋转
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using DG.Tweening;
public class MoveTest8 : MonoBehaviour {
//偏移量和中心店
Vector3 offest;
public Vector3 target;
//记录第一坐标
Vector3 P1;
public float distance = 422.0f; //记得提前测试好
public float xSpeed = 250.0f;
public float ySpeed = 120.0f;
public float x = 0.0f;
public float y = 0.0f;
//相机移动速度
public float Speed = 400.0f;
public float Gunlun = 5000;
public int yMaxLimit = 90;//最大y(单位是角度)
public int yMinLimit = 0;//最小y(单位是角度)
bool isOpenIntroducde = false;
bool isOpenData = false;
bool isLookScene = false;
public Image IntroduceImage;
public Image DateImage;
public GameObject GameMain;
public GameObject MainCameraa;
void Start ()
{
var angles = MainCameraa.transform.eulerAngles;
x = angles.y;
y = angles.x;
//旋转中心初始点 记得提前测试好
target = new Vector3(-549.4656f, 256.6572f, 225.1308f);
}
void LateUpdate()
{
//中间放大、缩小
if (Input.GetAxis("Mouse ScrollWheel") != 0)
MainCameraa.transform.Translate(new Vector3(0, 0, Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * Gunlun));
if (Input.GetMouseButton(1)) //右键旋转
{
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle(y, (float)this.yMinLimit, (float)this.yMaxLimit);
//返回一个四元数 绕某个轴旋转某个角度
var rotation = Quaternion.Euler(y, x, 0);
var position = rotation * new Vector3(0.0f, 0.0f, -distance) + target;
if (!isLookScene)
{
MainCameraa.transform.rotation = rotation;
MainCameraa.transform.position = position;
}
}
else if(Input.GetMouseButton(0)) //左键移动
{
float x;
float y;
x = Input.GetAxis("Mouse X");
y = Input.GetAxis("Mouse Y");
if (!isLookScene)
MainCameraa.transform.Translate(new Vector3(-x, -y, 0) * Time.deltaTime * Speed);
}
if (Input.GetMouseButtonDown(0))
P1 = MainCameraa.transform.position;
if (Input.GetMouseButtonUp(0))
{
利用射线检测来获取屏幕中心点坐标
Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider)
{
target = new Vector3(hit.point.x, hit.point.y, hit.point.z);
distance = (hit.point - MainCameraa.transform.position).magnitude;
}
}
else
{
offest = MainCameraa.transform.position - P1;
target = target + offest;
distance = (target - MainCameraa.transform.position).magnitude;
}
}
}
//把角度限制到给定范围内
public float ClampAngle(float angle, float min, float max)
{
while (angle < -360)
{
angle += 360;
}
while (angle > 360)
{
angle -= 360;
}
return Mathf.Clamp(angle, min, max);
}
}
注意:鼠标缩放视野后,想要再次右键旋转观察,要先点击左键!!!!,重新记录一下相机和中心位置的距离distance,在右键旋转。否则的话旋转的视野和上一次一样,会有一个跳跃的感觉。
另外:
注意围绕中心点的位置提前设置好,否则当初次运行后,立马右键旋转,会错位的。
做法:运行后先左键单击场景中心点,记录Target 中心点位置 和 Distance 距离值,结束运行,填入控制面板中或者脚本Start初始化里。
2 安卓版:手指控制中心物体缩放旋转
单指控制中心物体旋转,双指控制缩放物体
注意:相机定点观察,改变的是观察的物体。
using UnityEngine;
using System.Collections;
using System.IO;
public class hehe : MonoBehaviour
{
private Touch oldTouch1; //上次触摸点1(手指1)
private Touch oldTouch2; //上次触摸点2(手指2)
void Start()
{
}
void Update()
{
//没有触摸
if (Input.touchCount <= 0)
{
return;
}
//单点触摸, 水平上下旋转
if (1 == Input.touchCount)
{
Touch touch = Input.GetTouch(0);
Vector2 deltaPos = touch.deltaPosition;
transform.Rotate(Vector3.down * deltaPos.x, Space.World);
transform.Rotate(Vector3.right * deltaPos.y, Space.World);
}
//多点触摸, 放大缩小
Touch newTouch1 = Input.GetTouch(0);
Touch newTouch2 = Input.GetTouch(1);
//第2点刚开始接触屏幕, 只记录,不做处理
if (newTouch2.phase == TouchPhase.Began)
{
oldTouch2 = newTouch2;
oldTouch1 = newTouch1;
return;
}
//计算老的两点距离和新的两点间距离,变大要放大模型,变小要缩放模型
float oldDistance = Vector2.Distance(oldTouch1.position, oldTouch2.position);
float newDistance = Vector2.Distance(newTouch1.position, newTouch2.position);
//两个距离之差,为正表示放大手势, 为负表示缩小手势
float offset = newDistance - oldDistance;
//放大因子, 一个像素按 0.01倍来算(100可调整)
float scaleFactor = offset / 100f;
Vector3 localScale = transform.localScale;
Vector3 scale = new Vector3(localScale.x + scaleFactor,
localScale.y + scaleFactor,
localScale.z + scaleFactor);
//最小缩放到 0.3 倍
if (scale.x > 0.3f && scale.y > 0.3f && scale.z > 0.3f)
{
transform.localScale = scale;
}
//记住最新的触摸点,下次使用
oldTouch1 = newTouch1;
oldTouch2 = newTouch2;
}
}
3 安卓版:手指控制摄像机围绕物体缩放旋转
单指控制摄像机旋转,双指控制与物体的远近
注意:观察的物体不动,改变的是摄像机的位置
此方法结合上述前两个而成。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FingerTest : MonoBehaviour {
private Touch oldTouch1; //上次触摸点1(手指1)
private Touch oldTouch2; //上次触摸点2(手指2)
//偏移量和中心店
Vector3 offest;
public Vector3 target;
//记录第一坐标
Vector3 P1;
public float distance = 5f;
public float xSpeed = 12f;
public float ySpeed = 5f;
public float x = 0.0f;
public float y = 0.0f;
//相机移动速度
public float Speed = 10;
public float Gunlun = 10;
public int yMaxLimit = 90;//最大y(单位是角度)
public int yMinLimit = 0;//最小y(单位是角度)
Vector3 tempTarget;
void Start()
{
var angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
//旋转中心初始点
target = new Vector3(0f, 0f, 0f);
tempTarget = transform.localScale;
}
void Update()
{
//没有触摸
if (Input.touchCount <= 0)
{
return;
}
//单点触摸, 水平上下旋转
if (1 == Input.touchCount)
{
Touch touch = Input.GetTouch(0);
Vector2 deltaPos = touch.deltaPosition;
x += deltaPos.x * xSpeed * 0.02f;
y -= deltaPos.y * ySpeed * 0.02f;
y = ClampAngle(y, (float)this.yMinLimit, (float)this.yMaxLimit);
//返回一个四元数 绕某个轴旋转某个角度
var rotation = Quaternion.Euler(y, x, 0);
var position = rotation * new Vector3(0.0f, 0.0f, -distance) + target;
transform.rotation = rotation;
transform.position = position;
}
//多点触摸, 放大缩小
Touch newTouch1 = Input.GetTouch(0);
Touch newTouch2 = Input.GetTouch(1);
//第2点刚开始接触屏幕, 只记录,不做处理
if (newTouch2.phase == TouchPhase.Began)
{
oldTouch2 = newTouch2;
oldTouch1 = newTouch1;
return;
}
//计算老的两点距离和新的两点间距离,变大要放大模型,变小要缩放模型
float oldDistance = Vector2.Distance(oldTouch1.position, oldTouch2.position);
float newDistance = Vector2.Distance(newTouch1.position, newTouch2.position);
//两个距离之差,为正表示放大手势, 为负表示缩小手势
float offset = newDistance - oldDistance;
//放大因子, 一个像素按 0.01倍来算(100可调整)
float scaleFactor = offset / 100f;
Vector3 localScale = tempTarget;
Vector3 scale = new Vector3(localScale.x + scaleFactor,
localScale.y + scaleFactor,
localScale.z + scaleFactor);
//最大拉远0.3F, 最大拉近15f
if ((scale.x > 0.3f && scale.x < 15) && (scale.y > 0.3f && scale.y <15) && (scale.z> 0.3f && scale.z < 15))
{
tempTarget = scale; //根据上边脚本改动的, 就多了一个tempTarget临时变量值。把中心物体的缩放值 改成摄像机与物体的远近。
transform.Translate(new Vector3(0, 0, scaleFactor * Time.deltaTime * Gunlun));
}
distance = (target - transform.position).magnitude;
//记住最新的触摸点,下次使用
oldTouch1 = newTouch1;
oldTouch2 = newTouch2;
}
//把角度限制到给定范围内
public float ClampAngle(float angle, float min, float max)
{
while (angle < -360)
{
angle += 360;
}
while (angle > 360)
{
angle -= 360;
}
return Mathf.Clamp(angle, min, max);
}
}