I want to make a mechanic like this: on clicking one of the connected balls, all connected balls get destroyed.
So far I have come with the method in the script below. However, it does not work at all.
I tried storing balls as previous balls and next balls when a new ball enters the collider and then using this linked list getting the first ball and start deleting from there but I am not able to implement that.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum BallsType
{
yellow,
blue,
red,
green
}
public class ConnectedObject
{
public BallsController connectedBall;
public GameObject spawnedLine;
}
public class BallsController : MonoBehaviour
{
public BallsWithColor myColor;
public GameObject linePrefab;
public SpriteRenderer myrenderer;
[SerializeField]private ConnectedObject nextObj;
public ConnectedObject prevObj=new();
public string prevObjName;
void Start()
{
BallsWithColor returnedColor = GameManager.instance.GetRandomColor();
myColor = new BallsWithColor
{
ballSprite =returnedColor.ballSprite,
ballsType = returnedColor.ballsType,
ballColor = new Color
{
r=returnedColor.ballColor.r,
g=returnedColor.ballColor.g,
b=returnedColor.ballColor.b,
a=1,
}
};
myrenderer.color = myColor.ballColor;
}
// Update is called once per frame
void Update()
{
}
private bool connectedObjectHasMe(BallsController controller)
{
if (controller.nextObj == null)
return false;
if (controller.nextObj.connectedBall == null)
return false;
if (controller.nextObj.connectedBall == this)
return true;
BallsController nextcontoller = controller;
while(nextcontoller != null)
{
if (nextcontoller == this)
return true;
if (nextcontoller.nextObj == null)
return false;
nextcontoller = nextcontoller.nextObj.connectedBall;
}
return false;
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("Ball"))
{
BallsController other = collision.GetComponent<BallsController>();
if (other == null)
return;
if (myColor.ballsType != other.myColor.ballsType)
return;
//if (!isObjectInList(collision.GetComponent<BallsController>()) )
if (nextObj==null && !connectedObjectHasMe(other) )
{
Vector2 pos = new((transform.position.x + collision.transform.position.x) / 2,
(transform.position.y + collision.transform.position.y) / 2);
Vector3 targ =pos;
targ.z = 0;
Vector3 objectPos = transform.position;
targ.x -= objectPos.x;
targ.y -= objectPos.y;
float angle = Mathf.Atan2(targ.y, targ.x) * Mathf.Rad2Deg;
GameObject spawnedLine = Instantiate(linePrefab, pos, Quaternion.Euler(new Vector3(0, 0, angle)));
spawnedLine.GetComponent<SpriteRenderer>().color = myColor.ballColor;
nextObj=new ConnectedObject
{
connectedBall = collision.GetComponent<BallsController>(),
spawnedLine = spawnedLine
};
other.prevObj.connectedBall=this;
other.prevObjName = this.GetInstanceID().ToString();
}
}
}
private void OnTriggerStay2D(Collider2D collision)
{
if (collision.CompareTag("Ball"))
{
BallsController other = collision.GetComponent<BallsController>();
if (myColor.ballsType != other.myColor.ballsType)
return;
//if (isObjectInList(collision.GetComponent<BallsController>()))
if (nextObj == null &&!connectedObjectHasMe(other))
{
Vector2 pos = new((transform.position.x + collision.transform.position.x) / 2,
(transform.position.y + collision.transform.position.y) / 2);
Vector3 targ = pos;
targ.z = 0;
Vector3 objectPos = transform.position;
targ.x -= objectPos.x;
targ.y -= objectPos.y;
//Off by 90 degrees for some reasons
float angle = Mathf.Atan2(targ.y, targ.x) * Mathf.Rad2Deg;
GameObject spawnedLine = Instantiate(linePrefab, pos, Quaternion.Euler(new Vector3(0, 0, angle)));
spawnedLine.GetComponent<SpriteRenderer>().color = myColor.ballColor;
nextObj = new ConnectedObject
{
connectedBall = collision.GetComponent<BallsController>(),
spawnedLine = spawnedLine
};
other.prevObj.connectedBall = this;
other.prevObjName = this.GetInstanceID().ToString();
}
else if (nextObj != null)
{
//SetLinePos(collision.GetComponent<BallsController>());
Vector2 pos = new((transform.position.x + nextObj.connectedBall.transform.position.x) / 2,
(transform.position.y + nextObj.connectedBall.transform.position.y) / 2);
Vector3 targ = pos;
targ.z = 0;
Vector3 objectPos = transform.position;
targ.x -= objectPos.x;
targ.y -= objectPos.y;
float angle = Mathf.Atan2(targ.y, targ.x) * Mathf.Rad2Deg;
nextObj.spawnedLine.transform.SetPositionAndRotation(pos, Quaternion.Euler(new Vector3(0, 0, angle)));
}
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.CompareTag("Ball"))
{
BallsController other = collision.GetComponent<BallsController>();
if (myColor.ballsType != collision.GetComponent<BallsController>().myColor.ballsType)
return;
//if (isObjectInList(collision.GetComponent<BallsController>()))
if (nextObj != null)
{
//DestroyObjectInList(collision.GetComponent<BallsController>());
Destroy(nextObj.spawnedLine);
nextObj=null;
other.prevObjName = "";
other.prevObj.connectedBall = null;
}
}
}
private BallsController GetFirstInTheList(BallsController controller)
{
BallsController prev = controller;
while(prev != null)
{
Debug.Log(prev.GetInstanceID());
if (prev.prevObj.connectedBall == null)
{
return prev;
}
prev = prev.prevObj.connectedBall;
}
Debug.Log("A lot is wrong");
return null;
}
public void DestroyMe()
{
//BallsController firstInList = GetFirstInTheList(this);
if(nextObj != null)
{
if(nextObj.connectedBall != null)
{
nextObj.connectedBall.DestroyMe();
}
}
//GameManager.instance.AddScore(1);
//Some Effects
Destroy(gameObject);
}
public void DestroyOnlyMe()
{
if (nextObj != null)
{
if (nextObj.connectedBall != null)
{
nextObj.connectedBall.DestroyOnlyMe();
}
}
Destroy(gameObject);
}
}