# Disconnecting Power Flow from Source

I'm trying to design a wiring system that allows players to connect power sources to switches via wires. Think redstone in Minecraft. When a wire is placed, if it is not initially connected to the power source, it has no power (behaving as expected). The PROBLEM occurs when the wire is connected to power, detecting that it is powered, and then disconnects from power. After it has touched the power source, it then becomes it's own source if disconnected, which is not what it should be doing.

This is what SHOULD be happening

Here's what is ACTUALLY happening

And here is my code:

 using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Wire_Moveable : MonoBehaviour {

public static Wire_Moveable control;

public bool IsBlue;
public bool IsRed;
public bool powered;

void Start () {
IsBlue = false;
IsRed = false;
}

void Update () {
if (Input.GetMouseButtonUp (0)) {
following = false;
this.gameObject.GetComponent<Wire_Moveable>().SnapWire ();
}
}

void OnTriggerStay2D (Collider2D trigger) {
if (trigger.tag == "wire") {
if (trigger.gameObject.GetComponent<Wire_Moveable>().powered) {
powered = true;
}

if (trigger.gameObject.GetComponent<Wire_Moveable> ().IsBlue) {
IsBlue = true;
IsRed = false;
} else if (trigger.gameObject.GetComponent<Wire_Moveable> ().IsRed){
IsBlue = false;
IsRed = true;
}
}
}

void OnTriggerExit2D (Collider2D trigger) {
if (trigger.tag == "startnode_blue") {
IsBlue = false;
powered = false;
}

if (trigger.tag == "wire") {
if (trigger.gameObject.GetComponent<wire_Moveable>().powered) {
powered = false;
}
}
}

void SnapWire () {
if (this.gameObject.name == "Wire_Basic" || this.gameObject.name == "Wire_Basic(Clone)") {
StartCoroutine ("ActivatePower", 0);
}
}

IEnumerator ActivatePower () {
yield return new WaitForSeconds (0.1f);
if (powered) {
PowerBeam.SetActive (true);
} else if (!powered) {
PowerBeam.SetActive (false);
}
}


You can solve this one of two ways, either try to path to a source of power, or the tiles need to keep track of who its source neighbor is.

Pathing can get expensive as your wires become complex, so I'd suggest the second approach.

Basically you need to keep track of where the tile got power from, and check regularly to see if a neighbor has power when the tile doesn't.

I'm going to pseudocode this a bit, because i don't usually use colliders for this when I'm working in 2d, and event handling complicates the solution for future readers.

public class WireSegment : MonoBehaviour {

public bool powered=false;//whether or not we are powered
public WireSegment source;

//called when first created
void Start () {
checkNeighborsForPower();
}

//called each frame
void Update () {
if(powered && !source.powered){
//then our source is unpowered, and we need to turn off
source=null;
powered=false;
}
if(!powered){
//We lost our source, so see if we can find a new one.
checkNeighborsForPower();
}
}

private void checkNeighborsForPower() {
//we'll require adjacency to get power
WireSegment left= findMyNeighbor(transform.position+Vector2.LEFT);
WireSegment right= findMyNeighbor(transform.position+Vector2.RIGHT);
WireSegment top= findMyNeighbor(transform.position+Vector2.UP);
WireSegment bottom= findMyNeighbor(transform.position+Vector2.DOWN);

if(top.powered && top.source!=this){
source=top;
powered=true;
}else if(right.powered && right.source!=this){
source=right;
powered=true;
}else if(bottom.powered && bottom.source!=this){
source=bottom;
powered=true;
}else if(left.powered && left.source!=this){
source=left;
powered=true;
}
}

private WireSegment findMyNeighbor(Vector2 neighborLocation){
//Do a lookup from wherever we are storing our collection of WireSegments
}

}

• I don't know why it never occurred to me to check if each tile is the source, and to actually flag the source in the code. I have not tried the above suggestion yet, but I plan on doing so today, and I'll let you know what happens. – Trey Van Zandt Apr 19 '18 at 18:53