/// <summary> /// Fast and simple way to find attractor; /// But note, that not always nearest attractor is most proper /// </summary> /// <param name="body"></param> public void FindNearestAttractorForBody(CelestialBody body) { CelestialBody resultAttractor = null; float sqrDistance = 0; if (!Application.isPlaying) { _bodies = new List <CelestialBody>(GameObject.FindObjectsOfType <CelestialBody>()); } foreach (var otherBody in _bodies) { if (otherBody == body || otherBody.Mass < MinAttractorMass || (otherBody.transform.position - body.transform.position).magnitude > Mathf.Min(MaxAttractionRange, otherBody.MaxAttractionRange)) { continue; } float _sqrDistance = (body._transform.position - otherBody._transform.position).sqrMagnitude; if (resultAttractor == null || sqrDistance > _sqrDistance) { resultAttractor = otherBody; sqrDistance = _sqrDistance; } } if (!Application.isPlaying) { _bodies.Clear(); //_bodies must be empty in editor mode } if (resultAttractor != null) { if (resultAttractor != body.Attractor) { body.SetAttractor(resultAttractor, false, true); } } }
/// <summary> /// One more convenient way to set attractor; /// </summary> /// <param name="body"></param> public void SetBiggestAttractorForBody(CelestialBody body) { GetCentralAttractor(); if (_centralAttractor != null) { body.SetAttractor(_centralAttractor, false, true); } }
/// <summary> /// Find attractor which has biggest gravitational influence on body comparing to others. If fail, null will be assigned. /// It can be used in realtime for implementing more precise transitions beetween spheres of influence, /// but, without optimisations, performance cost definetly will be very high /// </summary> /// <param name="body"></param> public void FindMostProperAttractorForBody(CelestialBody body) { CelestialBody resultAttractor = null; if (!Application.isPlaying) { _bodies = new List <CelestialBody>(GameObject.FindObjectsOfType <CelestialBody>()); } // Search logic: // calculate mutual perturbation for every pair of attractors in scene and select one, // which attracts the body with biggest force and is least affected by others. foreach (var otherBody in _bodies) { if (otherBody == body || !otherBody.isActiveAndEnabled || otherBody.Mass < MinAttractorMass || (otherBody.transform.position - body.transform.position).magnitude > Mathf.Min(MaxAttractionRange, otherBody.MaxAttractionRange)) { continue; } if (!Application.isPlaying) { otherBody.FindReferences(); } if (resultAttractor == null) { resultAttractor = otherBody; continue; } if (RelativePerturbationRatio(body, resultAttractor, otherBody) > RelativePerturbationRatio(body, otherBody, resultAttractor)) { resultAttractor = otherBody; } } if (!Application.isPlaying) { _bodies.Clear(); //_bodies must be empty in editor mode } if (resultAttractor != body.Attractor) { body.SetAttractor(resultAttractor, false, true); //body.Attractor = resultAttractor; } }
/// <summary> /// Assign biggest attractor on scene to target body. /// </summary> /// <param name="body"></param> public void SetBiggestAttractorForBody(CelestialBody body) { body.SetAttractor(FindBiggestAttractor()); }
/// <summary> /// Find attractor which has biggest gravitational influence on body comparing to others. If fail, null will be assigned. /// It can be used in realtime for implementing more precise transitions beetween spheres of influence, /// but performance cost is high /// </summary> public void SetMostProperAttractorForBody(CelestialBody body) { body.SetAttractor(FindMostProperAttractor(body)); }
/// <summary> /// Fast and simple way to find attractor; /// But note, that not always nearest attractor is most proper /// </summary> public void SetNearestAttractorForBody(CelestialBody body) { body.SetAttractor(FindNearestAttractor(body)); }
/// <summary> /// Find attractor which has biggest gravitational influence on body comparing to others. If fail, null will be assigned. /// It can be used in realtime for implementing more precise transitions beetween spheres of influence, /// but, without optimisations, performance cost definetly will be very high /// </summary> /// <param name="body"></param> public void FindMostProperAttractorForBody(CelestialBody body) { CelestialBody resultAttractor = null; if (!Application.isPlaying) { _bodies = new List<CelestialBody>(GameObject.FindObjectsOfType<CelestialBody>()); } // Search logic: // calculate mutual perturbation for every pair of attractors in scene and select one, // which attracts the body with biggest force and is least affected by others. foreach (var otherBody in _bodies) { if (otherBody == body || !otherBody.isActiveAndEnabled || otherBody.Mass < MinAttractorMass || ( otherBody.transform.position - body.transform.position ).magnitude > Mathf.Min(MaxAttractionRange, otherBody.MaxAttractionRange)) { continue; } if (!Application.isPlaying) { otherBody.FindReferences(); } if (resultAttractor == null) { resultAttractor = otherBody; continue; } if (RelativePerturbationRatio(body, resultAttractor, otherBody) > RelativePerturbationRatio(body, otherBody, resultAttractor)) { resultAttractor = otherBody; } } if (!Application.isPlaying) { _bodies.Clear(); //_bodies must be empty in editor mode } if (resultAttractor != body.Attractor) { body.SetAttractor(resultAttractor, false, true); //body.Attractor = resultAttractor; } }
/// <summary> /// Fast and simple way to find attractor; /// But note, that not always nearest attractor is most proper /// </summary> /// <param name="body"></param> public void FindNearestAttractorForBody(CelestialBody body) { CelestialBody resultAttractor = null; float sqrDistance = 0; if (!Application.isPlaying) { _bodies = new List<CelestialBody>(GameObject.FindObjectsOfType<CelestialBody>()); } foreach (var otherBody in _bodies) { if (otherBody == body || otherBody.Mass < MinAttractorMass || ( otherBody.transform.position - body.transform.position ).magnitude > Mathf.Min(MaxAttractionRange, otherBody.MaxAttractionRange)) { continue; } float _sqrDistance = ( body._transform.position - otherBody._transform.position ).sqrMagnitude; if (resultAttractor == null || sqrDistance > _sqrDistance) { resultAttractor = otherBody; sqrDistance = _sqrDistance; } } if (!Application.isPlaying) { _bodies.Clear(); //_bodies must be empty in editor mode } if (resultAttractor != null) { if (resultAttractor != body.Attractor) { body.SetAttractor(resultAttractor, false, true); } } }