using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using Mogoson.Tooltip;
using HighlightingSystem;
using HedgehogTeam.EasyTouch;
public enum State
{
None,
//单指
Single,
//缩放
Pinch,
//滑动
Swipe
}
public class CameraController1 : MonoBehaviour
{
public float moveSpeed = 1;
public float rotateSpeed = 60;
public float zoomSpeed = 15;
public Transform m_Camera;
public State state;
Vector2 offset;
Touch[] touches;
int activeCount;
public static CameraController1 instance;
public Transform ModelRoot;
public Transform[] targets;
[HideInInspector]
public int index; // 当前的场景
private int comeBack = 0; // 返回主页计数
public Transform curtarget; // 当前摄像机锁定的目标
[System.Serializable]
public class CameraParameters
{
public bool smoothFollow; // 是否开启平滑跟随
public float followSpeed=15f; // 跟随速度
public float distance; // 相机的初始距离
public float minDistance; // 最小距离
public float maxDistance; // 最大距离
public float zoomSpeed; // 缩放速度
public float zoomSensitivity; // 缩放灵敏度
public float rotationSensitivity; // 旋转灵敏度
public float yMinLimit; // 垂直最小值
public float yMaxLimit; // 垂直最大值
public Vector3 offset; // 偏移量
public float inFade = 0.6f; // 材质淡入
public float outFade = 1.0f; // 材质淡出
}
public CameraParameters parameters; // 相机相关参数
public float x { get; private set; } // 相机X方向旋转量
public float y { get; private set; } // 相机Y方向旋转量
public float distanceTarget { get; private set; } // 目标距离
private Vector3 position;
private Quaternion rotation = Quaternion.identity;
private Vector3 smoothPosition;
private Camera cam;
[HideInInspector]
public bool isRay = true; // 射线检测开关,在主场景才开启射线拾取
private GameObject rayTarget;
public BoardController boardController;
// 设备开机相关参数
public static bool isStart = false;
void Awake()
{
instance = this;
parameters = new CameraParameters();
Init();
}
public void Init()
{
InitCameraParaDefault(); // 设置相机的默认参数
index = 0;
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
//目标距离
distanceTarget = parameters.distance;
smoothPosition = transform.position;
cam = Camera.main;
}
void Update()
{
Inspection();
UpdateTransform();
}
//射线检测
private void Inspection()
{
if (isRay)
{
Radiographic();
Operate();
}
}
//射线发射
private void Radiographic()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//从摄像机发出到点击坐标的射线
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
Debug.DrawLine(ray.origin, hitInfo.point, Color.blue);//划出射线,只有在scene视图中才能看到
rayTarget = hitInfo.collider.gameObject;
}
else
{
rayTarget = null;
}
}
//射线检测模型操作
private void Operate()
{
if (Input.GetMouseButtonUp(0))
{
if (rayTarget != null)
{
// Debug.Log("rayTarget: " + rayTarget.name);
// 场景切换
if (index == 0 && rayTarget.GetComponent<ModelID>())
{
index = rayTarget.GetComponent<ModelID>().id;
Debug.Log("获取id" + index);
ChangeScene(index);
}
}
}
}
#region 相机控制脚本
// 默认的相机参数设置
private void InitCameraParaDefault()
{
parameters.smoothFollow = true;
parameters.followSpeed = 2.0f;
parameters.minDistance = 14.0f;
parameters.maxDistance = 30.0f;
parameters.distance = 22.0f;
parameters.zoomSpeed = 10.0f;
parameters.zoomSensitivity = 1.0f;
parameters.rotationSensitivity = 3.5f;
parameters.yMinLimit = -20;
parameters.yMaxLimit = 80;
parameters.offset = new Vector3(0.0f, 1.0f, 6.0f);
}
// 单个模型场景的相机参数设置
/// <summary>
/// maxDistance参数大于或等于distance参数 差数越大 模型变大的数值越小
/// </summary>
/// <param name="distance"></param>
/// <param name="minDistance"></param>
/// <param name="maxDistance"></param>
/// <param name="offsetY"></param>
private void InitCameraParaOneModel(float distance, float minDistance, float maxDistance, float offsetY = 0.0f)
{
parameters.smoothFollow = true;
parameters.followSpeed = 5.0f;
parameters.minDistance = minDistance;
parameters.maxDistance = maxDistance;
parameters.distance = distance;
parameters.zoomSpeed = 5.0f;
parameters.zoomSensitivity = 1.0f;
parameters.rotationSensitivity = 3.5f;
parameters.yMinLimit = -20;
parameters.yMaxLimit = 80;
parameters.offset = new Vector3(0.0f, offsetY, 0.0f);
}
void LateUpdate()
{
if (Input.GetMouseButton(0))
{
//检测鼠标点击位置
Vector3 tmp = Input.mousePosition;
//检测手指点击位置
//Vector3 tmp = Input.GetTouch(0).position;
//Debug.Log(tmp);
if (Point(tmp))
{
UpdateInput();
}
}
}
private bool Point(Vector3 vector)
{
if (vector.x > 455 && vector.x < 1670 && vector.y > 200 && vector.y < 1000)
{
return true;
}
else
{
return false;
}
}
// 获取用户鼠标信息
public void UpdateInput()
{
// if (curtarget == null || !cam.enabled) return;
bool rotate = Input.GetMouseButton(0); // 判断鼠标是否右键按下
//delta rotation
if (rotate)
{
x += Input.GetAxis("Mouse X") * parameters.rotationSensitivity;
y = ClampAngle(y - Input.GetAxis("Mouse Y") * parameters.rotationSensitivity, parameters.yMinLimit, parameters.yMaxLimit);
}
// Distance
distanceTarget = Mathf.Clamp(distanceTarget + zoomAdd, parameters.minDistance, parameters.maxDistance);
}
// 更新相机位置
public void UpdateTransform()
{
UpdateTransform(Time.deltaTime);
}
public void UpdateTransform(float deltaTime)
{
//if (curtarget == null || !cam.enabled) return;
// Distance
parameters.distance += (distanceTarget - parameters.distance) * parameters.zoomSpeed * deltaTime;
// Rotation
rotation = Quaternion.AngleAxis(x, Vector3.up) * Quaternion.AngleAxis(y, Vector3.right);
// Smooth follow
if (curtarget != null)
{
if (!parameters.smoothFollow) smoothPosition = curtarget.position;
else smoothPosition = Vector3.Lerp(smoothPosition, curtarget.position, deltaTime * parameters.followSpeed);
}
// Position
position = smoothPosition + rotation * (parameters.offset - Vector3.forward * parameters.distance);
// Translating the camera
Vector3 tmps = new Vector3(position.x, position.y, transform.position.z);
transform.position = position;
transform.rotation = rotation;
}
// Zoom input 放大缩小
private float zoomAdd
{
//鼠标滚轮滑动缩放相机
get
{
float scrollAxis = Input.GetAxis("Mouse ScrollWheel");
if (scrollAxis > 0) return -parameters.zoomSensitivity;
if (scrollAxis < 0) return parameters.zoomSensitivity;
return 0;
}
}
// Clamping Euler angles
private float ClampAngle(float angle, float min, float max)
{
if (angle < -360) angle += 360;
if (angle > 360) angle -= 360;
return Mathf.Clamp(angle, min, max);
}
/// <summary>
/// 相机返回效果
/// </summary>
public void CameraBackEffect()
{
cam.transform.position = new Vector3(0, 4, 15);
cam.transform.rotation = Quaternion.identity;
ChangeScene(0);
}
#endregion
#region 模型控制脚本
/// <summary>
/// 切换场景
/// </summary>
/// <param name="index"></param>
public void ChangeScene(int id)
{
index = id;
Debug.Log(id);
switch (id)
{
// 回到主场景
case 0:
{
isRay = true;
TooltipAgent.Instance.active = true;
ShowAllModels();
ChangeTargetTo(id);
InitCameraParaDefault();
distanceTarget = parameters.distance;
smoothPosition = transform.position;
break;
}
// 模型
case 1:
{
isRay = true;
HideOtherObjects(id);
ChangeTargetTo(id);
InitCameraParaOneModel(5f, 4.0f, 20f);
distanceTarget = parameters.distance;
smoothPosition = transform.position;
break;
}
case 2:
{
isRay = true;
HideOtherObjects(id);
ChangeTargetTo(id);
InitCameraParaOneModel(5f, 4.0f, 20f);
distanceTarget = parameters.distance;
smoothPosition = transform.position;
break;
}
case 3:
{
isRay = true;
HideOtherObjects(id);
ChangeTargetTo(id);
InitCameraParaOneModel(5f, 4.0f, 20f);
distanceTarget = parameters.distance;
smoothPosition = transform.position;
break;
}
case 4:
{
isRay = true;
HideOtherObjects(id);
ChangeTargetTo(id);
InitCameraParaOneModel(27f, 4.0f, 30f);
distanceTarget = parameters.distance;
smoothPosition = transform.position;
break;
}
case 5:
{
isRay = true;
HideOtherObjects(id);
ChangeTargetTo(id);
InitCameraParaOneModel(5f, 4.0f, 20f);
distanceTarget = parameters.distance;
smoothPosition = transform.position;
break;
}
case 6:
{
isRay = true;
HideOtherObjects(id);
ChangeTargetTo(id);
InitCameraParaOneModel(27f, 4.0f, 30f);
distanceTarget = parameters.distance;
smoothPosition = transform.position;
break;
}
case 7:
{
isRay = true;
HideOtherObjects(id);
ChangeTargetTo(id);
InitCameraParaOneModel(27f, 4.0f, 30f);
distanceTarget = parameters.distance;
smoothPosition = transform.position;
break;
}
case 8:
{
isRay = true;
HideOtherObjects(id);
ChangeTargetTo(id);
InitCameraParaOneModel(5f, 4.0f, 20f);
distanceTarget = parameters.distance;
smoothPosition = transform.position;
break;
}
case 9:
{
isRay = true;
HideOtherObjects(id);
ChangeTargetTo(id);
InitCameraParaOneModel(5f, 4.0f, 20f);
distanceTarget = parameters.distance;
smoothPosition = transform.position;
break;
}
}
}
// 更换摄像机目标对象
private void ChangeTargetTo(int id)
{
curtarget = targets[id];
}
// 显示所有对象
private void ShowAllModels()
{
int count = ModelRoot.childCount;
// 先激活所有子模型
for (int i = 0; i < count; i++)
{
ModelRoot.GetChild(i).gameObject.SetActive(true);
}
if (ModelRoot != null)
{
for (int i = 0; i < count; i++)
{
Queue<Material> queue = new Queue<Material>();
GetAllMaterials(ModelRoot.GetChild(i), queue);
while (queue.Count > 0)
{
Material tmp = queue.Dequeue();
}
}
}
}
// 隐藏其他对象,单个模型场景时
private void HideOtherObjects(int index)
{
// 根据模型根节点,获取到所有子模型
if (ModelRoot != null)
{
int count = ModelRoot.childCount;
for (int i = 0; i < count; i++)
{
if (i != index)
{
if (ModelRoot.GetChild(i).gameObject.activeSelf)
{
Queue<Material> queue = new Queue<Material>();
GetAllMaterials(ModelRoot.GetChild(i), queue);
while (queue.Count > 0)
{
Material tmp = queue.Dequeue();
tmp.DOFade(0.0f, parameters.outFade);
}
}
ModelRoot.GetChild(i).gameObject.SetActive(false);
}
else
{
ModelRoot.GetChild(i).gameObject.SetActive(true);
Queue<Material> queue = new Queue<Material>();
GetAllMaterials(ModelRoot.GetChild(i), queue);
while (queue.Count > 0)
{
Material tmp = queue.Dequeue();
tmp.DOFade(1.0f, parameters.inFade);
}
}
}
}
}
// 获得模型的所有材质(需要使用递归,遍历到所有的子对象)
private void GetAllMaterials(Transform obj, Queue<Material> queue)
{
// 首先获取该模型的所有子对象
int count = obj.childCount;
for (int i = 0; i < count; i++)
{
if (obj.GetChild(i).GetComponent<MeshRenderer>() != null && obj.GetChild(i).name != "A子架开关灯" && obj.GetChild(i).name != "B子架开关灯")
{
if (obj.GetChild(i).GetComponent<MeshRenderer>().material != null)
{
queue.Enqueue(obj.GetChild(i).GetComponent<MeshRenderer>().material);
}
}
// 如果该对象还有子对象,就需要递归找到
if (obj.GetChild(i).childCount > 0)
{
GetAllMaterials(obj.GetChild(i), queue);
}
}
}
#endregion
// Start is called before the first frame update
void Start()
{
OnTwoTouch();
}
//单指
private void OnOneTouch(bool regiest = true)
{
if (regiest)
{
EasyTouch.On_Swipe += On_Swipe;
EasyTouch.On_SwipeEnd += On_SwipeEnd;
}
else
{
EasyTouch.On_Swipe -= On_Swipe;
EasyTouch.On_SwipeEnd -= On_SwipeEnd;
}
}
private void On_SwipeEnd(Gesture gesture)
{
state = State.None;
}
//双指
private void OnTwoTouch(bool regiest = true)
{
if (regiest)
{
EasyTouch.On_Swipe2Fingers += On_Swipe2Fingers;
EasyTouch.On_SwipeEnd2Fingers += On_SwipeEnd;
EasyTouch.On_Pinch += On_Pinch;
EasyTouch.On_PinchEnd += On_SwipeEnd;
}
else
{
EasyTouch.On_Pinch -= On_Pinch;
EasyTouch.On_Swipe2Fingers -= On_Swipe2Fingers;
EasyTouch.On_SwipeEnd2Fingers -= On_SwipeEnd;
EasyTouch.On_PinchEnd -= On_SwipeEnd;
}
}
private void Reset()
{
state = State.None;
m_Camera.transform.eulerAngles = Vector3.zero;
m_Camera.transform.localPosition = Vector3.zero; ;
}
/// <summary>
/// 缩放
/// </summary>
/// <param name="ges"></param>
void On_Pinch(Gesture ges)
{
Debug.Log(11111);
if (state == State.Pinch)
{
Debug.Log(222);
int dir = ges.deltaPinch < 0 ? 1 : -1;//如果同时监听单个手指的事件,返回值将获取为0
m_Camera.transform.GetComponent<Camera>().fieldOfView += 2 * dir;
}
else
{
Debug.Log(333);
//缩放
if (Mathf.Abs(ges.deltaPinch) > 2.5)
{
Debug.Log(444);
state = State.Pinch;
int dir = ges.deltaPinch < 0 ? -1 : 1;
}
else
{
Debug.Log(555);
On_Swipe2Fingers(ges);
}
}
}
/// <summary>
/// 双指滑动
/// </summary>
/// <param name="ges"></param>
void On_Swipe2Fingers(Gesture ges)
{
Debug.Log(111);
state = State.Swipe;
if (Mathf.Abs(ges.deltaPosition.x) > 10)
{
Debug.Log(222);
//m_Camera.transform.Rotate(-Vector3.up * rotateSpeed * ges.deltaPosition.normalized.x * Time.deltaTime);
m_Camera.transform.GetComponent<Camera>().fieldOfView += 2;
}
else
{
Debug.Log(333);
m_Camera.transform.GetComponent<Camera>().fieldOfView -= 2;
}
}
/// <summary>
/// 单指滑动
/// </summary>
/// <param name="ges"></param>
void On_Swipe(Gesture ges)
{
state = State.Swipe;
}
}