using System.Collections; using System.Collections.Generic; using UnityEngine; // Sci-Fi Ship Controller. Copyright (c) 2018-2023 SCSM Pty Ltd. All rights reserved. namespace SciFiShipController { /// /// A demo script that can be attached to an object to enable or disable the renderer at a given distance from the camera. /// [RequireComponent(typeof(MeshRenderer))] public class DemoSimpleLOD : MonoBehaviour { public float updateInterval = 1f; private float updateIntervalTimer = 0f; /// /// Use SetCamera(newCamera) at runtime. /// public Camera playerCamera; private Vector3 playerCameraPos; public float maxXZDistance = 50f; public float maxYDistance = 100f; private float sqrMaxXZDistance; private float sqrMaxYDistance; private float currentSqrXZDistance; private float currentSqrYDistance; private Vector3 meshToCameraOffset = Vector3.zero; private MeshRenderer meshRenderer; private Bounds meshBounds; private bool isInitialised = false; // Use this for initialization void Awake() { // Find the mesh renderer attached to this object if (TryGetComponent(out meshRenderer)) { // Get the bounds of the mesh meshBounds = meshRenderer.bounds; // Choose a random starting time for timer updateIntervalTimer = UnityEngine.Random.Range(0f, updateInterval); // Pre-calculate square distances sqrMaxXZDistance = maxXZDistance * maxXZDistance; sqrMaxYDistance = maxYDistance * maxYDistance; isInitialised = playerCamera != null; } } // Update is called once per frame void Update () { if (!isInitialised) { return; } // Increment the update interval timer updateIntervalTimer += Time.deltaTime; // Do an update if the update interval time has elapsed if (updateIntervalTimer >= updateInterval) { if (playerCamera != null) { // Decide whether or not to render the mesh bool renderMesh = false; playerCameraPos = playerCamera.transform.position; // Determine how far away from the mesh bounds we are on each axis // Get vector from centre of bounds to player camera position meshToCameraOffset = playerCameraPos - meshBounds.center; // Take absolute value of offset, then minus half of bounds size from it meshToCameraOffset.x = meshToCameraOffset.x > 0f ? (meshToCameraOffset.x - meshBounds.extents.x) : (-meshToCameraOffset.x - meshBounds.extents.x); // Discard negative values (they are inside of the bounds) meshToCameraOffset.x = meshToCameraOffset.x > 0f ? meshToCameraOffset.x : 0f; // Take absolute value of offset, then minus half of bounds size from it meshToCameraOffset.y = meshToCameraOffset.y > 0f ? (meshToCameraOffset.y - meshBounds.extents.y) : (-meshToCameraOffset.y - meshBounds.extents.y); // Discard negative values (they are inside of the bounds) meshToCameraOffset.y = meshToCameraOffset.y > 0f ? meshToCameraOffset.y : 0f; // Take absolute value of offset, then minus half of bounds size from it meshToCameraOffset.z = meshToCameraOffset.z > 0f ? (meshToCameraOffset.z - meshBounds.extents.z) : (-meshToCameraOffset.z - meshBounds.extents.z); // Discard negative values (they are inside of the bounds) meshToCameraOffset.z = meshToCameraOffset.z > 0f ? meshToCameraOffset.z : 0f; // Get square distances to edge of mesh bounds currentSqrXZDistance = (meshToCameraOffset.x * meshToCameraOffset.x) + (meshToCameraOffset.z * meshToCameraOffset.z); currentSqrYDistance = (meshToCameraOffset.y * meshToCameraOffset.y); // Compare distances to max distances to determine whether or not mesh should be rendered renderMesh = currentSqrXZDistance < sqrMaxXZDistance && currentSqrYDistance < sqrMaxYDistance; // If the render setting does not match what we have decided, change it if (meshRenderer.enabled != renderMesh) { meshRenderer.enabled = renderMesh; } } // Reset the update interval timer updateIntervalTimer = 0f; } } /// /// Used to set the camera at runtime. /// /// public void SetCamera (Camera newPlayerCamera) { playerCamera = newPlayerCamera; isInitialised = playerCamera != null; } } }