mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Zero-G Props (#308)
This commit is contained in:
commit
1b6e845bc0
@ -1,4 +1,5 @@
|
|||||||
using NewHorizons.Builder.General;
|
using NewHorizons.Builder.General;
|
||||||
|
using NewHorizons.Components;
|
||||||
using NewHorizons.External.Modules;
|
using NewHorizons.External.Modules;
|
||||||
using NewHorizons.Handlers;
|
using NewHorizons.Handlers;
|
||||||
using NewHorizons.Utility;
|
using NewHorizons.Utility;
|
||||||
@ -231,6 +232,14 @@ namespace NewHorizons.Builder.Props
|
|||||||
if (!detail.keepLoaded) GroupsBuilder.Make(prop, sector);
|
if (!detail.keepLoaded) GroupsBuilder.Make(prop, sector);
|
||||||
prop.SetActive(true);
|
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;
|
_detailInfoToCorrespondingSpawnedGameObject[detail] = prop;
|
||||||
|
|
||||||
return prop;
|
return prop;
|
||||||
|
|||||||
76
NewHorizons/Components/AddPhysics.cs
Normal file
76
NewHorizons/Components/AddPhysics.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
NewHorizons/External/Modules/PropModule.cs
vendored
18
NewHorizons/External/Modules/PropModule.cs
vendored
@ -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)
|
/// Should this detail stay loaded even if you're outside the sector (good for very large props)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool keepLoaded;
|
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]
|
[JsonObject]
|
||||||
|
|||||||
@ -1090,6 +1090,22 @@
|
|||||||
"keepLoaded": {
|
"keepLoaded": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Should this detail stay loaded even if you're outside the sector (good for very large props)"
|
"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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user