Zero-G Props (#308)

This commit is contained in:
Will Corby 2023-02-04 13:56:32 -08:00 committed by GitHub
commit 1b6e845bc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 119 additions and 0 deletions

View File

@ -1,4 +1,5 @@
using NewHorizons.Builder.General;
using NewHorizons.Components;
using NewHorizons.External.Modules;
using NewHorizons.Handlers;
using NewHorizons.Utility;
@ -231,6 +232,14 @@ namespace NewHorizons.Builder.Props
if (!detail.keepLoaded) GroupsBuilder.Make(prop, sector);
prop.SetActive(true);
if (detail.hasPhysics)
{
var addPhysics = prop.AddComponent<AddPhysics>();
addPhysics.Sector = sector;
addPhysics.Mass = detail.physicsMass;
addPhysics.Radius = detail.physicsRadius;
}
_detailInfoToCorrespondingSpawnedGameObject[detail] = prop;
return prop;

View File

@ -0,0 +1,76 @@
using System.Collections;
using UnityEngine;
namespace NewHorizons.Components;
/// <summary>
/// properly add physics to a detail
/// </summary>
[DisallowMultipleComponent]
public class AddPhysics : MonoBehaviour
{
[Tooltip("The sector that the rigidbody will be simulated in, or none for it to always be on.")]
public Sector Sector;
[Tooltip("The mass of the physics object.\n" +
"Most pushable props use the default value, which matches the player mass.")]
public float Mass = 0.001f;
[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;
private IEnumerator Start()
{
yield return new WaitForSeconds(.1f);
var parentBody = GetComponentInParent<OWRigidbody>();
// hack: make all mesh colliders convex
// triggers are already convex
// prints errors for non readable meshes but whatever
foreach (var meshCollider in GetComponentsInChildren<MeshCollider>(true))
meshCollider.convex = true;
var bodyGo = new GameObject($"{name}_Body");
bodyGo.SetActive(false);
bodyGo.transform.position = transform.position;
bodyGo.transform.rotation = transform.rotation;
var owRigidbody = bodyGo.AddComponent<OWRigidbody>();
owRigidbody._simulateInSector = Sector;
bodyGo.layer = LayerMask.NameToLayer("PhysicalDetector");
bodyGo.tag = "DynamicPropDetector";
// this collider is not included in groups. oh well
bodyGo.AddComponent<SphereCollider>().radius = Radius;
bodyGo.AddComponent<DynamicForceDetector>();
bodyGo.AddComponent<DynamicFluidDetector>();
var impactSensor = bodyGo.AddComponent<ImpactSensor>();
var audioSource = bodyGo.AddComponent<AudioSource>();
audioSource.maxDistance = 30;
audioSource.dopplerLevel = 0;
audioSource.rolloffMode = AudioRolloffMode.Custom;
audioSource.playOnAwake = false;
audioSource.spatialBlend = 1;
var owAudioSource = bodyGo.AddComponent<OWAudioSource>();
owAudioSource._audioSource = audioSource;
owAudioSource._track = OWAudioMixer.TrackName.Environment;
var objectImpactAudio = bodyGo.AddComponent<ObjectImpactAudio>();
objectImpactAudio._minPitch = 0.4f;
objectImpactAudio._maxPitch = 0.6f;
objectImpactAudio._impactSensor = impactSensor;
bodyGo.SetActive(true);
transform.parent = bodyGo.transform;
owRigidbody.SetMass(Mass);
owRigidbody.SetVelocity(parentBody.GetPointVelocity(transform.position));
Destroy(this);
}
private void OnDrawGizmosSelected()
{
Gizmos.DrawWireSphere(transform.position, Radius);
}
}

View File

@ -229,6 +229,24 @@ namespace NewHorizons.External.Modules
/// Should this detail stay loaded even if you're outside the sector (good for very large props)
/// </summary>
public bool keepLoaded;
/// <summary>
/// Should this object dynamically move around?
/// This tries to make all mesh colliders convex, as well as adding a sphere collider in case the detail has no others.
/// </summary>
public bool hasPhysics;
/// <summary>
/// The mass of the physics object.
/// Most pushable props use the default value, which matches the player mass.
/// </summary>
[DefaultValue(0.001f)] public float physicsMass = 0.001f;
/// <summary>
/// The radius that the added sphere collider will use for physics collision.
/// If there's already good colliders on the detail, you can make this 0.
/// </summary>
[DefaultValue(1f)] public float physicsRadius = 1f;
}
[JsonObject]

View File

@ -1090,6 +1090,22 @@
"keepLoaded": {
"type": "boolean",
"description": "Should this detail stay loaded even if you're outside the sector (good for very large props)"
},
"hasPhysics": {
"type": "boolean",
"description": "Should this object dynamically move around?\nThis tries to make all mesh colliders convex, as well as adding a sphere collider in case the detail has no others."
},
"physicsMass": {
"type": "number",
"description": "The mass of the physics object.\nMost pushable props use the default value, which matches the player mass.",
"format": "float",
"default": 0.001
},
"physicsRadius": {
"type": "number",
"description": "The radius that the added sphere collider will use for physics collision.\nIf there's already good colliders on the detail, you can make this 0.",
"format": "float",
"default": 1.0
}
}
},