Unity 3Dpc触摸屏禁止左右滑动,单指左右滑动360°旋转物体,上线旋转限制在60°之内,欧拉选转后还会恢复原来的角度

每一份收获,都带着我不懈的努力——小唐
Unity物体全方位旋转
大家好!我是小唐,在 做项目中经常会有需求对物体,模型进行旋转操作。下面就分享一下。
下面的脚本是通过对Input.GetAxis()分别获取鼠标在水平和垂直方向的增量,然后计算鼠标移动的距离,以此来确定模型被旋转的角度,以及阻尼效果的大小。通过Rigid()函数得出旋转速度的增量,以实现平缓的旋转效果。把下面的脚本附加到被旋转的物体上,即可实现物体的全方位旋转。
代码如下:
using UnityE
using System.C
public class test : MonoBehaviour
/// &summary&
/// 是否被拖拽
/// &/summary&
private bool Ondrag =
/// &summary&
/// 旋转速度
/// &/summary&
public float Speed = 6f;
/// &summary&
/// 阻尼速度
/// &/summary&
private float T
/// &summary&
/// 鼠标沿水平方向移动的增量
/// &/summary&
private float A
/// &summary&
/// 鼠标沿竖直方向移动的增量
/// &/summary&
private float A
/// &summary&
/// 鼠标移动的距离
/// &/summary&
private float C
/// &summary&
/// 接受鼠标按下的事件
/// &/summary&
void OnMouseDown()
Axisx = 0f;
Axisy = 0f;
/// &summary&
/// 鼠标拖拽时的操作
/// &/summary&
void OnMouseDrag()
//获得鼠标增量
Axisx = -Input.GetAxis("Mouse X");
Axisy = Input.GetAxis("Mouse Y");
//计算鼠标移动的长度
Cxy = Mathf.Sqrt(Axisx * Axisx + Axisy * Axisy);
if (Cxy == 0f)
/// &summary&
/// 计算阻尼速度
/// &/summary&
/// &returns&&/returns&
float Rigid()
if (Ondrag)
Tempspeed = S
if (Tempspeed & 0)
//通过除以鼠标移动长度实现拖拽越长速度减缓越慢
Tempspeed -= Speed * 2 * Time.deltaTime / C
Tempspeed = 0;
void Update()
gameObject.transform.Rotate(new Vector3(Axisy, Axisx, 0) * Rigid(), Space.World);
if (!Input.GetMouseButton(0))
程序员就是如此的苦逼,慢慢的熬吧,总有那么一天,你想的那一天。——小唐
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!Unity中关于四元数的API详解_达内Unity3D培训
400-111-8989
Unity中关于四元数的API详解
时间: 17:30
Unity中关于四元数的API详解Quaternion类
Quaternion(四元数)用于计算Unity旋转。它们计算紧凑高效,不受万向节锁的困扰,并且可以很方便快速地进行球面插值。
Unity内部使用四元数来表示所有的旋转。
Quaternion是基于复数,并不容易直观地理解。 不过你几乎不需要访问或修改单个四元数参数(x,y,z,w);
大多数情况下,你只需要获取和使用现有的旋转(例如来自“Transform”),或者用四元数来构造新的旋转(例如,在两次旋转之间平滑插入)。
大部分情况下,你可能会使用到这些函数:
Quaternion.LookRotation,
Quaternion.Angle
Quaternion.Euler
Quaternion.Slerp
Quaternion.FromToRotation
Quaternion.identity。
Quaternion 是一个结构体,本身成员变量相对简单,可以作为函数参数高效传递。
Unity默认方向
在深入了解API之前,我们需要先明确一些基本的概念,就是方向、旋转究竟是如何表示的。
Unity中使用左手坐标系,假如把世界坐标系跟东南西北进行结合起来看,大致如下图所示:
默认的方向对应如下表:
假设以你自己身体为例,你站立在地面上,面朝北方,此时就是默认方向,也就是Unity中的方向就是面向+Z轴方向,那么此时+X轴在东方,+Y轴对应正上方。此时对应的欧拉角是(0,0,0),此时对应的前方矢量是(0,0,1),上方矢量是(0,1,0)。
这里我区分了左右上下前后的概念,因为这些概念同时也对应了Vector3类、Transform类中的相应的方向函数。
方向的表示法①欧拉角表示法
假如你使用一组欧拉角表示旋转,XYZ三个参数代表相应轴向按照顺归YZX的旋转,因此(0、90、90)代表先进行+Z轴旋转90度,再沿着+Y轴进行90度旋转。
②前方上方矢量界定法
编程过程中,大部分需要明确指定方位的时候就需要使用这个方法。要确定一个朝向,我们可以使用两个向量来确定:即前方矢量和上方矢量。当一个朝向的前方和上方确定之后,这个朝向也就完全确定了。
举例来说,如果现在只提供一个朝向,就是你现在面朝北方,那么这个方向已经完全确定了吗?显然没有。因为你右侧躺在地上,看向北方,还是在面朝北方,这时候就需要另外一个矢量,也就是上方。当给出上方之后,这个朝向就完全确定了。
上方需要严格给出吗?
在Unity中,我们很多时候,不需要给出严格的上方朝向。比如,仍然是上面那个例子,如果我面朝北方,先给出(0,0,1)代表我的前方矢量。那么,如果我给出的方向不是严格的上方矢量,比如是(0,0.5,0.5),是否可以?
答案也是可以的,因为这两个矢量显然已经确定了一个方向,前方是严格的,而实际的上方可以通过前方朝着你给出的上方矢量旋转90度得出。也就是说,你给(0,1,0)作为上方矢量,和给出在下图中弧度范围内(不包含+Z和-Z)所有方向的矢量都是相同的结果。
上方矢量参数范围
③绕轴旋转界定法
第三种定义旋转的方法就是围绕某个指定的轴向旋转一定的角度。这个方法也可以确定一个相对旋转,它以从默认方向(此时前方+Z,上方+Y)出发,沿着指定的轴向进行指定角度的旋转,旋转后的前方和上方是确定的。因此这个方法也可以用来确定朝向。
④A向到B向相对旋转表示法
还有一种方法就是从A向到B向的相对旋转,这种表示了一个旋转的相对变化。比如A为(0,1,0),B为(0,0,1),也就是相对旋转量代表原来的上方被旋转到了前方,这样的一个四元数也可以用欧拉角表示成(90,0,0),也就是沿着+X轴旋转了90度。
注意上面四中表示方法中,有的明确表明了上方矢量,有的好像只明确了前方矢量,要明确的一点就是,它们都是从默认矢量出发的,如果没有明确指定上方朝向,那么就是使用默认的上方,也就是+Y方向。
eulerAngles 欧拉角,返回当前四元数所对应的欧拉角
this[int] 可以使用类似数组和下标的形式从四元数中获取四个四元数参数
x、y、z、w 分别代表x、y、z、w 参数,你最好不要通过修改四个参数来改变四元数,除非你真的非常了解它们的含义。
identity 单位四元数,也就是默认的无旋转状态,此时与世界坐标相同,前方指向+Z,上方指向+Y
void Set(float new_x, float new_y, float new_z, float new_w)设置x、y、z、w
分量,与this[]功能相同
void SetFromToRotation(Vector3 fromDirection, Vector3
toDirection)设置成静态函数FromToRotation的结果
void SetLookRotation(Vector3 view, Vector3 up =
Vector3.up)设置成静态函数LookRotation的结果
void ToAngleAxis(out float angle, out Vector3 axis)设置成静态函数AngleAxis的结果
说明:成员函数几个set方法多用于将当前四元数设置成目标四元数,目标四元数的构建方法与对应名称的静态函数相同。
static float Angle(Quaternion a, Quaternion b)计算两个四元数前方矢量之间的夹角度数
static Quaternion AngleAxis(float angle, Vector3
axis)构建一个四元数,它表示沿着一个轴旋转固定角度,即上述表示法③
static float Dot(Quaternion a, Quaternion
b)计算两个四元数之间的点积,返回一个标量,这个函数一般用不到,它的点积不代表什么具体的物理含义,具体定义方法见我的前述文章
static Quaternion Euler(float x, float y, float
z)构建一个四元数,它用欧拉旋转表示,即上述表示法①
static Quaternion FromToRotation(Vector3 fromDirection, Vector3
toDirection)构建一个四元数,它表示从指向fromDirection方向到指向toDirection方向的相对旋转量,见上述表示法④
static Quaternion Inverse(Quaternion
rotation)构建一个四元数,它是指定的四元数的逆,也就是逆向旋转,比如原四元数表示相对+X轴旋转了90度,那么此函数结果就是相对+X轴旋转了-90度
static Quaternion Lerp(Quaternion a, Quaternion b, float
t)构建一个四元数,表示从四元数a到b的球面插值,所谓的插值也就是中间旋转量,从a作为起点,此时对应t为0,到b为终点,此时对应t为1。当t取0-1之间的小数时,就代表了中间的插值结果。这个方法与Slerp相同,计算速度快,但是精度低,如果相对旋转变化量很小,则效果不理想
static Quaternion LerpUnclamped(Quaternion a, Quaternion b, float
t)与Lerp相同,区别是,Lerp的t值会被钳制在[0,1]之间,而此方法则不会,t允许超出计算
static Quaternion LookRotation(Vector3 forward, Vector3 upwards =
Vector3.up)构建一个四元数,使用前方上方矢量确定朝向,也就是上述表示法②
static Quaternion RotateTowards(Quaternion from, Quaternion to, float
maxDegreesDelta)构建一个四元数,表示从一个四元数from(的前方)向着另外一个四元数(的前方)旋转,但不能超出指定的角度,也就是如果两个前方矢量夹角超过指定角度,则旋转到达指定角度时就停止,若是夹角本身不足的话,则结果直接为目标四元数to,与上述表示法④的意思很接近
static Quaternion Slerp(Quaternion a, Quaternion b, float
t)球面插值,与Lerp功能相同,t值也被钳制,计算精度高,但是速度相对较慢
static Quaternion SlerpUnclamped(Quaternion a, Quaternion b, float
t)与Slerp功能相同,只是t值不被钳制,允许超出计算
static Quaternion operator * (Quaternion lhs, Quaternion
rhs)乘法运算符重载,当表示两个连续的旋转时,可以使用lhs *
rhs的形式得出连续旋转的结果,lhs为左值,rhs为右值。注意左值是先进行的旋转,叠加右值旋转。用法示例:lhs = lhs *
static Vector3 operator *(Quaternion rotation, Vector3
point)乘法运算符重载,表示对一个矢量point施加旋转rotation,得出旋转后的结果矢量。用法示例:Vector3 result=rotation *
point验证前方上方矢量表示法
为了验证前方上方矢量表示法的实际上方会重新计算,我设计了以下小实验。
在场景中设置三个物体,它们的朝向是打乱的,从左到右分别对应1、2、3。可以使用以下代码将三个物体朝向调整为一致。
//前方上方矢量界定法的实际上方会重新计算
m_t1.transform.rotation = Quaternion.LookRotation(Vector3.forward,
Vector3.up);
m_t2.transform.rotation = Quaternion.LookRotation(Vector3.forward, new
Vector3(0,0.5f,-0.5f));
m_t3.transform.rotation = Quaternion.LookRotation(Vector3.forward, new
Vector3(0,0.5f,0.5f));
在start方法中执行上述代码后,如下:
小实验结果
三个物体朝向是一致的,也就说明了上方矢量确实是进行了重新计算。
总结几种表示方法
下面使用代码总结几种表示法,对应同样的四元数,大致有四种表示方法。
//旋转量的4种表示形式
Quaternion q1=Quaternion.Euler(90, 0, 0);
Quaternion q2 = Quaternion.LookRotation(Vector3.down ,Vector3.forward);
Quaternion q3 = Quaternion.AngleAxis(90,Vector3.right);
Quaternion q4 = Quaternion.FromToRotation(Vector3.up, Vector3.forward);
showQ("q1",q1);
showQ("q2",q2);
showQ("q3",q3);
showQ("q4",q4);
它们的输出结果是:
几种表示法结果
也就是说,这几种形式表示的四元数结果完全相同。
将四元数旋转应用于子弹射击示例
当枪管转动起来,子弹仍然沿着正确的朝向发射出去,可以使用很简单的几句话,修改之前的代码后如下:
Bullet_2 bullet = m_compPool.takeUnit();
//发射时,将子弹的初始位置为枪口的当前位置
bullet.m_transform.position = m_transform.
//将子弹的初始化旋转设置为指向当前枪口前方
bullet.m_transform.rotation =
Quaternion.LookRotation(m_transform.forward);
此文章由机构转载自网络,如有侵权请联系我们感谢您的关注
虽然虚拟现实与增强现实总同时被提及,但虚拟现实与增强现实却如泾渭分明的两条河流。虽殊途同归,有广大的应用前景,但却是不折不扣的两个领域。
今天区块链技术被互联网科技领域所看好,并且用在了许多领域中。日前游戏引擎Unity3D就与虚拟货币恩金公司展开合作,双方将联手布局区块链游戏开发领域并提供技术支持,主要提供区块链游戏道具或其他加密资产的交易帮助。
一年一年不断升级的Unity引擎,也试图跳出“游戏引擎”这个固有的形象,朝着更大、更广的范围发展。影视、工业、教育、AR……今年的Unite大会,从引擎端反映出了市场的变化。
5月12日,由Unity举办的Unite Beijing 2018大会在北京国家会议中心进行,其中来自Unity的全球技术专家,从各自的领域分享了他们眼中游戏行业的趋势与机会。
Copyright (C)
Tedu.cn All Rights Reserved 京ICP备号-56 版权所有
选择城市和中心
达内北京亦庄大学生实训基地
达内北京网络营销中心
达内北京会计中心unity 向量旋转角度 完美作业网 www.wanmeila.com
如何在Unity3D中计算“法向量A向任意法向量B旋转,使得两个向量夹角减小N度后的A向量” 其实我不太明白你究竟想要什么……如果只是返回zero或者B的话,我只需要判断AB方向就可以了,何苦还要计算旋转呢?判断方向很容易,可以使用Vector3.Angle()靠拢的话,有这样一个函数public static Vector3 RotateTowards(Vector3 current, Vector3 target, float maxRadiansDelta, float maxMagnitudeDelta);第一个参数是原向量A,第二个是目标向量B,第三个是角度,第四个设置成0.0f就可以了。(当然,A,B都是单位向量的话。)但是这个函数看起来是这样的意思,我并没有实践过。可参考:[]
unity3d 欧拉角怎么转换为方向向量 void updateCameraVectors(){// Calculate the new Front vectorglm::vec3front.x = cos(glm::radians(this->Yaw)) * cos(glm::radians(this->Pitch));front.y = sin(glm::radians(this->Pitch));front.z = sin(glm::radians(this->Yaw)) * cos(glm::radians(this->Pitch));this->Front = glm::normalize(front);// Also re-calculate the Right and Up vector...}
怎么使用unity的四元数旋转一个向量 百度上说,四元数 x,y,z 表示轴,w表示旋转的角度;假如有一个物体Object,那么Object.Quaternion(x,y,z,w)就表示Object围绕着轴(x,y,z)旋转w度。到这里我就不明白了,(x,y,z) 只是一个向量,但并没有指定通过哪个点,所以它代表了无数条平行线,那到底是哪一条作为轴呢?
unity三维向量的旋转 dcost=-sintdt,令sint=x原式化为(先当做不定积分化简)∫xe^xdx=∫xde^x=xe^x-∫e^xdx=xe^x-e^x=e^x(x-1)sint在t从0到2π上的积分由sint的图象可知转化为x应该是2倍的x从0到1的积分和2倍的x从0到-1的积分,代入得原式=4-4/e
怎么使用unity的四元数旋转一个向量 特征根方程假设解是e^(r*t)r是待定常数代入可以得到(r^2+k^2)e^(r*t)=0r^2+k^2=0r=ki,-ki然后由欧拉公式e^(ki)=cosk+isinke^(-ki)=cosk-isinkx=A(cosk+isink)+B(cosk-isink)
怎么使用unity的四元数旋转一个向量 在z=1处化: 令t=z-1, 则z=t+1 f(z)=1/t(t+1-3) =1/t(t-2) =0.5/(t-2)-0.5/t =-0.25/(1-t/2)-0.5/t =-0.25[1+t/2+t^2/4+t^3/8+...]-0.5/t 此即为在z=1处展开。 在z=3处化,也同理: 令t=z-3, 则z=t+3 f(z)=1/t(t+3-1) =1/t(t+2) =0.5/t-0.5/(t+2) =0.5/t-0.25/(1+t/2) =0.5/t-0.25[1-t/2+t^2/4-t^3/8+..] 此即为在z=3处展开
怎么使用unity的四元数旋转一个向量 特征根方程假设解是e^(r*t)r是待定常数代入可以得到(r^2+k^2)e^(r*t)=0r^2+k^2=0r=ki,-ki然后由欧拉公式e^(ki)=cosk+isinke^(-ki)=cosk-isinkx=A(cosk+isink)+B(cosk-isink)
Unity3d做的2D游戏,2D对象旋转问题! 向量计算,朝向就是向量的方向,知道向量,用Quaternion.LookRotation找到角度,旋转,如果某个坐标轴不对,再继续旋转响应角度即可,其实用lookat也是可以的,再乘以一个四元数把错误的角度纠正就可以了,或者直接加个父物体来保证正确朝向
unity3d 点到向量的距离算法和判断点位于向量哪一侧的算法 使用以下算法:如果跟右方向 this.transform.right 夹角在90度以内呈现锐角,反之如果呈现钝角在左边。//如果跟右方向夹角在90度以内,准星在炮管右边炮塔右转,否则在左边。float angle = Vector3.Angle(this.transform.right , point);获取的夹角 angle 判断 如果是锐角则在右侧,如果是钝角则在左侧。if (angle <90.0) {点在 this.transform.forward 右侧} else {点在 this.transform.forward 左侧}
unity3D里四元向量左乘z轴方向单位向量是什么意思 四元数乘以向量,表示将向量表示的点用四元数表示的旋转进行旋转操作例如 Quaternion rotation = Quaternion.Euler(90,0,0); Vector3 point= (0,0,1);就是将p在x轴方向上旋转90度,最后就变成了(0,-1,0)参考文献:[]Unity3D 中旋转和变换
Transform 变换,是场景中最常打交道的类,用于控制物体的位移,旋转,缩放等功能。
Class, inherits from Component, IEnumerable
Position, rotation and scale of an object.
控制物体的位置,旋转和缩放。
Every object in a scene has a Transform. It's used to store and manipulate the position, rotation and scale of the object. Every Transform can have a parent, which allows you to apply position, rotation and scale hierachically. This is the hierarchy seen in
the Hierarchy pane. They also support enumerators so you can loop through children using:
all transform children 10 units upwards!
for (var child
: Transform in transform) {
child.position += Vector3.up *
每一个场景中的物体都有Transform这个类,他是用来储存和处理物体的位移,旋转和缩放的。每一个Transform都可以有一个父物体,这可以让你得到下游节点的位移旋转和缩放。这个层次结构关系可以从Hierarchy面板中看到。他还支持enumerators,以使用循环来遍寻所有的子节点。
position: Vector3
物体在世界坐标中的位置。 transform.position=Vector3(10,10,10)//把物体放到(x=10,y=10,z=10)的位置
localPosition: Vector3
相对位置,或自身位置,物体相对于父物体的位置。
eulerAngles: Vector3
轴向旋转角度,相对于世界坐标。单位为度(°)
localPosition: Vector3 相对轴向旋转角度,或自身的旋转角度,物体相对于父物体的旋转。一般使用和处理物体的旋转角度时都会使用到这个数值。
right: Vector3
物体自身的红色轴向(X轴)在世界坐标中所指向的位置。注意在maya中x轴指向物体的左边,而unity中的x轴则指向物体的右边。rigidbody.velotity=transform.right*moveS//向物体的右侧以moveSpeed的速度移动
up: Vector3
物体自身的绿色轴向(Y轴)在世界坐标中所指向的位置。
forward: Vector3
物体自身的蓝色轴向(Z轴)在世界坐标中所指向的位置。
rotation: Quaternion
以四元数来表达的物体自身的旋转。四元数可以快速的处理物体的旋转方向的计算,搭配Quaternion可以用来计算各种需要的旋转方案。具体应用方法参见Quaternion篇
localRotation: Quaternion 相对于父物体的用四元数来表达的旋转。
localScale: Vector3 物体相对于父物体的缩放
parent: Transform 物体的父物体。 如果没有则返回null。 如果改变父物体的位置,旋转和缩放,会同时影响并改变子物体的位置,旋转和缩放,但是保持相对位置,相对旋转和相对缩放。
worldToLocalMatrix: Matrix4x4 一个表达从世界坐标到相对坐标位置的四维矩阵,Read Only。 如果你对矩阵不是很了解,请使用Transform.InverseTransformPoint。
LocalToWorldMatrix: Matrix4x4 一个表达从相对坐标到世界坐标位置的四维矩阵,Read Only。 如果你对矩阵不是很了解,请使用Transform.TransformPoint。
root: Transform
返回物体的最高层的父物体。如果物体本身就是最高层,则返回物体本身。
childCount: Int
返回物体的子物体数量。
lossyScale:Vector3 返回物体相对于世界坐标的缩放值。 Read Only。没什么用的一个属性,当子物体被旋转后也不是特别精确,也不推荐大家用。如果想要计算物体的世界坐标缩放,最好自己写计算公式。
1)Translate, 用来移动物体的函数,非常常用的一个函数。
function Translate (translation : Vector3, relativeTo : Space = Space.Self) : void
把物体向translation方向移动,距离为translation.magnitude。 relativeTo表示这个移动的参考坐标系。
function Translate (x : float, y : float, z : float, relativeTo : Space = Space.Self) : void
function Translate (translation : Vector3, relativeTo : Transform) : void
如果relativeTo 不是null, 则以目标物体relativeTo的自身轴向作为参考坐标系。
function Translate (x : float, y : float, z : float, relativeTo : Transform) : void
var speed=30;
//将物体以30米每秒的速度向前移动。
trasform.Translate(Vector3.forward*speed*Time.deltaTime);
2)Rotate,用来旋转物体的函数,非常常用,在知道需要旋转的角度的情况下。如果要让物体旋转到指定位置,需要搭配Quaternion来使用。
function Rotate (eulerAngles : Vector3, relativeTo : Space = Space.Self) : void
旋转eulerAngles度(3个轴向分别旋转),以relativeTo为参考坐标系
function Rotate (xAngle : float, yAngle : float, zAngle : float, relativeTo : Space = Space.Self) : void
function Rotate (axis : Vector3, angle : float, relativeTo : Space = Space.Self) : void
以axis为轴旋转angle度,以relativeTo为参考坐标系
3)RotateAround 让物体以某一点为轴心成圆周运动。
function RotateAround (point : Vector3, axis : Vector3, angle : float) : void
让物体以point为中心,绕axis为轴向旋转angle度。 保持原来与point的距离。
4)LookAt 让物体的z轴看向目标物体
function LookAt (target : Transform, worldUp : Vector3 = Vector3.up) : void
让物体的z轴看向target的位置,并以worldUp为y轴指向方向。
function LookAt (worldPosition : Vector3, worldUp : Vector3 = Vector3.up) : void
让物体看向worldPosition
5)TransformDirection
function TransformDirection (direction : Vector3) : Vector3
返回以物体自身为坐标轴的向量direction在世界坐标中的朝向向量。
function TransformDirection (x : float, y : float, z : float) : Vector3
6)InverseTransformDirection
function InverseTransformDirection (direction : Vector3) : Vector3
function InverseTransformDirection (x : float, y : float, z : float) : Vector3
与TransformDirection相反,从世界坐标转换到自身相对坐标。
7)TransformPoint
function TransformPoint (position : Vector3) : Vector3
function TransformPoint (x : float, y : float, z : float) : Vector3
把一个点从自身相对坐标转换到世界坐标
8)InverseTransformPoint
function InverseTransformPoint (position : Vector3) : Vector3
function InverseTransformPoint (x : float, y : float, z : float) : Vector3
把一个点从时间坐标转换到自身坐标的位置。
9)DetachChildren
function DetachChildren () : void
把自身所有的子物体的父物体都设成世界,也就是跟自己的所有子物体接触父子关系。
function Find (name : string) : Transform
找到一个名字是name的物体并返回
如果没有找到则返回null。 如果字符串被/隔离,函数则会像文件路径一样逐级下查。
magical rotating finger
function Update() {
aFinger = transform.Find("LeftShoulder/Arm/Hand/Finger");
aFinger.Rotate(Time.deltaTime*20,
11)IsChildOf
function IsChildOf (parent : Transform) : bool
如果物体是parent的父子层级关系下的一员,返回
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!

我要回帖

更多关于 wpf 触摸屏滑动相册 的文章

 

随机推荐