Пятница, 19 Апреля 2024, 09:00

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Выделение рамкой
Выделение рамкой
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, Я переводил оба эти скрипта на С# полностью, но они не работали , я решил написать всё с нуля и спросил знающих людей как это работает т.к. я плохо разбираюсь в векторных вычислениях. Спасибо за обьяснение, хотя я уже и сам пришел к этому happy

Сообщение отредактировал 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, Спасибо happy

Добавлено (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)
---------------------------------------------
Извините biggrin , сам понял happy

Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Выделение рамкой
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг