init push 0.2.4
This commit is contained in:
293
Runtime/Player/CameraController.cs
Normal file
293
Runtime/Player/CameraController.cs
Normal file
@@ -0,0 +1,293 @@
|
||||
#if CREST_UNITY_INPUT && ENABLE_INPUT_SYSTEM
|
||||
#define INPUT_SYSTEM_ENABLED
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
#if INPUT_SYSTEM_ENABLED
|
||||
using UnityEngine.InputSystem;
|
||||
#endif
|
||||
#if ENABLE_VR && ENABLE_VR_MODULE
|
||||
using UnityEngine.XR;
|
||||
#endif
|
||||
|
||||
namespace Deconstruction.Runtime.Player
|
||||
{
|
||||
/// <summary>
|
||||
/// 一个简单且功能有限的摄像机脚本,可通过 WASD 键和鼠标进行控制。
|
||||
/// </summary>
|
||||
public class CameraController : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// 此资产的版本。可用于不同版本之间的迁移。只有在编辑器升级版本时才应更改此值。
|
||||
/// </summary>
|
||||
[SerializeField, HideInInspector]
|
||||
#pragma warning disable 414
|
||||
int _version = 0;
|
||||
#pragma warning restore 414
|
||||
|
||||
public float linSpeed = 10f;
|
||||
public float rotSpeed = 70f;
|
||||
|
||||
public bool simForwardInput = false;
|
||||
public bool _requireLMBToMove = false;
|
||||
|
||||
public bool enableWalkMode = false;
|
||||
|
||||
Vector2 _lastMousePos = -Vector2.one;
|
||||
bool _dragging = false;
|
||||
|
||||
public float _fixedDt = 1 / 60f;
|
||||
|
||||
Transform _targetTransform;
|
||||
|
||||
public CharacterController _moveComponent;
|
||||
|
||||
[Space(10)]
|
||||
|
||||
[SerializeField]
|
||||
DebugFields _debug = new DebugFields();
|
||||
|
||||
#pragma warning disable CS0108
|
||||
// 在编辑器中,我们需要使用“new”来屏蔽警告,但在构建时会再次给出警告,所以应该使用“pragma”来替代。
|
||||
private Camera camera;
|
||||
#pragma warning restore CS0108
|
||||
|
||||
[System.Serializable]
|
||||
class DebugFields
|
||||
{
|
||||
[Tooltip("Allows the camera to roll (rotating on the z axis).")]
|
||||
public bool _enableCameraRoll = false;
|
||||
|
||||
[Tooltip("Disables the XR occlusion mesh for debugging purposes. Only works with legacy XR.")]
|
||||
public bool _disableOcclusionMesh = false;
|
||||
|
||||
[Tooltip("Sets the XR occlusion mesh scale. Useful for debugging refractions. Only works with legacy XR."), UnityEngine.Range(1f, 2f)]
|
||||
public float _occlusionMeshScale = 1f;
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
if (_moveComponent == null)
|
||||
{
|
||||
_moveComponent = GetComponent<CharacterController>();
|
||||
}
|
||||
else if (Application.isEditor)
|
||||
{
|
||||
_moveComponent.enabled = enableWalkMode;
|
||||
}
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_targetTransform = transform;
|
||||
|
||||
if (!TryGetComponent(out camera))
|
||||
{
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_moveComponent != null)
|
||||
{
|
||||
_moveComponent.enabled = enableWalkMode;
|
||||
}
|
||||
#if ENABLE_VR && ENABLE_VR_MODULE
|
||||
if (XRSettings.enabled)
|
||||
{
|
||||
// Seems like the best place to put this for now. Most XR debugging happens using this component.
|
||||
// @FixMe: useOcclusionMesh doesn't work anymore. Might be a Unity bug.
|
||||
XRSettings.useOcclusionMesh = !_debug._disableOcclusionMesh;
|
||||
XRSettings.occlusionMaskScale = _debug._occlusionMeshScale;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
float dt = Time.deltaTime;
|
||||
if (_fixedDt > 0f)
|
||||
dt = _fixedDt;
|
||||
|
||||
UpdateMovement(dt);
|
||||
|
||||
#if ENABLE_VR && ENABLE_VR_MODULE
|
||||
// These aren't useful and can break for XR hardware.
|
||||
if (!XRSettings.enabled || XRSettings.loadedDeviceName.Contains("MockHMD"))
|
||||
#endif
|
||||
{
|
||||
UpdateDragging(dt);
|
||||
UpdateKillRoll();
|
||||
}
|
||||
|
||||
#if ENABLE_VR && ENABLE_VR_MODULE
|
||||
if (XRSettings.enabled)
|
||||
{
|
||||
// Check if property has changed.
|
||||
if (XRSettings.useOcclusionMesh == _debug._disableOcclusionMesh)
|
||||
{
|
||||
// @FixMe: useOcclusionMesh doesn't work anymore. Might be a Unity bug.
|
||||
XRSettings.useOcclusionMesh = !_debug._disableOcclusionMesh;
|
||||
}
|
||||
|
||||
XRSettings.occlusionMaskScale = _debug._occlusionMeshScale;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void UpdateMovement(float dt)
|
||||
{
|
||||
// New input system works even when game view is not focused.
|
||||
if (!Application.isFocused)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if INPUT_SYSTEM_ENABLED
|
||||
if (!Mouse.current.leftButton.isPressed && _requireLMBToMove) return;
|
||||
float forward = (Keyboard.current.wKey.isPressed ? 1 : 0) - (Keyboard.current.sKey.isPressed ? 1 : 0);
|
||||
#else
|
||||
if (!Input.GetMouseButton(1) && _requireLMBToMove) return;
|
||||
float forward = (Input.GetKey(KeyCode.W) ? 1 : 0) - (Input.GetKey(KeyCode.S) ? 1 : 0);
|
||||
#endif
|
||||
if (simForwardInput)
|
||||
{
|
||||
forward = 1f;
|
||||
}
|
||||
|
||||
_targetTransform.position += linSpeed * _targetTransform.forward * forward * dt;
|
||||
var speed = linSpeed;
|
||||
|
||||
#if INPUT_SYSTEM_ENABLED
|
||||
if (Keyboard.current.leftShiftKey.isPressed)
|
||||
#else
|
||||
if (Input.GetKey(KeyCode.LeftShift))
|
||||
#endif
|
||||
{
|
||||
speed *= 3f;
|
||||
}
|
||||
|
||||
var offset = _targetTransform.forward * forward;
|
||||
// _targetTransform.position += speed * _targetTransform.forward * forward * dt;
|
||||
//_transform.position += linSpeed * _transform.right * Input.GetAxis( "Horizontal" ) * dt;
|
||||
#if INPUT_SYSTEM_ENABLED
|
||||
offset += _targetTransform.up * (Keyboard.current.eKey.isPressed ? 1 : 0);
|
||||
offset -= _targetTransform.up * (Keyboard.current.qKey.isPressed ? 1 : 0);
|
||||
offset -= _targetTransform.right * (Keyboard.current.aKey.isPressed ? 1 : 0);
|
||||
offset += _targetTransform.right * (Keyboard.current.dKey.isPressed ? 1 : 0);
|
||||
#else
|
||||
offset += _targetTransform.up * (Input.GetKey(KeyCode.E) ? 1 : 0);
|
||||
offset -= _targetTransform.up * (Input.GetKey(KeyCode.Q) ? 1 : 0);
|
||||
offset -= _targetTransform.right * (Input.GetKey(KeyCode.A) ? 1 : 0);
|
||||
offset += _targetTransform.right * (Input.GetKey(KeyCode.D) ? 1 : 0);
|
||||
#endif
|
||||
offset *= speed * dt;
|
||||
|
||||
// 使用控制器移动
|
||||
if (enableWalkMode)
|
||||
{
|
||||
UpdateWalk(offset);
|
||||
}
|
||||
// 直接设置坐标移动
|
||||
else
|
||||
{
|
||||
_targetTransform.position += offset;
|
||||
}
|
||||
{
|
||||
float rotate = 0f;
|
||||
#if INPUT_SYSTEM_ENABLED
|
||||
rotate += (Keyboard.current.rightArrowKey.isPressed ? 1 : 0);
|
||||
rotate -= (Keyboard.current.leftArrowKey.isPressed ? 1 : 0);
|
||||
#else
|
||||
rotate += (Input.GetKey(KeyCode.RightArrow) ? 1 : 0);
|
||||
rotate -= (Input.GetKey(KeyCode.LeftArrow) ? 1 : 0);
|
||||
#endif
|
||||
|
||||
rotate *= 5f;
|
||||
Vector3 ea = _targetTransform.eulerAngles;
|
||||
ea.y += 0.1f * rotSpeed * rotate * dt;
|
||||
_targetTransform.eulerAngles = ea;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateDragging(float dt)
|
||||
{
|
||||
// New input system works even when game view is not focused.
|
||||
if (!Application.isFocused)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 mousePos =
|
||||
#if INPUT_SYSTEM_ENABLED
|
||||
Mouse.current.position.ReadValue();
|
||||
#else
|
||||
Input.mousePosition;
|
||||
#endif
|
||||
|
||||
var wasLeftMouseButtonPressed =
|
||||
#if INPUT_SYSTEM_ENABLED
|
||||
Mouse.current.leftButton.wasPressedThisFrame;
|
||||
#else
|
||||
Input.GetMouseButtonDown(1);
|
||||
#endif
|
||||
|
||||
if (!_dragging && wasLeftMouseButtonPressed && camera.rect.Contains(camera.ScreenToViewportPoint(mousePos)) )
|
||||
//!Crest.OceanDebugGUI.OverGUI(mousePos))
|
||||
{
|
||||
_dragging = true;
|
||||
_lastMousePos = mousePos;
|
||||
}
|
||||
#if INPUT_SYSTEM_ENABLED
|
||||
if (_dragging && Mouse.current.leftButton.wasReleasedThisFrame)
|
||||
#else
|
||||
if (_dragging && Input.GetMouseButtonUp(1))
|
||||
#endif
|
||||
{
|
||||
_dragging = false;
|
||||
_lastMousePos = -Vector2.one;
|
||||
}
|
||||
|
||||
if (_dragging)
|
||||
{
|
||||
Vector2 delta = mousePos - _lastMousePos;
|
||||
|
||||
Vector3 ea = _targetTransform.eulerAngles;
|
||||
ea.x += -0.1f * rotSpeed * delta.y * dt;
|
||||
ea.y += 0.1f * rotSpeed * delta.x * dt;
|
||||
_targetTransform.eulerAngles = ea;
|
||||
|
||||
_lastMousePos = mousePos;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateKillRoll()
|
||||
{
|
||||
if (_debug._enableCameraRoll) return;
|
||||
Vector3 ea = _targetTransform.eulerAngles;
|
||||
ea.z = 0f;
|
||||
transform.eulerAngles = ea;
|
||||
}
|
||||
|
||||
private float gravity = 0;
|
||||
void UpdateWalk(Vector3 offset)
|
||||
{
|
||||
if (_moveComponent != null)
|
||||
{
|
||||
_moveComponent.enabled = enableWalkMode;
|
||||
if (enableWalkMode)
|
||||
{
|
||||
if (offset.y > 0)
|
||||
gravity = 0;
|
||||
else
|
||||
{
|
||||
gravity -= 0.01f;
|
||||
gravity = Mathf.Max(gravity, -0.98f);
|
||||
}
|
||||
offset.y = offset.y <= 0 ? gravity : offset.y;
|
||||
_moveComponent.Move(offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user