public void CreatFromButton() { //通过点击按钮创建一个本零件的实例时,会由按钮脚本呼叫本函数 if (!unit_blueprint.have_power_part) { //如果蓝图里没有任何动力组件,就设置为被拾取状态自由移动 be_picked = true; unit_blueprint.mouse_picking_a_part = true; } else { //如果有动力组件先逐个取出动力组件 foreach (var t in unit_blueprint.all_power_parts) { //检测动力输出挂点是否被占满了 foreach (var MP in t.GetComponent <PowerPart>().self_poweroutput_MP) { if (MP.link_info[0] == -999) { //如果发现了一个空节点,看节点法线方向是否吻合 if (MP.normal == -1 * self_powerinput_MP.transform.forward) { Debug.Log("从按钮新实例化出来的腿零件找到了一个空的且法线吻合的动力输入节作为预制挂点"); //吻合的话直接把两个零件互挂 bool b = self_powerinput_MP.Link2MountPoint(MP); //正确挂上了之后自动解除被拾取状态 if (b) { be_picked = false; unit_blueprint.mouse_picking_a_part = false; //UnitInfo.GetUnitInfo.CountNeedPower(usepower_value); } //最后不管零件是以什么形式入场的,都要添加进蓝图 unit_blueprint.AddPart2Unit(this); return; } else { //不吻合的话接着找 continue; } } } } //如果上面的遍历跑完一遍后本零件没有被挂在任何节点上(link_info[0]还是-999),就设置为被拾取状态 if (self_powerinput_MP.link_info[0] == -999) { be_picked = true; unit_blueprint.mouse_picking_a_part = true; } } //最后不管零件是以什么形式入场的,都要添加进蓝图 unit_blueprint.AddPart2Unit(this); }
void AutoLink2MountPoint() { //动力组件会自动吸附能被看到的任何节点,而不是只吸附合法零件上的节点 //对于动力组件来说父节点永远为空,如果这个组件没有被拾取,不需要开启自动吸附 if (!be_picked) { return; } //每帧清空投影坐标列表: project_allMP.Clear(); //更新吸附的距离阈值 float auto_link_threshold = Screen.width * auto_link_threshold_scale; Debug.Log("auto_link_threshold = " + auto_link_threshold); for (int i = 0; i < mount_points.Count; i++) { MountPoint MP_now = mount_points[i]; if (MP_now.link_info[0] != -999) { Debug.LogError("严重错误:一个组件正在运行自动吸附,但是它的这个节点的信息没有被清空!" + MP_now.name); } else { Vector3 project_thisMP = Camera.main.WorldToScreenPoint(MP_now.transform.position); project_thisMP.z = 0; project_allMP.Add(project_thisMP); } } //节点的投影到另一个节点的投影的距离 float dis_self2mp = -1000f; //把所有位于设计平台上的零件的所有节点(不论是否合法)投影到虚拟平面上 foreach (var GB in unit_blueprint.all_parts) { Part part = GB.GetComponent <Part>(); if (part.transform == transform) { //如果找到的零件是自身,就跳过 continue; } //如果找到的零件不是自身,就开始投影--判断吸附的逻辑 foreach (var mp in part.mount_points) { //如果不是一个空节点,就跳过这个节点接着分析下一个节点 if (mp.link_info[0] != -999) { continue; } Vector3 this_mp_screen_pos = Camera.main.WorldToScreenPoint(mp.transform.position); #region 见的节点应该被屏蔽掉,还没写 //Ray ray = Camera.main.ScreenPointToRay(this_mp_screen_pos); //if (Physics.Raycast(ray,)) #endregion this_mp_screen_pos.z = 0; //对于自身每一个节点,都需要分别执行一次距离计算: for (int i = 0; i < project_allMP.Count; i++) { MountPoint self_MP_now = mount_points[i]; Vector3 project_thisMP = project_allMP[i]; float dis_self2mp_now = Vector3.Distance(project_thisMP, this_mp_screen_pos); if (dis_self2mp < 0) { dis_self2mp = dis_self2mp_now; } if (dis_self2mp_now <= auto_link_threshold) { //判断法线方向是否相符: if (mp.transform.forward == -1 * self_MP_now.transform.forward) { //法线方向吻合的话直接把两个零件互挂 bool b = self_MP_now.Link2MountPoint(mp); //正确的挂完了之后自动解除被拾取状态 if (b) { be_picked = false; unit_blueprint.mouse_picking_a_part = false; return; } } } } } } }