-
-
Save brihernandez/9ebbaf35070181fa1ee56f9e702cc7a5 to your computer and use it in GitHub Desktop.
// Based on the Unity Wiki FloatingOrigin script by Peter Stirling | |
// URL: http://wiki.unity3d.com/index.php/Floating_Origin | |
using UnityEngine; | |
using UnityEngine.SceneManagement; | |
public class FloatingOrigin : MonoBehaviour | |
{ | |
[Tooltip("Point of reference from which to check the distance to origin.")] | |
public Transform ReferenceObject = null; | |
[Tooltip("Distance from the origin the reference object must be in order to trigger an origin shift.")] | |
public float Threshold = 5000f; | |
[Header("Options")] | |
[Tooltip("When true, origin shifts are considered only from the horizontal distance to orign.")] | |
public bool Use2DDistance = false; | |
[Tooltip("When true, updates ALL open scenes. When false, updates only the active scene.")] | |
public bool UpdateAllScenes = true; | |
[Tooltip("Should ParticleSystems be moved with an origin shift.")] | |
public bool UpdateParticles = true; | |
[Tooltip("Should TrailRenderers be moved with an origin shift.")] | |
public bool UpdateTrailRenderers = true; | |
[Tooltip("Should LineRenderers be moved with an origin shift.")] | |
public bool UpdateLineRenderers = true; | |
private ParticleSystem.Particle[] parts = null; | |
void LateUpdate() | |
{ | |
if (ReferenceObject == null) | |
return; | |
Vector3 referencePosition = ReferenceObject.position; | |
if (Use2DDistance) | |
referencePosition.y = 0f; | |
if (referencePosition.magnitude > Threshold) | |
{ | |
MoveRootTransforms(referencePosition); | |
if (UpdateParticles) | |
MoveParticles(referencePosition); | |
if (UpdateTrailRenderers) | |
MoveTrailRenderers(referencePosition); | |
if (UpdateLineRenderers) | |
MoveLineRenderers(referencePosition); | |
} | |
} | |
private void MoveRootTransforms(Vector3 offset) | |
{ | |
if (UpdateAllScenes) | |
{ | |
for (int z = 0; z < SceneManager.sceneCount; z++) | |
{ | |
foreach (GameObject g in SceneManager.GetSceneAt(z).GetRootGameObjects()) | |
g.transform.position -= offset; | |
} | |
} | |
else | |
{ | |
foreach (GameObject g in SceneManager.GetActiveScene().GetRootGameObjects()) | |
g.transform.position -= offset; | |
} | |
} | |
private void MoveTrailRenderers(Vector3 offset) | |
{ | |
var trails = FindObjectsOfType<TrailRenderer>() as TrailRenderer[]; | |
foreach (var trail in trails) | |
{ | |
Vector3[] positions = new Vector3[trail.positionCount]; | |
int positionCount = trail.GetPositions(positions); | |
for (int i = 0; i < positionCount; ++i) | |
positions[i] -= offset; | |
trail.SetPositions(positions); | |
} | |
} | |
private void MoveLineRenderers(Vector3 offset) | |
{ | |
var lines = FindObjectsOfType<LineRenderer>() as LineRenderer[]; | |
foreach (var line in lines) | |
{ | |
Vector3[] positions = new Vector3[line.positionCount]; | |
int positionCount = line.GetPositions(positions); | |
for (int i = 0; i < positionCount; ++i) | |
positions[i] -= offset; | |
line.SetPositions(positions); | |
} | |
} | |
private void MoveParticles(Vector3 offset) | |
{ | |
var particles = FindObjectsOfType<ParticleSystem>() as ParticleSystem[]; | |
foreach (ParticleSystem system in particles) | |
{ | |
if (system.main.simulationSpace != ParticleSystemSimulationSpace.World) | |
continue; | |
int particlesNeeded = system.main.maxParticles; | |
if (particlesNeeded <= 0) | |
continue; | |
// ensure a sufficiently large array in which to store the particles | |
if (parts == null || parts.Length < particlesNeeded) | |
{ | |
parts = new ParticleSystem.Particle[particlesNeeded]; | |
} | |
// now get the particles | |
int num = system.GetParticles(parts); | |
for (int i = 0; i < num; i++) | |
{ | |
parts[i].position -= offset; | |
} | |
system.SetParticles(parts, num); | |
} | |
} | |
} |
Unfortunately, this threshold-based shifting is not floating origin. It never was. Real floating origin has no threshold. It never moves the player from the origin. Therefore, this shifting system is really the exact opposite.
Please rename the references to "floating origin" to something that reflects the truth: Unreal used the term "origin-rebasing". It serves no good purpose to misrepresent the work of others and mislead developers.
@AviaSimDev whenever there is a shift there is a large instantaneous acceleration, so it is not a surprise there are issues. Also, try moving at a speed that exceeds the shift size per second. That is when the shifting system goes into continuous failure.
@skyspy mom: we have floating origin at home
floating origin at home:
It fascinates me, how at least at a surface level this looks relatively straightforward to do in Unity.
In terms of getting references to things like all relevant particle systems in the world and then moving them around etc...
One of the blessings that come with a curse in Unreal I've noticed is that you get a lot of very feature rich systems out of the box, but doing something like this is very much non trivial without making relatively significant changes to the engine source.
It fascinates me, how at least at a surface level this looks relatively straightforward to do in Unity. In terms of getting references to things like all relevant particle systems in the world and then moving them around etc...
One of the blessings that come with a curse in Unreal I've noticed is that you get a lot of very feature rich systems out of the box, but doing something like this is very much non trivial without making relatively significant changes to the engine source.
You are right, the basic idea is very simple, and the continuous floating origin method is simpler than the shifty approach, but designing such an algorithm at the core of a framework for games/sim requires an entirely new structure.
Does this support multiplayer?