1. 程式人生 > >unity。。。完美簡單解決靠滑鼠在螢幕上的移動來控制相機水平,垂直旋轉的c#指令碼

unity。。。完美簡單解決靠滑鼠在螢幕上的移動來控制相機水平,垂直旋轉的c#指令碼

   花了一天時間琢磨這個,看網上的解決辦法。。沒幾個徹底解決的。。。都是說什麼方法複雜。。讓我們自己去看視訊教程。。!!!!

感覺跟沒有回答一樣敲打。。。。自己也是很多方法都試了。。不是有這種問題,就是那種問題。。。。。。煩!!!最後自己琢磨出這個不是辦法的辦法。。。。。。

  雖然沒有用到什麼高深的東西,複雜的演算法。。。。但是自己花時間琢磨的。親測效果還過得去。注意有三個版本(全當學習過程了尷尬),最後版本為最簡單最完美的.

using UnityEngine;

using System.Collections;


public class CameraFollow : MonoBehaviour
{
    public float V_upAngle;            // 螢幕從z軸向上擡的高度的限制
    public float V_downAngle;           //螢幕從z軸向下低頭的限制
    public float H_Angle;               //螢幕左右旋轉的最大角度的限制。繞y軸
    public float smooth;                // how smooth the camera movement is
    public float distance_obj;
    public float distance_h;
    public Transform targe_position;        //player
    private Vector3 mouse_point;
    private float screen_w;         //螢幕資訊
    private float screen_h;
    private float H_unit_rotation;          //滑鼠在螢幕移動距離投射到三維世界的角度旋轉單位大小
    private float V_up_unit_rotation;
    private float V_down_unit_rotation;
    private Vector3 screen_center;          
    private Quaternion center_rotation;     //最終旋轉結果
    private Quaternion current_rotation_H;      //水平旋轉結果
    private Quaternion current_rotation_V;  //垂直旋轉結果
    void Start()
    {
        center_rotation = new Quaternion();
        center_rotation=transform.rotation;
        FixedUpdate();
    }
    void LateUpdate()//利用尤拉角旋轉相機
    {
        transform.rotation = center_rotation;
        mouse_point = Input.mousePosition;
        current_rotation_V = Quaternion.AngleAxis((mouse_point.x - screen_center.x) * H_unit_rotation, Vector3.up);
        if (mouse_point.y >= screen_center.y)
        {
            current_rotation_H = Quaternion.AngleAxis((mouse_point.y - screen_center.y) * V_up_unit_rotation, Vector3.left);
        }
        if (mouse_point.y < screen_center.y)
        {
            current_rotation_H = Quaternion.AngleAxis((mouse_point.y - screen_center.y) * V_down_unit_rotation, Vector3.left);


        }
        //move
        transform.rotation =current_rotation_V*current_rotation_H;   //利用向量叉乘得到最終效果。。。注意順序不能改變(不滿足交換律);
        transform.position=(targe_position.position + Vector3.up * distance_h - Vector3.forward * distance_obj);        
   }
    private void FixedUpdate()
    {
        screen_w = Screen.width; screen_h = Screen.height;
        screen_center = new Vector3(screen_w / 2, screen_h / 2, 0);     //參考點。決定視角往那一邊旋轉
        H_unit_rotation =H_Angle/ screen_w;
        V_up_unit_rotation = V_upAngle / screen_h / 2;
        V_down_unit_rotation = V_downAngle / screen_h / 2;
    }

 }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///這是後面改良版,加入了以目標為視野焦點的旋轉。

using UnityEngine;
using System.Collections;


public class CameraFollow : MonoBehaviour
{
    public float distance_v;
    public float distance_h;
    public float H_unit_rotation;          //滑鼠在螢幕移動距離投射到三維世界的角度旋轉單位大小
    public float V_unit_rotation;
    public float max_up_angle=320;              //越小,頭擡得越高
    public float max_down_angle=50;            //越大,頭擡得越低
    public Transform targe_position;        //player


    private Vector3 mouse_point;
    private Quaternion previous_rotation;
    private Vector3 mouse_start_pos;          
    private Quaternion current_rotation_H;      //垂直旋轉結果
    private Quaternion current_rotation_V;  //水平旋轉結果
    void Start()
    {
        mouse_start_pos = Input.mousePosition;
        previous_rotation = transform.rotation;
    }


    private void Update()           //改變旋轉
    {
        mouse_point = Input.mousePosition;
        transform.rotation = previous_rotation;
        if (mouse_point == mouse_start_pos) return;
        ///////////////每次旋轉是以世界座標為參考
        if (mouse_point.x != mouse_start_pos.x)      //水平旋轉
        {
            current_rotation_V = Quaternion.AngleAxis((mouse_point.x - mouse_start_pos.x)
                * H_unit_rotation, Vector3.up);
        }
        if (mouse_point.y!=mouse_start_pos.y)          //垂直旋轉
        {
            current_rotation_H = Quaternion.AngleAxis((mouse_point.y - mouse_start_pos.y)
                * V_unit_rotation, Vector3.left);
        }
        //rotation,向量叉乘得到組合效果
        transform.rotation*=(current_rotation_V*current_rotation_H);   //利用向量叉乘得到最終效果。。。注意順序不能改變(不滿足交換律);  
        mouse_start_pos = mouse_point;
        float angle_x = transform.rotation.eulerAngles.x;
        //200只是區別是擡頭還是低頭,因為尤拉角的性質
        if (angle_x<=max_up_angle&&angle_x>200)         //往上擡頭
        {
            transform.rotation = Quaternion.Euler(
           new Vector3(max_up_angle, transform.rotation.eulerAngles.y, 0f));
        }
        if(angle_x>=max_down_angle&&angle_x<200) {          //低頭
            transform.rotation = Quaternion.Euler(
           new Vector3(max_down_angle, transform.rotation.eulerAngles.y, 0f));
            }
            transform.rotation=Quaternion.Euler(
            new Vector3(transform.rotation.eulerAngles.x,transform.rotation.eulerAngles.y,0f));     //阻止相機繞z軸旋轉(會讓視野傾斜) 
        previous_rotation = transform.rotation;
    }
    void LateUpdate()           //改變位置
    {
        transform.position = targe_position.position;
        transform.Translate(Vector3.back * distance_h, Space.Self);
        transform.Translate(Vector3.up * distance_v, Space.World);          //相對於世界座標y軸向上
   }
 
}

///////////////////////////////////////////////////////////////////////

////////////////////////最終版

using UnityEngine;
using System.Collections;
public class CameraController : MonoBehaviour {
    public float distance_v;
    public float distance_h;
    public float rotation_H_speed=1;
    public float rotation_V_speed=1;
    public float max_up_angle = 80;              //越大,頭擡得越高
    public float max_down_angle =-60;            //越小,頭擡得越低
    public Transform follow_obj;        //player


    private float current_rotation_H;      //水平旋轉結果
    private float current_rotation_V;  //垂直旋轉結果
    void LateUpdate()      
    {
        //控制旋轉
        current_rotation_H+= Input.GetAxis("Mouse X")*rotation_H_speed;
        current_rotation_V += Input.GetAxis("Mouse Y")*rotation_V_speed;
        current_rotation_V=Mathf.Clamp(current_rotation_V, max_down_angle, max_up_angle);       //限制垂直旋轉角度
        transform.localEulerAngles = new Vector3(-current_rotation_V,current_rotation_H,0f);
        
        //改變位置,以跟蹤的目標為視野中心,且視野中心總是面向follow_obj
        transform.position =follow_obj.position;
        transform.Translate(Vector3.back * distance_h, Space.Self);
        transform.Translate(Vector3.up * distance_v, Space.World);          //相對於世界座標y軸向上
    }
}

相關推薦

unity完美簡單解決滑鼠螢幕移動控制相機水平垂直旋轉c#指令碼

   花了一天時間琢磨這個,看網上的解決辦法。。沒幾個徹底解決的。。。都是說什麼方法複雜。。讓我們自己去看視訊教程。。!!!! 感覺跟沒有回答一樣。。。。自己也是很多方法都試了。。不是有這種問題,就是那種問題。。。。。。煩!!!最後自己琢磨出這個不是辦法的辦法。。。。。。

解決安卓手機傳圖片沒有拍照選項修改後又出現的安卓手機能載入相簿和攝像頭但蘋果手機不能載入相簿的問題

<input type="file" id="choose" accept="image/*" multiple> 上面是原始碼,下面修改後可以讓安卓手機顯示攝像頭 <inp

傳頭像 呼叫相機拍照 簡單的呼叫相簿的照片傳頭像

首先我在對應的主頁面 xml裡面進行一個相關的UI介面的佈局 對應的兩個Button按鈕 一個拍照,一個呼叫相簿 一個Imageview 的一張小機器人的圖片 <?xml version="1.0" encoding="utf-8"?> <LinearLa

Unity攝像機 向指定位置移動旋轉 C#指令碼

using UnityEngine; using System.Collections; public class CameraCtrl : MonoBehaviour {float frameCount = 50.0f; // 希望多少幀內完成場景轉移// 目標位置:寫死

unity 字型、數字模糊的解決方案2017或2018版本

Rendering Mode 必選hinted RasterCharacter選Dynamic注意那個font-size 這個值就是最佳不會模糊的字型大小,儘量設定為你程式中能用到的最大的字型。但不要設定為超大,例如你用到16px.就別填32 。字型大會佔更多記憶體。

Android 按鍵防止過快點選(防抖)在ButterKnife中的簡單解決方案

其實自己也在網上找了一些防抖的方案,比如RxBinding啊,NoDoubleClickListener啊,原始解決方案啊等等,不過那都不是我想要的。 因為專案中使用了ButterKnife繫結控制元件和為控制元件註冊點選事件。所以上面搜到的那些方案都不太好使

簡單介紹一下在CentOS安裝Docker

簡單介紹一下在CentOS上安裝Docker。 前置條件: 64-bit 系統 kernel 3.10+  1.檢查核心版本,返回的值大於3.10即可。   $ uname -r 2.使用 sudo 或 root 許可權的使用者登入終端。 3.確保yu

Unity 接入Facebook登入、分享、邀請、好友列表等功能

版本環境:Unity版本 5.3.4f1 Facebook版本 7.9.4 Facebook 提供了Unity SDK, 這比原生的方式接要方便很多。 1、在開發者後臺建立應用。 後臺地址:https://developers.facebook.com/apps/ 2、下載Unity

12月11日發生大面積的包含 react-native-image-picker 的安卓專案啟動崩潰現象解決方案(我的已經解決

12月11日,發生大面積的包含 react-native-image-picker 的安卓專案啟動崩潰現象。疑似原因為maven源丟失。解決方案見github:https://github.com/react-native-community/react-native-image-picke

【小菜鳥】本人部落格沒有任何侵權的想法僅僅是總結了一些前輩們的經驗做了一些小筆記發表 在以往學習過程中遇到太多太多的小問題網上都有答案只不過太多太雜,解決問題的答案也是可遇不可求 總是事倍功半特此總結出一些自己的小經驗希望能夠幫助大家

小菜鳥 本人部落格,沒有任何侵權的想法,僅僅是總結了一些前輩們的經驗,做了一些小筆記發表。 在以往學習過程中,遇到太多太多的小問題,網上都有答案,只不過太多太雜,解決問題的答案也是可遇不可求, 總是事倍功半。特...

Java修改JVM記憶體大小整理(java heap space 解決方案)

JAVA程式啟動時JVM都會分配一個初始記憶體和最大記憶體給這個應用程式。這個初始記憶體和最大記憶體在一定程度都會影響程式的效能;Tomcat預設可以使用的記憶體為128MB,在較大型的應用專案中,這點記憶體是不夠的,需要調大。有以下幾種方法可以選用:第一種 環境myeclipse修改在選單windo

Spring工作原理原理就是這麼簡單

IoC與DI   首先想說說IoC(Inversion of Control,控制倒轉)。這是spring的核心,貫穿始終。所謂IoC,對於spring框架來說,就是由spring來負責控制物件的生命週期和物件間的關係。這是什麼意思呢,舉個簡單的例子,我們是如何找女朋友的?

JavaScript封裝自己的一個彈窗是雙按鈕的比較簡單一些 其中引用了jQuery寫的方法最後暴露出去有更好的建議歡迎評論

$(function(){ // 設定自執行函式 (function(jQuery){ // 定義建構函式 var Popup = function (title,text,fn) { this.title = title || '

我是一個新手小白想學習C++程式設計但是不知道該如何入手請大神們給出一個簡單的思路

如題所示,我現在準備學習C++程式語言,因為是0基礎,所以入門也顯的很迷茫,也看過一些視訊,感覺講的很好,但就是聽得雲裡霧裡,看著視訊也會嘗試敲一些程式碼,但是程式碼的意思,也都不懂,不知道該如何入手,所以就想到,如果要

spring boot入門(七) springboot的攔截器Interceptor最完整、簡單易懂、詳細的spring boot教程

很多同學搞不懂攔截器和過濾器的區別,我們先說一下他們的區別: 過濾器和攔截器非常相似,但是它們有很大的區別 最簡單明瞭的區別就是過濾器可以修改request,而攔截器不能 過濾器需要在servlet容器中實現,攔截器可以適用於javaEE,javaSE等各種環境 攔截

spring boot入門(四) springboot事務管理最完整、簡單易懂、詳細的spring boot教程

本文緊接spring boot入門(三)。 事務管理是對於一系列資料庫操作進行管理,一個事務包含一個或多個SQL語句,是邏輯管理的工作單元(原子單元)。通俗的講,事務管理是指的“一次操作”要不就全做,要不就全不做。例如,在一個訂單系統中,包括生成訂單,扣除商品存庫等操作,如

NFS檔案共享解決tomcat叢集檔案

URL url= new URL(“http://localhost:8080/resources/4.docx”);URLConnection conn = url.openConnection();conn.getInputStream();本來打算將檔案存放在tomca

6-3 簡單求和(10 分) 本題要求實現一個函式求給定的N個整數的和

int Sum ( int List[], int N ){  int sum=0;  for(int i=0;i<N;i++)  {    sum+=List[i];  }  return sum;}list的L大寫還有N,就醬。

解決XML 根級別的資料無效

真正解決XML 根級別上的資料無效: UTF8或者Unicode編碼轉換時,第一個字元轉換會出現一個?號。 所以,為避免異常。還應加上。 xml = xml.Substring(1, xml.Length - 1); 然後再 LoadXml(xml) 就不會出錯了。