一、實現思路
①創建一個RenderTexture,渲染設備模型;
②創建一個攝像機,就只照射UI面板的設備,且移除AudioListener組件;
③設置該創建出來的只照射UI面板設備攝像機的【Target Texture】屬性爲該RenderTexture;
④創建一個顯示設備模型的圖片組件RawImage,且指定該RawImage的屬性Texture爲RenderTexture;
⑤最後創建一個設備物體在這個只照射UI面板設備的攝像機前面即可。
二、實現效果
三、控制三維物體自由旋轉
①控制設備自由旋轉的核心腳本如下:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MyFunction
{
public class ModelRotationController : MonoBehaviour
{
//變量枚舉
public enum RotationAxes
{
MouseXAndY = 0,
MouseX = 1,
MouseY = 2
}
public bool interactable;
[Header("操作的物體")]
public GameObject Obj;
[Header("主相機")]
public GameObject MainCamera;
[Space(20)]
[Header("旋轉速度"), Range(0, 2)]
public float aroundRadius = 0.5f;//角速度
[Header("自動旋轉時間間隔"), Range(0, 10)]
public float timeinterval = 4f;//時間間隔
[Header("上下翻轉開關")]
public bool SwitchVertical = false;
[Header("上下旋轉角度限制")]
public float eulerUp = 60;
public float eulerDown = -60f;
[Space(20)]
[Header("默認距離")]
public float distence = 6f;
[Header("縮放速度"), Range(0, 30)]
public float speed = 15; //縮放速度
[Header("縮放最遠距離"), Range(0, 50)]
public float distenceMax = 20f;
[Header("縮放最近距離"), Range(2, 20)]
public float distenceMin = 3f;
[Header("縮放最大速度")]
public float maxSpeed = 30;
[Header("縮放最小速度")]
public float minSpeed = 1;
[Header("縮放加速度")]
public float Acceleration = 1;
float m_rotationY = 0f; //偏移量
[HideInInspector]
private Vector3 direction = new Vector3(0, 1, 0);//自動旋轉的方向
[HideInInspector]
public bool Switch_detail = false;//細節開關
[HideInInspector]
public RotationAxes m_axes = RotationAxes.MouseXAndY; //實例化枚舉
public static ModelRotationController _instance;
[HideInInspector]
public Vector3 eulerObj;
float eulerYNow;
float angled;//當前角度
float _TimeNow = 0f;
float _EulerX = 0;
float _EulerY = 0;
bool auto = false;
public float notChangeminDistance;
public float notChangemaxDistance;
bool setminValue = true;
bool setmaxValue = true;
[HideInInspector]
public float EulerOffentY; //Y值偏移量
private void Awake()
{
notChangeminDistance = distenceMin;
notChangemaxDistance = distenceMax;
EulerOffentY = 0;
_instance = this;
interactable = true;
maxSpeed = speed * 2;
}
private void Update()
{
if (Obj)
{
eulerObj = Obj.transform.rotation.eulerAngles;
}
if (Obj != null && interactable && !GameObject.Find("Dropdown List") && !GameObject.Find("AlarmTable") && !Switch_detail)
{
ManualController();
if (auto)
{
_TimeNow = 0;
AutoController();
}
else
{
_TimeNow += Time.deltaTime;
}
VerticalRotate();
HoriZontalRotate();
CameraMove();
}
}
/// <summary>
/// 交互控制開關
/// </summary>
public void CameraSwitch()
{
interactable = !interactable;
}
#region 相機控制
/// <summary>
/// 相機縮放
/// </summary>
void CameraMove()
{
if (Obj != null)
{
// MainCamera.transform.LookAt(Obj.transform);
}
if (Input.GetAxis("Mouse ScrollWheel") > 0)
{
auto = false;
_TimeNow = 0;
distence = Mathf.Sqrt((Obj.transform.position - MainCamera.transform.position).sqrMagnitude);
//distence = Obj.transform.position.z - MainCamera.transform.position.z;\
MainCamera.transform.Translate(new Vector3(0, 0, 1) * speed * Time.deltaTime, Space.Self);
if (distence < distenceMin)
{
MainCamera.transform.position = Obj.transform.position - new Vector3(0, 0, distenceMin);
}
else
{
//近慢
if (Mathf.Approximately(speed, minSpeed))
{
if (setminValue)
{
notChangeminDistance = distence;
setminValue = false;
}
}
if (distence < notChangemaxDistance)
{
speed -= Acceleration;
speed = Mathf.Clamp(speed, minSpeed, maxSpeed);
}
}
}
else if (Input.GetAxis("Mouse ScrollWheel") < 0)
{
auto = false;
_TimeNow = 0;
distence = Mathf.Sqrt((Obj.transform.position - MainCamera.transform.position).sqrMagnitude);
MainCamera.transform.Translate(new Vector3(0, 0, -1) * speed * Time.deltaTime, Space.Self);
if (distence > distenceMax)
{
MainCamera.transform.position = Obj.transform.position - new Vector3(0, 0, distenceMax);
}
else
{
//遠快
if (Mathf.Approximately(speed, maxSpeed))
{
if (setmaxValue)
{
notChangemaxDistance = distence;
setmaxValue = false;
}
}
if (distence > notChangeminDistance)
{
speed += Acceleration;
speed = Mathf.Clamp(speed, minSpeed, maxSpeed);
}
}
}
}
/// <summary>
/// 相機對象重置
/// </summary>
/// <param name="cur"></param>
public void MachineReset(GameObject cur)
{
notChangeminDistance = 0;
notChangemaxDistance = 30;
setminValue = true;
setmaxValue = true;
speed = 15;
Obj = cur;
distence = 6;
if (Switch_detail)
{
MainCamera.transform.position = Obj.transform.position - new Vector3(0, 0, 4);
}
else
{
MainCamera.transform.position = new Vector3(Obj.transform.position.x, Obj.transform.position.y, -distence);
}
}
#endregion
#region 物體旋轉控制
/// <summary>
///手動控制
/// </summary>
void ManualController()
{
if (Input.GetKey(KeyCode.Mouse0))
{
auto = false;
_TimeNow = 0;
Obj.transform.Rotate(new Vector3(0, _EulerY, 0), Space.Self);
EulerOffentY += _EulerX;
if (EulerOffentY > eulerUp)
{
EulerOffentY = eulerUp;
_EulerX = 0;
}
else if (EulerOffentY < eulerDown)
{
EulerOffentY = eulerDown;
_EulerX = 0;
}
Obj.transform.Rotate(new Vector3(_EulerX, 0, 0), Space.World);
}
else if (_TimeNow > timeinterval && Input.GetAxis("Mouse ScrollWheel") == 0f)
{
auto = false; //關閉自動旋轉
}
}
/// <summary>
/// 自動旋轉
/// </summary>
void AutoController()
{
Obj.transform.Rotate(direction * aroundRadius);
}
/// <summary>
/// 水平旋轉
/// </summary>
void HoriZontalRotate()
{
float eularAboutY = -Input.GetAxis("Mouse X") * aroundRadius * 200 * Time.deltaTime;
//Debug.Log("eularAboutY:"+ eularAboutY);
_EulerY = eularAboutY;
}
/// <summary>
/// 垂直旋轉
/// </summary>
void VerticalRotate()
{
if (SwitchVertical)
{
float eularAboutX = Input.GetAxis("Mouse Y") * aroundRadius * 200 * Time.deltaTime;
//Debug.Log("eularAboutX:" + eularAboutX);
_EulerX = eularAboutX;
}
}
/// <summary>
/// 角度限制
/// </summary>
/// <param name="minZ">最小角度</param>
/// <param name="maxZ">最大角度</param>
public void RotateLimite()
{
if (Obj)
{
float _EulerOfY = Obj.transform.rotation.eulerAngles.y;
Mathf.Clamp(CheckAngle(_EulerOfY), eulerDown, eulerUp);
Obj.transform.rotation = Quaternion.Euler(_EulerOfY, Obj.transform.rotation.y, Obj.transform.rotation.z);
}
}
/// <summary>
/// 角度限制操作
/// </summary>
/// <param name="angle">當前角度</param>
/// <param name="min">最小角度</param>
/// <param name="max">最大角度</param>
/// <returns></returns>
protected float CheckAngle(float angle, float min, float max)
{
if (angle < 90 || angle > 270)
{ // if angle in the critic region...
if (angle > 180) angle -= 360; // convert all angles to -180..+180
if (max > 180) max -= 360;
if (min > 180) min -= 360;
}
angle = Mathf.Clamp(angle, min, max);
if (angle < 0) angle += 360; // if angle negative, convert to 0..360
return angle;
}
/// <summary>
/// 角度轉換方法
/// </summary>
/// <param name="angle"></param>
/// <returns></returns>
protected float CheckAngle(float value) // 將大於180度角進行以負數形式輸出
{
float angle = value - 180;
if (angle > 0)
{
return angle - 180;
}
if (value == 0)
{
return 0;
}
return angle + 180;
}
#endregion
}
}
②將該腳本掛載到任意物體上,然後指定對應需要旋轉的設備和照射三維模型的攝像機即可