Insanely huge initial commit

This commit is contained in:
2026-02-21 17:04:05 -08:00
parent 9cdd36191a
commit 613d75914a
22525 changed files with 4035207 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c20c27063571a2642918daa9b7b087cf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,224 @@
using System.Collections;
#if MM_CINEMACHINE
using Cinemachine;
#endif
using UnityEngine;
using UnityEngine.Events;
namespace MoreMountains.Tools
{
/// <summary>
/// An abstract class that lets you define a zone that, when entered, enables a virtual camera, and takes care
/// of all the boilerplate setup
/// </summary>
[AddComponentMenu("")]
[ExecuteAlways]
public abstract class MMCinemachineZone : MonoBehaviour
{
public enum Modes { Enable, Priority }
[Header("Virtual Camera")]
/// whether to enable/disable virtual cameras, or to play on their priority for transitions
[Tooltip("whether to enable/disable virtual cameras, or to play on their priority for transitions")]
public Modes Mode = Modes.Enable;
/// whether or not the camera in this zone should start active
[Tooltip("whether or not the camera in this zone should start active")]
public bool CameraStartsActive = false;
#if MM_CINEMACHINE
/// the virtual camera associated to this zone (will try to grab one in children if none is set)
[Tooltip("the virtual camera associated to this zone (will try to grab one in children if none is set)")]
public CinemachineVirtualCamera VirtualCamera;
#endif
/// when in priority mode, the priority this camera should have when the zone is active
[Tooltip("when in priority mode, the priority this camera should have when the zone is active")]
[MMEnumCondition("Mode", (int)Modes.Priority)]
public int EnabledPriority = 10;
/// when in priority mode, the priority this camera should have when the zone is inactive
[Tooltip("when in priority mode, the priority this camera should have when the zone is inactive")]
[MMEnumCondition("Mode", (int)Modes.Priority)]
public int DisabledPriority = 0;
[Header("Collisions")]
/// a layermask containing all the layers that should activate this zone
[Tooltip("a layermask containing all the layers that should activate this zone")]
public LayerMask TriggerMask;
[Header("Confiner Setup")]
/// whether or not the zone should auto setup its camera's confiner on start - alternative is to manually click the ManualSetupConfiner, or do your own setup
[Tooltip("whether or not the zone should auto setup its camera's confiner on start - alternative is to manually click the ManualSetupConfiner, or do your own setup")]
public bool SetupConfinerOnStart = false;
/// a debug button used to setup the confiner on click
[MMInspectorButton("ManualSetupConfiner")]
public bool GenerateConfinerSetup;
[Header("Events")]
/// a UnityEvent to trigger when entering the zone
[Tooltip("a UnityEvent to trigger when entering the zone")]
public UnityEvent OnEnterZoneEvent;
/// a UnityEvent to trigger when exiting the zone
[Tooltip("a UnityEvent to trigger when exiting the zone")]
public UnityEvent OnExitZoneEvent;
[Header("Debug")]
/// whether or not to draw shape gizmos to help visualize the zone's bounds
[Tooltip("whether or not to draw shape gizmos to help visualize the zone's bounds")]
public bool DrawGizmos = true;
/// the color of the gizmos to draw in edit mode
[Tooltip("the color of the gizmos to draw in edit mode")]
public Color GizmosColor;
protected GameObject _confinerGameObject;
protected Vector3 _gizmoSize;
#if MM_CINEMACHINE
/// <summary>
/// On Awake we proceed to init if app is playing
/// </summary>
protected virtual void Awake()
{
AlwaysInitialization();
if (!Application.isPlaying)
{
return;
}
Initialization();
}
/// <summary>
/// On Awake we initialize our collider
/// </summary>
protected virtual void AlwaysInitialization()
{
InitializeCollider();
}
/// <summary>
/// On init we grab our virtual camera
/// </summary>
protected virtual void Initialization()
{
if (VirtualCamera == null)
{
VirtualCamera = GetComponentInChildren<CinemachineVirtualCamera>();
}
if (VirtualCamera == null)
{
Debug.LogWarning("[MMCinemachineZone2D] " + this.name + " : no virtual camera is attached to this zone. Set one in its inspector.");
}
if (SetupConfinerOnStart)
{
SetupConfinerGameObject();
}
}
/// <summary>
/// On Start we setup the confiner
/// </summary>
protected virtual void Start()
{
if (!Application.isPlaying)
{
return;
}
if (SetupConfinerOnStart)
{
SetupConfiner();
}
StartCoroutine(EnableCamera(CameraStartsActive, 1));
}
/// <summary>
/// Describes what happens when initializing the collider
/// </summary>
protected abstract void InitializeCollider();
/// <summary>
/// Describes what happens when setting up the confiner
/// </summary>
protected abstract void SetupConfiner();
/// <summary>
/// A method used to manually create a confiner
/// </summary>
protected virtual void ManualSetupConfiner()
{
Initialization();
SetupConfiner();
}
/// <summary>
/// Creates an object to host the confiner
/// </summary>
protected virtual void SetupConfinerGameObject()
{
// we remove the object if needed
Transform child = this.transform.Find("Confiner");
if (child != null)
{
DestroyImmediate(child.gameObject);
}
// we create an empty child object
_confinerGameObject = new GameObject();
_confinerGameObject.transform.localPosition = Vector3.zero;
_confinerGameObject.transform.SetParent(this.transform);
_confinerGameObject.name = "Confiner";
}
/// <summary>
/// An extra test you can override to add extra collider conditions
/// </summary>
/// <param name="collider"></param>
/// <returns></returns>
protected virtual bool TestCollidingGameObject(GameObject collider)
{
return true;
}
/// <summary>
/// Enables the camera, either via enabled state or priority
/// </summary>
/// <param name="state"></param>
/// <param name="frames"></param>
/// <returns></returns>
protected virtual IEnumerator EnableCamera(bool state, int frames)
{
if (VirtualCamera == null)
{
yield break;
}
if (frames > 0)
{
yield return MMCoroutine.WaitForFrames(frames);
}
if (Mode == Modes.Enable)
{
VirtualCamera.enabled = state;
}
else if (Mode == Modes.Priority)
{
VirtualCamera.Priority = state ? EnabledPriority : DisabledPriority;
}
}
/// <summary>
/// On Reset we initialize our gizmo color
/// </summary>
protected virtual void Reset()
{
GizmosColor = MMColors.RandomColor();
GizmosColor.a = 0.2f;
}
#endif
}
}

View File

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

View File

@@ -0,0 +1,163 @@
#if MM_CINEMACHINE
using Cinemachine;
#endif
using UnityEngine;
namespace MoreMountains.Tools
{
/// <summary>
/// 2D Implementation of the CinemachineZone abstract class
/// </summary>
[RequireComponent(typeof(Collider2D))]
public class MMCinemachineZone2D : MMCinemachineZone
{
protected Collider2D _collider2D;
protected Collider2D _confinerCollider2D;
protected Rigidbody2D _confinerRigidbody2D;
protected CompositeCollider2D _confinerCompositeCollider2D;
protected BoxCollider2D _boxCollider2D;
protected CircleCollider2D _circleCollider2D;
protected PolygonCollider2D _polygonCollider2D;
#if MM_CINEMACHINE
protected CinemachineConfiner _cinemachineConfiner;
/// <summary>
/// Gets and sets up the colliders
/// </summary>
protected override void InitializeCollider()
{
_collider2D = GetComponent<Collider2D>();
_boxCollider2D = GetComponent<BoxCollider2D>();
_circleCollider2D = GetComponent<CircleCollider2D>();
_polygonCollider2D = GetComponent<PolygonCollider2D>();
_collider2D.isTrigger = true;
}
/// <summary>
/// Creates and sets up the camera's confiner
/// </summary>
protected override void SetupConfiner()
{
// we add a rigidbody2D to it and set it up
_confinerRigidbody2D = _confinerGameObject.AddComponent<Rigidbody2D>();
_confinerRigidbody2D.bodyType = RigidbodyType2D.Static;
_confinerRigidbody2D.simulated = false;
_confinerRigidbody2D.useAutoMass = true;
_confinerRigidbody2D.bodyType = RigidbodyType2D.Dynamic;
// we copy the collider and set it up
CopyCollider();
_confinerGameObject.transform.localPosition = Vector3.zero;
// we reset these settings, set differently initially to avoid a weird Unity warning
_confinerRigidbody2D.bodyType = RigidbodyType2D.Static;
_confinerRigidbody2D.useAutoMass = false;
// we add a composite collider 2D and set it up
_confinerCompositeCollider2D = _confinerGameObject.AddComponent<CompositeCollider2D>();
_confinerCompositeCollider2D.geometryType = CompositeCollider2D.GeometryType.Polygons;
// we set the composite collider as the virtual camera's confiner
_cinemachineConfiner = VirtualCamera.gameObject.MMGetComponentAroundOrAdd<CinemachineConfiner>();
_cinemachineConfiner.m_ConfineMode = CinemachineConfiner.Mode.Confine2D;
_cinemachineConfiner.m_ConfineScreenEdges = true;
_cinemachineConfiner.m_BoundingShape2D = _confinerCompositeCollider2D;
}
/// <summary>
/// Copies the initial collider to the composite
/// </summary>
protected virtual void CopyCollider()
{
if (_boxCollider2D != null)
{
BoxCollider2D boxCollider2D = _confinerGameObject.AddComponent<BoxCollider2D>();
boxCollider2D.size = _boxCollider2D.size;
boxCollider2D.offset = _boxCollider2D.offset;
boxCollider2D.usedByComposite = true;
boxCollider2D.isTrigger = true;
}
if (_circleCollider2D != null)
{
CircleCollider2D circleCollider2D = _confinerGameObject.AddComponent<CircleCollider2D>();
circleCollider2D.isTrigger = true;
circleCollider2D.usedByComposite = true;
circleCollider2D.offset = _circleCollider2D.offset;
circleCollider2D.radius = _circleCollider2D.radius;
}
if (_polygonCollider2D != null)
{
PolygonCollider2D polygonCollider2D = _confinerGameObject.AddComponent<PolygonCollider2D>();
polygonCollider2D.isTrigger = true;
polygonCollider2D.usedByComposite = true;
polygonCollider2D.offset = _polygonCollider2D.offset;
polygonCollider2D.points = _polygonCollider2D.points;
}
}
/// <summary>
/// On enter, enables the camera and triggers the enter event
/// </summary>
/// <param name="collider"></param>
protected virtual void OnTriggerEnter2D(Collider2D collider)
{
if (!TestCollidingGameObject(collider.gameObject))
{
return;
}
if (TriggerMask.MMContains (collider.gameObject))
{
StartCoroutine(EnableCamera(true, 0));
OnEnterZoneEvent.Invoke();
}
}
/// <summary>
/// On exit, disables the camera and invokes the exit event
/// </summary>
/// <param name="collider"></param>
protected virtual void OnTriggerExit2D(Collider2D collider)
{
if (!TestCollidingGameObject(collider.gameObject))
{
return;
}
if (TriggerMask.MMContains (collider.gameObject))
{
StartCoroutine(EnableCamera(false, 0));
OnExitZoneEvent.Invoke();
}
}
#endif
#if UNITY_EDITOR
/// <summary>
/// Draws gizmos to show the shape of the zone
/// </summary>
protected virtual void OnDrawGizmos()
{
if (!DrawGizmos)
{
return;
}
Gizmos.color = GizmosColor;
if ((_boxCollider2D != null) && _boxCollider2D.enabled)
{
_gizmoSize.x = _boxCollider2D.bounds.size.x ;
_gizmoSize.y = _boxCollider2D.bounds.size.y ;
_gizmoSize.z = 1f;
Gizmos.DrawCube(_boxCollider2D.bounds.center, _gizmoSize);
}
if (_circleCollider2D != null && _circleCollider2D.enabled)
{
Gizmos.DrawSphere((Vector2)this.transform.position + _circleCollider2D.offset, _circleCollider2D.radius);
}
}
#endif
}
}

View File

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

View File

@@ -0,0 +1,148 @@
#if MM_CINEMACHINE
using Cinemachine;
#endif
using UnityEngine;
namespace MoreMountains.Tools
{
/// <summary>
/// 3D Implementation of the CinemachineZone abstract class
/// </summary>
[RequireComponent(typeof(Collider))]
public class MMCinemachineZone3D : MMCinemachineZone
{
protected Collider _collider;
protected Collider _confinerCollider;
protected Rigidbody _confinerRigidbody;
protected BoxCollider _boxCollider;
protected SphereCollider _sphereCollider;
#if MM_CINEMACHINE
protected CinemachineConfiner _cinemachineConfiner;
/// <summary>
/// Gets and sets up the colliders
/// </summary>
protected override void InitializeCollider()
{
_collider = GetComponent<Collider>();
_boxCollider = GetComponent<BoxCollider>();
_sphereCollider = GetComponent<SphereCollider>();
_collider.isTrigger = true;
}
/// <summary>
/// Creates and sets up the camera's confiner
/// </summary>
protected override void SetupConfiner()
{
// we add a rigidbody to it and set it up
_confinerRigidbody = _confinerGameObject.AddComponent<Rigidbody>();
_confinerRigidbody.useGravity = false;
_confinerRigidbody.gameObject.isStatic = true;
_confinerRigidbody.isKinematic = true;
// we copy the collider and set it up
CopyCollider();
_confinerGameObject.transform.localPosition = Vector3.zero;
// we set the composite collider as the virtual camera's confiner
_cinemachineConfiner = VirtualCamera.gameObject.MMGetComponentAroundOrAdd<CinemachineConfiner>();
_cinemachineConfiner.m_ConfineMode = CinemachineConfiner.Mode.Confine3D;
_cinemachineConfiner.m_ConfineScreenEdges = true;
if (_boxCollider != null)
{
_cinemachineConfiner.m_BoundingVolume = _boxCollider;
}
if (_sphereCollider != null)
{
_cinemachineConfiner.m_BoundingVolume = _sphereCollider;
}
}
/// <summary>
/// Copies the initial collider to the composite
/// </summary>
protected virtual void CopyCollider()
{
if (_boxCollider != null)
{
BoxCollider boxCollider = _confinerGameObject.AddComponent<BoxCollider>();
boxCollider.size = _boxCollider.size;
boxCollider.center = _boxCollider.center;
boxCollider.isTrigger = true;
}
if (_sphereCollider != null)
{
SphereCollider sphereCollider = _confinerGameObject.AddComponent<SphereCollider>();
sphereCollider.isTrigger = true;
sphereCollider.center = _sphereCollider.center;
sphereCollider.radius = _sphereCollider.radius;
}
}
/// <summary>
/// On enter, enables the camera and triggers the enter event
/// </summary>
/// <param name="collider"></param>
protected virtual void OnTriggerEnter(Collider collider)
{
if (!TestCollidingGameObject(collider.gameObject))
{
return;
}
if (TriggerMask.MMContains (collider.gameObject))
{
StartCoroutine(EnableCamera(true, 0));
OnEnterZoneEvent.Invoke();
}
}
/// <summary>
/// On exit, disables the camera and invokes the exit event
/// </summary>
/// <param name="collider"></param>
protected virtual void OnTriggerExit(Collider collider)
{
if (!TestCollidingGameObject(collider.gameObject))
{
return;
}
if (TriggerMask.MMContains (collider.gameObject))
{
StartCoroutine(EnableCamera(false, 0));
OnExitZoneEvent.Invoke();
}
}
#endif
#if UNITY_EDITOR
/// <summary>
/// Draws gizmos to show the shape of the zone
/// </summary>
protected virtual void OnDrawGizmos()
{
if (!DrawGizmos)
{
return;
}
Gizmos.color = GizmosColor;
if ((_boxCollider != null) && _boxCollider.enabled)
{
_gizmoSize = _boxCollider.bounds.size ;
Gizmos.DrawCube(_boxCollider.bounds.center, _gizmoSize);
}
if (_sphereCollider != null && _sphereCollider.enabled)
{
Gizmos.DrawSphere(this.transform.position + _sphereCollider.center, _sphereCollider.radius);
}
}
#endif
}
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: dfa4f578826ffdb4eaa08a7ec896f075
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,153 @@
#if MM_CINEMACHINE
using Cinemachine;
#endif
using MoreMountains.Tools;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Tools
{
/// <summary>
/// A class used to store gyro properties per camera
/// </summary>
[Serializable]
[AddComponentMenu("More Mountains/Tools/Cinemachine/MMGyroCam")]
public class MMGyroCam
{
#if MM_CINEMACHINE
/// the bound cinemachine camera
public CinemachineVirtualCamera Cam;
#endif
/// the transform this camera should look at
public Transform LookAt;
/// the transform this camera should rotate around
public Transform RotationCenter;
/// the minimum rotation to apply to this camera (in degrees)
public Vector2 MinRotation = new Vector2(-2f, -2f);
/// the maximum rotation to apply to this camera (in degrees)
public Vector2 MaxRotation = new Vector2(2f, 2f);
/// a transform to follow if the camera is animated
public Transform AnimatedPosition;
/// the camera's initial angles
[MMReadOnly]
public Vector3 InitialAngles;
/// the camera's initial position
[MMReadOnly]
public Vector3 InitialPosition;
}
/// <summary>
/// Add this class to a camera rig (an empty object), bind some Cinemachine virtual cameras to it, and they'll move around the specified object as your gyro powered device moves
/// </summary>
public class MMGyroParallax : MMGyroscope
{
[Header("Cameras")]
/// the list of cameras to move as the gyro moves
public List<MMGyroCam> Cams;
protected Vector3 _newAngles;
#if MM_CINEMACHINE
/// <summary>
/// On start we initialize our rig
/// </summary>
protected override void Start()
{
base.Start();
Initialization();
}
/// <summary>
/// Grabs the cameras and stores their position
/// </summary>
public virtual void Initialization()
{
foreach (MMGyroCam cam in Cams)
{
cam.InitialAngles = cam.Cam.transform.localEulerAngles;
cam.InitialPosition = cam.Cam.transform.position;
}
}
/// <summary>
/// On Update we move our cameras
/// </summary>
protected override void Update()
{
base.Update();
MoveCameras();
}
/// <summary>
/// Moves cameras around based on gyro input
/// </summary>
protected virtual void MoveCameras()
{
foreach (MMGyroCam cam in Cams)
{
float newX = 0f;
float newY = 0f;
var gyroGravity = LerpedCalibratedGyroscopeGravity;
if (gyroGravity.x > 0)
{
newX = MMMaths.Remap(LerpedCalibratedGyroscopeGravity.x, 0.5f, 0, cam.MinRotation.x, 0);
}
if (gyroGravity.x < 0)
{
newX = MMMaths.Remap(LerpedCalibratedGyroscopeGravity.x, 0, -.5f, 0, cam.MaxRotation.x);
}
if (gyroGravity.y > 0)
{
newY = MMMaths.Remap(LerpedCalibratedGyroscopeGravity.y, 0.5f, 0, cam.MinRotation.y, 0f);
}
if (gyroGravity.y < 0)
{
newY = MMMaths.Remap(LerpedCalibratedGyroscopeGravity.y, 0f, -0.5f, 0f, cam.MaxRotation.y);
}
var camTransform = cam.Cam.transform;
if (cam.AnimatedPosition != null)
{
_newAngles = cam.AnimatedPosition.localEulerAngles;
_newAngles.x += newX;
_newAngles.z += newY;
camTransform.position = cam.AnimatedPosition.position;
camTransform.localEulerAngles = cam.AnimatedPosition.localEulerAngles;
}
else
{
_newAngles = cam.InitialAngles;
_newAngles.x += newX;
_newAngles.z += newY;
camTransform.position = cam.InitialPosition;
camTransform.localEulerAngles = cam.InitialAngles;
}
var rotationTransform = cam.RotationCenter.transform;
camTransform.RotateAround(rotationTransform.position, rotationTransform.up, newX);
camTransform.RotateAround(rotationTransform.position, rotationTransform.right, newY);
if (cam.Cam.LookAt == null) // cinemachine is not tracking a target
{
if (cam.LookAt != null) // local lookout target
{
camTransform.LookAt(cam.LookAt);
}
else
{
camTransform.LookAt(cam.RotationCenter);
}
}
}
}
#endif
}
}

View File

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