Unity 3D 簡易制作攝像機圍繞物體隨鼠標旋轉效果


Unity 3D 簡易制作攝像機圍繞物體隨鼠標旋轉效果

梗概:

一. 攝像機圍繞目標物體旋轉, 即攝像機離目標物體有一定的距離且旋轉軸心為該物體的位置.

 

二. 當目標物體被障礙物擋住后, 需要將攝像機移動到障礙物前方能看見目標物體的位置.

思路:

一. 攝像機繞軸心旋轉, 可以在軸心處創建一個空物體, 將攝像機設為該軸心的子物體. 如圖:

 

這樣便可以簡單地實現攝像機旋轉軸心 (注意: 旋轉時應旋轉軸心而不是單獨旋轉攝像機) . 還應注意, 如果攝像機的目標物體可以移動的話, 就應每幀將軸心的坐標設為目標物體的坐標 (盡量不要直接將軸心設為目標物體的子物體! 除非有特別需要) .

二. 當目標物體被障礙物擋住后, 可以在目標物體處發射一條射線, 射線原點就是目標物體的坐標 (也就是軸心) , 射線方向就是從原點到攝像機的方向. 此時射線的碰撞點就是將要把攝像機調整到的位置.

 

三. 當將攝像機移動到后方沒有障礙物的位置時, 就應將攝像機移回至原距離.

 

過程:

  1. 創建任意目標物體;

  2. 創建一個空物體並命名, 這個空物體就是軸心, 並將其 Tag 設為 "3rdCameraAxle":

    或者將其 Tag 設為你喜歡的一個都可以;

  3. 創建攝像機, 將其 Tag 設為 "MainCamera", 並設為剛創建的軸心的子物體;

  4. 創建任意障礙物.

代碼:

一. 此時繞物體旋轉攝像機便可簡化為直接旋轉軸心, 代碼也簡化了許多:

  1. 定義鼠標靈敏度:

    public float mouseSensitivity = 2;
  1. 定義目標物體的  Transform  :

    public Transform targetTrans;
  1. 定義軸心  Transform  與軸心旋轉角度:

    Transform thirdPCamAxle;
    Vector3 thirdPCamEuler;

    在  void Start()  下對其賦值:

    void Start () {
        thirdPCamAxle = GameObject.FindGameObjectWithTag("3rdCameraAxle").transform; //括號里的引號中也可以寫上你自己對軸心設的 Tag.
        thirdPCamEuler = thirdPCamAxle.localEulerAngles; //推薦寫 localEulerAngles, 要不之后處理起來會比較麻煩.
    }
  2. 定義攝像機:

    Camera thirdPCam;

    在  void Start()  下對其賦值:

    void Start () {
        thirdPCam = Camera.main;
    }
  3. 定義並賦值攝像機離物體的最大距離, 攝像機離物體的當前距離:

    float camForwardMaxDistance = 9;
    float camForwardDistance;
    float camBackDistance;
  4. 在  void Update()  下寫:

    thirdPCamAxle.position = targetTrans.position; //將攝像機旋轉軸心位置設為目標物體位置
    //定義旋轉量
    float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity; 
    float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity;
    thirdPCamEuler.y += mouseX; //控制攝像機左右旋轉
    //控制攝像機上下旋轉, 並且上下旋轉范圍不能超過90°或-90°, 此方法適用於 localEulerAngles.
    if (thirdPCamEuler.z < 90 && mouseY > 0) { thirdPCamEuler.z += mouseY; }
    if (thirdPCamEuler.z > -90 && mouseY < 0) { thirdPCamEuler.z += mouseY; }
    thirdPCamAxle.localEulerAngles = thirdPCamEuler; //將旋轉量應用到攝像機上.

至此, 控制攝像機旋轉完成. 此部分代碼如下:

 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4  5 public class ThirdPCamC : MonoBehaviour {
 6     public float mouseSensitivity = 2;
 7     public Transform targetTrans;
 8  9     Transform thirdPCamAxle;
10     Vector3 thirdPCamEuler;
11 12     Camera thirdPCam;
13     float camForwardMaxDistance = 9;
14     float camForwardDistance;
15     float camBackDistance;
16 17     void Start () {
18         thirdPCamAxle = GameObject.FindGameObjectWithTag("3rdCameraAxle").transform;
19         thirdPCamEuler = thirdPCamAxle.localEulerAngles;
20 21         thirdPCam = Camera.main;
22     }
23     
24     void Update () {
25         thirdPCamAxle.position = targetTrans.position;
26 27         float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
28         float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity;
29         thirdPCamEuler.y += mouseX;
30         if (thirdPCamEuler.z < 90 && mouseY > 0) { thirdPCamEuler.z += mouseY; }
31         if (thirdPCamEuler.z > -90 && mouseY < 0) { thirdPCamEuler.z += mouseY; }
32         thirdPCamAxle.localEulerAngles = thirdPCamEuler;
33     }
34 }

二. 攝像機避開障礙物, 並在后方沒有障礙物時移回原距離 (原距離可通過設置對  camForwardMaxDistance  的賦值來改變):

在   void Update()   下寫:

Ray camForwardRay = new Ray(thirdPCam.transform.position, thirdPCam.transform.forward); //在攝像機處發射一條向前的射線, 用來檢測攝像機當前離目標的距離 (此處不必擔心射線碰撞處是障礙物的情況).
RaycastHit forwardRayHit; //定義射線碰撞.
if (Physics.Raycast(camForwardRay, out forwardRayHit)) //當射線有碰撞物時 (也就是目標物體), 
{
    camForwardDistance = Vector3.Distance(thirdPCam.transform.position, forwardRayHit.point); //計算從攝像機到碰撞點的距離 (碰撞點也可以改為目標物體的位置).
}
​
Vector3 dir = thirdPCam.transform.position - targetTrans.position; //定義從目標物體到攝像機的方向.
dir = dir.normalized; //將方向單位化.
Ray ray = new Ray(targetTrans.position, dir); //在目標物體處發射一條射線, 方向即為剛剛定義的向量.
RaycastHit hit; //定義射線碰撞.
if (Physics.Raycast(ray, out hit)) //當該射線有碰撞, 即目標物體被障礙物擋住時, 
{
    thirdPCam.transform.position = hit.point; //將攝像機位置設為碰撞點位置.
}
else //如果沒有碰撞, 即目標物體沒有被障礙物擋住, 
{
    if (camForwardDistance < camForwardMaxDistance) //並且當前距離沒有超過最大距離時, 
    {
        thirdPCam.transform.Translate(Vector3.back * Time.deltaTime * 5); //將攝像機緩慢后移至最大距離.
    }
}

全部代碼如下:

 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4  5 public class ThirdPCamC : MonoBehaviour {
 6     public float mouseSensitivity = 2;
 7     public Transform targetTrans;
 8  9     Transform thirdPCamAxle;
10     Vector3 thirdPCamEuler;
11 12     Camera thirdPCam;
13     float camForwardMaxDistance = 9;
14     float camForwardDistance;
15     float camBackDistance;
16 17     void Start () {
18         thirdPCamAxle = GameObject.FindGameObjectWithTag("3rdCameraAxle").transform;
19         thirdPCamEuler = thirdPCamAxle.localEulerAngles;
20 21         thirdPCam = Camera.main;
22     }
23     
24     void Update () {
25         thirdPCamAxle.position = targetTrans.position;
26 27         float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
28         float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity;
29         thirdPCamEuler.y += mouseX;
30         if (thirdPCamEuler.z < 90 && mouseY > 0) { thirdPCamEuler.z += mouseY; }
31         if (thirdPCamEuler.z > -90 && mouseY < 0) { thirdPCamEuler.z += mouseY; }
32         thirdPCamAxle.localEulerAngles = thirdPCamEuler;
33 34         Ray camForwardRay = new Ray(thirdPCam.transform.position, thirdPCam.transform.forward);
35         RaycastHit forwardRayHit;
36         if (Physics.Raycast(camForwardRay, out forwardRayHit))
37         {
38             camForwardDistance = Vector3.Distance(thirdPCam.transform.position, forwardRayHit.point);
39         }
40 41         Vector3 dir = thirdPCam.transform.position - targetTrans.position;;
42         dir = dir.normalized;
43         Ray ray = new Ray(targetTrans.position, dir);
44         RaycastHit hit;
45         if (Physics.Raycast(ray, out hit))
46         {
47             Debug.DrawLine(ray.origin, hit.point, Color.green);
48             thirdPCam.transform.position = hit.point;
49         }
50         else
51         {
52             if (camForwardDistance < camForwardMaxDistance)
53             {
54                 thirdPCam.transform.Translate(Vector3.back * Time.deltaTime * 5);
55             }
56         }
57     }
58 }

最終效果圖:

希望本篇教程能夠幫到大家!

源碼: [GitHub](https://github.com/JadMax/Unity3D-Miscellaneous/blob/master/ThirdpersonCameraController.cs)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM