Выделение рамкой
| |
sinoptis | Дата: Суббота, 30 Июня 2012, 10:14 | Сообщение # 1 |
почетный гость
Сейчас нет на сайте
| Помогите разобраться. На официальном форуме нашел исходник , этого самого выделения. Но все скрипты на Js и я не как не могу понять ( т.к. пишу на C#), как оно реализованно. Кому не сложно обьясните на С# только ту часть которая отвечает за определение находится обьект в таргете или нет. UnitSelection.js Code
private var mouseButton1DownPoint : Vector2; private var mouseButton1UpPoint : Vector2; private var mouseButton1DownTerrainHitPoint : Vector3; private var mouseButton2DownPoint : Vector2; private var mouseButton2UpPoint : Vector2; private var selectionPointStart : Vector3; private var selectionPointEnd : Vector3; private var mouseLeftDrag : boolean = false; private var terrainLayerMask = 1 << 8; private var nonTerrainLayerMask = ~terrainLayerMask; private var raycastLength : float = 200.0; // semi transparent texture for the selection rectangle var selectionTexture : Texture; // range in which a mouse down and mouse up event will be treated as "the same location" on the map. private var mouseButtonReleaseBlurRange : int = 20;
function OnGUI() { if (mouseLeftDrag) { var width : int = mouseButton1UpPoint.x - mouseButton1DownPoint.x; var height : int = (Screen.height - mouseButton1UpPoint.y) - (Screen.height - mouseButton1DownPoint.y); var rect : Rect = Rect(mouseButton1DownPoint.x, Screen.height - mouseButton1DownPoint.y, width, height); GUI.DrawTexture (rect, selectionTexture, ScaleMode.StretchToFill, true); } }
function Update () { // Left mouse button if (Input.GetButtonDown("Fire1")) { Mouse1Down(Input.mousePosition); } if (Input.GetButtonUp("Fire1")) { Mouse1Up(Input.mousePosition); } if (Input.GetButton("Fire1")) { // Used to determine if there is some mouse drag operation going on. Mouse1DownDrag(Input.mousePosition); } // Right mouse button if (Input.GetButtonDown("Fire2")) { mouseButton2DownPoint = Input.mousePosition; } if (Input.GetButtonUp("Fire2")) { mouseButton2UpPoint = Input.mousePosition; // De-selection if right mouse button is pressed at the same point (more or less) where it was clicked down. // Use this inRange with a slight offset so if right mb was not released _exactly_ at the button down position, but with a slight offset. if (IsInRange(mouseButton2DownPoint, mouseButton2UpPoint)) { UnitManager.GetInstance().ClearSelectedUnitsList(); } } }
function Mouse1DownDrag(screenPosition : Vector2) { // Only show the drag selection texture if the mouse has been moved and not if the user made only a single left mouse click if (screenPosition != mouseButton1DownPoint) { mouseLeftDrag = true; // while dragging, update the current mouse pos for the selection rectangle. mouseButton1UpPoint = screenPosition; var hit : RaycastHit; ray = Camera.main.ScreenPointToRay (screenPosition); if ( Physics.Raycast (ray, hit, raycastLength, terrainLayerMask) ) { //print ("Hit Terrain 2 " + hit.point); selectionPointEnd = hit.point; UnitManager.GetInstance().ClearSelectedUnitsList(); UnitManager.GetInstance().SelectUnitsInArea(selectionPointStart, selectionPointEnd); } } }
function Mouse1Down(screenPosition : Vector2) { mouseButton1DownPoint = screenPosition; var hit : RaycastHit; var ray = Camera.main.ScreenPointToRay (mouseButton1DownPoint); //Debug.DrawRay (ray.origin, ray.direction * 100.0, Color.green); if ( Physics.Raycast (ray, hit, raycastLength) ) // terrainLayerMask { if (hit.collider.name == "Terrain") { mouseButton1DownTerrainHitPoint = hit.point; selectionPointStart = hit.point; } else { //print ("Mouse Down Hit something: " + hit.collider.name);
// Ray hit a unit, not the terrain. Deselect all units as the fire 1 up // event will then select that just recently clicked unit! UnitManager.GetInstance().ClearSelectedUnitsList(); } //Debug.DrawRay (ray.origin, ray.direction * 100.0, Color.green); } }
function Mouse1Up(screenPosition : Vector2) { mouseButton1UpPoint = screenPosition; var hit : RaycastHit; //print("currently selected units: " + UnitManager.GetInstance().GetSelectedUnitsCount()); mouseLeftDrag = false; if (IsInRange(mouseButton1DownPoint, mouseButton1UpPoint)) { // user just did a click, no dragging. mouse 1 down and up pos are equal. // if units are selected, move them. If not, select that unit. if (UnitManager.GetInstance().GetSelectedUnitsCount() == 0) { // no units selected, select the one we clicked - if any. ray = Camera.main.ScreenPointToRay (mouseButton1DownPoint); if ( Physics.Raycast (ray, hit, raycastLength, nonTerrainLayerMask) ) { // Ray hit something. Try to select that hit target. //print ("Hit something: " + hit.collider.name); hit.collider.gameObject.SendMessage("SetSelected"); } } else { // untis are selected, move them. Unit Manager's unit count is > 0! UnitManager.GetInstance().MoveSelectedUnitsToPoint(mouseButton1DownTerrainHitPoint); } } }
function IsInRange(v1 : Vector2, v2 : Vector2) : boolean { var dist = Vector2.Distance(v1, v2); print("Right click release button distance: " + dist); if (Vector2.Distance(v1, v2) < mouseButtonReleaseBlurRange) { return true; } return false; } UnitManager.js Code
// the one and only instance for the unit manager private static var instance : UnitManager; private var allUnitsList = new Array(); private var selectedUnitsList = new Array(); private var debugMode = false;
// accessor that delivers always the one and only instance of the UnitManager // Use it like this: UnitManager.GetInstance().<function name> static function GetInstance() : UnitManager { if (instance == null) { instance = FindObjectOfType(UnitManager); } return instance; }
function GetSelectedUnitsCount() { return selectedUnitsList.length; }
function AddUnit(go : GameObject) { allUnitsList.Add(go); if (debugMode) { print("UnitManager: added unit: " + go.name); } }
function AddSelectedUnit(go : GameObject) { selectedUnitsList.Push(go); go.SendMessage("SetUnitSelected", true); if (debugMode) { print("UnitManager: added selected unit: " + go.name); } }
function ClearSelectedUnitsList() { if (debugMode) { print("ClearSelectedUnitsList"); } for (var go : GameObject in allUnitsList) { go.SendMessage("SetUnitSelected", false); } selectedUnitsList.Clear(); }
function MoveSelectedUnitsToPoint(destinationPoint : Vector3) { for (var go : GameObject in selectedUnitsList) { if (debugMode) { print("MoveSelectedUnits: Moving unit " + go.name); } go.SendMessage("MoveToPoint", destinationPoint); } }
function SelectUnitsInArea(point1 : Vector3, point2 : Vector3) { if (debugMode) { print("Select Units in area..."); } if (point2.x < point1.x) { // swap x positions. Selection rectangle is beeing drawn from right to left var x1 = point1.x; var x2 = point2.x; point1.x = x2; point2.x = x1; } if (point2.z > point1.z) { // swap z positions. Selection rectangle is beeing drawn from bottom to top var z1 = point1.z; var z2 = point2.z; point1.z = z2; point2.z = z1; } for (var go : GameObject in allUnitsList) { var goPos : Vector3 = go.transform.position; //print("goPos:" + goPos + " 1:" + point1 + " 2:" + point2); if (goPos.x > point1.x && goPos.x < point2.x && goPos.z < point1.z && goPos.z > point2.z) { selectedUnitsList.Push(go); if (debugMode) print("Unit inside: " + go.name); go.SendMessage("SetUnitSelected", true); } } }
function Test() { print("UnitManager: Test!"); }
function OnApplicationQuit() { instance = null; }
|
|
| |
pixeye | Дата: Суббота, 30 Июня 2012, 11:54 | Сообщение # 2 |
Red Winter Software
Сейчас нет на сайте
| Да оно все взаимосвязано.
Ну под твой запрос больше всего подходит проверка такого плана, если логика сооветствует названию функции. Тут идет возрат булевого значения по условию "если что-то находится в радиусе"
JS Code function IsInRange(v1 : Vector2, v2 : Vector2) : boolean { var dist = Vector2.Distance(v1, v2); print("Right click release button distance: " + dist); if (Vector2.Distance(v1, v2) < mouseButtonReleaseBlurRange) { return true; } return false; }
C# Code bool IsInRange(Vector2 v1, Vector2 v2) { float dist = Vector2.Distance(v1, v2); print("Right click release button distance: " + dist); if (Vector2.Distance(v1, v2) < mouseButtonReleaseBlurRange) { return true; } return false; }
Эта насколько понятно добавляет по проверкам объекты в список выделенных. JS Code function SelectUnitsInArea(point1 : Vector3, point2 : Vector3) { if (debugMode) { print("Select Units in area..."); } if (point2.x < point1.x) { // swap x positions. Selection rectangle is beeing drawn from right to left var x1 = point1.x; var x2 = point2.x; point1.x = x2; point2.x = x1; } if (point2.z > point1.z) { // swap z positions. Selection rectangle is beeing drawn from bottom to top var z1 = point1.z; var z2 = point2.z; point1.z = z2; point2.z = z1; } for (var go : GameObject in allUnitsList) { var goPos : Vector3 = go.transform.position; //print("goPos:" + goPos + " 1:" + point1 + " 2:" + point2); if (goPos.x > point1.x && goPos.x < point2.x && goPos.z < point1.z && goPos.z > point2.z) { selectedUnitsList.Push(go); if (debugMode) print("Unit inside: " + go.name); go.SendMessage("SetUnitSelected", true); } }
C# Code void SelectUnitsInArea(Vector3 point1, Vector3 point2) { if (debugMode) { print("Select Units in area..."); } if (point2.x < point1.x) { // swap x positions. Selection rectangle is beeing drawn from right to left float x1 = point1.x; float x2 = point2.x; point1 = new Vector3(x2,point1.y,point1.z); point2 = new Vector3(x1,point2.y,point2.z); } if (point2.z > point1.z) { // swap z positions. Selection rectangle is beeing drawn from bottom to top float z1 = point1.z; float z2 = point2.z; point1 = new Vector3(point1.x,point1.y,z2); point2 = new Vector3(point2.x,point2.y,z1); } foreach(GameObject go in allUnitsList){ Vector3 goPos = go.transform.position; if (goPos.x > point1.x && goPos.x < point2.x && goPos.z < point1.z && goPos.z > point2.z) { selectedUnitsList.Push(go); if (debugMode) print("Unit inside: " + go.name);
go.SendMessage("SetUnitSelected", true); } }
ЗЫ. Перевод кода из JS в C# является крайне тривиальной задачей. У меня есть основания думать, что ты не знаешь ни того, ни другого. Так же стоит сменить тип контейнера на что-то более подходящие типа arrayList
ACTORS - мой фреймворк на Unity Until We Die - игра над которой работаю
|
|
| |
sinoptis | Дата: Суббота, 30 Июня 2012, 17:06 | Сообщение # 3 |
почетный гость
Сейчас нет на сайте
| pixeye, Я переводил оба эти скрипта на С# полностью, но они не работали , я решил написать всё с нуля и спросил знающих людей как это работает т.к. я плохо разбираюсь в векторных вычислениях. Спасибо за обьяснение, хотя я уже и сам пришел к этому
Сообщение отредактировал sinoptis - Суббота, 30 Июня 2012, 17:07 |
|
| |
pixeye | Дата: Суббота, 30 Июня 2012, 17:20 | Сообщение # 4 |
Red Winter Software
Сейчас нет на сайте
| Линейная алгебра для разработчиков игр - наглядно и популярно;-)
ACTORS - мой фреймворк на Unity Until We Die - игра над которой работаю
|
|
| |
sinoptis | Дата: Понедельник, 02 Июля 2012, 13:44 | Сообщение # 5 |
почетный гость
Сейчас нет на сайте
| pixeye, Спасибо Добавлено (01.07.2012, 17:14) --------------------------------------------- Вот переписал эти скрипты на С# и совместил в одном. Но теперь не выделяются обьекты посмотрите может где я допустил ошибку? Code
using UnityEngine; using System.Collections; using System.Collections.Generic;
public class RTSPlayer : MonoBehaviour { //==Публичные переменные================ public GameObject target; public List<GameObject> selectedUnitsList; public List<GameObject> AllUnits; //====================================== public GUIStyle style;
private Vector2 startPos; private Vector2 endPos;
private Rect rect; private bool drawRect;
private readonly GUIContent cont = new GUIContent();
// Use this for initialization void Start () { AllUnits = new List<GameObject>(); selectedUnitsList = new List<GameObject>(); AddAllUnit(); } // Update is called once per frame void Update () { //====Выделение и снятие единичной цели================================================== if(Input.GetMouseButton(0)){ Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if(Physics.Raycast(ray, out hit, 100 )&& hit.collider.tag == "Building"){ target = hit.collider.gameObject; Target tr = (Target)target.GetComponent("Target"); tr.ShowHealthBar(); } } if(Input.GetMouseButton(1)){ if(target !=null){ Target tr = (Target)target.GetComponent("Target"); tr.HideHealthBar(); target = null; } } //=============================================================================== } void OnGUI () { if (Input.GetMouseButtonDown(0)) { startPos = Input.mousePosition; drawRect = true; } if (Input.GetMouseButtonUp(0)){ drawRect = false; SelectUnitsInArea(startPos, endPos); }
if (drawRect) { endPos = Input.mousePosition; if(startPos==endPos)return;
rect = new Rect(Mathf.Min(endPos.x, startPos.x), Screen.height - Mathf.Max(endPos.y, startPos.y), Mathf.Max(endPos.x, startPos.x) - Mathf.Min(endPos.x, startPos.x), Mathf.Max(endPos.y, startPos.y) - Mathf.Min(endPos.y, startPos.y) );
GUI.Box(rect,cont,style); } } //поиск и добавление всех юнитов в список public void AddAllUnit(){ //помещаем всех врагов в массив go GameObject[] go = GameObject.FindGameObjectsWithTag("Unit"); //каждый элемент из найденных засовываем в массив потенциальных целей if(go != null){ foreach(GameObject unit in go) AddUnit(unit); } } //метод по добавлению в массив очередного элемента public void AddUnit(GameObject unit) { AllUnits.Add(unit); } void SelectUnitsInArea(Vector3 point1, Vector3 point2) { Debug.Log("SelectUnitsInArea"); if (point2.x < point1.x) { float x1 = point1.x; float x2 = point2.x; point1.x = x2; point2.x = x1; } if (point2.z > point1.z) { float z1 = point1.z; float z2 = point2.z; point1.z = z2; point2.z = z1; } foreach(GameObject go in AllUnits){ Vector3 goPos = go.transform.position; if (goPos.x > point1.x && goPos.x < point2.x && goPos.z < point1.z && goPos.z > point2.z) { selectedUnitsList.Add(go); Debug.Log("Select"); Solidier sl = (Solidier)go.GetComponent("Solidier"); sl.SetUnitSelected(true); } }
} }
Добавлено (02.07.2012, 13:44) --------------------------------------------- Извините , сам понял
|
|
| |
|