222 lines
7.8 KiB
C#
222 lines
7.8 KiB
C#
using Fragilem17.MirrorsAndPortals;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
#if ENABLE_LEGACY_INPUT_MANAGER
|
|
using UnityEngine.XR;
|
|
#endif
|
|
#if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
|
|
using UnityEngine.InputSystem;
|
|
#endif
|
|
namespace Fragilem17.MirrorsAndPortals
|
|
{
|
|
public class PortalGunExample : MonoBehaviour
|
|
{
|
|
public LayerMask layerMask;
|
|
public Portal portal1;
|
|
public Portal portal2;
|
|
|
|
private Dictionary<Portal, Vector3> _portalSizes;
|
|
|
|
private Portal _targetPortal;
|
|
|
|
public new Light light;
|
|
|
|
private bool _shooting = false;
|
|
|
|
public bool alignWithViewDirectionOnHorizontalSurfaces = false;
|
|
|
|
#if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
|
|
public InputAction ShootAction1;
|
|
public InputAction ShootAction2;
|
|
|
|
|
|
private void OnEnable()
|
|
{
|
|
ShootAction1.Enable();
|
|
ShootAction2.Enable();
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
ShootAction1.Disable();
|
|
ShootAction2.Disable();
|
|
}
|
|
#endif
|
|
|
|
|
|
#if ENABLE_LEGACY_INPUT_MANAGER
|
|
private UnityEngine.XR.InputDevice _rightHandDevice;
|
|
|
|
void OnEnable()
|
|
{
|
|
List<InputDevice> allDevices = new List<InputDevice>();
|
|
InputDevices.GetDevices(allDevices);
|
|
foreach (InputDevice device in allDevices)
|
|
InputDevices_deviceConnected(device);
|
|
|
|
InputDevices.deviceConnected += InputDevices_deviceConnected;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
InputDevices.deviceConnected -= InputDevices_deviceConnected;
|
|
}
|
|
|
|
private void InputDevices_deviceConnected(InputDevice device)
|
|
{
|
|
bool discardedValue;
|
|
if (device.TryGetFeatureValue(CommonUsages.primaryButton, out discardedValue))
|
|
{
|
|
if ((device.characteristics & InputDeviceCharacteristics.Right) == InputDeviceCharacteristics.Right)
|
|
{
|
|
_rightHandDevice = device;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
private void Start()
|
|
{
|
|
_portalSizes = new Dictionary<Portal, Vector3>();
|
|
if (portal1 && portal2)
|
|
{
|
|
_portalSizes[portal1] = portal1.transform.localScale;
|
|
_portalSizes[portal2] = portal2.transform.localScale;
|
|
}
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
_targetPortal = portal1;
|
|
|
|
bool shouldShoot = false;
|
|
|
|
|
|
#if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
|
|
if (!_shooting && ShootAction1.ReadValue<float>() > 0)
|
|
{
|
|
shouldShoot = true;
|
|
_shooting = true;
|
|
}
|
|
if (!_shooting && ShootAction2.ReadValue<float>() > 0)
|
|
{
|
|
shouldShoot = true;
|
|
_shooting = true;
|
|
_targetPortal = portal2;
|
|
}
|
|
|
|
if (_shooting && ShootAction1.ReadValue<float>() == 0 && ShootAction2.ReadValue<float>() == 0)
|
|
{
|
|
_shooting = false;
|
|
}
|
|
#endif
|
|
|
|
#if ENABLE_LEGACY_INPUT_MANAGER
|
|
|
|
bool buttonValue;
|
|
_rightHandDevice.TryGetFeatureValue(UnityEngine.XR.CommonUsages.primaryButton, out buttonValue);
|
|
//Debug.Log("buttonValue: " + buttonValue);
|
|
|
|
if (!_shooting && (Input.GetMouseButton(0) || (_rightHandDevice.TryGetFeatureValue(UnityEngine.XR.CommonUsages.primaryButton, out buttonValue) && buttonValue)))
|
|
{
|
|
shouldShoot = true;
|
|
_shooting = true;
|
|
}
|
|
if (!_shooting && (Input.GetMouseButton(1) || (_rightHandDevice.TryGetFeatureValue(UnityEngine.XR.CommonUsages.secondaryButton, out buttonValue) && buttonValue)))
|
|
{
|
|
shouldShoot = true;
|
|
_shooting = true;
|
|
_targetPortal = portal2;
|
|
}
|
|
|
|
if (_shooting && !(Input.GetMouseButton(0) || Input.GetMouseButton(1) || (_rightHandDevice.TryGetFeatureValue(UnityEngine.XR.CommonUsages.primaryButton, out buttonValue) && buttonValue) || (_rightHandDevice.TryGetFeatureValue(UnityEngine.XR.CommonUsages.secondaryButton, out buttonValue) && buttonValue)))
|
|
{
|
|
_shooting = false;
|
|
}
|
|
#endif
|
|
|
|
if (shouldShoot)
|
|
{
|
|
//Debug.DrawRay(transform.position, transform.forward);
|
|
RaycastHit hit;
|
|
Ray ray = new Ray(transform.position, transform.forward);
|
|
if (Physics.Raycast(ray, out hit, 40, layerMask))
|
|
{
|
|
if (hit.collider)
|
|
{
|
|
StopAllCoroutines();
|
|
StartCoroutine(FadeInOut());
|
|
|
|
_targetPortal.transform.position = hit.point;
|
|
_targetPortal.transform.rotation = Quaternion.FromToRotation(Vector3.back, hit.normal);
|
|
_targetPortal.transform.localScale = Vector3.zero;
|
|
_targetPortal.wallCollider = hit.collider.gameObject.GetComponentInChildren<Collider>();
|
|
|
|
Vector3 euler = _targetPortal.transform.rotation.eulerAngles;
|
|
_targetPortal.transform.rotation = Quaternion.Euler(euler.x, euler.y, 0);
|
|
|
|
// is it a vertical wall?
|
|
float vertical = Mathf.Abs(Vector3.Dot(_targetPortal.transform.up, Vector3.up));
|
|
//Debug.Log("verical: " + vertical);
|
|
if (alignWithViewDirectionOnHorizontalSurfaces && vertical < 0.5f)
|
|
{
|
|
// Calculate the direction from the hit point to the player's position
|
|
Vector3 playerDirection = transform.position - hit.point;
|
|
|
|
// Calculate a new forward direction for the portal that is opposite to the direction towards the player
|
|
Vector3 portalForward = -playerDirection.normalized;
|
|
|
|
// Create a new rotation that aligns the portal's up direction with the direction towards the player, and its forward direction with the wall's normal
|
|
Quaternion finalRotation = Quaternion.LookRotation(hit.normal, portalForward);
|
|
|
|
// Set the rotation of the portal object
|
|
_targetPortal.transform.rotation = finalRotation;
|
|
_targetPortal.transform.Rotate(_targetPortal.transform.InverseTransformDirection(_targetPortal.transform.up), 180);
|
|
}
|
|
|
|
_targetPortal.transform.localScale = Vector3.zero;
|
|
StartCoroutine(Scale(_targetPortal, 1));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
IEnumerator FadeInOut()
|
|
{
|
|
if (light != null)
|
|
{
|
|
light.enabled = true;
|
|
yield return StartCoroutine(Fade(5f));
|
|
yield return StartCoroutine(Fade(0));
|
|
light.enabled = false;
|
|
}
|
|
}
|
|
IEnumerator Fade(float to)
|
|
{
|
|
float diff = (to - light.intensity);
|
|
while (Mathf.Abs(diff) > 0.01f)
|
|
{
|
|
//Debug.Log("diff " + diff);
|
|
light.intensity += diff * 0.5f;
|
|
diff = (to - light.intensity);
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
IEnumerator Scale(Portal portal, float to)
|
|
{
|
|
float diff = ((to * _portalSizes[portal].x) - portal.transform.localScale.x);
|
|
while (Mathf.Abs(diff) > 0.01f)
|
|
{
|
|
//Debug.Log("diff " + diff);
|
|
portal.transform.localScale += _portalSizes[portal] * diff * 0.1f;
|
|
diff = ((to * _portalSizes[portal].x) - portal.transform.localScale.x);
|
|
yield return null;
|
|
}
|
|
}
|
|
}
|
|
}
|