mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Make AddPhysics a bit better (#689)
<!-- A new module or something else important --> ## Major features - <!-- A new parameter added to a module, or API feature --> ## Minor features - Add option to freeze a physics detail until its touched. Good for things in zero g <!-- Some improvement that requires no action on the part of add-on creators i.e., improved star graphics --> ## Improvements - <!-- Be sure to reference the existing issue if it exists --> ## Bug fixes -
This commit is contained in:
commit
7438ed3076
@ -218,9 +218,10 @@ namespace NewHorizons.Builder.Props
|
||||
if (detail.hasPhysics)
|
||||
{
|
||||
var addPhysics = prop.AddComponent<AddPhysics>();
|
||||
addPhysics.Sector = sector;
|
||||
addPhysics.Sector = detail.keepLoaded ? null : sector;
|
||||
addPhysics.Mass = detail.physicsMass;
|
||||
addPhysics.Radius = detail.physicsRadius;
|
||||
addPhysics.SuspendUntilImpact = detail.physicsSuspendUntilImpact;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(detail.activationCondition))
|
||||
@ -259,6 +260,7 @@ namespace NewHorizons.Builder.Props
|
||||
// Not doing else if here because idk if any of the classes below implement ISectorGroup
|
||||
|
||||
// Null check else shuttles controls break
|
||||
// parent sector is always null before Awake so this code actually never runs lol
|
||||
if (component is Sector s && s.GetParentSector() != null && !existingSectors.Contains(s.GetParentSector()))
|
||||
{
|
||||
s.SetParentSector(sector);
|
||||
|
||||
@ -52,6 +52,7 @@ namespace NewHorizons.Builder.Props
|
||||
neutralSlot._attractive = true;
|
||||
neutralSlot._muteAudio = true;
|
||||
nhShuttleController._neutralSlot = neutralSlot;
|
||||
// TODO: at some point delay rigidbody parenting so we dont have to find orb via references. mainly to fix orbs on existing details and rafts not rotating with planets
|
||||
_orbPrefab = shuttleController._orb.gameObject?.InstantiateInactive()?.Rename("Prefab_QM_Shuttle_InterfaceOrbSmall")?.DontDestroyOnLoad();
|
||||
nhShuttleController._orb = _orbPrefab.GetComponent<NomaiInterfaceOrb>();
|
||||
nhShuttleController._orb._sector = nhShuttleController._interiorSector;
|
||||
|
||||
@ -18,9 +18,16 @@ public class AddPhysics : MonoBehaviour
|
||||
[Tooltip("The radius that the added sphere collider will use for physics collision.\n" +
|
||||
"If there's already good colliders on the detail, you can make this 0.")]
|
||||
public float Radius = 1f;
|
||||
[Tooltip("If true, this detail will stay still until it touches something.\n" +
|
||||
"Good for zero-g props.")]
|
||||
public bool SuspendUntilImpact;
|
||||
|
||||
private OWRigidbody _body;
|
||||
private ImpactSensor _impactSensor;
|
||||
|
||||
private IEnumerator Start()
|
||||
{
|
||||
// detectors dont detect unless we wait for some reason
|
||||
yield return new WaitForSeconds(.1f);
|
||||
|
||||
var parentBody = GetComponentInParent<OWRigidbody>();
|
||||
@ -37,8 +44,8 @@ public class AddPhysics : MonoBehaviour
|
||||
bodyGo.transform.position = transform.position;
|
||||
bodyGo.transform.rotation = transform.rotation;
|
||||
|
||||
var owRigidbody = bodyGo.AddComponent<OWRigidbody>();
|
||||
owRigidbody._simulateInSector = Sector;
|
||||
_body = bodyGo.AddComponent<OWRigidbody>();
|
||||
_body._simulateInSector = Sector;
|
||||
|
||||
bodyGo.layer = Layer.PhysicalDetector;
|
||||
bodyGo.tag = "DynamicPropDetector";
|
||||
@ -53,7 +60,7 @@ public class AddPhysics : MonoBehaviour
|
||||
fluidDetector._buoyancy = Locator.GetProbe().GetOWRigidbody()._attachedFluidDetector._buoyancy;
|
||||
fluidDetector._splashEffects = Locator.GetProbe().GetOWRigidbody()._attachedFluidDetector._splashEffects;
|
||||
|
||||
var impactSensor = bodyGo.AddComponent<ImpactSensor>();
|
||||
_impactSensor = bodyGo.AddComponent<ImpactSensor>();
|
||||
var audioSource = bodyGo.AddComponent<AudioSource>();
|
||||
audioSource.maxDistance = 30;
|
||||
audioSource.dopplerLevel = 0;
|
||||
@ -66,24 +73,73 @@ public class AddPhysics : MonoBehaviour
|
||||
var objectImpactAudio = bodyGo.AddComponent<ObjectImpactAudio>();
|
||||
objectImpactAudio._minPitch = 0.4f;
|
||||
objectImpactAudio._maxPitch = 0.6f;
|
||||
objectImpactAudio._impactSensor = impactSensor;
|
||||
objectImpactAudio._impactSensor = _impactSensor;
|
||||
|
||||
bodyGo.SetActive(true);
|
||||
|
||||
transform.parent = bodyGo.transform;
|
||||
owRigidbody.SetMass(Mass);
|
||||
owRigidbody.SetVelocity(parentBody.GetPointVelocity(transform.position));
|
||||
_body.SetMass(Mass);
|
||||
_body.SetVelocity(parentBody.GetPointVelocity(_body.GetWorldCenterOfMass()));
|
||||
_body.SetAngularVelocity(parentBody.GetAngularVelocity());
|
||||
|
||||
// #536 - Physics objects in bramble dimensions not disabled on load
|
||||
// sectors wait 3 frames and then call OnSectorOccupantsUpdated
|
||||
// however we wait .1 real seconds which is longer
|
||||
// so we have to manually call this
|
||||
if (owRigidbody._simulateInSector != null)
|
||||
owRigidbody.OnSectorOccupantsUpdated();
|
||||
if (_body._simulateInSector) _body.OnSectorOccupantsUpdated();
|
||||
|
||||
if (SuspendUntilImpact)
|
||||
{
|
||||
// copied from OWRigidbody.Suspend
|
||||
_body._suspensionBody = parentBody;
|
||||
_body.MakeKinematic();
|
||||
_body._transform.parent = parentBody.transform;
|
||||
_body._suspended = true;
|
||||
_body._unsuspendNextUpdate = false;
|
||||
|
||||
// match velocity doesnt work so just make it not targetable
|
||||
_body.SetIsTargetable(false);
|
||||
|
||||
_impactSensor.OnImpact += OnImpact;
|
||||
Locator.GetProbe().OnAnchorProbe += OnAnchorProbe;
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_impactSensor) _impactSensor.OnImpact -= OnImpact;
|
||||
Locator.GetProbe().OnAnchorProbe -= OnAnchorProbe;
|
||||
}
|
||||
|
||||
private void OnImpact(ImpactData impact)
|
||||
{
|
||||
_body.UnsuspendImmediate(false);
|
||||
_body.SetIsTargetable(true);
|
||||
Destroy(this);
|
||||
}
|
||||
|
||||
private void OnAnchorProbe()
|
||||
{
|
||||
var attachedOWRigidbody = Locator.GetProbe().GetAttachedOWRigidbody(true);
|
||||
if (attachedOWRigidbody == _body)
|
||||
{
|
||||
OnImpact(null);
|
||||
|
||||
// copied from ProbeAnchor.AnchorToObject
|
||||
var _probeBody = Locator.GetProbe().GetOWRigidbody();
|
||||
var hitPoint = _probeBody.GetWorldCenterOfMass();
|
||||
if (attachedOWRigidbody.GetMass() < 100f)
|
||||
{
|
||||
Vector3 vector = _probeBody.GetVelocity() - attachedOWRigidbody.GetPointVelocity(_probeBody.GetPosition());
|
||||
attachedOWRigidbody.GetRigidbody().AddForceAtPosition(vector.normalized * 0.005f, hitPoint, ForceMode.Impulse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
Gizmos.DrawWireSphere(transform.position, Radius);
|
||||
|
||||
@ -195,6 +195,8 @@ namespace NewHorizons.Components.Stars
|
||||
|
||||
// Some effects use Locator.GetSunTransform so hopefully its fine to change it
|
||||
Locator._sunTransform = transform;
|
||||
|
||||
// TODO?: maybe also turn off star controller stuff (mainly proxy light) since idk if that can handle more than 1 being on
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,6 +75,12 @@ namespace NewHorizons.External.Modules.Props
|
||||
/// </summary>
|
||||
[DefaultValue(1f)] public float physicsRadius = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// If true, this detail will stay still until it touches something.
|
||||
/// Good for zero-g props.
|
||||
/// </summary>
|
||||
[DefaultValue(false)] public bool physicsSuspendUntilImpact = false;
|
||||
|
||||
/// <summary>
|
||||
/// Set to true if this object's lighting should ignore the effects of sunlight
|
||||
/// </summary>
|
||||
|
||||
@ -1339,6 +1339,11 @@
|
||||
"format": "float",
|
||||
"default": 1.0
|
||||
},
|
||||
"physicsSuspendUntilImpact": {
|
||||
"type": "boolean",
|
||||
"description": "If true, this detail will stay still until it touches something.\nGood for zero-g props.",
|
||||
"default": false
|
||||
},
|
||||
"ignoreSun": {
|
||||
"type": "boolean",
|
||||
"description": "Set to true if this object's lighting should ignore the effects of sunlight"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user