This commit is contained in:
2025-09-17 18:56:28 +08:00
commit 54c72710a5
5244 changed files with 5717609 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
using UnityEngine;
using System.Collections;
namespace DestroyIt
{
/// <summary>
/// This script provides extra features to the BulbFlash particle effect.
/// It removes the "Powered" tag from its parent, and removes the PoweredTag
/// script which manages the parent's powered state.
/// </summary>
public class BulbFlash : MonoBehaviour
{
void OnEnable()
{
// start a coroutine because we want to wait until the particle effect has had a
// chance to be a child under something.
StartCoroutine(RemovePower());
}
IEnumerator RemovePower()
{
// wait one frame
yield return 0;
Transform parent = this.transform.parent;
if (parent != null)
{
parent.gameObject.RemoveTag(Tag.Powered);
parent.gameObject.RemoveComponent<PoweredTag>();
}
StopCoroutine("RemovePower");
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 30d4ab45655a90647910eb3f46ce8013
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@@ -0,0 +1,43 @@
using UnityEngine;
using UnityEngine.SceneManagement;
#if UNITY_EDITOR
using UnityEditor.SceneManagement;
#endif
namespace DestroyIt
{
public class DemoNavigation : MonoBehaviour
{
private readonly LoadSceneParameters lsp = new LoadSceneParameters { loadSceneMode = LoadSceneMode.Single, localPhysicsMode = LocalPhysicsMode.None };
public void Start()
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
public void LoadMainScenariosDemoScene()
{
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
#if UNITY_EDITOR
EditorSceneManager.LoadSceneAsyncInPlayMode("Assets/DestroyIt/Demos (safe to delete)/Main Scenarios Scene.unity", lsp);
#else
SceneManager.LoadSceneAsync("Assets/DestroyIt/Demos (safe to delete)/Main Scenarios Scene.unity", lsp);
#endif
}
public void LoadSUVShowcaseDemoScene()
{
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
#if UNITY_EDITOR
EditorSceneManager.LoadSceneAsyncInPlayMode("Assets/DestroyIt/Demos (safe to delete)/SUV Showcase Scene/SUV Showcase Scene.unity", lsp);
#else
SceneManager.LoadSceneAsync("Assets/DestroyIt/Demos (safe to delete)/SUV Showcase Scene/SUV Showcase Scene.unity", lsp);
#endif
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d2026aafc48b78744acae1d6a3a0ed23
timeCreated: 1495512015
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,37 @@
using UnityEngine;
namespace DestroyIt
{
public class DisableAfter : MonoBehaviour
{
public float seconds; // seconds to wait before disabling this game object.
public bool removeScript; // remove this script after disabled?
private float timeLeft;
private bool isInitialized;
void Start()
{
timeLeft = seconds;
isInitialized = true;
}
void OnEnable()
{
timeLeft = seconds;
}
void Update()
{
if (!isInitialized) return;
timeLeft -= Time.deltaTime;
if (timeLeft <= 0)
{
this.gameObject.SetActive(false);
if (removeScript)
Destroy(this);
}
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4415e549706669c419f43ca86a7843e5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@@ -0,0 +1,28 @@
using System.Collections.Generic;
using UnityEngine;
namespace DestroyIt
{
public class DynamicDestructible : MonoBehaviour
{
public GameObject objectToSpawn;
public GameObject destroyedPrefab;
public List<MaterialMapping> materialsToReplace;
public void Start()
{
if (objectToSpawn != null)
{
GameObject go = Instantiate(objectToSpawn, transform, false);
Destructible dest = go.AddComponent<Destructible>();
if (destroyedPrefab != null)
{
dest.destroyedPrefab = destroyedPrefab;
if (materialsToReplace != null && materialsToReplace.Count > 0)
dest.replaceMaterials = materialsToReplace;
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c9d79d9038467ae45ab07e2d09ded8d0
timeCreated: 1491084134
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,174 @@
using System.Collections.Generic;
using UnityEngine;
namespace DestroyIt
{
/// <summary>
/// Attach this script to any object that has a transparent shader on its mesh renderer.
///
/// Also, you can attach this script to a destroyed prefab that has child "debris" objects. Example: a broken wall object that
/// is composed of multiple child rubble pieces. This script will fade-out and clean up all the child rubble pieces for you.
/// </summary>
public class FadeOut : MonoBehaviour
{
[Range(0f, 30f)]
public float afterSeconds = 6f; // seconds to wait before starting the fade.
[Range(0f, 10f)]
public float fadeLength = 2f; // how long (in seconds) to fade-out objects before destroying them.
private List<ObjectToFade> objectsToFade;
private float timeLeft;
private bool isInitialized;
private bool isBeingDestroyed;
void Start()
{
timeLeft = afterSeconds;
isInitialized = true;
MeshRenderer[] meshRenderers = transform.GetComponentsInChildren<MeshRenderer>();
if (meshRenderers.Length == 0)
{
Debug.LogWarning("FadeOut: No MeshRenderers found under \"" + transform.name + "\". Cannot fade out.");
Destroy(this);
}
else
{
// Collect all the objects to fade into a list.
objectsToFade = new List<ObjectToFade>();
for (int i = 0; i < meshRenderers.Length; i++)
{
objectsToFade.Add(new ObjectToFade()
{
MeshRenderer = meshRenderers[i],
Colliders = meshRenderers[i].GetComponentsInChildren<Collider>(),
Rigidbody = meshRenderers[i].GetComponent<Rigidbody>(),
CanBeFaded = true
});
}
}
}
void OnEnable()
{
timeLeft = afterSeconds;
}
void Update()
{
if (!isInitialized || isBeingDestroyed) return;
timeLeft -= Time.deltaTime;
if (timeLeft <= 0)
{
if (timeLeft <= -1*fadeLength)
{
isBeingDestroyed = true;
Destroy(transform.gameObject);
}
else
Fade();
}
}
private void StripColliders(ObjectToFade obj)
{
// Try to strip Colliders
if (obj.Colliders.Length == 0)
obj.IsStripped = true;
else
{
for (int i=0; i<obj.Colliders.Length; i++)
Destroy(obj.Colliders[i]);
obj.IsStripped = true;
}
}
/// <summary>Fade this object and its children one step towards invisible.</summary>
private void Fade()
{
foreach (ObjectToFade obj in objectsToFade)
{
if (obj.MeshRenderer == null) continue;
// Try to strip Rigidbody and Colliders
if (!obj.IsStripped)
{
if (obj.Rigidbody == null)
{
// No Rigidbody, so try to strip Colliders
StripColliders(obj);
}
else if (obj.Rigidbody.IsSleeping())
{
// Rigidbody is sleeping, so destroy it and then strip Colliders
Destroy(obj.Rigidbody);
StripColliders(obj);
}
// Else Rigidbody isn't sleeping, so leave it alone for now.
}
if (!obj.IsTransparencyChecked)
{
Material[] mats = obj.MeshRenderer.materials;
for (int i = 0; i < mats.Length; i++)
{
// If the material on the object doesn't have a transparency property...
if (!mats[i].HasProperty("_Transparency"))
{
// Try to find the appropriate "Transparent" version of its shader.
mats[i].shader = mats[i].shader.GetTransparentVersion();
mats[i].SetFloat("_Transparency", 0f);
}
}
obj.MeshRenderer.materials = mats;
obj.IsTransparencyChecked = true;
}
for (int i = 0; i < obj.MeshRenderer.materials.Length; i++)
{
float currTransparency = obj.MeshRenderer.materials[i].GetFloat("_Transparency");
if (currTransparency >= 1f)
continue;
currTransparency += Mathf.Clamp01(Time.deltaTime / fadeLength);
obj.MeshRenderer.materials[i].SetFloat("_Transparency", currTransparency);
}
}
}
}
public class ObjectToFade
{
public MeshRenderer MeshRenderer { get; set; }
/// <summary>Are the rigidbody and colliders stripped from this object?</summary>
public bool IsStripped { get; set; }
public bool CanBeFaded { get; set; }
public Rigidbody Rigidbody { get; set; }
public Collider[] Colliders { get; set; }
public bool IsTransparencyChecked { get; set; }
}
public static class ShaderExtensions
{
public static Shader GetTransparentVersion(this Shader currentShader)
{
Shader transShader;
// Try to find the appropriate "Transparent" version of the shader.
if (currentShader.name.Contains("DestroyIt/"))
transShader = Shader.Find(currentShader.name.Replace("DestroyIt/", "DestroyIt/Transparent"));
else
transShader = Shader.Find("DestroyIt/Transparent" + currentShader.name.Replace(" ", ""));
if (transShader != null)
return transShader;
// Transparent version of shader not found. Try to fallback on DestroyIt/TransparentDiffuse.
transShader = Shader.Find("DestroyIt/TransparentDiffuse");
if (transShader != null)
return transShader;
// if no transparency shader could be found, log an error and destroy this script
Debug.LogError("DestroyIt: No progressive damage transparency shader could be found. Cannot fade out material with shader \"" + currentShader.name + "\" object.");
return currentShader;
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7eb932bf1c55c054a9a0c925e5040a2f
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@@ -0,0 +1,58 @@
using UnityEngine;
namespace DestroyIt
{
public class Follow : MonoBehaviour
{
public Transform objectToFollow;
public FacingDirection facingDirection = FacingDirection.FollowedObject;
[HideInInspector]
public bool isPositionFixed;
[HideInInspector]
public Vector3 fixedFromPosition = Vector3.zero;
[HideInInspector]
public float fixedDistance;
void Start()
{
if (objectToFollow == null)
{
Debug.Log("[DestroyIt-Follow]: No transform was provided. Nothing to follow. Removing script...");
Destroy(this);
}
}
void LateUpdate()
{
if (objectToFollow != null)
{
if (isPositionFixed)
{
// get point along line from player to shockwave start
Vector3 followPoint = objectToFollow.position.LerpByDistance(fixedFromPosition, fixedDistance);
transform.position = followPoint;
}
else
transform.position = objectToFollow.position;
switch (facingDirection)
{
case FacingDirection.FollowedObject:
transform.LookAt(objectToFollow);
break;
case FacingDirection.FixedPosition:
transform.LookAt(fixedFromPosition);
break;
}
}
}
void OnDrawGizmos()
{
if (isPositionFixed && objectToFollow != null)
Gizmos.DrawLine(fixedFromPosition, objectToFollow.position);
Gizmos.DrawWireSphere(transform.position, .5f);
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d4f42c95654649941acc8d8566df4024
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@@ -0,0 +1,116 @@
using UnityEngine;
using UnityEngine.UI;
namespace DestroyIt
{
/// <summary>This script provides performance and basic control info for the demo scene.</summary>
public class HeadsUpDisplay : MonoBehaviour
{
public RectTransform hud;
[Tooltip("The number of times per second the UI updates.")]
public float updateRate = 15f;
public Text destroyedPrefabsText;
public Text destroyedParticlesText;
public Text debrisCountText;
public Image reticleImage;
public Image selectedWeapon;
public Sprite unknownWeapon;
public Sprite assaultRifle;
public Sprite rocketLauncher;
public Sprite fireAxe;
public Sprite cannon;
public Sprite nuke;
public Sprite wrench;
private float nextUpdate;
private void Start()
{
if (DestructionManager.Instance != null)
{
DestructionManager.Instance.DestroyedPrefabCounterChangedEvent += OnDestroyedPrefabCounterChanged;
DestructionManager.Instance.ActiveDebrisCounterChangedEvent += OnActiveDebrisCounterChanged;
}
if (ParticleManager.Instance != null)
ParticleManager.Instance.ActiveParticlesCounterChangedEvent += OnActiveParticlesCounterChanged;
OnDestroyedPrefabCounterChanged();
OnActiveDebrisCounterChanged();
OnActiveParticlesCounterChanged();
}
private void OnDisable()
{
// Unregister the event listeners when disabled/destroyed. Very important to prevent memory leaks due to orphaned event listeners!
if (DestructionManager.Instance != null)
{
DestructionManager.Instance.DestroyedPrefabCounterChangedEvent -= OnDestroyedPrefabCounterChanged;
DestructionManager.Instance.ActiveDebrisCounterChangedEvent -= OnActiveDebrisCounterChanged;
}
if (ParticleManager.Instance != null)
ParticleManager.Instance.ActiveParticlesCounterChangedEvent -= OnActiveParticlesCounterChanged;
}
private void OnDestroyedPrefabCounterChanged()
{
// Destroyed Prefab Updates
destroyedPrefabsText.text = "Destroyed Prefabs (last " + DestructionManager.Instance.withinSeconds + "s): " + DestructionManager.Instance.DestroyedPrefabCounter.Count;
}
private void OnActiveParticlesCounterChanged()
{
// Destroyed Particles Updates
destroyedParticlesText.text = "Destroyed Particles (last " + ParticleManager.Instance.withinSeconds + "s): " + ParticleManager.Instance.ActiveParticles.Length;
}
private void OnActiveDebrisCounterChanged()
{
// Debris Count Updates
debrisCountText.text = "Debris Count: " + DestructionManager.Instance.ActiveDebrisCount;
}
private void Update()
{
if (!(Time.time > nextUpdate)) return;
nextUpdate = Time.time + (1.0f / updateRate);
// HUD Visibility Updates
int showHud = PlayerPrefs.GetInt("ShowHud", -1);
hud.gameObject.SetActive(showHud == -1);
// Reticle HUD Updates
int showReticle = PlayerPrefs.GetInt("ShowReticle", -1);
reticleImage.gameObject.SetActive(showReticle == -1);
if (InputManager.Instance != null)
{
// Selected Weapon Silhouette Update
switch (InputManager.Instance.SelectedWeapon)
{
case WeaponType.Gun:
selectedWeapon.sprite = assaultRifle;
break;
case WeaponType.Rocket:
selectedWeapon.sprite = rocketLauncher;
break;
case WeaponType.Melee:
selectedWeapon.sprite = fireAxe;
break;
case WeaponType.Cannonball:
selectedWeapon.sprite = cannon;
break;
case WeaponType.Nuke:
selectedWeapon.sprite = nuke;
break;
case WeaponType.RepairWrench:
selectedWeapon.sprite = wrench;
break;
default: // This should never happen.
selectedWeapon.sprite = unknownWeapon;
break;
}
}
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 19f260da355be4e49b2b66749b83875d
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@@ -0,0 +1,104 @@
using System.Collections.Generic;
using UnityEngine;
namespace DestroyIt
{
public class MeleeArea : MonoBehaviour
{
public int damageAmount = 30;
public int repairAmount = 20;
public float meleeRadius = 1.3f;
public float additionalForceAmount = 150f;
public float additionalForceRadius = 2f;
public ParticleSystem repairEffect;
public void OnMeleeDamage()
{
Collider[] objectsInRange = Physics.OverlapSphere(transform.position, meleeRadius);
List<Destructible> damagedObjects = new List<Destructible>(); // Keep track of what objects have been damaged so we don't do damage multiple times per collider.
bool hasPlayedHitEffect = false;
foreach (Collider col in objectsInRange)
{
// Ignore terrain colliders
if (col is TerrainCollider) continue;
// Ignore trigger colliders
if (col.isTrigger) continue;
// Ignore the player's character controller (ie, don't allow hitting yourself)
if (col is CharacterController && col.tag == "Player") continue;
if (!hasPlayedHitEffect) // Only play the hit effect once per melee attack.
{
// Play hit effects
HitEffects hitEffects = col.gameObject.GetComponentInParent<HitEffects>();
if (hitEffects != null && hitEffects.effects.Count > 0)
hitEffects.PlayEffect(HitBy.Axe, transform.position, transform.forward * -1);
hasPlayedHitEffect = true;
}
// Apply impact force to rigidbody hit
Rigidbody rbody = col.attachedRigidbody;
if (rbody != null)
rbody.AddForceAtPosition(transform.forward * 3f, transform.position, ForceMode.Impulse);
// Apply damage if object hit was Destructible
// Only do this for active and enabled Destructible scripts found in parent objects
// Special Note: Destructible scripts are turned off on terrain trees by default (to save resources), so we will make an exception for them and process the hit anyway
Destructible[] destObjs = col.gameObject.GetComponentsInParent<Destructible>(false);
foreach (Destructible destObj in destObjs)
{
if (damagedObjects.Contains(destObj)) continue;
if (!destObj.isActiveAndEnabled && !destObj.isTerrainTree) continue;
damagedObjects.Add(destObj);
ImpactDamage meleeImpact = new ImpactDamage() { DamageAmount = damageAmount, AdditionalForce = additionalForceAmount,
AdditionalForcePosition = transform.position, AdditionalForceRadius = additionalForceRadius };
destObj.ApplyDamage(meleeImpact);
}
}
}
private void OnMeleeRepair()
{
Collider[] objectsInRange = Physics.OverlapSphere(transform.position, meleeRadius);
List<Destructible> repairedObjects = new List<Destructible>(); // Keep track of what objects have been repaired so we don't repair multiple times per collider.
bool hasPlayedRepairEffect = false;
// Repair items within range
foreach (Collider col in objectsInRange)
{
// Ignore terrain colliders
if (col is TerrainCollider) continue;
// Ignore trigger colliders
if (col.isTrigger) continue;
// Ignore the player's character controller (ie, don't allow hitting yourself)
if (col is CharacterController && col.tag == "Player") continue;
// Repair object if it is a Destructible
Destructible destObj = col.gameObject.GetComponentInParent<Destructible>();
if (destObj != null && !repairedObjects.Contains(destObj) && destObj.CurrentHitPoints < destObj.TotalHitPoints && destObj.canBeRepaired)
{
repairedObjects.Add(destObj);
destObj.RepairDamage(repairAmount);
// Play repair particle effect
if (repairEffect != null && !hasPlayedRepairEffect)
{
repairEffect.GetComponent<ParticleSystem>().Clear(true);
repairEffect.Play(true);
hasPlayedRepairEffect = true;
}
}
}
}
private void OnDrawGizmos()
{
Gizmos.DrawWireSphere(transform.position, meleeRadius);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d65e0b9e2f047aa408e2fe38b55123e2
timeCreated: 1482099782
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,31 @@
using UnityEngine;
namespace DestroyIt
{
public class OpenCloseChest : MonoBehaviour
{
void Start()
{
InvokeRepeating("SwapOpenClose", 3.5f, 3.5f);
}
public void SwapOpenClose()
{
HingeJoint joint = this.GetComponent<HingeJoint>();
if (joint != null)
{
joint.motor = new JointMotor()
{
targetVelocity = -1 * joint.motor.targetVelocity,
force = 10
};
joint.useMotor = true;
GetComponent<Rigidbody>().WakeUp();
}
else
Destroy(this);
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1a708abe01b83cd4b97a5da08881fbcd
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@@ -0,0 +1,18 @@
using UnityEngine;
namespace DestroyIt
{
public class PowerSource : MonoBehaviour
{
public bool hasPower = true;
public bool cutPowerOnRapidTilt = true;
public float tiltThreshold = 1.5f;
void Update()
{
// Cut power when object is tilted suddenly (angular velocity goes up)
if (cutPowerOnRapidTilt && hasPower && GetComponent<Rigidbody>() != null && GetComponent<Rigidbody>().angularVelocity.magnitude > tiltThreshold)
Destroy(this);
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f6d069f57f5e5e644a174e37962e8e7c
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@@ -0,0 +1,64 @@
using UnityEngine;
using System.Linq;
using System.Collections.Generic;
namespace DestroyIt
{
/// <summary>
/// This script checks if an object that contains lights is getting power from its
/// parent, determined by whether the parent is tagged as "Powered".
/// </summary>
public class PoweredLight : MonoBehaviour
{
public PowerSource powerSource; // The source of power for this light.
public MeshRenderer emissiveMesh; // Any additional mesh for which to turn off the emissive property of its shader when this light is unpowered. (For example, the lampshade of a light bulb.)
public Material emissiveOffMaterial;
private List<Light> lights;
private Transform parent;
private bool isPowered;
void Start()
{
isPowered = false;
lights = gameObject.GetComponentsInChildren<Light>().ToList();
if (lights.Count == 0)
{
Debug.Log("PoweredLight: No Light components found on [" + gameObject.name + "]. Removing script.");
Destroy(this);
}
parent = this.gameObject.transform.parent;
if (parent == null)
{
Debug.Log("PoweredLight: No parent found for [" + gameObject.name + "]. Removing script.");
Destroy(this);
}
}
void Update()
{
// remove any light from the list that is null or missing.
lights.RemoveAll(x => x == null);
// find out if we have power from the parent.
if (parent.gameObject.HasTag(Tag.Powered))
isPowered = true;
else
isPowered = false;
if (isPowered)
{
for (int i = 0; i < lights.Count; i++)
lights[i].enabled = true;
}
else
{
for (int i = 0; i < lights.Count; i++)
lights[i].enabled = false;
// Turn off emissive material
emissiveMesh.material = emissiveOffMaterial;
}
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cd8d816adf0b1274d8219452269ed1e1
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@@ -0,0 +1,17 @@
using UnityEngine;
namespace DestroyIt
{
public class PoweredTag : MonoBehaviour
{
public PowerSource powerSource;
void Update()
{
if (powerSource == null || !powerSource.hasPower)
gameObject.RemoveTag(Tag.Powered);
else
gameObject.AddTag(Tag.Powered);
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a33bf757133652244a37eec56402e1a1
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@@ -0,0 +1,56 @@
using UnityEngine;
namespace DestroyIt
{
/// <summary>
/// Place this script on your destroyed prefab, at the highest parent level.
/// When your destroyed prefab spawns in, it will wait for a while and then reset itself to whatever game object you have assigned to resetToPrefab.
/// </summary>
public class ResetDestructible : MonoBehaviour
{
[Tooltip("The game object prefab you want to reset this destructible object to after it has been destroyed. (Usually a Pristine version of this destroyed object.)")]
public GameObject resetToPrefab;
[Tooltip("The minimum amount of time to wait (in seconds) before resetting the destructible object. (3600 seconds = 1 hour)")]
public float minWaitSeconds = 30.0f;
[Tooltip("The maximum amount of time to wait (in seconds) before resetting the destructible object. (3600 seconds = 1 hour)")]
public float maxWaitSeconds = 45.0f;
private float _timeLeft;
private bool _isInitialized;
void Start()
{
if (resetToPrefab == null)
{
Debug.LogError("ResetDestructible Script: You need to assign a prefab to the [resetToPrefab] field.");
Destroy(this);
return;
}
// Randomly determine when to reset the destroyed object, based on the min/max wait seconds.
_timeLeft = maxWaitSeconds <= minWaitSeconds ? 0f : Random.Range(minWaitSeconds, maxWaitSeconds);
Debug.Log($"[{gameObject.name}] will be reset in approximately {Mathf.RoundToInt(_timeLeft)} seconds.");
_isInitialized = true;
}
void Update()
{
if (!_isInitialized) return;
_timeLeft -= Time.deltaTime;
if (_timeLeft <= 0)
{
// Spawn the resetToPrefab object after the required wait time.
GameObject go = Instantiate(resetToPrefab, transform.position, transform.rotation, transform.parent);
go.transform.localScale = transform.localScale; // in case the destroyed object was scaled in the scene
Debug.Log($"[{gameObject.name}] has been reset to [{resetToPrefab.name}].");
Destroy(gameObject); // remove this gameObject to cleanup the scene
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f20d9c5d4088ba74f9a6c389f11f5384
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,22 @@
using UnityEngine;
namespace DestroyIt
{
public class RocketLoading : MonoBehaviour
{
public bool isLoaded = true; // start off with the rocket loaded into the launcher
private void OnEnable()
{
if (isLoaded) // if the rocket is already loaded, position the game object so it is in the launcher.
transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, 0.74f);
else // if rocket is not currently loaded, play the rocket loading animation
{
Animation anim = gameObject.GetComponent<Animation>();
if (anim != null)
anim.Play("Rocket Loading");
isLoaded = true;
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: afd04edbf4cf42949a3c5e4d46ff5e98
timeCreated: 1477871320
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: