用鼠标绘制线渲染器然后从起点缩短它(飞行控制样式)
Draw a line renderer by mouse then shorten it from the starting point (flight control style)
我正在创建一个类似于 "Flight control" 的游戏。现在我可以通过在屏幕上拖动鼠标来创建一个 linerenderer,对象将跟随它。这是代码:
void Update ()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, 1000))
{
if(mouseDown)
{
if (pathList.Count == lineNum)
{
GameObject x = new GameObject();
x.AddComponent<LineRenderer>();
LineRenderer lr = x.GetComponent<LineRenderer>();
lr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
lr.receiveShadows = false;
lr.SetWidth(0.4f, 0.4f);
lr.material = m;
List<Vector3> path = new List<Vector3>();
lrList.Add(lr);
pathList.Add(path);
pathList[lineNum] = new List<Vector3>();
finalPath.Add(hit.point);
}
if(Vector3.Distance(finalPath[finalPath.Count-1], hit.point) >5)
{
finalPath.Add(hit.point);
}
pathList[lineNum].Add(hit.point);
lrList[lineNum].SetVertexCount(pathList[lineNum].Count);
lrList[lineNum].SetPosition(pathList[lineNum].Count - 1, hit.point + new Vector3(0, 0.1f, 0));
hitPoints.Add(hit.point);
}
}
问题是我希望当从动对象到达时线条消失。就像从起点到终点。
这是我在追随者对象上的代码:
public class FollowLine : MonoBehaviour {
LineGenerator ln;
Vector3[] path;
int i = 0;
int y = 0;
void Start ()
{
ln = FindObjectOfType<LineGenerator>();
}
void Update ()
{
path = ln.finalPath.ToArray();
if (path.Length != 0 && Vector3.Distance(transform.position, path[i]) > 1)
{
transform.position = Vector3.MoveTowards(transform.position, path[i], Time.deltaTime*3);
}
else if(path.Length > i+1)
{
i++;
}
if(ln.pathList.Count != 0 && Vector3.Distance(transform.position, ln.pathList[0][0]) < 1)
{
ln.pathList[0].RemoveAt(ln.pathList.Count-1);
}
}
问题是即使这段代码实际上删除了线渲染器中的点,但它不会影响屏幕上的任何内容
你的代码真的很难读,但你似乎并没有真正从线渲染器中删除点,而且它可能还有其他多个问题。
您将线渲染器组件引用存储在 lrList 中。你叫
ln.pathList[0].RemoveAt(ln.pathList.Count-1);
在第二个脚本中,它删除了索引 pathList.Count-1 处的 pathList[0] 中的点(注意,您引用 pathList[0] 列表和 pathList 中的索引,这是错字吗?你做了什么如果不是,请尝试通过此实现?),从第一个脚本看来,这只是一个 Vector3 列表。
现在回到第一个脚本,你有
lrList[lineNum].SetVertexCount(pathList[lineNum].Count);
将线渲染器的点数截断为 pathList[lineNum]
的长度(尽管第二个脚本实际上可以从 pathList[0] 的中间删除点)。注意它在 if mouseDown
子句下,所以它只会在鼠标按下时发生。另外,它会立即在鼠标点击的位置添加另一个点,所以会造成一些额外的混乱。
您应该考虑重写这段代码。首先:
如果要删除线渲染器,请使用 Object.Destroy
函数:
Destroy(lrList[someIdx].gameObject); // Destroy the game object
lrList.RemoveAt(someIdx); // Remove from list if we don't need it
如果您只想清除线渲染器上的点,请将顶点数设置为 0:
lrList[someIdx].SetVertexCount(0);
如果你想删除线渲染器中的特定点,那就更复杂了。您清除并使用备份数据重新创建它的点列表(看起来就像您在 pathList 中),因此它可能看起来像这样:
pathList[someIdx].RemoveAt(whatever_you_want); // Remove the point you want
lrList[someIdx].SetVertexCount(pathList[someIdx].Count); // Truncate line renderer points
// Set new points
for (int i = 0; i < pathList[someIdx].Count; ++i) {
lrList[someIdx].SetPosition(i, pathList[someIdx][i]);
}
希望对您有所帮助。
我正在创建一个类似于 "Flight control" 的游戏。现在我可以通过在屏幕上拖动鼠标来创建一个 linerenderer,对象将跟随它。这是代码:
void Update ()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, 1000))
{
if(mouseDown)
{
if (pathList.Count == lineNum)
{
GameObject x = new GameObject();
x.AddComponent<LineRenderer>();
LineRenderer lr = x.GetComponent<LineRenderer>();
lr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
lr.receiveShadows = false;
lr.SetWidth(0.4f, 0.4f);
lr.material = m;
List<Vector3> path = new List<Vector3>();
lrList.Add(lr);
pathList.Add(path);
pathList[lineNum] = new List<Vector3>();
finalPath.Add(hit.point);
}
if(Vector3.Distance(finalPath[finalPath.Count-1], hit.point) >5)
{
finalPath.Add(hit.point);
}
pathList[lineNum].Add(hit.point);
lrList[lineNum].SetVertexCount(pathList[lineNum].Count);
lrList[lineNum].SetPosition(pathList[lineNum].Count - 1, hit.point + new Vector3(0, 0.1f, 0));
hitPoints.Add(hit.point);
}
}
问题是我希望当从动对象到达时线条消失。就像从起点到终点。 这是我在追随者对象上的代码:
public class FollowLine : MonoBehaviour {
LineGenerator ln;
Vector3[] path;
int i = 0;
int y = 0;
void Start ()
{
ln = FindObjectOfType<LineGenerator>();
}
void Update ()
{
path = ln.finalPath.ToArray();
if (path.Length != 0 && Vector3.Distance(transform.position, path[i]) > 1)
{
transform.position = Vector3.MoveTowards(transform.position, path[i], Time.deltaTime*3);
}
else if(path.Length > i+1)
{
i++;
}
if(ln.pathList.Count != 0 && Vector3.Distance(transform.position, ln.pathList[0][0]) < 1)
{
ln.pathList[0].RemoveAt(ln.pathList.Count-1);
}
}
问题是即使这段代码实际上删除了线渲染器中的点,但它不会影响屏幕上的任何内容
你的代码真的很难读,但你似乎并没有真正从线渲染器中删除点,而且它可能还有其他多个问题。
您将线渲染器组件引用存储在 lrList 中。你叫
ln.pathList[0].RemoveAt(ln.pathList.Count-1);
在第二个脚本中,它删除了索引 pathList.Count-1 处的 pathList[0] 中的点(注意,您引用 pathList[0] 列表和 pathList 中的索引,这是错字吗?你做了什么如果不是,请尝试通过此实现?),从第一个脚本看来,这只是一个 Vector3 列表。
现在回到第一个脚本,你有
lrList[lineNum].SetVertexCount(pathList[lineNum].Count);
将线渲染器的点数截断为 pathList[lineNum]
的长度(尽管第二个脚本实际上可以从 pathList[0] 的中间删除点)。注意它在 if mouseDown
子句下,所以它只会在鼠标按下时发生。另外,它会立即在鼠标点击的位置添加另一个点,所以会造成一些额外的混乱。
您应该考虑重写这段代码。首先:
如果要删除线渲染器,请使用 Object.Destroy
函数:
Destroy(lrList[someIdx].gameObject); // Destroy the game object
lrList.RemoveAt(someIdx); // Remove from list if we don't need it
如果您只想清除线渲染器上的点,请将顶点数设置为 0:
lrList[someIdx].SetVertexCount(0);
如果你想删除线渲染器中的特定点,那就更复杂了。您清除并使用备份数据重新创建它的点列表(看起来就像您在 pathList 中),因此它可能看起来像这样:
pathList[someIdx].RemoveAt(whatever_you_want); // Remove the point you want
lrList[someIdx].SetVertexCount(pathList[someIdx].Count); // Truncate line renderer points
// Set new points
for (int i = 0; i < pathList[someIdx].Count; ++i) {
lrList[someIdx].SetPosition(i, pathList[someIdx][i]);
}
希望对您有所帮助。