Initial commit

This commit is contained in:
Thorbjoern
2025-05-26 00:46:28 +02:00
commit e5bca03433
3896 changed files with 1434297 additions and 0 deletions
@@ -0,0 +1,523 @@
using Fragilem17.MirrorsAndPortals;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Unity.Collections;
using UnityEngine;
namespace Fragilem17.MirrorsAndPortals
{
public class CloneRenderer : MonoBehaviour
{
[Tooltip("Leave empty to target this gameObject")]
public GameObject GameObjectToClone;
protected static GameObject _cloneHolder;
protected static List<GameObject> _clones;
protected GameObject _clone;
protected static readonly Quaternion halfTurn = Quaternion.Euler(0.0f, 180.0f, 0.0f);
protected Dictionary<Transform, Transform> _tranforms = new Dictionary<Transform, Transform>();
//protected Dictionary<Rigidbody, Rigidbody> _rigidbodies = new Dictionary<Rigidbody, Rigidbody>();
//public Dictionary<Collider, Collider> Colliders = new Dictionary<Collider, Collider>();
protected Dictionary<MeshRenderer, MeshRenderer> _meshRenderers = new Dictionary<MeshRenderer, MeshRenderer>();
protected Dictionary<MeshRenderer, MeshFilter> _meshFilters = new Dictionary<MeshRenderer, MeshFilter>();
protected Dictionary<SkinnedMeshRenderer, MeshRenderer> _skinnedMeshRenderers = new Dictionary<SkinnedMeshRenderer, MeshRenderer>();
protected Dictionary<SkinnedMeshRenderer, MeshFilter> _skinnedMeshRendererFilters = new Dictionary<SkinnedMeshRenderer, MeshFilter>();
protected Dictionary<SkinnedMeshRenderer, Mesh> _skinnedMeshRendererMeshes = new Dictionary<SkinnedMeshRenderer, Mesh>();
protected Portal _inPortal;
protected Transform _inTransform;
protected Transform _outTransform;
/*public bool CloneColliders = false;
public bool CloneRigidbodies = false;
public bool DisableClonedCollidersAtStart = true;
*/
protected virtual void OnEnable()
{
if (GameObjectToClone == null)
{
GameObjectToClone = gameObject;
}
GenerateClone();
_clone.SetActive(false);
}
protected virtual void OnDisable()
{
DestroyClone();
}
protected virtual void OnDestroy()
{
DestroyClone();
}
protected virtual void DestroyClone()
{
if (_clones != null)
{
_clones.Remove(_clone);
}
if (_clones.Count == 0 || !_cloneHolder)
{
// destroy the holder
DestroyImmediate(_cloneHolder);
_cloneHolder = null;
}
_meshRenderers.Clear();
_meshFilters.Clear();
_skinnedMeshRenderers.Clear();
_skinnedMeshRendererMeshes.Clear();
//_rigidbodies.Clear();
//Colliders.Clear();
if (_clone)
{
DestroyImmediate(_clone);
_clone = null;
}
}
protected virtual void GenerateClone()
{
if (!_cloneHolder)
{
_cloneHolder = new GameObject();
_cloneHolder.transform.SetParent(null);
_cloneHolder.hideFlags = HideFlags.DontSave;
_cloneHolder.name = "Portal ClonesHolder";
_clones = new List<GameObject>();
}
if (!_clone)
{
_clone = new GameObject();
_clones.Add(_clone);
_clone.hideFlags = HideFlags.DontSave;
_clone.name = "clone_" + name;
_clone.layer = gameObject.layer;
CreateMeshrendererChildren(_clone, GameObjectToClone, _cloneHolder.transform);
}
}
protected virtual void CreateMeshrendererChildren(GameObject target, GameObject original, Transform parent)
{
_tranforms[original.transform] = target.transform;
target.transform.localScale = original.transform.lossyScale;
target.transform.SetParent(parent);
target.transform.SetPositionAndRotation(original.transform.position, original.transform.rotation);
MeshRenderer originalMr = original.GetComponent<MeshRenderer>();
if (originalMr != null)
{
MeshFilter originalMf = originalMr.GetComponent<MeshFilter>();
if (originalMf != null)
{
_meshFilters[originalMr] = target.AddComponent<MeshFilter>();
_meshFilters[originalMr].sharedMesh = originalMf.sharedMesh;
_meshRenderers[originalMr] = target.AddComponent<MeshRenderer>();
_meshRenderers[originalMr].sharedMaterials = originalMr.sharedMaterials;
}
}
SkinnedMeshRenderer originalSmr = original.GetComponent<SkinnedMeshRenderer>();
if (originalSmr != null)
{
_skinnedMeshRenderers[originalSmr] = target.AddComponent<MeshRenderer>();
_skinnedMeshRendererFilters[originalSmr] = target.AddComponent<MeshFilter>();
_skinnedMeshRendererMeshes[originalSmr] = new Mesh();
originalSmr.BakeMesh(_skinnedMeshRendererMeshes[originalSmr], true);
_skinnedMeshRendererFilters[originalSmr].sharedMesh = _skinnedMeshRendererMeshes[originalSmr];
_skinnedMeshRenderers[originalSmr].sharedMaterials = originalSmr.sharedMaterials;
}
/*if (CloneColliders)
{
Collider[] originalColliders = original.GetComponents<Collider>();
if (originalColliders.Length > 0)
{
for (int i = 0; i < originalColliders.Length; i++)
{
Collider originalCollider = originalColliders[i];
Type type = originalCollider.GetType();
Colliders[originalCollider] = target.AddComponent(originalCollider, originalCollider.GetType());
Physics.IgnoreCollision(Colliders[originalCollider], originalCollider);
if (DisableClonedCollidersAtStart)
{
Colliders[originalCollider].enabled = false;
}
}
}
}
if (CloneRigidbodies)
{
Rigidbody[] originalRBs = original.GetComponents<Rigidbody>();
if (originalRBs.Length > 0)
{
for (int i = 0; i < originalRBs.Length; i++)
{
Rigidbody originalRB = originalRBs[i];
Type type = originalRB.GetType();
_rigidbodies[originalRB] = target.AddComponent(originalRB, originalRB.GetType());
}
}
}*/
for (int i = 0; i < original.transform.childCount; i++)
{
Transform child = original.transform.GetChild(i);
CloneRenderer childsCloneRenderer = child.GetComponent<CloneRenderer>();
MeshRenderer originalMrChildren = child.GetComponentInChildren<MeshRenderer>(false);
SkinnedMeshRenderer originalSmrChildren = child.GetComponentInChildren<SkinnedMeshRenderer>(false);
Collider originalCollider = child.GetComponentInChildren<Collider>(false);
if (childsCloneRenderer == null && (originalMrChildren != null || originalSmrChildren != null || originalCollider != null))
{
GameObject clonedChild = new GameObject(child.gameObject.name);
clonedChild.hideFlags = HideFlags.DontSave;
CreateMeshrendererChildren(clonedChild, child.gameObject, target.transform);
clonedChild.layer = child.gameObject.layer;
}
}
}
/**
* Only enables a collider that is active in the original
*/
/*public virtual void EnableCloneColliders()
{
foreach (KeyValuePair<Collider, Collider> entry in Colliders)
{
entry.Value.enabled = entry.Key.enabled;
}
}*/
/**
* disables all colliders in the clone
*/
/*public virtual void DisableCloneColliders()
{
foreach (KeyValuePair<Collider, Collider> entry in Colliders)
{
entry.Value.enabled = false;
}
}*/
public virtual void SetIsInPortal(Portal portal, bool physicsDriven = false)
{
if (_clone != null && _inPortal != portal)
{
//Debug.Log(gameObject.name + " IN, inPortal: " + portal.name + " physicsDriven: " + physicsDriven);
_inPortal = portal;
_inTransform = _inPortal.PortalSurface.transform;
_outTransform = _inPortal.OtherPortal.PortalSurface.transform;
/*if (portal.OtherPortal && portal.OtherPortal.wallCollider)
{
foreach (KeyValuePair<Collider, Collider> entry in Colliders)
{
Physics.IgnoreCollision(entry.Value, portal.OtherPortal.wallCollider);
Physics.IgnoreCollision(entry.Value, portal.wallCollider);
}
}*/
_clone.SetActive(true);
CloneAnimations();
//UpdateRigidbodies();
PositionClone();
}
}
public virtual void ExitPortal(Portal portal, bool physicsDriven = false)
{
if (!_clone) {
return;
}
if (portal != _inPortal)
{
return;
}
/*if (portal.OtherPortal && portal.OtherPortal.wallCollider)
{
foreach (KeyValuePair<Collider, Collider> entry in Colliders)
{
Physics.IgnoreCollision(entry.Value, portal.OtherPortal.wallCollider, false);
Physics.IgnoreCollision(entry.Value, portal.wallCollider, false);
}
}*/
//Debug.Log(gameObject.name + " OUT, portal: " + portal?.name + " : " + physicsDriven);
_clone.SetActive(false);
foreach (KeyValuePair<MeshRenderer, MeshRenderer> entry in _meshRenderers)
{
if (entry.Key.sharedMaterial.HasProperty("_SectionPos"))
{
foreach (Material m in entry.Key.materials)
{
m.SetFloat("_DoClipping", 0);
}
}
}
foreach (KeyValuePair<SkinnedMeshRenderer, MeshRenderer> entry in _skinnedMeshRenderers)
{
if (entry.Key.sharedMaterial.HasProperty("_SectionPos"))
{
foreach (Material m in entry.Key.materials)
{
m.SetFloat("_DoClipping", 0);
}
}
}
_inPortal = null;
}
void LateUpdate()
{
if (_inPortal)
{
if (!_clone)
{
DestroyClone();
GenerateClone();
}
CloneAnimations();
PositionClone();
UpdateLayers();
}
}
/*private void FixedUpdate()
{
if (CloneRigidbodies)
{
UpdateRigidbodies();
}
}*/
private void UpdateLayers()
{
foreach (KeyValuePair<Transform, Transform> entry in _tranforms)
{
entry.Value.gameObject.layer = entry.Key.gameObject.layer;
}
}
/*protected void UpdateRigidbodies()
{
if (CloneRigidbodies && _inPortal != null && _clone.activeSelf)
{
foreach (KeyValuePair<Rigidbody, Rigidbody> entry in _rigidbodies)
{
//if (Vector3.Distance(Camera.main.transform.position, entry.Key.transform.position) < Vector3.Distance(Camera.main.transform.position, entry.Value.transform.position))
//{
entry.Value.GetCopyOf<Rigidbody>(entry.Key);
Vector3 relativeVel = _inTransform.InverseTransformDirection(entry.Key.velocity);
relativeVel = halfTurn * relativeVel;
entry.Value.velocity = _outTransform.TransformDirection(relativeVel);
Vector3 relativeAngVel = _inTransform.InverseTransformDirection(entry.Key.angularVelocity);
relativeAngVel = halfTurn * relativeAngVel;
entry.Value.angularVelocity = _outTransform.TransformDirection(relativeAngVel);
// Update position of clone.
Vector3 relativePos = _inTransform.InverseTransformPoint(entry.Key.position);
relativePos = halfTurn * relativePos;
entry.Value.MovePosition(_outTransform.TransformPoint(relativePos));
// Update rotation of clone.
Quaternion relativeRot = Quaternion.Inverse(_inTransform.rotation) * entry.Key.rotation;
relativeRot = halfTurn * relativeRot;
entry.Value.MoveRotation(_outTransform.rotation * relativeRot);
/*}
else
{
entry.Key.GetCopyOf<Rigidbody>(entry.Value);
Vector3 relativeVel = _outTransform.InverseTransformDirection(entry.Value.velocity);
relativeVel = halfTurn * relativeVel;
entry.Key.velocity = _inTransform.TransformDirection(relativeVel);
Vector3 relativeAngVel = _outTransform.InverseTransformDirection(entry.Value.angularVelocity);
relativeAngVel = halfTurn * relativeAngVel;
entry.Key.angularVelocity = _inTransform.TransformDirection(relativeAngVel);
// Update position of clone.
Vector3 relativePos = _outTransform.InverseTransformPoint(entry.Value.position);
relativePos = halfTurn * relativePos;
entry.Key.MovePosition(_inTransform.TransformPoint(relativePos));
// Update rotation of clone.
Quaternion relativeRot = Quaternion.Inverse(_outTransform.rotation) * entry.Value.rotation;
relativeRot = halfTurn * relativeRot;
entry.Key.MoveRotation(_inTransform.rotation * relativeRot);
}*/
//}
//}
//}
protected virtual void CloneAnimations()
{
if (_inPortal != null && _clone.activeSelf)
{
// reset pos of root element
//float scaleFactor = (inPortal.OtherPortal.transform.localScale.x / inPortal.transform.localScale.x);
_clone.transform.localScale = GameObjectToClone.transform.lossyScale;
_clone.transform.SetPositionAndRotation(GameObjectToClone.transform.position, transform.rotation);
foreach (KeyValuePair<Transform, Transform> entry in _tranforms)
{
entry.Value.gameObject.SetActive(entry.Key.gameObject.activeSelf);
if (entry.Key.gameObject.activeSelf)
{
entry.Value.transform.localScale = entry.Key.transform.localScale;
entry.Value.transform.localPosition = entry.Key.transform.localPosition;
entry.Value.transform.localRotation = entry.Key.transform.localRotation;
//cloneMr.transform.SetPositionAndRotation(orginalMr.transform.position, entry.Key.transform.rotation);
}
}
foreach (KeyValuePair<SkinnedMeshRenderer, Mesh> entry in _skinnedMeshRendererMeshes)
{
entry.Key.BakeMesh(entry.Value, true);
}
}
}
protected virtual void PositionClone()
{
if (_inPortal != null && _inTransform != null)
{
float scaleFactor = (_inPortal.OtherPortal.transform.lossyScale.x / _inPortal.transform.lossyScale.x);
_clone.transform.localScale = GameObjectToClone.transform.lossyScale * scaleFactor;
// Update position of clone.
Vector3 relativePos = _inTransform.InverseTransformPoint(GameObjectToClone.transform.position);
relativePos = halfTurn * relativePos;
Vector3 wantedPos = _outTransform.TransformPoint(relativePos);
//if (!CloneRigidbodies || (CloneRigidbodies && Vector3.Distance(wantedPos, _clone.transform.position) > 0.25f))
//{
_clone.transform.position = wantedPos;
// Update rotation of clone.
Quaternion relativeRot = Quaternion.Inverse(_inTransform.rotation) * GameObjectToClone.transform.rotation;
relativeRot = halfTurn * relativeRot;
_clone.transform.rotation = _outTransform.rotation * relativeRot;
//}
if (_meshRenderers.Count > 0)
{
foreach (KeyValuePair<MeshRenderer, MeshRenderer> entry in _meshRenderers)
{
if (entry.Key.sharedMaterial.HasProperty("_SectionPos"))
{
foreach (Material m in entry.Key.materials)
{
m.SetVector("_SectionPos", _inTransform.position + (_inTransform.forward * 0.02f));
m.SetVector("_SectionNormal", _inTransform.forward);
m.SetFloat("_DoClipping", 1);
}
foreach (Material m in entry.Value.materials)
{
m.SetVector("_SectionPos", _outTransform.position + (_outTransform.forward * 0.02f));
m.SetVector("_SectionNormal", _outTransform.forward);
m.SetFloat("_DoClipping", 1);
}
}
}
}
if (_skinnedMeshRenderers.Count > 0)
{
foreach (KeyValuePair<SkinnedMeshRenderer, MeshRenderer> entry in _skinnedMeshRenderers)
{
if (entry.Key && entry.Key.sharedMaterial.HasProperty("_SectionPos"))
{
foreach (Material m in entry.Key.materials)
{
m.SetVector("_SectionPos", _inTransform.position + (_inTransform.forward * 0.02f));
m.SetVector("_SectionNormal", _inTransform.forward);
m.SetFloat("_DoClipping", 1);
}
foreach (Material m in entry.Value.materials)
{
m.SetVector("_SectionPos", _outTransform.position + (_outTransform.forward * 0.02f));
m.SetVector("_SectionNormal", _outTransform.forward);
m.SetFloat("_DoClipping", 1);
}
}
}
}
}
}
public static void DrawBounds(Bounds b, float delay = 0)
{
// bottom
var p1 = new Vector3(b.min.x, b.min.y, b.min.z);
var p2 = new Vector3(b.max.x, b.min.y, b.min.z);
var p3 = new Vector3(b.max.x, b.min.y, b.max.z);
var p4 = new Vector3(b.min.x, b.min.y, b.max.z);
Debug.DrawLine(p1, p2, Color.blue, delay);
Debug.DrawLine(p2, p3, Color.red, delay);
Debug.DrawLine(p3, p4, Color.yellow, delay);
Debug.DrawLine(p4, p1, Color.magenta, delay);
// top
var p5 = new Vector3(b.min.x, b.max.y, b.min.z);
var p6 = new Vector3(b.max.x, b.max.y, b.min.z);
var p7 = new Vector3(b.max.x, b.max.y, b.max.z);
var p8 = new Vector3(b.min.x, b.max.y, b.max.z);
Debug.DrawLine(p5, p6, Color.blue, delay);
Debug.DrawLine(p6, p7, Color.red, delay);
Debug.DrawLine(p7, p8, Color.yellow, delay);
Debug.DrawLine(p8, p5, Color.magenta, delay);
// sides
Debug.DrawLine(p1, p5, Color.white, delay);
Debug.DrawLine(p2, p6, Color.gray, delay);
Debug.DrawLine(p3, p7, Color.green, delay);
Debug.DrawLine(p4, p8, Color.cyan, delay);
}
}
}