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. codeforces547a

    http://codeforces.com/contest/547/problem/A 题意:确定是否在某一时刻高度都同时为a1和a2. step1:找到青蛙首次到a1的时间pri1以及重复到a1的周 ...

  2. android --------学习流程图

    如何快速入门和进阶安卓开发,是很多技术小白的疑问. 大家都知道,Android开发要学的技能非常多,技术更新速度还快,但是总的来说:掌握最核心的技术,最规范的开发流程,成为专业.出色的安卓开发工程师也 ...

  3. MVC实战之排球计分(一)—— 需求分析与数据库设计

    此系列博客目的是制作一款排球计分程序.这系列博客讲讲述此软件的 各个功能的设计与实现. 一.需求分析: 这个程序是排球计分程序,其业务非常简单,具体如下: 1.本程序可以选择用户身份,通过不同角度记录 ...

  4. js对象合并

    实现js对象大合并,ES6之前就只有循环遍历咯.可以用ES6的话可以用Object.assign(). 以下是Object.assign()示例: var o1 = { a: 1 }; var o2 ...

  5. Oracle PL/SQL游标

    游标的提出: SQL是面向集合的,其结果一般是集合量(多条记录),而PL/SQL的变量一本是标量,其一组变量异常一直只能存放一条记录.所以仅仅使用变量并不能完全满足SQL语句向应用程序输出数据的要求. ...

  6. element中使用button会刷新一遍页面

     会刷新:   <el-form-item> <button @click="register('form')" class="submitBtn&qu ...

  7. SQL 经典回顾:JOIN 表连接操作不完全指南

    ​   2017-02-23 小峰 ITPUB 点击上方“蓝字”可以关注我们哦  |转载自:码农网 |原文链接:www.codeceo.com/article/sql-join-guide.html ...

  8. UI基础六:UI报弹窗确认

    数据检查部分: IF gv_zzzcustmodeno1 <> gv_zzzcustmodeno2 AND gv_plg_name NE 'YES'. lv_title = 'Confir ...

  9. Linux在shell中输入历史命令

    在Linux的shell中,经常输入的命令有很多雷同,甚至是一样的, 如果是长命令,再次敲一遍效率真的是很低, 不过可以通过Ctl+r,  查找history中以前输入的命令,很是好用. 按Ctrl+ ...

  10. oracle having sum group by 详解

    Aggregate functions (like SUM) often need an added GROUP BY functionality. 集合函数(类似SUM)经常需要用GROUP BY来 ...