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:
Nick 2023-08-10 22:06:29 -04:00 committed by GitHub
commit 7438ed3076
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 81 additions and 9 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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
}
}
}

View File

@ -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>

View File

@ -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"