is there a way to duplicate a game object 8 times and sync them to the original?
I am making a Wrap2D script that’s purpose is to simulate a 2 dimensional seamless wrap by duplicating the gameobject 8 times with a offset of wrapSize.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Wrap2D : MonoBehaviour
{
GameObject[] copies = new GameObject[8];
Vector2 [] offset = new Vector2[8];
public Vector2 wrapMin;
public Vector2 wrapMax;
public Vector2 wrapSize => (wrapMax - wrapMin);
GameObject CreateCopy(int index)
{
var rad = (index * (260/8)) * Mathf.PI / 180;
offset[index] = new Vector2(Mathf.Cos(rad), Mathf.Sin(rad));
copies[index] = new GameObject(name + "Wrap2DCopy" + index);
copies[index].hideFlags = HideFlags.HideAndDontSave;
copies[index].transform.parent = transform;
copies[index].transform.position = offset[index] * wrapSize;
return copies[index];
}
public void OnEnable ()
{
for (var i = 0; i < copies.Length; i++)
{
CreateCopy(i);
}
}
public void OnDisable()
{
for (var i = 0; i < copies.Length; i++)
{
DestroyImmediate(copies[i]);
}
}
public void LateUpdate()
{
for (var i=0; i<copies.Length; i++)
{
var copy = copies[i];
if (copy == null) copy = CreateCopy(i);
//Sync copies to me exept for offset
}
}
}
Instead of creating a new GameObject and manually duplicating everything on them, I’d try just using Instantiate 8 times on the original. It is what is used for placing instances of prefabs into your scene, but I believe it works just fine on a GameObject already in the scene.
but isn’t Instantiate a value copy?
like what if I attach this to a tilemap? I would want the tiles to be the same on all 9 instances
here is another attempt at creating a wrap2D script this time trying to check if two gameobjects equal by value…
using Sirenix.OdinInspector;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Wrap2D : MonoBehaviour
{
bool original;
GameObject[] copies = new GameObject[9];
[ReadOnly]
public Vector2 offset;
public Vector2 wrapMin;
public Vector2 wrapMax;
public Vector2 wrapSize => (wrapMax - wrapMin);
Wrap2D CreateCopy(int index)
{
if (copies[index] == null || copies[index] != gameObject)
{
var angle = (index * (360 / 8)) * Mathf.PI / 180;
var offset = (index == 0 ? new Vector3() : new Vector3(Mathf.Cos(angle), Mathf.Sin(angle), 0));
copies[index]=Instantiate(gameObject, transform.position+offset, Quaternion.identity);
copies[index].GetComponent<Wrap2D>().copies = copies;
copies[index].GetComponent<Wrap2D>().offset = offset;
copies[index].GetComponent<Wrap2D>().original = index == 0;
Debug.Log("Created Index: " + index.ToString());
}
else
{
Debug.Log("Returned Index: " + index.ToString());
}
return copies[index].GetComponent<Wrap2D>();
}
public void LateUpdate()
{
CreateCopy(0);
//If original make sure we updaqte the copies
if (original)
{
for (var i = 0; i < copies.Length; i++)
{
var copy = CreateCopy(i);
}
}
//Wrap self
var diffX = Mathf.Floor((transform.position.x - offset.x) % wrapSize.x) * wrapSize.x;
var diffY = Mathf.Floor((transform.position.y - offset.y) % wrapSize.y) * wrapSize.y;
if (diffX != 0) offset.x = transform.position.x;
if (diffX != 0) offset.y = transform.position.y;
transform.position += new Vector3(diffX, diffY, 0);
}
}
this doesn’t account for a infinite wrap but I am beginning to think something like this is impossible to do in unity.
this script assumes that C# can check reference types equality by value which it can’t.
is there no way to create a infinitely wrapped 2d plane in unity?
I would assume it would be something like this…
but it would account for changes to the original gameobject
Hogwash. You can override .Equals() and make equality mean whatever you’d like for any Class. I’d encourage implementing https://docs.microsoft.com/en-us/dotnet/api/system.iequatable-1?view=netcore-3.1 and overriding GetHashCode() as well.
that would requires to override every single C# classes equals
I am trying to compare the whole game object and all its components and all their data by value weather its equal