AddPhysics on planet allows it to be deorbited #194 (#688)

## Minor features
- `AddPhysics` on `Base` module for planets allows a planet to be pushed
out of orbit. Intended for satellites or small props floating in orbit.
Implements #194

## Bug Fixes
- Fix default system override being unreliable #687
This commit is contained in:
Nick 2023-08-11 16:45:28 -04:00 committed by GitHub
commit 3cf224540b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 104 additions and 42 deletions

View File

@ -1,15 +1,17 @@
using NewHorizons.External;
using NewHorizons.External.Configs;
using NewHorizons.Utility;
using NewHorizons.Utility.OWML;
using UnityEngine;
namespace NewHorizons.Builder.General
{
public static class RigidBodyBuilder
{
public static OWRigidbody Make(GameObject body, float sphereOfInfluence)
public static OWRigidbody Make(GameObject body, float sphereOfInfluence, PlanetConfig config)
{
body.AddComponent<ProxyShadowCasterSuperGroup>()._bounds.radius = sphereOfInfluence;
Rigidbody rigidBody = body.AddComponent<Rigidbody>();
rigidBody.mass = 10000;
rigidBody.drag = 0f;
rigidBody.angularDrag = 0f;
rigidBody.useGravity = false;
@ -17,18 +19,60 @@ namespace NewHorizons.Builder.General
rigidBody.interpolation = RigidbodyInterpolation.None;
rigidBody.collisionDetectionMode = CollisionDetectionMode.Discrete;
KinematicRigidbody kinematicRigidBody = body.AddComponent<KinematicRigidbody>();
OWRigidbody owRigidBody = body.AddComponent<OWRigidbody>();
owRigidBody._kinematicSimulation = true;
owRigidBody._autoGenerateCenterOfMass = true;
owRigidBody.SetIsTargetable(true);
owRigidBody._maintainOriginalCenterOfMass = true;
owRigidBody._rigidbody = rigidBody;
owRigidBody._kinematicRigidbody = kinematicRigidBody;
owRigidBody._origParent = SearchUtilities.Find("SolarSystemRoot")?.transform;
owRigidBody.EnableKinematicSimulation();
KinematicRigidbody kinematicRigidBody = body.AddComponent<KinematicRigidbody>();
owRigidBody._kinematicRigidbody = kinematicRigidBody;
owRigidBody._kinematicSimulation = true;
owRigidBody.MakeKinematic();
owRigidBody.EnableKinematicSimulation();
rigidBody.mass = 10000;
if (config.Base.addPhysics)
{
// hack: make all mesh colliders convex
// triggers are already convex
// prints errors for non readable meshes but whatever
foreach (var meshCollider in body.GetComponentsInChildren<MeshCollider>(true))
meshCollider.convex = true;
var shape = body.AddComponent<SphereShape>();
shape._collisionMode = Shape.CollisionMode.Detector;
shape._layerMask = (int)(Shape.Layer.Default | Shape.Layer.Gravity);
shape._radius = config.Base.surfaceSize;
var impactSensor = body.AddComponent<ImpactSensor>();
var audioSource = body.AddComponent<AudioSource>();
audioSource.maxDistance = 30;
audioSource.dopplerLevel = 0;
audioSource.rolloffMode = AudioRolloffMode.Custom;
audioSource.playOnAwake = false;
audioSource.spatialBlend = 1;
var owAudioSource = body.AddComponent<OWAudioSource>();
owAudioSource._audioSource = audioSource;
owAudioSource._track = OWAudioMixer.TrackName.Environment;
var objectImpactAudio = body.AddComponent<ObjectImpactAudio>();
objectImpactAudio._minPitch = 0.4f;
objectImpactAudio._maxPitch = 0.6f;
objectImpactAudio._impactSensor = impactSensor;
// For some reason when originally testing, not doing MakeKinematic caused the body to not move relative to the player character
// It seems that turning it on and then off makes it actually work properly
owRigidBody.MakeNonKinematic();
owRigidBody.DisableKinematicSimulation();
// Should make this number changeable, if anybody ever asks
// For some reason, setting this on the exact same frame as it is created doesn't work.
// I imagine something strange is happening on Awake/Start, hence the delay
Delay.FireOnNextUpdate(() => owRigidBody.SetMass(0.001f));
}
return owRigidBody;
}

View File

@ -17,7 +17,7 @@ namespace NewHorizons.Builder.Orbital
if (_dottedLineMaterial == null || _lineMaterial == null) return null;
GameObject orbitGO = new GameObject("Orbit");
var orbitGO = new GameObject("Orbit");
orbitGO.transform.parent = planetGO.transform;
orbitGO.transform.localPosition = Vector3.zero;
@ -83,6 +83,16 @@ namespace NewHorizons.Builder.Orbital
Delay.FireOnNextUpdate(orbitLine.InitializeLineRenderer);
// If the planet has physics and a regular orbit line, make sure that when it's bumped into the old orbit line vanishes
if (config.Base.addPhysics && !config.Orbit.trackingOrbitLine)
{
var impactSensor = planetGO.GetComponent<ImpactSensor>();
impactSensor.OnImpact += (ImpactData _) =>
{
orbitGO.SetActive(false);
};
}
return orbitLine;
}
}

View File

@ -71,6 +71,14 @@ namespace NewHorizons.External.Modules
/// </summary>
[DefaultValue(0)] public int gravityVolumePriority = 0;
/// <summary>
/// Apply physics to this planet when you bump into it. Will have a spherical collider the size of surfaceSize.
/// For custom colliders they have to all be convex and you can leave surface size as 0.
/// This is meant for stuff like satellites which are relatively simple and can be de-orbited.
/// If you are using an orbit line but a tracking line, it will be removed when the planet is bumped in to.
/// </summary>
public bool addPhysics;
#region Obsolete
[Obsolete("IsSatellite is deprecated, please use ShowMinimap instead")]

View File

@ -348,7 +348,7 @@ namespace NewHorizons.Handlers
const float sphereOfInfluence = 2000f;
var owRigidBody = RigidBodyBuilder.Make(go, sphereOfInfluence);
var owRigidBody = RigidBodyBuilder.Make(go, sphereOfInfluence, body.Config);
var ao = AstroObjectBuilder.Make(go, null, body.Config, false);
var sector = SectorBuilder.Make(go, owRigidBody, sphereOfInfluence);
@ -423,7 +423,7 @@ namespace NewHorizons.Handlers
var sphereOfInfluence = GetSphereOfInfluence(body);
var owRigidBody = RigidBodyBuilder.Make(go, sphereOfInfluence);
var owRigidBody = RigidBodyBuilder.Make(go, sphereOfInfluence, body.Config);
var ao = AstroObjectBuilder.Make(go, primaryBody, body.Config, false);
var sector = SectorBuilder.Make(go, owRigidBody, sphereOfInfluence * 2f);

View File

@ -3,8 +3,10 @@ using NewHorizons.Builder.Atmosphere;
using NewHorizons.Builder.Body;
using NewHorizons.Builder.General;
using NewHorizons.Builder.Props;
using NewHorizons.Builder.Props.Audio;
using NewHorizons.Builder.Props.TranslatorText;
using NewHorizons.Components.Fixers;
using NewHorizons.Components.Ship;
using NewHorizons.Components.SizeControllers;
using NewHorizons.External;
using NewHorizons.External.Configs;
@ -14,9 +16,11 @@ using NewHorizons.OtherMods.MenuFramework;
using NewHorizons.OtherMods.OWRichPresence;
using NewHorizons.OtherMods.VoiceActing;
using NewHorizons.Utility;
using NewHorizons.Utility.DebugTools;
using NewHorizons.Utility.DebugTools.Menu;
using NewHorizons.Utility.Files;
using NewHorizons.Utility.OWML;
using NewHorizons.Utility.OuterWilds;
using NewHorizons.Utility.OWML;
using OWML.Common;
using OWML.ModHelper;
using OWML.Utils;
@ -29,12 +33,6 @@ using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using NewHorizons.Utility.DebugTools;
using NewHorizons.Utility.DebugTools.Menu;
using NewHorizons.Components.Ship;
using NewHorizons.Builder.Props.Audio;
using Epic.OnlineServices;
namespace NewHorizons
{
@ -116,12 +114,12 @@ namespace NewHorizons
else if (Debug) NHLogger.UpdateLogLevel(NHLogger.LogType.Log);
else NHLogger.UpdateLogLevel(NHLogger.LogType.Error);
var oldDefaultSystemOverride = _defaultSystemOverride;
_defaultSystemOverride = config.GetSettingsValue<string>("Default System Override");
// Else it doesn't get set idk
if (currentScene == "TitleScreen" && SystemDict.ContainsKey(_defaultSystemOverride))
if (oldDefaultSystemOverride != _defaultSystemOverride)
{
_currentStarSystem = _defaultSystemOverride;
ResetCurrentStarSystem();
NHLogger.Log($"Changed default star system override to {_defaultSystemOverride}");
}
var wasUsingCustomTitleScreen = _useCustomTitleScreen;
@ -553,17 +551,7 @@ namespace NewHorizons
}
else
{
// Reset back to original solar system after going to main menu.
// If the override is a valid system then we go there
if (SystemDict.ContainsKey(_defaultSystemOverride))
{
_currentStarSystem = _defaultSystemOverride;
IsWarpingFromShip = true; // always do this else sometimes the spawn gets messed up
}
else
{
_currentStarSystem = _defaultStarSystem;
}
ResetCurrentStarSystem();
}
}
@ -614,7 +602,7 @@ namespace NewHorizons
if (starSystemName != "SolarSystem")
{
SetDefaultSystem(starSystemName);
_currentStarSystem = starSystemName;
_currentStarSystem = DefaultStarSystem;
}
}
@ -905,15 +893,23 @@ namespace NewHorizons
{
if (SystemDict[_currentStarSystem].Config.respawnHere) return;
// If the override is a valid system then we go there
ResetCurrentStarSystem();
}
}
private void ResetCurrentStarSystem()
{
if (SystemDict.ContainsKey(_defaultSystemOverride))
{
_currentStarSystem = _defaultSystemOverride;
// Sometimes the override will not support spawning regularly, so always warp in
IsWarpingFromShip = true;
}
else
{
_currentStarSystem = _defaultStarSystem;
}
IsWarpingFromShip = false;
}
}
#endregion Change star system

View File

@ -573,6 +573,10 @@
"description": "Optional. You can force this planet's gravity to be felt over other gravity/zero-gravity sources by increasing this number.",
"format": "int32",
"default": 0
},
"addPhysics": {
"type": "boolean",
"description": "Apply physics to this planet when you bump into it. Will have a spherical collider the size of surfaceSize. \nFor custom colliders they have to all be convex and you can leave surface size as 0.\nThis is meant for stuff like satellites which are relatively simple and can be de-orbited.\nIf you are using an orbit line but a tracking line, it will be removed when the planet is bumped in to."
}
}
},