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. SWUST OJ(955)

    单链表上查找算法的实现 #include <stdio.h> #include <stdlib.h> typedef struct LinkNode //单链表节点结构的定义 ...

  2. 在写makefile过程中遇到的问题

    老师布置了linux实验作业,本身不打算写了,反正也不交实验报告,但刚好项目也需要,所以就研究了makefile.不过还是要批评自己,怎么能这么的颓废呢? 刚开始做的时候出现了这样的错误,代码如下: ...

  3. http认证中的nonce与timestamp解释

    Nonce是由服务器生成的一个随机数,在客户端第一次请求页面时将其发回客户端:客户端拿到这个Nonce,将其与用户密码串联在一起并进行非可逆加密(MD5.SHA1等等),然后将这个加密后的字符串和用户 ...

  4. 浅谈cookie、session

    揭秘Cookie: cookie说的直白点就是保存在用户浏览器端的一个键值对,举个例子,你现在登录了京东商城,你把浏览器关闭之后,你再打开京东,你还是可以对你的账户继续操作,已经购买的商品,订单都是可 ...

  5. 文件名简体转繁体bat

    @echo off rem 指定文件夹路径 set "fd=D:\下载的图片" rem 0为转换文件名,1为转换文件夹名,2为同时转换文件名和文件夹名 set f=0 rem 0为 ...

  6. python 常用代码

    获取标签名 h1 class 是h1usersoup.find(name="h1", attrs={"class":"h1user"});获 ...

  7. Opatch使用细则

    Patch 21352635 - Database Patch Set Update 11.2.0.4.8 一.OPatch工具检查及升级 OPatch工具包,在安装目录$ORACLE_HOME下,P ...

  8. 将本地项目推送至gitee或者github

    将本地项目推送到Git github上的版本和本地版本冲突的解决方法 初始化项目时,在git中新建项目. 在Github中创建了一个Repository之后,会给你列出如何将自己本地项目Push到Gi ...

  9. [NOIP 2015TG D2T3] 运输计划

    题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家 ...

  10. Python3组播通信编程实现教程(发送者+接收者)

    一.说明 1.1 标准组播解释 通信分为单播.多播(即组播).广播三种方式 单播指发送者发送之后,IP数据包被路由器发往目的IP指定的唯一一台设备的通信形式,比如你现在与web服务器通信就是单播形式 ...