2025-02-14 13:20:54 +08:00
using DG.Tweening ;
2025-02-08 16:22:00 +08:00
using UnityEngine ;
using UnityEngine.EventSystems ;
public class Show3DCamera : MonoBehaviour
{
2025-02-10 10:54:47 +08:00
public Vector3 targetPos ; // Χ <> <CEA7> <EFBFBD> <EFBFBD> ת<EFBFBD> <D7AA> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD>
2025-02-08 16:22:00 +08:00
public float rotateSpeed = 10f ; // <20> <> ת<EFBFBD> ٶ<EFBFBD>
public float moveSpeed = 10f ; // <20> ƶ<EFBFBD> <C6B6> ٶ<EFBFBD>
public float distance = 10f ; // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> ľ<EFBFBD> <C4BE> <EFBFBD>
2025-02-10 10:54:47 +08:00
public float distanceMin = 0.2f ;
public float distanceMax = 20f ;
2025-02-08 16:22:00 +08:00
public Vector2 pitchMinMax = new Vector2 ( - 20 , 80 ) ; // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Χ
private Vector3 offset ; // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD> ƫ<EFBFBD> <C6AB> <EFBFBD> <EFBFBD>
private float yaw = 0f ; // ƫ<> <C6AB> <EFBFBD> ǣ<EFBFBD> <C7A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ת<EFBFBD> <D7AA>
private float pitch = 0f ; // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ǣ<EFBFBD> <C7A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ת<EFBFBD> <D7AA>
public static Show3DCamera instance ;
2025-02-10 10:54:47 +08:00
RectTransform inputRect ;
2025-02-08 16:22:00 +08:00
Camera self ;
2025-02-10 10:54:47 +08:00
private GameObject lastHitObject = null ;
2025-02-13 17:21:18 +08:00
public RenderTexture texture ;
public bool lockMove = false ;
2025-02-14 13:20:54 +08:00
private Vector2 mouseDownPosition ; // <20> <> ¼<EFBFBD> <C2BC> <EFBFBD> 갴<EFBFBD> <EAB0B4> ʱ<EFBFBD> <CAB1> λ<EFBFBD> <CEBB>
2025-02-08 16:22:00 +08:00
private void Awake ( )
{
instance = this ;
self = transform . GetComponent < Camera > ( ) ;
DontDestroyOnLoad ( this ) ;
2025-02-08 17:33:21 +08:00
gameObject . SetActive ( false ) ;
2025-02-08 16:22:00 +08:00
}
2025-02-13 17:21:18 +08:00
2025-02-14 13:20:54 +08:00
public void Set ( Transform target , float rotateSpeed = 10 , float moveSpeed = 0.1f , float distance = 0.1f , float pitchMin = - 20 , float pitchMax = 80 , float distanceMin = 0.2f , float distanceMax = 20f , RectTransform inputRect = null , bool isRenderTexture = true , float moveTime = - 1 )
2025-02-08 16:22:00 +08:00
{
if ( target = = null )
{
Debug . LogError ( "Target is not assigned!" ) ;
return ;
}
2025-02-10 10:54:47 +08:00
2025-02-08 16:22:00 +08:00
yaw = 0 ;
pitch = 0 ;
2025-02-10 10:54:47 +08:00
this . inputRect = inputRect ;
this . targetPos = target . transform . position ;
2025-02-08 16:22:00 +08:00
this . rotateSpeed = rotateSpeed ;
this . moveSpeed = moveSpeed ;
this . distance = distance ;
2025-02-10 10:54:47 +08:00
this . distanceMin = distanceMin ;
this . distanceMax = distanceMax ;
2025-02-08 16:22:00 +08:00
this . pitchMinMax = new Vector2 ( pitchMin , pitchMax ) ;
// <20> <> ʼ <EFBFBD> <CABC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> λ<EFBFBD> <CEBB>
offset = new Vector3 ( 0 , 0 , - distance ) ;
2025-02-13 17:21:18 +08:00
if ( isRenderTexture )
{
self . targetTexture = texture ;
}
else
{
self . targetTexture = null ;
}
2025-02-14 13:20:54 +08:00
UpdateCameraPosition ( moveTime ) ;
2025-02-08 16:22:00 +08:00
}
2025-02-10 10:54:47 +08:00
2025-02-08 16:22:00 +08:00
void Update ( )
{
2025-02-14 13:20:54 +08:00
if ( targetPos ! = null & & lockMove = = false & & EventSystem . current . IsPointerOverGameObject ( ) = = false )
2025-02-08 16:22:00 +08:00
{
2025-02-14 13:20:54 +08:00
if ( Input . GetMouseButtonDown ( 0 ) )
{
// <20> <> ¼<EFBFBD> <C2BC> <EFBFBD> 갴<EFBFBD> <EAB0B4> ʱ<EFBFBD> <CAB1> λ<EFBFBD> <CEBB>
mouseDownPosition = Input . mousePosition ;
}
2025-02-08 16:22:00 +08:00
// <20> <> ס <EFBFBD> <D7A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> ת<EFBFBD> <D7AA> <EFBFBD> <EFBFBD>
if ( Input . GetMouseButton ( 0 ) )
{
2025-02-14 13:20:54 +08:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 갴<EFBFBD> º<EFBFBD> ̧<EFBFBD> <CCA7> λ<EFBFBD> <CEBB> ֮<EFBFBD> <D6AE> <EFBFBD> ľ<EFBFBD> <C4BE> <EFBFBD>
float distance = Vector2 . Distance ( mouseDownPosition , Input . mousePosition ) ;
if ( distance > 1f )
{
RotateCamera ( ) ;
}
2025-02-08 16:22:00 +08:00
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
float scroll = Input . GetAxis ( "Mouse ScrollWheel" ) ;
if ( scroll ! = 0 )
{
ZoomCamera ( scroll ) ;
}
// <20> <> ס <EFBFBD> <D7A1> <EFBFBD> <EFBFBD> <EFBFBD> Ҽ<EFBFBD> ʱ<EFBFBD> ƶ<EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD>
if ( Input . GetMouseButton ( 1 ) )
{
MoveTarget ( ) ;
}
DetectHoveredObject ( ) ;
}
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͣ<EFBFBD> <CDA3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2025-02-10 10:54:47 +08:00
public void DetectHoveredObject ( )
2025-02-08 16:22:00 +08:00
{
2025-02-10 10:54:47 +08:00
GameObject obj = null ;
Vector2 mousePosition = Input . mousePosition ;
if ( inputRect ! = null )
2025-02-08 16:22:00 +08:00
{
2025-02-10 10:54:47 +08:00
var pos = ( mousePosition - ( Vector2 ) inputRect . position ) / inputRect . lossyScale - inputRect . rect . position ;
mousePosition = pos / inputRect . rect . size ;
2025-02-08 16:22:00 +08:00
}
2025-02-10 10:54:47 +08:00
var ray = self . ViewportPointToRay ( mousePosition ) ;
RaycastHit raycastHit ;
if ( Physics . Raycast ( ray , out raycastHit ) )
{
//Debug.Log(raycastHit.transform.name);
obj = raycastHit . transform . gameObject ;
2025-02-08 16:22:00 +08:00
2025-02-10 10:54:47 +08:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> λ<EFBFBD> <CEBB> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> 岻ͬ<E5B2BB> <CDAC> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> ߽<EFBFBD> <DFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
if ( obj ! = lastHitObject )
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ¼<EFBFBD>
OnMouseEnterObj ( obj ) ;
2025-02-08 16:22:00 +08:00
2025-02-10 10:54:47 +08:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> λ<EFBFBD> <CEBB> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> 岻Ϊ<E5B2BB> գ <EFBFBD> <D5A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 뿪<EFBFBD> ¼<EFBFBD>
if ( lastHitObject ! = null & & lastHitObject ! = obj )
{
OnMouseExitObj ( lastHitObject ) ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> λ<EFBFBD> <CEBB> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD>
lastHitObject = obj ;
}
2025-02-08 16:22:00 +08:00
2025-02-10 10:54:47 +08:00
}
}
else
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> л<EFBFBD> <D0BB> <EFBFBD> <EFBFBD> κ<EFBFBD> <CEBA> <EFBFBD> <EFBFBD> 壬<EFBFBD> <E5A3AC> <EFBFBD> <EFBFBD> һ <EFBFBD> λ<EFBFBD> <CEBB> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> 岻Ϊ<E5B2BB> գ <EFBFBD> <D5A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 뿪<EFBFBD> ¼<EFBFBD>
if ( lastHitObject ! = null )
{
OnMouseExitObj ( lastHitObject ) ;
lastHitObject = null ;
}
}
2025-02-08 16:22:00 +08:00
}
2025-02-14 13:20:54 +08:00
/// <summary>
/// <20> ۽<EFBFBD> ij<EFBFBD> <C4B3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
2025-02-14 17:09:41 +08:00
public void FocusObj ( Vector3 target , float distance = 1f , float moveTime = - 1 )
2025-02-14 13:20:54 +08:00
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǰ<EFBFBD> <C7B0> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> λ<EFBFBD> ã<EFBFBD> <C3A3> <EFBFBD> ΪCube<62> <65> Ŀ<EFBFBD> <C4BF> λ<EFBFBD> <CEBB>
// <20> <> <EFBFBD> Ը<EFBFBD> <D4B8> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
Vector3 cameraPos = target - transform . forward * distance ;
targetPos = target ;
this . distance = distance ;
offset = new Vector3 ( 0 , 0 , - distance ) ;
2025-02-17 15:14:40 +08:00
if ( moveTime ! = - 1 )
2025-02-14 17:09:41 +08:00
{
transform . DOMove ( cameraPos , moveTime ) ;
}
else
{
transform . position = cameraPos ;
}
2025-02-14 13:20:54 +08:00
}
2025-02-10 10:54:47 +08:00
public void OnMouseEnterObj ( GameObject obj )
{
TipItem tip = obj . GetComponent < TipItem > ( ) ;
if ( tip ! = null )
{
tip . OnEnter ( ) ;
}
}
public void OnMouseExitObj ( GameObject obj )
{
TipItem tip = obj . GetComponent < TipItem > ( ) ;
if ( tip ! = null )
{
tip . OnExit ( ) ;
}
}
2025-02-08 16:22:00 +08:00
// <20> ƶ<EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD>
private void MoveTarget ( )
{
float mouseX = Input . GetAxis ( "Mouse X" ) * moveSpeed ;
float mouseY = Input . GetAxis ( "Mouse Y" ) * moveSpeed ;
transform . Translate ( new Vector3 ( - mouseX , - mouseY , 0 ) ) ;
2025-02-17 15:14:40 +08:00
targetPos + = new Vector3 ( - mouseX , - mouseY , 0 ) ;
2025-02-08 16:22:00 +08:00
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
private void ZoomCamera ( float scroll )
{
distance - = scroll * 5f ; // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ٶ<EFBFBD>
2025-02-10 10:54:47 +08:00
distance = Mathf . Clamp ( distance , distanceMin , distanceMax ) ; // <20> <> <EFBFBD> ƾ<EFBFBD> <C6BE> 뷶Χ
2025-02-08 16:22:00 +08:00
offset = new Vector3 ( 0 , 0 , - distance ) ;
UpdateCameraPosition ( ) ;
}
// <20> <> ת<EFBFBD> <D7AA> <EFBFBD> <EFBFBD>
private void RotateCamera ( )
{
// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ƶ<EFBFBD> <C6B6> <EFBFBD>
float mouseX = Input . GetAxis ( "Mouse X" ) * rotateSpeed ;
float mouseY = Input . GetAxis ( "Mouse Y" ) * rotateSpeed ;
// <20> <> <EFBFBD> <EFBFBD> ƫ<EFBFBD> <C6AB> <EFBFBD> Ǻ<C7BA> <CDB8> <EFBFBD> <EFBFBD> <EFBFBD>
yaw + = mouseX ;
pitch - = mouseY ; // ע<> ⣺<EFBFBD> <E2A3BA> <EFBFBD> <EFBFBD> Y <20> <> <EFBFBD> ƶ<EFBFBD> <C6B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 븩<EFBFBD> <EBB8A9> <EFBFBD> <EFBFBD> <EFBFBD> ෴
pitch = Mathf . Clamp ( pitch , pitchMinMax . x , pitchMinMax . y ) ; // <20> <> <EFBFBD> Ƹ<EFBFBD> <C6B8> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Χ
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> λ<EFBFBD> <CEBB>
UpdateCameraPosition ( ) ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> λ<EFBFBD> úͳ<C3BA> <CDB3> <EFBFBD>
2025-02-14 13:20:54 +08:00
private void UpdateCameraPosition ( float moveTime = - 1 )
2025-02-08 16:22:00 +08:00
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ת<EFBFBD> <D7AA> <EFBFBD> <EFBFBD> ƫ<EFBFBD> <C6AB> <EFBFBD> <EFBFBD>
Quaternion rotation = Quaternion . Euler ( pitch , yaw , 0 ) ;
Vector3 rotatedOffset = rotation * offset ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> λ<EFBFBD> <CEBB>
2025-02-14 13:20:54 +08:00
if ( moveTime ! = - 1 )
{
transform . DOMove ( targetPos + rotatedOffset , moveTime ) . onUpdate = ( ) = >
// <20> <> <EFBFBD> <EFBFBD> ʼ <EFBFBD> ճ<EFBFBD> <D5B3> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD>
transform . LookAt ( targetPos ) ;
}
else
{
transform . position = targetPos + rotatedOffset ;
// <20> <> <EFBFBD> <EFBFBD> ʼ <EFBFBD> ճ<EFBFBD> <D5B3> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD>
transform . LookAt ( targetPos ) ;
}
2025-02-08 16:22:00 +08:00
}
}