unity控制相機圍繞物體旋轉移動

記錄一下控制相機圍繞物體旋轉與移動的腳本,相機操作思路分為兩塊,一部分為旋轉,一部分為移動,旋轉是根據當前center中心點的坐標,根據距離設置與默認的旋轉進行位置移動,移動是根據相機的左右和前后進行計算,當獲取到移動的值時把中心點進行移動,而不是移動相機,相機是根據中心點的坐標進行計算自己的坐標
這個中心點是一個空物體放在模型下方,不要把模型放進去
默認的角度設置需要提前說一下,例如當前我相機在場景的旋轉為(39,135,0),
如果我想在運行的時候也是這個角度 就需要吧相機x軸填入到腳本的y軸上,需要取反為負數
相機的y軸放到腳本的x上,但是腳本的y需要自身的旋轉減去180 設置就為(-45,-39,0)
這樣做的理由就是把360的角度映射為正負1800
剩下的就是是否開啟自旋轉與是否可以低于地面
在這里插入圖片描述在這里插入圖片描述
在這里插入圖片描述

using QFramework;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;public class Camera_模型相機 : MonoBehaviour
{// public Transform target; // 目標物體public GameObject center;//圍繞點public float rotateSpeed = 5.0f; // 旋轉速度public float scrollSpeed = 5.0f; // 滾輪速度public float minDistance = 20f; // 最小距離public float maxDistance = 150; // 最大距離public float initialDistance = 20.0f; // 初始距離public Vector2 initialAngles = new Vector2(0f, 30f); // 初始角度(水平,垂直)public float moveSpeed;//移動速度float move_X,move_Y;private float currentDistance;private float horizontalAngle;private float verticalAngle;public bool enableAutoRotate = false; // 是否啟用自動旋轉public float autoRotateSpeed = 10f; // 自動旋轉速度bool bl_旋轉控制;Vector3 initialPos;float time_自選擇控制=5;public bool allowBelowGround = true; //是否允許低于地面public float groundHeight = 0f; // 地面高度(可自定義)void Start(){currentDistance = initialDistance;horizontalAngle = initialAngles.x;verticalAngle = initialAngles.y;initialPos = center.transform.position;UpdateCameraPosition();}void Update(){HandleMouseInput();HandleScrollInput();if (enableAutoRotate){if (!bl_旋轉控制){time_自選擇控制 += Time.deltaTime;if (time_自選擇控制 >= 5) { bl_旋轉控制 = true; time_自選擇控制 = 0; }}AutoRotateCenter();}UpdateCameraPosition();}void AutoRotateCenter(){if (bl_旋轉控制) horizontalAngle -= autoRotateSpeed * Time.deltaTime;}void HandleMouseInput(){if (Input.GetMouseButton(1)){bl_旋轉控制 = false;time_自選擇控制 = 0;// 獲取鼠標移動量horizontalAngle += Input.GetAxis("Mouse X") * rotateSpeed;verticalAngle += Input.GetAxis("Mouse Y") * rotateSpeed;verticalAngle = Mathf.Clamp(verticalAngle, -89f, 89f); // 限制垂直角度}   // 新增右鍵平移邏輯// 鼠標左鍵移動if (Input.GetMouseButton(0)){bl_旋轉控制 = false;time_自選擇控制 = 0;move_X = moveSpeed * Input.GetAxis("Mouse X");move_Y= moveSpeed* Input.GetAxis("Mouse Y");Vector3 right = transform.right * move_X;Vector3 forward = transform.forward * move_Y;forward.y = 0; // 保持水平移動// print((right + forward));center.transform.Translate(-(right + forward), Space.World);}}void HandleScrollInput(){float scroll = Input.GetAxis("Mouse ScrollWheel");currentDistance -= scroll * scrollSpeed;currentDistance = Mathf.Clamp(currentDistance, minDistance, maxDistance);}public void ResetCamera(){// 重置到初始狀態currentDistance = initialDistance;horizontalAngle = initialAngles.x;verticalAngle = initialAngles.y;center.Position(initialPos); bl_旋轉控制 = false;}void UpdateCameraPosition(){// 計算旋轉Quaternion yaw = Quaternion.AngleAxis(horizontalAngle, Vector3.up);Quaternion pitch = Quaternion.AngleAxis(verticalAngle, Vector3.right);Quaternion combinedRotation = yaw * pitch;// 計算相機位置Vector3 offset = combinedRotation * Vector3.forward * currentDistance;Vector3 targetPos = center.transform.position + offset;// 新增地面高度限制if (!allowBelowGround && targetPos.y < groundHeight){targetPos.y = groundHeight+0.2f; 重新計算距離保持原有水平距離//float horizontalDist = Mathf.Sqrt(//    Mathf.Pow(targetPos.x - center.transform.position.x, 2) +//    Mathf.Pow(targetPos.z - center.transform.position.z, 2)//);//currentDistance = horizontalDist / Mathf.Cos(Mathf.Asin(//    (groundHeight - center.transform.position.y) / currentDistance//));}transform.position = targetPos;// 確保相機看向目標transform.LookAt(center.transform.position);}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/82569.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/82569.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/82569.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python打卡day38@浙大疏錦行

知識點回顧&#xff1a; Dataset類的__getitem__和__len__方法&#xff08;本質是python的特殊方法&#xff09;Dataloader類minist手寫數據集的了解 作業&#xff1a;了解下cifar數據集&#xff0c;嘗試獲取其中一張圖片 一、首先加載CIFAR數據集 import torch import torchvi…

用戶配置文件(Profile)

2.4.5 用戶配置文件&#xff08;Profile&#xff09; 用戶配置文件由以下組件構成&#xff1a; 一個運營商安全域&#xff08;MNO-SD&#xff09; 輔助安全域&#xff08;SSD&#xff09;和CASD Applets 應用程序&#xff08;如NFC應用&#xff09; 網絡接入應用&#xff…

如何給自研MCP加上安全驗證

前言 剛過去兩個月,市面的 MCP 服務,如雨后春筍一般不斷涌現出來,包括;百度、高德、網盤、支付寶。這些 MCP 服務,可以讓我們基于 Spring AI 框架構建的 Agent 具備非常豐富的使用功能。同時這也說明,程序員???????,應該具備開發 MCP 服務的能力,Spring AI 讓 J…

Unity網絡開發實踐項目

摘要&#xff1a;該網絡通信系統基于Unity實現&#xff0c;包含以下幾個核心模塊&#xff1a; 協議配置&#xff1a;通過XML定義枚舉&#xff08;如玩家/英雄類型&#xff09;、數據結構&#xff08;如PlayerData&#xff09;及消息協議&#xff08;如PlayerMsg&#xff09;&a…

OpenCV CUDA模塊圖像過濾------創建一個 Sobel 濾波器函數createSobelFilter()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 該函數用于創建一個 Sobel 濾波器&#xff0c;用于在 GPU 上進行邊緣檢測。它基于圖像的梯度計算&#xff1a; dx 表示對 x 方向求導的階數&…

【JavaSE】枚舉和注解學習筆記

枚舉和注解 -枚舉 規定多選一數據類型的解決方案-枚舉 枚舉對應英文(enumeration,簡寫 enum) 2)枚舉是一組常量的集合。 3)可以這里理解:枚舉屬于一種特殊的類&#xff0c;里面只包含一組有限的特定的對象。 枚舉的兩種實現方式 自定義實現枚舉 使用enum關鍵字實現枚舉 自…

Spark SQL進階:解鎖大數據處理的新姿勢

目錄 一、Spark SQL&#xff0c;為何進階&#xff1f; 二、進階特性深剖析 2.1 窗口函數&#xff1a;數據洞察的新視角 2.2 高級聚合&#xff1a;挖掘數據深度價值 2.3 自定義函數&#xff08;UDF 和 UDTF&#xff09;&#xff1a;拓展功能邊界 三、性能優化實戰 3.1 數…

如何利用 Conda 安裝 Pytorch 教程 ?

如何利用 Conda 安裝 Pytorch 教程 &#xff1f; 總共分為六步走&#xff1a; &#xff08;1&#xff09;第一步&#xff1a;驗證conda 環境是否安裝好&#xff1f; 1) conda -V2) conda --version&#xff08;2&#xff09;第二步&#xff1a;查看現有環境 conda env list…

什么是HTTP

HTTP&#xff08;HyperText Transfer Protocol&#xff09;是萬維網數據通信的基礎協議&#xff0c;作為應用層協議具有以下關鍵特性&#xff1a; 客戶端-服務器模型&#xff1a;基于請求/響應模式 無狀態協議&#xff1a;默認不保留通信狀態 可擴展性&#xff1a;通過首部字…

2025-05-27 學習記錄--Python-模塊

合抱之木&#xff0c;生于毫末&#xff1b;九層之臺&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、模塊 ?? &#xff08;一&#xff09;模塊的導入與使用 &#x1f36d; 模塊的導入&#xff1a;&#x1f41d; 模塊 就好比…

leetcode 131. Palindrome Partitioning

目錄 一、題目描述 二、方法1、回溯法每次暴力判斷回文子串 三、方法2、動態規劃回溯法 一、題目描述 分割回文子串 131. Palindrome Partitioning 二、方法1、回溯法每次暴力判斷回文子串 class Solution {vector<vector<string>> res;vector<string>…

重構開發范式!飛算JavaAI革新Spring Cloud分布式系統開發

分布式系統憑借高可用性、可擴展性等核心優勢&#xff0c;成為大型軟件項目的標配架構。Spring Cloud作為Java生態最主流的分布式開發框架&#xff0c;雖被廣泛應用于微服務架構搭建&#xff0c;但其傳統開發模式卻面臨效率瓶頸——從服務注冊中心配置到網關路由規則編寫&#…

python 生成復雜表格,自動分頁等功能

py&#xff54;&#xff48;&#xff4f;&#xff4e; 生成復雜表格&#xff0c;自動分頁等功能 解決將Python中的樹形目錄數據轉換為Word表格&#xff0c;并生成帶有合并單元格的檢測報告的問題。首先&#xff0c;要解決“tree目錄數據”和“Word表格互換”&#xff0c;指將樹…

根據Cortex-M3(包括STM32F1)權威指南講解MCU內存架構與如何查看編譯器生成的地址具體位置

首先我們先查看官方對于Cortex-M3預定義的存儲器映射 1.存儲器映射 1.1 Cortex-M3架構的存儲器結構 內部私有外設總線&#xff1a;即AHB總線&#xff0c;包括NVIC中斷&#xff0c;ITM硬件調試&#xff0c;FPB, DWT。 外部私有外設總線&#xff1a;即APB總線&#xff0c;用于…

Linux中硬件信息查詢利器——lshw命令詳解!

lshw&#xff08;List Hardware&#xff09;是 Linux 系統下的一款命令行工具&#xff0c;用于全面檢測并顯示詳細的硬件信息。它能夠報告 CPU、內存、主板、存儲設備、顯卡、網絡設備等幾乎所有硬件組件的詳細信息&#xff0c;適用于系統管理、故障排查和硬件兼容性檢查等場景…

用llama3微調了一個WiFiGPT 用于室內定位

一段話總結 本文提出WiFiGPT,一種基于Decoder-Only Transformer(如LLaMA 3)的室內定位系統,通過將WiFi遙測數據(如CSI、FTM、RSSI)轉換為文本序列進行端到端訓練,無需手工特征工程即可實現高精度定位。實驗表明,WiFiGPT在LOS環境中實現亞米級精度(MAE低至0.90米),在…

大模型系列22-MCP

大模型系列22-MCP 玩轉 MCP 協議&#xff1a;用 Cline DeepSeek 接入天氣服務什么是 MCP&#xff1f;環境準備&#xff1a;VScode Cline DeepSeek**配置 DeepSeek 模型&#xff1a;****配置 MCP 工具****uvx是什么&#xff1f;****安裝 uv&#xff08;會自動有 uvx 命令&…

Go語言Map的底層原理

概念 map 又稱字典&#xff0c;是一種常用的數據結構&#xff0c;核心特征包含下述三點&#xff1a; &#xff08;1&#xff09;存儲基于 key-value 對映射的模式&#xff1b; &#xff08;2&#xff09;基于 key 維度實現存儲數據的去重&#xff1b; &#xff08;3&#x…

循環神經網絡(RNN):原理、架構與實戰

循環神經網絡&#xff08;Recurrent Neural Network, RNN&#xff09;是一類專門處理序列數據的神經網絡&#xff0c;如時間序列、自然語言、音頻等。與前饋神經網絡不同&#xff0c;RNN 引入了循環結構&#xff0c;能夠捕捉序列中的時序信息&#xff0c;使模型在不同時間步之間…

java 項目登錄請求業務解耦模塊全面

登錄是統一的閘機&#xff1b; 密碼存在數據庫中&#xff0c;用的是密文&#xff0c;后端加密&#xff0c;和數據庫中做對比 1、UserController public class UserController{Autowiredprivate IuserService userservicepublic JsonResult login(Validated RequestBody UserLo…