C# 统一RTS全面战争风格点击和拖动部队编队
我一直在unity工作,试图通过点击和拖动来实现单位队形宽度/深度创建的全面战争风格,如本视频中15秒左右所示: 我已经写了一些代码,但我正在摆脱索引错误。到目前为止:C# 统一RTS全面战争风格点击和拖动部队编队,c#,unity3d,C#,Unity3d,我一直在unity工作,试图通过点击和拖动来实现单位队形宽度/深度创建的全面战争风格,如本视频中15秒左右所示: 我已经写了一些代码,但我正在摆脱索引错误。到目前为止: using System.Collections; using System.Collections.Generic; using UnityEngine; public class Formation : MonoBehaviour { // Use this for initialization voi
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Formation : MonoBehaviour {
// Use this for initialization
void Start()
{
formationMaker();
}
private void FixedUpdate()
{
formationShape();
}
public GameObject unit;//this is a cube prefab with scale dimensions .45,1.8,.3
public Transform parent;//this is the parent object of the cubes acting as anchor point
private Vector3 startClick;
private Vector3 endClick;
private float width;
private List<GameObject> unitsList = new List<GameObject>();
private int numberOfMen;
private int rows;
private int leftOverMen;//was going to use these two to calculate the number of men in the last row and...
private int lastRowSpace;//...the amount of space needed to center them
private int count;
private float manWidth = (float)4.5;
private void formationMaker()//this makes the formation upon start
{
for(int x = -10; x< 10; x++)
{
for(int z = -4; z< 4; z++)
{
Instantiate(unit, new Vector3(x* .7F, .9f, z*1.0f), Quaternion.identity, parent);
unitsList.Add(unit);
}
}
}
private void formationShape()
{
if (Input.GetMouseButtonDown(1))
{
startClick = Input.mousePosition;
}
else if (Input.GetMouseButtonUp(1))
{
endClick = Input.mousePosition;
}
//ERROR HERE?
width = Vector3.Distance(startClick, endClick)/manWidth;//width has to be the width in terms of number of men, but i'm not sure where to get this width
//ERROR HERE
numberOfMen = unitsList.Count;
rows = (int)Mathf.Floor(numberOfMen / width);
leftOverMen = (int)Mathf.Ceil(numberOfMen % width);
lastRowSpace = ((int)width - leftOverMen) / 2;
Debug.Log(rows);
Debug.Log(width);
Debug.Log(numberOfMen);
if (width != 0)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < width; j++)
{
unitsList[count].transform.position = new Vector3(i * .7F, .9f, j * 1.0f) + startClick;
count++;
}
}
}
width = 0;
}
void Update () {
}
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共阶层的形成:单一行为{
//用于初始化
void Start()
{
formationMaker();
}
私有void FixedUpdate()
{
形成形态();
}
公共游戏对象单元;//这是一个具有比例尺寸的立方体预制体。45,1.8,3
public Transform parent;//这是作为定位点的多维数据集的父对象
私人矢量3星点;
私有向量3结束单击;
私有浮动宽度;
私有列表单元列表=新列表();
私家侦探;
私有int行;
private int leftOverMen;//将使用这两个来计算最后一行的男性人数,然后。。。
private int lastRowSpace;//…使其居中所需的空间量
私人整数计数;
专用浮点数宽度=(浮点数)4.5;
private void formationMaker()//这会在开始时生成表单
{
对于(int x=-10;x<10;x++)
{
for(intz=-4;z<4;z++)
{
实例化(单位,新向量3(x*.7F、.9f、z*1.0f)、四元数.identity、父);
单位列表。添加(单位);
}
}
}
私有无效格式形状()
{
if(Input.GetMouseButtonDown(1))
{
startClick=Input.mousePosition;
}
else if(Input.GetMouseButtonUp(1))
{
endClick=Input.mousePosition;
}
//这里有错误吗?
width=Vector3.Distance(startClick,endClick)/manWidth;//width必须是以男性数量表示的宽度,但我不确定从何处获得此宽度
//这里出错
numberOfMen=单位列表计数;
行=(内部)主楼层(人数/宽度);
leftOverMen=(int)Mathf.Ceil(numberOfMen%宽度);
lastRowSpace=((int)宽度-左撇子)/2;
Debug.Log(行);
调试日志(宽度);
调试日志(numberOfMen);
如果(宽度!=0)
{
对于(int i=0;i
谢谢你的帮助 您的计数没有重置为零,您应该将宽度转换为int以消除错误
PS.Input.mousePosition是像素坐标,而不是世界位置 使用Input.mousePosition无法获得世界位置(请改用Raycast)
您的宽度可以是零=>(int)Mathf.Floor(人数/宽度);可能会导致错误 如果您仍在寻找解决方案,可以参考此代码(我根据您的代码编辑)
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共阶层的形成:单一行为
{
公共整数典当;
//用于初始化
私人空间
{
m_BoxSelected=新选择的BoxSelected();
}
void Start()
{
//计数=0;
//formationMaker();
formationMaker(新向量3(1,1,1),新向量3(1,1,1),30,数字兵);
//formationMaker3(新向量3(),新向量3(-20,0,-20),2f,ref unitsList);
}
私有void FixedUpdate()
{
}
公共箱选择m_箱选择;
公共摄像机;
私人雷穆雷;
公共游戏对象单元;//这是一个具有比例尺寸的立方体预制体。45,1.8,3
public Transform parent;//这是作为定位点的多维数据集的父对象
私人矢量3星点;
私有向量3结束单击;
私有浮动宽度;
[序列化字段]
私有列表单元列表=新列表();
私家侦探;
[序列化字段]
专用浮点数宽度=(浮点数)4.5;
private void formationMaker()//这会在开始时生成表单
{
对于(int x=0;x<4;x++)
{
对于(intz=0;z<4;z++)
{
实例化(单位,新向量3(x*.7F,0f,z*1.0f),四元数.identity,父);
单位列表。添加(单位);
}
}
}
私有void formationMaker(Vector3 _StartPos,Vector3 _EndPos,float SizeObj,int _NumberObj)//这会在开始时生成表单
{
浮点数_width=Mathf.Abs(_StartPos.x-_EndPos.x);
浮动高度=Mathf.Abs(_StartPos.z-_EndPos.z);
int行=0,列=0;
如果(_-width>SizeObj&&u-height>SizeObj)
{
浮动dt=_宽度*_高度;
浮点数_SumCanContain=dt/SizeObj;
如果(\u sumcontain>=\u NumberObj)
{
//嗯
}
其他的
{
//碘化钾ểm tra xem mả吴đựng vừaố 奥布·科昂
浮子温度=数学Sqrt(_NumberObj);
如果((内部)(温度+0.5)!=(内部)温度)//Phầ第n条ập ph–lớn hơn 0.5
{
行=(int)(临时+1);
列=(内部)(温度+1);
_宽度=(内部)(温度+1)*SizeObj;
_高度=(内部)(温度+1)*SizeObj;
}
其他的
{
行=((内部)(临时)+1);
col=(int)(Temp);
_宽度=((内部)(温度)+1)*SizeObj;
_高度=(内部)(温度)*SizeObj;
}
}
}
其他的
{
//碘化钾ểm tra xem mả吴đựng vừaố 奥布·科昂
浮球
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Formation : MonoBehaviour
{
public int numberSpawn;
// Use this for initialization
private void Awake()
{
m_BoxSelected = new BoxSelected();
}
void Start()
{
//count = 0;
//formationMaker();
formationMaker(new Vector3(1, 1, 1), new Vector3(1, 1, 1), 30, numberSpawn);
//formationMaker3(new Vector3(), new Vector3(-20, 0, -20), 2f, ref unitsList);
}
private void FixedUpdate()
{
}
public BoxSelected m_BoxSelected;
public Camera m_MainCamera;
private Ray m_ray;
public GameObject unit;//this is a cube prefab with scale dimensions .45,1.8,.3
public Transform parent;//this is the parent object of the cubes acting as anchor point
private Vector3 startClick;
private Vector3 endClick;
private float width;
[SerializeField]
private List<GameObject> unitsList = new List<GameObject>();
private int numberOfMen;
[SerializeField]
private float manWidth = (float)4.5;
private void formationMaker()//this makes the formation upon start
{
for (int x = 0; x < 4; x++)
{
for (int z = 0; z < 4; z++)
{
Instantiate(unit, new Vector3(x * .7F, 0f, z * 1.0f), Quaternion.identity, parent);
unitsList.Add(unit);
}
}
}
private void formationMaker(Vector3 _StartPos, Vector3 _EndPos, float SizeObj, int _NumberObj)//this makes the formation upon start
{
float _width = Mathf.Abs(_StartPos.x - _EndPos.x);
float _height = Mathf.Abs(_StartPos.z - _EndPos.z);
int row = 0, col = 0;
if (_width > SizeObj && _height > SizeObj)
{
float dt = _width * _height;
float _SumCanContain = dt / SizeObj;
if (_SumCanContain >= _NumberObj)
{
// OK
}
else
{
// kiểm tra xem mảng có đựng vừa số Obj không
float Temp = Mathf.Sqrt(_NumberObj);
if ((int)(Temp + 0.5) != (int)Temp) // Phần thập phân lớn hơn 0.5
{
row = (int)(Temp + 1);
col = (int)(Temp + 1);
_width = (int)(Temp + 1) * SizeObj;
_height = (int)(Temp + 1) * SizeObj;
}
else
{
row = ((int)(Temp) + 1);
col = (int)(Temp);
_width = ((int)(Temp) + 1) * SizeObj;
_height = (int)(Temp) * SizeObj;
}
}
}
else
{
// kiểm tra xem mảng có đựng vừa số Obj không
float Temp = Mathf.Sqrt(_NumberObj);
if ((int)(Temp + 0.5) != (int)Temp) // Phần thập phân lớn hơn 0.5
{
row = (int)(Temp + 1);
col = (int)(Temp + 1);
_width = (int)(Temp + 1);
_height = (int)(Temp + 1);
}
else
{
row = ((int)(Temp) + 1);
col = (int)(Temp);
_width = ((int)(Temp) + 1);
_height = (int)(Temp);
}
}
int cout = 0;
for (int x = 0; x < _width; x++)
{
for (int z = 0; z < _height; z++)
{
if (cout < _NumberObj)
{
//Instantiate(unit, new Vector3(x * .7F, .9f, z * 1.0f), Quaternion.identity, parent);
unitsList.Add(Instantiate(unit, new Vector3(x * .7F, .9f, z * 1.0f), Quaternion.identity, parent));
cout++;
}
}
}
}
#region Add Funtion
public int ReverseToOne(int value)
{
if (value > 0)
{
return -1;
}
else
{
return 1;
}
}
private void FormationShapeSquad(Vector3 _StartPos, Vector3 _EndPos, float SizeObj, ref List<GameObject> ListObj)//this makes the formation upon start
{
float _NumberObj = ListObj.Count;
float _width = Mathf.Abs(_StartPos.x - _EndPos.x);
float _height = Mathf.Abs(_StartPos.z - _EndPos.z);
int Cols = 0, Rows = 0;
if (_width > SizeObj && _height > SizeObj)
{
float Acreage = _width * _height;
float _SumCanContain = Acreage / SizeObj;
if (_SumCanContain >= _NumberObj)
{
// OK
Debug.Log("OK");
Cols = (int)(_width / SizeObj);
Rows = (int)(_height / SizeObj);
}
else
{
// kiểm tra xem mảng có đựng vừa số Obj không
float Temp = Mathf.Sqrt(_NumberObj);
if ((int)(Temp + 0.5) != (int)Temp) // Phần thập phân lớn hơn 0.5
{
Cols = (int)(Temp + 1);
Rows = (int)(Temp + 1);
_width = Cols * SizeObj;
_height = Rows * SizeObj;
}
else
{
Cols = ((int)(Temp) + 1);
Rows = (int)(Temp);
_width = Cols * SizeObj;
_height = Rows * SizeObj;
}
}
}
else
{
// kiểm tra xem mảng có đựng vừa số Obj không
float Temp = Mathf.Sqrt(_NumberObj);
if ((int)(Temp + 0.5) != (int)Temp) // Phần thập phân lớn hơn 0.5
{
Cols = (int)(Temp + 1);
Rows = (int)(Temp + 1);
_width = (int)(Temp + 1) * SizeObj;
_height = (int)(Temp + 1) * SizeObj;
}
else
{
Cols = ((int)(Temp) + 1);
Rows = (int)(Temp);
_width = ((int)(Temp) + 1) * SizeObj;
_height = (int)(Temp) * SizeObj;
}
}
int cout = 0;
int _dirZ = ReverseToOne((int)(_StartPos.z - _EndPos.z));
int _dirX = ReverseToOne((int)(_StartPos.x - _EndPos.x));
float TempWeight = _StartPos.x;
float TempHeight = _StartPos.z;
for (int i = 0; i < Cols; i++)
{
for (int j = 0; j < Rows; j++)
{
if (cout < _NumberObj)
{
ListObj[cout].transform.position = new Vector3(TempWeight, 0f, TempHeight);
cout++;
TempHeight += _dirZ * SizeObj;
}
}
TempWeight += _dirX * SizeObj;
TempHeight = _StartPos.z;
}
}
private void FormationLine(Vector3 _StartPos, Vector3 _EndPos, float SizeObj, ref List<GameObject> ListObj)//this makes the formation upon start
{
float _NumberObj = ListObj.Count;
//float _distance = Vector2.Distance(new Vector2 (_StartPos.x, _StartPos.z) , new Vector2( _EndPos.x, _EndPos.z));
float _distance = Vector3.Distance(_StartPos, _EndPos);
int Row = 0, Col = 0;
float _width = 0, _height = 0;
/*if(_distance > SizeObj)
{*/
//Use Default value
float Temp = Mathf.Sqrt(_NumberObj);
if ((int)(Temp + 0.5) != (int)Temp) // Phần thập phân lớn hơn 0.5
{
Row = (int)(Temp + 1);
Col = (int)(Temp + 1);
_width = Row * SizeObj;
_height = Col * SizeObj;
}
else
{
Row = ((int)(Temp));
Col = (int)(Temp) + 1;
_width = Row * SizeObj;
_height = Col * SizeObj;
}
//Debug.Log("_distance " + _distance + " ; witdh = " + _width, gameObject);
if (_distance > _width)
{
//Debug.Log("Out Wrong _distance "+_distance+" ; witdh = " + _width , gameObject);
// Use dyamin setRTS
Row = (int)(Mathf.Ceil(_NumberObj / Row));
Col = (int)(_distance / SizeObj);
}
else
{
//Use default Arange => do not change col, row
// Handle StartPos and EndPpos same Pos (just Click, not drag Mouse)
if (_distance == 0)
{
Vector3 Dir = new Vector3(-1, 0, -1);
_EndPos += Dir;
}
}
int cout = 0;
Vector3 TempEndPos = _EndPos;
Vector3 TempStartPos = _StartPos;
for (int i = 0; i < Row; i++)
{
Vector3 Dir = _EndPos - _StartPos;
Dir = Dir.normalized;
Vector2 VTPT = new Vector2(Dir.z, -Dir.x);
VTPT = VTPT.normalized;
Debug.DrawLine(_StartPos, _EndPos, Color.yellow);
for (int j = 0; j < Col; j++)
{
if (cout >= _NumberObj)
{
break;
}
ListObj[cout].transform.position = TempStartPos;
cout++;
Vector3 _dir = TempEndPos - TempStartPos;
_dir = _dir.normalized;
TempStartPos += _dir * SizeObj;
TempEndPos += _dir * SizeObj;
}
if (cout >= _NumberObj)
{
break;
}
TempStartPos = _StartPos + new Vector3(VTPT.x, 0, VTPT.y) * SizeObj;
TempEndPos = _EndPos + new Vector3(VTPT.x, 0, VTPT.y) * SizeObj;
Debug.DrawLine(_StartPos, TempStartPos, Color.red);
Debug.DrawLine(_EndPos, TempEndPos, Color.green);
_StartPos = TempStartPos;
_EndPos = TempEndPos;
}
}
#endregion
private void formationShape()
{
if (Input.GetMouseButtonDown(0))
{
//Debug.LogWarning("Click Button Down");
//startClick = Input.mousePosition;
RaycastHit hit;
m_ray = m_MainCamera.ScreenPointToRay(Input.mousePosition);
Physics.Raycast(m_ray, out hit, 1000f);
startClick = hit.point;
m_BoxSelected.m_baseMin = startClick;
}
if (Input.GetMouseButton(0))
{
RaycastHit hit;
m_ray = m_MainCamera.ScreenPointToRay(Input.mousePosition);
Physics.Raycast(m_ray, out hit, 1000f);
endClick = hit.point;
m_BoxSelected.m_baseMax = endClick;
//FormationShapeSquad(startClick, endClick, 1.5f, ref unitsList);
FormationLine(startClick, endClick, 1.5f, ref unitsList);
}
if (Input.GetMouseButtonUp(0))
{
//formationMaker3(startClick, endClick, 1.5f, ref unitsList);
}
}
void Update()
{
formationShape();
}
private void OnDrawGizmos()
{
Gizmos.DrawWireCube(m_BoxSelected.m_Center, m_BoxSelected.m_Size);
}
}
public class BoxSelected
{
public BoxSelected() { }
public Vector3 m_baseMin, m_baseMax;
public Vector3 m_Center
{
get
{
Vector3 _center = m_baseMin + (m_baseMax - m_baseMin) * 0.5f;
_center.y = (m_baseMax - m_baseMin).magnitude * 0.5f;
return _center;
}
}
public Vector3 m_Size
{
get
{
return new Vector3(
Mathf.Abs(m_baseMax.x - m_baseMin.x),
(m_baseMax - m_baseMin).magnitude,
Mathf.Abs(m_baseMax.z - m_baseMin.z)
);
}
}
public Vector3 m_Extents
{
get
{
return m_Size * 0.5f;
}
}
}