using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

//[Serializable] 由于class.struct不被Unity3d识别为可以Serialize的结构一般用于外部
//[SerializeField] 用于内部

[Serializable]
public struct CameraParameter
{
public bool limitXAngle;
public float minXAngle;
public float maxXAngle;

public bool limitYAngle;
public float minYAngle;
public float maxYAngle;

[Tooltip("敏感度")]
public float orbitSensitive;
[Tooltip("频率")]
public float mouseMoveRatio;

/// <summary>
///
/// </summary>
/// <param name="limitXAngle">是否是在限制x轴的范围</param>
/// <param name="minXAngle">最小x轴选择角度</param>
/// <param name="maxXAngle">最大x轴选择角度</param>
/// <param name="limitYAngle">是否是在限制y轴的范围</param>
/// <param name="minYAngle">最小x轴选择角度</param>
/// <param name="maxYAngle">最大x轴选择角度</param>
/// <param name="orbitSensitive">敏感度</param>
/// <param name="mouseMoveRatio">频率</param>
public CameraParameter(bool limitXAngle = true
, float minXAngle = 0f
, float maxXAngle = 80f
, bool limitYAngle = false
,float minYAngle=0f
,float maxYAngle=80f
,float orbitSensitive=10f
,float mouseMoveRatio = 0.3f)
{
this.limitXAngle = limitXAngle;
this.minXAngle = minXAngle;
this.maxXAngle = maxXAngle;
this.limitYAngle = limitYAngle;
this.minYAngle = minYAngle;
this.maxYAngle = maxYAngle;
this.orbitSensitive = orbitSensitive;
this.mouseMoveRatio = mouseMoveRatio;
}
}
public class RotateFinal : MonoBehaviour {

private Vector3 lastMousePos; //最近一次鼠标位置
private Vector3 targetEulerAngle; //目标角度
private Vector3 eulerAngle; //每次更新的角度

//public CameraParameter freeOrbitParameter; //自由轨道参数
public CameraParameter currentCameraParameter; //当前相机参数

public Transform cameraRootTf;
public Transform cameraTf;

private float cameraDistance;
private float targetCameraDistance;

private float lastTouchDistance;

public float minDistance = 5f;
public float maxDistance = 30f;
public float mouseScrollRadio = 1f;
public float zoomSensitive = 1f;

private Quaternion originalRotate;

//public float[] yMinAngles;
//public float[] yMaxAngles;
//public bool[] isAlreadyFire;

private void Start()
{
originalRotate = cameraRootTf.rotation;
cameraDistance = cameraTf.localPosition.z;
targetCameraDistance = cameraDistance;
//currentCameraParameter = freeOrbitParameter;
}

private void Update()
{
Oribit();
Zoom();
}

void Oribit()
{
if (Input.GetMouseButtonDown(0))
{
lastMousePos = Input.mousePosition;
}
if (Input.GetMouseButton(0))
{
targetEulerAngle.x += (-Input.mousePosition.y + lastMousePos.y) * currentCameraParameter.mouseMoveRatio;
targetEulerAngle.y += (Input.mousePosition.x - lastMousePos.x) * currentCameraParameter.mouseMoveRatio;
if (currentCameraParameter.limitXAngle)
{
targetEulerAngle.x = Mathf.Clamp(targetEulerAngle.x, currentCameraParameter.minXAngle, currentCameraParameter.maxXAngle);
}
if (currentCameraParameter.limitYAngle)
{
targetEulerAngle.y = Mathf.Clamp(targetEulerAngle.y, currentCameraParameter.minYAngle, currentCameraParameter.maxYAngle);
}
lastMousePos = Input.mousePosition;
}
if (Input.touchCount<2) //如果触碰的小于2时,可用在触摸屏上
{
eulerAngle = Vector3.Lerp(eulerAngle, targetEulerAngle, Time.fixedDeltaTime * currentCameraParameter.orbitSensitive);
cameraRootTf.rotation = originalRotate*Quaternion.Euler(eulerAngle);
}
}
/*
// 手指刚触摸到屏幕的时候
Input.GetTouch(0).phase == TouchPhase.Began;
// 手指在屏幕上移动
Input.GetTouch(0).phase == TouchPhase.Moved;
// 手指触摸屏幕,但并未移动
Input.GetTouch(0).phase == TouchPhase.Stationary;
// 手指从屏幕上移开,这是一个触控的最后状态
Input.GetTouch(0).phase == TouchPhase.Ended;
// 系统取消追踪触控。这常发生在用户把屏幕放到脸上或者同时触控超过了5根手指,同样也是触控的最后一个状态
Input.GetTouch(0).phase == TouchPhase.Canceled;
*/
private void Zoom()
{
if (Input.touchCount<2)
{
if (Input.GetAxis("Mouse ScrollWheel")!=0)
{
cameraDistance = -cameraTf.localPosition.z; //有滑动就减去得到滑动了距离
targetCameraDistance = cameraDistance - Input.GetAxis("Mouse ScrollWheel") * cameraDistance * mouseScrollRadio;
targetCameraDistance = Mathf.Clamp(targetCameraDistance, minDistance, maxDistance);
}
}
else
{
if (Input.GetTouch(1).phase==TouchPhase.Began)
{
lastTouchDistance = Vector2.Distance(Input.GetTouch(0).position, Input.GetTouch(1).position);
}
if (Input.GetTouch(1).phase==TouchPhase.Moved||Input.GetTouch(0).phase==TouchPhase.Moved)
{
cameraDistance = -cameraTf.localPosition.z;
targetCameraDistance = cameraDistance - (Vector2.Distance(Input.GetTouch(0).position, Input.GetTouch(1).position) - lastTouchDistance) * mouseScrollRadio;
lastMousePos = Input.mousePosition;
}
}
if (Mathf.Abs(targetCameraDistance-cameraDistance)>0.1f)
{
cameraDistance = Mathf.Lerp(cameraDistance, targetCameraDistance, Time.fixedDeltaTime * zoomSensitive);
cameraTf.localPosition = new Vector3(0, 0, -cameraDistance);
}
}
}

PC或者手机上实现相机拉近和旋转的更多相关文章

  1. 如何在Android手机上进行自动化测试(下)

    版权声明:允许转载,但转载必须保留原链接:请勿用作商业或者非法用途 前言 通过阅读本篇教程,你将会了解到: 如何使用Poco对Android原生应用进行测试 Poco支持直接对任何Android原生应 ...

  2. 相机拍的图,电脑上画的图,word里的文字,电脑屏幕,手机屏幕,相机屏幕显示大小一切的一切都搞明白了!

    相机拍的图,电脑上画的图,word里的文字,电脑屏幕,手机屏幕,相机屏幕显示大小一切的一切都搞明白了! 先说图片X×dpi=点数dotX是图片实际尺寸,简单点,我们只算图片的高吧,比如说拍了张图片14 ...

  3. [Android Pro] 将你的安卓手机屏幕共享到PC或Mac上

    有时候为了方便演示一个手机app,需要把手机屏幕显示到PC或Mac上.这里提供一个方法 — 使用Vysor达到此功能. Vysor的吸引力在于3个方面: 它适用于Windows.Linux或Mac. ...

  4. 解决ios手机上传竖拍照片旋转90度问题

    html5+canvas进行移动端手机照片上传时,发现ios手机上传竖拍照片会逆时针旋转90度,横拍照片无此问题:Android手机没这个问题. 因此解决这个问题的思路是:获取到照片拍摄的方向角,对非 ...

  5. Nginx配置网站适配PC和手机

    考虑到网站的在多种设备下的兼容性,有很多网站会有手机版和电脑版两个版本.访问同一个网站URL,当服务端识别出用户使用电脑访问,就打开电脑版的页面,用户如果使用手机访问,则会得到手机版的页面. 1.判断 ...

  6. 【转】Nginx区分PC或手机访问不同网站

    原文链接:http://www.nginx.cn/784.html 近几年来,随着手机和pad的普及,越来越多的用户选择使用移动客户端访问网站,而为了获取更好的用户体验,就需要针对不同的设备显示出最合 ...

  7. 手机上的页面转换page slider

    小伙伴们是不是经常在手机上见到“转场"的情况,手机上的页面转换已经不像pc上整体的页面跳转,很多都是利用动画平滑地在页面之间的切换.   那么如何来做页面之间的转换呢?首先要明确的是,所谓的 ...

  8. 我想要个pc和手机共有的客户端,就像百度云(iBarn网盘好用)

    https://github.com/zhimengzhe/iBarn iBarn网盘是一个基于PHP开发的先进的云存储系统,提供文件的网络备份,同步和分享服务:支持断点续传,秒传等功能:可选择文件下 ...

  9. 如何在 Android 手机上实现抓包?

    如何在 Android 手机上实现抓包? http://www.zhihu.com/question/20467503 我想知道某个应用究竟在数据提交到哪里,提交了什么.网上的教程太复杂,不想麻烦.有 ...

随机推荐

  1. 『MXNet』第六弹_Gluon性能提升

    一.符号式编程 1.命令式编程和符号式编程 命令式: def add(a, b): return a + b def fancy_func(a, b, c, d): e = add(a, b) f = ...

  2. bzoj3926: [Zjoi2015]诸神眷顾的幻想乡 后缀自动机在tire树上拓展

    题意:有棵树每个点有个颜色(不超过10种),每个节点不超过20个儿子,问你每两点之间的颜色序列不同的有多少种 题解:先建出树,对于每个叶子节点,bfs一遍建在sam上,每次保留当前点在sam上的位置, ...

  3. Navicat 的安装及破解

    本地环境: ubutun 14 1.安装. ①先老实选择官方试用版安装(不推荐在各个下载平台去下载) 中文版:http://www.navicat.com.cn/download/navicat-fo ...

  4. awr相关

    手工生成awr快照SQL> exec dbms_workload_repository.create_snapshot; PL/SQL procedure successfully comple ...

  5. Hadoop 2.7.3 完全分布式维护-部署篇

    测试环境如下  IP       host JDK linux hadop role 172.16.101.55 sht-sgmhadoopnn-01 1.8.0_111 CentOS release ...

  6. MySQL5.6复制技术(1)-原理详解

    SQL复制功能介绍 MySQL内建的复制功能是构建大型,高性能应用程序的基础.这类应用使用所谓的“水平扩展”的架构.我们可以通过为服务器配置一个或多个备库的方式来进行数据同步,将MySQL的数据分布到 ...

  7. java旅程(二) 基本语法

    java变量: 数值型        整数类型(byte,short,int,long)浮点类型(float,double) 字符型 char 基本数据类型                       ...

  8. Mysql设置自增字段的方法

    #int : 字段类型 alter table 表名 modify 字段名 int auto_increment primary key

  9. ROM、PROM、EPROM、EEPROM、FLASH ROM、FLASH、eMMC

    ROM(Read Only Memory,只读存储器)芯片:在微机的发展初期,BIOS都存放在ROM芯片中.ROM内部的资料是在ROM的制造工序中,在工厂里用特殊的方法被烧录进去的,其中的内容只能读不 ...

  10. 你应该这样理解JVM内存管理

    在进行Java程序设计时,一般不涉及内存的分配和内存回收的相关代码,此处引用一句话: Java和C++之间存在一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外的人想进去,墙里面的人想出来 ,个人从这 ...