物理画线,首先确定我们要实现的效果,是画一条任意形状的线,松手的同时,使这条线具有重力和物理效果,然后使小球进入到相应的位置。
1.先获取屏幕上的点,然后通过linerender,设置获取所有的点两两进行连线。
刚开始的时候,我先是设置的每隔固定的时间间隔和OnMouseButton(0)来获取鼠标的位置,然后发现,这一样有一个问题就是在划线时速度不均匀的话,获取到的点的密集度也是不均匀的,然后我们是new 一个空物体,设置linerender里面的points,这样就得重新计算重心,并且进行移动到合适的位置,然后我是用的把获取到所有点的x.y分别累加起来除以个数,从而获得重心的位置。所以当画的线密集度不均匀时,所计算得到的重心就是不正确的。所以我改成,设置一个距离Dl,当鼠标位置距离上一个点的位置超过这个间隔时,取这个向量上的这个间隔的长度的点,然后它可能会在画的很快的时候跟不上鼠标,所以通过改变间隔来改变画线时候的体验
2.然后就是,在鼠标抬起的时候,给画的线添加Edge collider,也是将之前list存的点,转存到一个vecter2 的数组中,设置到collider里面。同时也添加上刚体。但是遇到的问题是,edge collider跟石头的boxcollider 是可以发生碰撞,但是两条线之间并不会发生碰撞,到现在也没有解决这个问题。
附上代码:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
public class HA_DrawLine : MonoBehaviour
{
private static HA_DrawLine instance;
public static HA_DrawLine Instance
{
get
{
return instance;
}
}
/// <summary>
/// Linerender
/// </summary>
private LineRenderer line;
/// <summary>
/// 画线开始点
/// </summary>
public Vector3 startpos;
/// <summary>
/// 折线碰撞器
/// </summary>
private EdgeCollider2D edge;
/// <summary>
/// 要赋值给collider的所有点2d
/// </summary>
private Vector2[] Allpos;
/// <summary>
/// 获取到的鼠标转换成的世界坐标
/// </summary>
private List<Vector3> poslist;
/// <summary>
/// 画线的材质
/// </summary>
private Material materrial;
/// <summary>
/// 累加的所有点x值,用于计算重心
/// </summary>
private float PosX = 0;
/// <summary>
/// 累加的所有点y值,用于计算重心
/// </summary>
private float PosY = 0;
private bool isUp = false;
private bool CanDown = true;
private bool isfirst;
private void Awake()
{
instance = this;
}
void Start()
{
poslist = new List<Vector3>();
Material mat = Resources.Load("Prefabs/LineMaterial") as Material;
materrial = Instantiate<Material>(mat);
IsUp = false;
isfirst = true;
Object obj = Resources.Load("Prefabs/level" + HA_Tool.zhe);
GameObject go = GameObject.Instantiate(obj) as GameObject;
}
/// <summary>
/// 坐标点的下标
/// </summary>
private int i = 1;
public bool IsUp
{
get
{
return isUp;
}
set
{
isUp = value;
}
}
public bool CanDown1
{
get
{
return CanDown;
}
set
{
CanDown = value;
}
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0)&& CanDown1)
{
Clear();
CreatLine();
Vector3 Initpos = Input.mousePosition;
Initpos.z = -10;
startpos = Camera.main.ScreenToWorldPoint(Initpos);
startpos.z = 0;
line.SetPosition(0, startpos);
poslist.Add(startpos);
}
if (Input.GetMouseButton(0) && i < 500 && CanDown1)
{
Vector3 mosepos = Input.mousePosition;
mosepos.z = -10;
Vector3 pos = Camera.main.ScreenToWorldPoint(mosepos);
pos.z = 0;
if (Vector3.Distance(pos, poslist[i - 1]) >= 0.15f)
{
line.SetVertexCount(i + 1);
pos = ((pos - poslist[i - 1]).normalized * 0.15f) + poslist[i - 1];
line.SetPosition(i, pos);
poslist.Add(pos);
i++;
}
}
if ((Input.GetMouseButtonUp(0) || i == 500) && i > 1)
{
if (poslist.Count != 0)
SetAllPos();
isUp = false;
}
else if ((Input.GetMouseButtonUp(0) || i == 500) && i <=1)
{
CanDown1 = true;
}
if (IsUp)
{
CanDown1 = false;
if (poslist.Count != 0)
SetAllPos();
IsUp = false;
}
}
public void SetAllPos()
{
PosX = 0;
PosY = 0;
for (int k = 0; k < poslist.Count; k++)
{
PosX += poslist[k].x;
PosY += poslist[k].y;
}
Vector3 v3 = line.transform.position;
float junX = PosX / poslist.Count;
float junY = PosY / poslist.Count;
v3.x = junX;
v3.y = junY;
line.transform.position = v3;
line.SetVertexCount(poslist.Count);
for (int j = 0; j < poslist.Count; j++)
{
line.SetPosition(j, poslist[j] - v3);
}
Allpos = new Vector2[poslist.Count];
for (int j = 0; j < poslist.Count; j++)
{
Allpos[j] = poslist[j] - line.transform.position;
}
ADDCollider();
Clear();
}
public void Clear()
{
i = 1;
Allpos = null;
poslist.Clear();
IsUp = false;
}
/// <summary>
/// 添加碰撞盒和刚体
/// </summary>
public void ADDCollider()
{
edge = line.gameObject.AddComponent<EdgeCollider2D>();
edge.points = Allpos;
line.gameObject.AddComponent<Rigidbody2D>();
line.gameObject.GetComponent<Rigidbody2D>().angularDrag = 2;
line.gameObject.GetComponent<Rigidbody2D>().gravityScale = 8;
if (isfirst)
{
HA_PlayerCtrl.Instance.AddGravity();
isfirst = false;
}
}
/// <summary>
/// 创建空物体添加线
/// </summary>
public void CreatLine()
{
line = new GameObject().AddComponent<LineRenderer>();
line.gameObject.name = "Line";
line.SetWidth(0.04f, 0.04f);
line.SetColors(Color.black, Color.black);
line.useWorldSpace = false;
line.SetVertexCount(1);
line.material = materrial;
}
}