相机控制脚本
常规RTS相机的移动缩放
using System.Collections; using System.Collections.Generic; using UnityEngine; public class TopCameraController : MonoBehaviour { public Vector2 cameraOffsetXYSpeed = Vector2.one; public Vector2 cameraOffset = Vector2.one; public LayerMask ground; public float height=5; public float mouseWheelSpeed=0.05f; Vector2 viewheightClimp=new Vector2(5,15); Camera my_Camera; void Awake() { my_Camera = GetComponent<Camera>(); } private void Start() { my_Camera.transform.position = new Vector3(cameraOffset.x, height, cameraOffset.y); } private void LateUpdate() { if (Input.mousePosition.x<1) my_Camera.transform.position += new Vector3(-cameraOffsetXYSpeed.x*Time.deltaTime, 0, 0); else if (Input.mousePosition.x > Screen.width-1) my_Camera.transform.position += new Vector3(cameraOffsetXYSpeed.x * Time.deltaTime, 0, 0); if (Input.mousePosition.y <1) my_Camera.transform.position += new Vector3(0,0, -cameraOffsetXYSpeed.y * Time.deltaTime); else if (Input.mousePosition.y > Screen.height-1) my_Camera.transform.position += new Vector3(0,0, cameraOffsetXYSpeed.y * Time.deltaTime); if (Input.GetMouseButtonDown(1)) { RaycastHit hit; Ray ray = my_Camera.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray,out hit,100, ground)) { //选择物移动 //Debug.Log(hit.point); } } // 滚轮实现镜头缩进和拉远 if (Input.GetAxis("Mouse ScrollWheel") != 0) { my_Camera.orthographicSize = my_Camera.orthographicSize - Input.GetAxis("Mouse ScrollWheel") * mouseWheelSpeed; my_Camera.orthographicSize = Mathf.Clamp(my_Camera.orthographicSize, viewheightClimp.x, viewheightClimp.y); } if (Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Vertical")!=0) transform.position = transform.position + new Vector3(Input.GetAxis("Horizontal")*cameraOffsetXYSpeed.x*0.1f,0, Input.GetAxis("Vertical")*cameraOffsetXYSpeed.y*0.1f); if (Input.GetKeyDown(KeyCode.F)) { if (TopCameraSelect.Instance.HasSelectObj()) { Vector3 center = TopCameraSelect.Instance.GetSelectObjCenter(); my_Camera.transform.position = center + new Vector3(cameraOffset.x, height, cameraOffset.y); my_Camera.transform.LookAt(center); } } } }
相机选择脚本
功能:选择物体,核心是创建一个碰撞盒的物体,物体旋转x轴度数等于相机旋转x-90度,通过选择坐标缩放碰撞盒的尺寸,OnTriggerEnter的物体添加到选择物体中。借鉴RTSCamera做了一些修改,原本是2D选择,改进成3D选择
using System.Collections; using System.Collections.Generic; using UnityEngine; public class TopCameraSelect : MonoBehaviour { public static TopCameraSelect Instance; public bool disableSelect = false; public Color selectColor = Color.green; public float selectLineWidth = 2f; public float lookDamper = 5f; public string selectionObjectName = "RTS Selection"; private bool isDrag; private Vector3 selectStartPosition; private Texture2D pixel; private GameObject selection; public List<GameObject> selectObjects=new List<GameObject>(); private void Awake() { Instance = this; } void Start() { setPixel(selectColor); selection = new GameObject(selectionObjectName); { var collider = selection.AddComponent<BoxCollider>() as BoxCollider; collider.isTrigger = true; Vector3 size = new Vector3(1, 100000f, 1); collider.size = size; } var body = selection.AddComponent<Rigidbody>() as Rigidbody; body.useGravity = false; selection.SetActive(false); } void Update() { updateDragging(); } public bool HasSelectObj() { if (selectObjects.Count > 0) return true; return false; } public Vector3 GetSelectObjCenter() { if (!HasSelectObj()) { Debug.LogError("错误"); return Vector3.zero; } Vector3 vector3=new Vector3(); for (int i = 0; i < selectObjects.Count; i++) { vector3 += selectObjects[0].transform.position; } vector3 = vector3/selectObjects.Count; return vector3; } void OnGUI() { if (!isDrag || disableSelect) return; var x = selectStartPosition.x; var y = Screen.height - selectStartPosition.y; var width = (Input.mousePosition - selectStartPosition).x; var height = (Screen.height - Input.mousePosition.y) - y; GUI.DrawTexture(new Rect(x, y, width, selectLineWidth), pixel); GUI.DrawTexture(new Rect(x, y, selectLineWidth, height), pixel); GUI.DrawTexture(new Rect(x, y + height, width, selectLineWidth), pixel); GUI.DrawTexture(new Rect(x + width, y, selectLineWidth, height), pixel); } public void AddSelectObj(GameObject obj) { if (selectObjects.Contains(obj)) return; selectObjects.Add(obj); } private void setPixel(Color color) { pixel = new Texture2D(1, 1); pixel.SetPixel(0, 0, color); pixel.Apply(); } private void updateDragging() { if (Input.GetMouseButtonDown(0) && !isDrag) { isDrag = true; selectStartPosition = Input.mousePosition; if (selection != null) { selection.SetActive(true); if (selectObjects.Count > 0) { for (int i = 0; i < selectObjects.Count; i++) { selectObjects[i].GetComponent<Renderer>().material.color = Color.red; } selectObjects.Clear(); } } } else if (Input.GetMouseButtonUp(0) && isDrag) { isDrag = false; dropSelection(selectStartPosition, Input.mousePosition); if (selectObjects.Count > 0) { for (int i = 0; i < selectObjects.Count; i++) { selectObjects[i].GetComponent<Renderer>().material.color = Color.green; } } if (selection != null) { selection.SetActive(false); } } if (selection.activeSelf) { dropSelection(selectStartPosition, Input.mousePosition); } } private void dropSelection(Vector3 screenStart, Vector3 screenEnd) { var start = GetComponent<Camera>().ScreenToWorldPoint(screenStart); var finish = GetComponent<Camera>().ScreenToWorldPoint(screenEnd); selection.transform.rotation = Quaternion.Euler(transform.localEulerAngles.x-90, transform.rotation.y, transform.rotation.z); selection.transform.position = new Vector3((start.x + finish.x) / 2.0f, (start.y + finish.y) / 2.0f, (start.z + finish.z) / 2.0f); selection.transform.localScale = new Vector3(Mathf.Abs(start.x - finish.x), 1f, Mathf.Abs(start.z - finish.z)); } }选择物体挂的脚本
using UnityEngine; using System.Collections; public class Selectable : MonoBehaviour { void Start() { GetComponent<Renderer>().material.color = Color.red; } void OnTriggerEnter(Collider other) { if (other.gameObject.name == "RTS Selection") { TopCameraSelect.Instance.AddSelectObj(gameObject); } } }