2013-04-16 23:37:00 weixin_30662539 阅读数 19

一个控制摄像头移动的脚本,直接绑定到摄像机就可以使用.功能描述如下:

1.鼠标左键拖动观察

2.鼠标右键定点旋转

3.鼠标滚轴放大缩小

4.鼠标左键快速双击进行定点放大

 1 #pragma strict
 2 /***
 3 **摄影机控制
 4 *@author felly
 5 */
 6 
 7 private var rayRotate :Ray = Ray(Vector3.zero, Vector3(0,1,0));
 8 private var rayTranslate :Ray = Ray(Vector3.zero, Vector3(0,1,0));
 9 private var hitInfo : RaycastHit ;
10 
11 private var preTime :float = 0.0;
12 
13 
14 //它标记是否能旋转
15 private var flag :boolean = false ;
16 
17 function Update () {///事件监视
18 
19      var direction :Vector3 = Vector3.zero;
20      var px:float ;
21      var pz:float ;
22      
23      
24      if(Input.GetMouseButtonDown(0)){
25          rayTranslate = camera.ScreenPointToRay(Input.mousePosition);
26         //以摄像机为起点画射线,射线去地板碰撞点就是那个焦点
27         Physics.Raycast(camera.transform.position, rayTranslate.direction, hitInfo);
28         if (Time.time - preTime  < 0.3f ){
29           hitInfo.point=hitInfo.point+Vector3(0,5,0);
30           transform.position=Vector3.MoveTowards(camera.transform.position,hitInfo.point,10.0);
31         }
32          
33          preTime = Time.time ;
34      }
35      
36      //上下左右拖动
37     if(Input.GetMouseButton(0)){
38         px = Input.GetAxis("Mouse X") ;
39         pz = Input.GetAxis("Mouse Y") ;
40         direction = Vector3(px, pz, pz);
41         transform.Translate( -1 * direction * 30 * Time.deltaTime);
42     }
43     
44     //滚轴放到缩小
45     pz = Input.GetAxis("Mouse ScrollWheel");
46     direction = Vector3(0, 0, pz);
47     transform.Translate(direction * 100 * Time.deltaTime);
48     
49     //旋转
50     if(Input.GetMouseButtonDown(1)){
51         rayRotate = camera.ScreenPointToRay(Input.mousePosition);
52         flag = true ;
53     }
54     if(Input.GetMouseButtonUp(1)){
55         rayRotate = Ray(Vector3.zero, Vector3(0,1,0));
56         flag = false ;
57     }
58     if(Input.GetMouseButton(1) && flag){
59         Physics.Raycast(camera.transform.position, rayRotate.direction, hitInfo);
60         px = Input.GetAxis("Mouse X") ;
61         transform.RotateAround(hitInfo.point, Vector3.up, 100 * px * Time.deltaTime);
62     }
63 }

 

转载于:https://www.cnblogs.com/huntdream/archive/2013/04/16/3025291.html

2013-10-28 17:55:38 l2008l 阅读数 3018
其实不需要什么空物体了,war3式的平移效果其实是高度不变平行地面的一个平面上四处移动的问题了,光translate摄像机是不行的 
 
贴上我完整的代码吧
 
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//rts方式镜头移动 旋转 缩放控制 javascript
var ZoomSpeed = 30;//镜头缩放速率
var MovingSpeed = 1;//镜头移动速率
var RotateSpeed = 1;  //镜头旋转速率
private var distance = 0.0f;//保存镜头和中心点的直线距离
  
function Start () {
    //先用镜头斜视的角度和离地面的高度算出距离视野中心的直线距离
    //要省事也可以直接指定一个距离 这个不重要
    //镜头的高度可以减去一个修正值 这样就是正视地图上方的效果 看需要
    distance = Mathf.Abs(transform.position.y/Mathf.Sin(transform.eulerAngles.x));
}
  
function LateUpdate () {
    var rotation;
    var position;
  
    //按住鼠标左键移动鼠标拖动镜头,改成键盘输入或者鼠标靠近屏幕边缘输入都是可以的   
    if(Input.GetMouseButton(0))
    {
        var delta_x = Input.GetAxis("Mouse X") * MovingSpeed;
         var delta_y = Input.GetAxis("Mouse Y") * MovingSpeed;
  
        //镜头其实就是在平行地面的水平面上四处移动 所以构造一个变换矩阵 与世界坐标唯一的差异就是y轴旋转的角度
        rotation = Quaternion.Euler(0, transform.rotation.eulerAngles.y,0 );
        //把镜头要移动的分量乘以这个变化矩阵就是相对世界坐标的移动量啦 再加上镜头当前坐标 就是镜头新位置啦
        transform.position =rotation * Vector3(-delta_x,0,-delta_y)+transform.position;
      }
  
            //用滚轮控制镜头拉伸和推进
      if(Input.GetAxis("Mouse ScrollWheel")){   
          var delta_z = -Input.GetAxis("Mouse ScrollWheel") * ZoomSpeed;
          //直接用镜头的translate函数在镜头参考系Z方向上运动就可以啦
        transform.Translate(0,0,-delta_z);
        //再用delta_z修正镜头与视野中心点的距离 其实不记录也是可以的 每次都用sin算比较麻烦
        distance += delta_z;
    }
  
      //按住鼠标右键移动鼠标旋转镜头
      if (Input.GetMouseButton(1)) {
        var delta_rotation_x = Input.GetAxis("Mouse X") * RotateSpeed;
        var delta_rotation_y = -Input.GetAxis("Mouse Y") * RotateSpeed;
  
       //旋转是以镜头当前视野中心点为原点进行的 在一个平行于地面的水平面上旋转
  
       //先算出当前视野中心的坐标,中心的概念就是正对 上下左右都对齐,离开一个distance距离
       //所以中心点相对镜头参照系的坐标就是0,0,distance,乘以镜头的变换,在加上镜头的世界坐标 就是中心点的世界坐标了
       position =transform.rotation* Vector3(0,0,distance)+transform.position;
  
       //Y轴方向上用世界坐标的变换就可以拉 否则镜头会歪的       
       transform.Rotate(0,delta_rotation_x,0,Space.World);
       //x轴方向的旋转是相对自身的 否则镜头也会歪
       transform.Rotate(delta_rotation_y,0,0);
       //转完以后 把这个新的旋转角度 乘以一个“正对中心”的相对坐标 再加上中心点的坐标 就是新的镜头世界坐标啦
       transform.position =transform.rotation* Vector3(0,0,-distance)+position;
     }
}


 
另存为一个什么xxxx.js 拖给你的摄像机,随便搞个地形走走看吧
如果速度太快/太慢 就调整3个参数吧
 
除去鸡婆的注释和输入 if什么的,全部平移 旋转 缩放 也就是8行代码 基本没有用神马内建的转换功能(用了一次translate),也没有搞什么空物体指引方向、投射x/y/z一堆sin cos什么的。那都不太符合3d编程的基本精神,只用了转换矩阵 坐标变换来搞定全部控制了
 
要注意的是:
旋转其实有两种意思 一种是以摄像机为中心的旋转,那种效果很简单了 就是摄像机在世界的y方向上转一个角度就行了。但是那种旋转不符合rts游戏的要求,举个例子我建了个铁匠铺,挡住了我的小兵,我想转一个角度去点小兵,如果是以摄像机为中心转,那铁匠铺就转出视野了。所以应该是以视野中心转比较符合,虽然这样实现起来麻烦一些。
 
在摄像机的参照系里,屏幕上的东西永远是前方 是z方向上加,摄像机的最中心就是正对位置,在这个位置上中心和摄像机的坐标偏移永远是0,0,镜头距离,有这个前提就能做出各种变化的效果来
 
以摄像机为参照点计算中心,那就是加上镜头距离(摄像机z轴的前方),以中心为参照点计算摄像机应该的位置,就是减去镜头距离,所以这个distance一会加一会减的 想明白了就很好理解了。
 
把中心点的position换成一个目标的position那就是跟随目标进行这3种变换,效果都是一样的,会自动跟随。
紧跟目标屁股后面 那变换方法就是:
Quaternion.Euler(0,target.rotation.eulerAngles.y,0)*(0,0,与目标的距离)+目标当前位置 
想要斜后方紧跟,那就是目标的
Quaternion.Euler(斜视角度,target.rotation.eulerAngles.y,0)*(0,0,与目标的距离)+目标当前位置, 
距离为0那就是
Quaternion.Euler(0,target.rotation.eulerAngles.y,0)*(0,0,0)=0 + 目标当前位置,fps第一人称视角啦。
目标的x z旋转都不用理会的 他摔倒镜头也不用水平转吧。。他往前倾我们也不用跟着他看地板(fps需要这样。。所以很晕)

有变换,神马都是一样的原理。


再贴一个自己写的适合RPG用的镜头跟随脚本,C#的 
 
复制代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
using UnityEngine;
using System.Collections;
  
public class MouseFollow_ForRPG_CSharp : MonoBehaviour {
  
    public GameObject target;
    public float ZoomSpeed = 30;//镜头缩放速率
    public float MovingSpeed = 1;//镜头移动速率
    public float RotateSpeed = 1;  //镜头旋转速率
    public float distance = 20;//设置距离角色的距离
    public float ViewAngle = 30;//设置镜头斜视的角度
  
    void Start () {
        if(target){
            transform.rotation = Quaternion.Euler(ViewAngle, target.transform.rotation.eulerAngles.y,0 );
            transform.position = transform.rotation * new Vector3(0,0,-distance)+target.transform.position;   
        }
    }
  
    void Update () {
        Quaternion rotation;
        Vector3 position;
        float delta_x,delta_y;
        float delta_rotation_x,delta_rotation_y;
  
        if(target){
            if(Input.GetMouseButton(0))
            {
                delta_x = Input.GetAxis("Mouse X") * MovingSpeed;
                delta_y = Input.GetAxis("Mouse Y") * MovingSpeed;
                 rotation = Quaternion.Euler(0, transform.rotation.eulerAngles.y,0 );
                  transform.position = rotation * new Vector3(-delta_x,0,-delta_y)+ transform.position;
              }
            else{
                  if(Input.GetAxis("Mouse ScrollWheel")!= 0){   
                      distance += -Input.GetAxis("Mouse ScrollWheel") * ZoomSpeed;
                }
                  if (Input.GetMouseButton(1)) {
                    delta_rotation_x = Input.GetAxis("Mouse X") * RotateSpeed;
                    delta_rotation_y = -Input.GetAxis("Mouse Y") * RotateSpeed;
                       transform.Rotate(0,delta_rotation_x,0,Space.World);
                       transform.Rotate(delta_rotation_y,0,0);
                 }
                else {
                    transform.rotation = Quaternion.Slerp(transform.rotation,
                        Quaternion.Euler(transform.rotation.eulerAngles.x, target.transform.rotation.eulerAngles.y,0
                        ),Time.deltaTime*2);
                }
                transform.position = transform.rotation* new Vector3(0,0,-distance)+ target.transform.position;
            }
        }
    }
}


copy另存为MouseFollow_ForRPG_CSharp.cs,拖给你的镜头,就能用啦。想跟随哪一个就把目标物体拖到Inspector里target那一栏。
自动跟随角色正后方,按住鼠标右键移动鼠标,围着角色上下左右旋转镜头,滚轮缩放,放开鼠标镜头自动平滑的转回后方跟随的角度,镜头高度不变,经典的魔兽世界控制方式。另外多一个魔兽没有的功能,左键按住移动鼠标可以冻结摄像机镜头上下左右拖动,因为只是演示控制,一般左键都是战斗相关的功能,不想要把那几行删掉就行啦。全部这些核心变换代码也就10行左右。
 
如果不是用理论的旋转模型,那这个问题就太复杂啦 目标在动 在旋转,镜头相对目标又在动在旋转,要加多少参考物体,搞多少x/y/z分量的投射变换啊。。思维方式很重要
 
原理都一样 不细说了,变化就是把rts的以视野中心为参考改成了以目标为参考
一个细节就是因为要跟随,所以不管有没有输入每次update都要参考目标位置修正镜头位置的,否则就不叫跟随了。

转载自 http://game.ceeger.com/forum/read.php?tid=2703&fid=2

2015-01-07 09:18:29 u011713224 阅读数 868

菜鸟初学unity3d 需要的效果,鼠标左键绕中心模型旋转摄像机,滚轮调整摄像头与模型距离,右键暂时保留

因为有js版和c#(不会),不过自己整理了一下,可供大家选择

鼠标左键,摄像头旋转(c#版)

using UnityEngine;
using System.Collections;

public class control : MonoBehaviour {
	public float roate_Speed=200.0f;//旋转速度 
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
			if (Input.GetMouseButton(0)){
					//Debug.Log("射线取得对象");
					float mousX = Input.GetAxis("Mouse X") * roate_Speed;//得到鼠标横向移动距离
					float mousY = Input.GetAxis("Mouse Y") * roate_Speed;//得到鼠标纵向移动距离
					// 绕Y轴旋转
					transform.RotateAround (Vector3.zero, Vector3.up, mousX * Time.deltaTime);
					// 绕x轴旋转(效果不是很好,使用时可注掉)
					transform.RotateAround (Vector3.zero, Vector3.right, -mousY * Time.deltaTime);
				}
			}
	}



鼠标滚轮调整摄像头与模型间距离

c#版

using UnityEngine;
using System.Collections;

public class carmera : MonoBehaviour {
	public float minFov = 15f;
	public float maxFov = 90f;
	public float sensitivity = 10f;
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
		float fov = Camera.main.fieldOfView;
		fov += -Input.GetAxis("Mouse ScrollWheel") * sensitivity;
		fov = Mathf.Clamp(fov, minFov, maxFov);
		Camera.main.fieldOfView = fov;
	}
}

javascript版

#pragma strict
var viewSpeed=5;
// 与模型最近距离
var minFov=8.0;
// 与模型最远距离
var maxFov=100.0;
var fov:float;

function Start () {

}

function Update () {
	if(Input.GetAxis("Mouse ScrollWheel")) { 
		// 从当前位置进行变更
		fov = this.GetComponent.<Camera>().fieldOfView;
		//Debug.Log("检测到滑轮"+Input.GetAxis("Mouse ScrollWheel"));
		fov -= Input.GetAxis("Mouse ScrollWheel") * viewSpeed;
		fov = Mathf.Clamp(fov, minFov, maxFov);
		this.GetComponent.<Camera>().fieldOfView = fov;
	}
}

如果发现什么问题大家可以评论,共同进步吗!

2017-03-25 16:57:14 bzzbzz7 阅读数 1143

一、利用重力加速度传感器,控制摄像头方向

重力加速度传感器精度为:0.1 范围(0—±1)

unity3d Inspector 窗口里面:position是global position, rotation是local rotation

gravity参考坐标系:
这里写图片描述

camara参考坐标系:
这里写图片描述

原理:手机倾斜,坐标系跟着倾斜,根据重力向量在世界坐标系中恒定不变,求得手机坐标系倾斜角度,把该角度赋予场景中的camara 使得相机跟随手机同步倾斜
求gravity关于原点的对称点,把该点角度赋予相机:
Quaternion qgravity = Quaternion.LookRotation(gyro.gravity*-1);
transform.localRotation = qgravity;

效果:不理想,只能同步倾斜,不能同步旋转。

2017-10-20 13:10:57 qq_33994566 阅读数 6458

最近公司的几个项目开发内容基本相同,很多脚本直接复制过来就可以拼接项目。之前一直是代码爱好者,能自己敲的绝对不去复制粘贴。但是开发速度确实是被耽误了,所以接下来打算把开发中常用的脚本都发到博客上。自己需要的时候直接拿来。也希望能帮到你们。

unity编辑器中按住鼠标右键,在通过控制键盘的wasdqe键可以自由控制视野。下面就是实现操作的代码:

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

//巡游模式摄像机控制
public class CameraMove : MonoBehaviour
{

    public static CameraMove Instance = null;
    
    private Vector3 dirVector3;
    private Vector3 rotaVector3;
    private float paramater = 0.1f;
    //旋转参数
    private float xspeed = -0.05f;
    private float yspeed = 0.1f;

	private float dis;

    void Awake ()
	{
	    Instance = this;
	}

    private void Start()
    {
        rotaVector3 = transform.localEulerAngles;
		dis = UIFuc.Instance.Dis;
    }

    // Update is called once per frame
	void FixedUpdate ()
    {
        //旋转
        if (Input.GetMouseButton(1))
        {
            rotaVector3.y += Input.GetAxis("Horizontal") * yspeed;
            rotaVector3.x += Input.GetAxis("Vertical") * xspeed;
            transform.rotation = Quaternion.Euler(rotaVector3);
        }

        //移动
        dirVector3 =Vector3.zero;

        if (Input.GetKey(KeyCode.W))
        {
            if(Input.GetKey(KeyCode.LeftShift)) dirVector3.z = 3;
            else dirVector3.z = 1;
        }
        if (Input.GetKey(KeyCode.S))
        {
            if (Input.GetKey(KeyCode.LeftShift)) dirVector3.z = -3;
            else dirVector3.z = -1;
        }
        if (Input.GetKey(KeyCode.A))
        {
            if (Input.GetKey(KeyCode.LeftShift)) dirVector3.x = -3;
            else dirVector3.x = -1;
        }
        if (Input.GetKey(KeyCode.D))
        {
            if (Input.GetKey(KeyCode.LeftShift)) dirVector3.x = 3;
            else dirVector3.x = 1;
        }
        if (Input.GetKey(KeyCode.Q))
        {
            if (Input.GetKey(KeyCode.LeftShift)) dirVector3.y = -3;
            else dirVector3.y = -1;
        }
        if (Input.GetKey(KeyCode.E))
        {
            if (Input.GetKey(KeyCode.LeftShift)) dirVector3.y = 3;
            else dirVector3.y = 1;
        }
        transform.Translate(dirVector3 * paramater,Space.Self);
        //限制摄像机范围
		transform.position = Vector3.ClampMagnitude(transform.position, dis);
    }
}


由于项目需要限制摄像机的移动范围,所以我在最后加上了限制的代码。

Unity3D中四元数

阅读数 4321

unity镜头控制脚本

阅读数 1008

没有更多推荐了,返回首页