427 lines
12 KiB
C#
427 lines
12 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
#endif
|
|
|
|
namespace HighlightingSystem.Demo
|
|
{
|
|
#if UNITY_EDITOR
|
|
[CustomEditor(typeof(CameraFlyController))]
|
|
public class CameraFlyControllerEditor : Editor
|
|
{
|
|
static private readonly GUIContent labelSetupAxes = new GUIContent("Setup Input Axes");
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
base.OnInspectorGUI();
|
|
|
|
if (GUILayout.Button(labelSetupAxes, GUILayout.Height(30f)))
|
|
{
|
|
SetupControllerAxes();
|
|
}
|
|
}
|
|
|
|
private struct Axis
|
|
{
|
|
public string m_Name;
|
|
public string descriptiveName;
|
|
public string descriptiveNegativeName;
|
|
public string negativeButton;
|
|
public string positiveButton;
|
|
public string altNegativeButton;
|
|
public string altPositiveButton;
|
|
public float gravity;
|
|
public float dead;
|
|
public float sensitivity;
|
|
public bool snap;
|
|
public bool invert;
|
|
public int type; // Enum
|
|
public int axis; // Enum
|
|
public int joyNum; // Enum
|
|
|
|
//
|
|
public void Serialize(SerializedProperty p)
|
|
{
|
|
p.FindPropertyRelative("m_Name").stringValue = m_Name;
|
|
p.FindPropertyRelative("descriptiveName").stringValue = descriptiveName;
|
|
p.FindPropertyRelative("descriptiveNegativeName").stringValue = descriptiveNegativeName;
|
|
p.FindPropertyRelative("negativeButton").stringValue = negativeButton;
|
|
p.FindPropertyRelative("positiveButton").stringValue = positiveButton;
|
|
p.FindPropertyRelative("altNegativeButton").stringValue = altNegativeButton;
|
|
p.FindPropertyRelative("altPositiveButton").stringValue = altPositiveButton;
|
|
p.FindPropertyRelative("gravity").floatValue = gravity;
|
|
p.FindPropertyRelative("dead").floatValue = dead;
|
|
p.FindPropertyRelative("sensitivity").floatValue = sensitivity;
|
|
p.FindPropertyRelative("snap").boolValue = snap;
|
|
p.FindPropertyRelative("invert").boolValue = invert;
|
|
p.FindPropertyRelative("type").intValue = type;
|
|
p.FindPropertyRelative("axis").intValue = axis;
|
|
p.FindPropertyRelative("joyNum").intValue = joyNum;
|
|
}
|
|
}
|
|
|
|
static public void SetupControllerAxes()
|
|
{
|
|
List<Axis> axes = new List<Axis>();
|
|
Axis axis = new Axis();
|
|
|
|
// JoystickAxis commons
|
|
axis.dead = 0f;
|
|
axis.sensitivity = 1f;
|
|
axis.snap = false;
|
|
axis.invert = false;
|
|
axis.type = 2;
|
|
axis.joyNum = 0;
|
|
|
|
// JoystickAxis1
|
|
axis.m_Name = CameraFlyController.axisJoystickAxis1;
|
|
axis.axis = 0;
|
|
axes.Add(axis);
|
|
|
|
// JoystickAxis2
|
|
axis.m_Name = CameraFlyController.axisJoystickAxis2;
|
|
axis.axis = 1;
|
|
axes.Add(axis);
|
|
|
|
// JoystickAxis4
|
|
axis.m_Name = CameraFlyController.axisJoystickAxis4;
|
|
axis.axis = 3;
|
|
axes.Add(axis);
|
|
|
|
// JoystickAxis5
|
|
axis.m_Name = CameraFlyController.axisJoystickAxis5;
|
|
axis.axis = 4;
|
|
axes.Add(axis);
|
|
|
|
// Mouse commons
|
|
axis.dead = 0f;
|
|
axis.sensitivity = 0.1f;
|
|
axis.snap = false;
|
|
axis.invert = false;
|
|
axis.type = 1;
|
|
axis.joyNum = 0;
|
|
|
|
// Mouse X
|
|
axis.m_Name = CameraFlyController.axisMouseX;
|
|
axis.axis = 0;
|
|
axes.Add(axis);
|
|
|
|
// Mouse Y
|
|
axis.m_Name = CameraFlyController.axisMouseY;
|
|
axis.axis = 1;
|
|
axes.Add(axis);
|
|
|
|
SetupAxes(axes);
|
|
}
|
|
|
|
static private void SetupAxes(List<Axis> samples)
|
|
{
|
|
string path = "ProjectSettings/InputManager.asset";
|
|
Object inputManagerFile = AssetDatabase.LoadAllAssetsAtPath(path)[0];
|
|
if (inputManagerFile == null)
|
|
{
|
|
Debug.LogErrorFormat("Failed to load asset at path '{0}'", path);
|
|
return;
|
|
}
|
|
|
|
SerializedObject inputManagerAsset = new SerializedObject(inputManagerFile);
|
|
|
|
HashSet<int> toIgnore = new HashSet<int>();
|
|
SerializedProperty axesProperty = inputManagerAsset.FindProperty("m_Axes");
|
|
for (int i = 0, l = axesProperty.arraySize; i < l; i++)
|
|
{
|
|
SerializedProperty axisProperty = axesProperty.GetArrayElementAtIndex(i);
|
|
string name = axisProperty.FindPropertyRelative("m_Name").stringValue;
|
|
int sampleIndex = samples.FindIndex(delegate(Axis obj) { return obj.m_Name == name; });
|
|
if (sampleIndex != -1)
|
|
{
|
|
// Replace axis
|
|
Axis sample = samples[sampleIndex];
|
|
sample.Serialize(axisProperty);
|
|
toIgnore.Add(sampleIndex);
|
|
}
|
|
}
|
|
|
|
for (int i = 0, l = samples.Count; i < l; i++)
|
|
{
|
|
if (toIgnore.Contains(i)) { continue; }
|
|
|
|
// Add axis
|
|
Axis sample = samples[i];
|
|
int arrayIndex = axesProperty.arraySize;
|
|
axesProperty.InsertArrayElementAtIndex(arrayIndex);
|
|
SerializedProperty p = axesProperty.GetArrayElementAtIndex(arrayIndex);
|
|
sample.Serialize(p);
|
|
}
|
|
|
|
inputManagerAsset.ApplyModifiedProperties();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
public class CameraFlyController : MonoBehaviour
|
|
{
|
|
#region Constants
|
|
public const string axisJoystickAxis1 = "JoystickAxis1";
|
|
public const string axisJoystickAxis2 = "JoystickAxis2";
|
|
public const string axisJoystickAxis4 = "JoystickAxis4";
|
|
public const string axisJoystickAxis5 = "JoystickAxis5";
|
|
public const string axisMouseX = "Mouse X";
|
|
public const string axisMouseY = "Mouse Y";
|
|
|
|
private float keyboardMoveSpeed = 4f;
|
|
|
|
private float joystickAxisThresholdMin = 0.2f;
|
|
private float joystickAxisThresholdMax = 1f;
|
|
|
|
private float joystickMoveSpeedXMin = 0f;
|
|
private float joystickMoveSpeedXMax = 5f;
|
|
private float joystickMoveSpeedY = 4f;
|
|
private float joystickMoveSpeedZMin = 0f;
|
|
private float joystickMoveSpeedZMax = 5f;
|
|
|
|
private float joystickRotationSpeedMin = 0f;
|
|
private float joystickRotationSpeedMax = 126f;
|
|
|
|
static private readonly KeyCode[] keysForward = new KeyCode[] { KeyCode.W, KeyCode.UpArrow };
|
|
static private readonly KeyCode[] keysBackward = new KeyCode[] { KeyCode.S, KeyCode.DownArrow };
|
|
|
|
static private readonly KeyCode[] keysLeft = new KeyCode[] { KeyCode.A, KeyCode.LeftArrow };
|
|
static private readonly KeyCode[] keysRight = new KeyCode[] { KeyCode.D, KeyCode.RightArrow };
|
|
|
|
static private readonly KeyCode[] keysUp = new KeyCode[] { KeyCode.E, KeyCode.Space };
|
|
static private readonly KeyCode[] keysDown = new KeyCode[] { KeyCode.Q, KeyCode.C };
|
|
|
|
static private readonly KeyCode[] keysRun = new KeyCode[] { KeyCode.LeftShift, KeyCode.RightShift };
|
|
|
|
static private readonly KeyCode[] joystickUp = new KeyCode[] { KeyCode.Joystick1Button5, KeyCode.Joystick2Button5, KeyCode.Joystick3Button5, KeyCode.Joystick4Button5 };
|
|
static private readonly KeyCode[] joystickDown = new KeyCode[] { KeyCode.Joystick1Button4, KeyCode.Joystick2Button4, KeyCode.Joystick3Button4, KeyCode.Joystick4Button4 };
|
|
#endregion
|
|
|
|
#region PrivateFields
|
|
private Transform tr;
|
|
private bool rmbDownInRect;
|
|
private Vector3 mpStart;
|
|
private Vector3 originalRotation;
|
|
private float t;
|
|
#endregion
|
|
|
|
private Vector3 mousePosition
|
|
{
|
|
get
|
|
{
|
|
Camera cam = GetComponent<Camera>();
|
|
return cam == null ? Vector3.Scale(Input.mousePosition, new Vector3(1f/Screen.width, 1f/Screen.height, 1f)) : cam.ScreenToViewportPoint(Input.mousePosition);
|
|
}
|
|
}
|
|
|
|
//
|
|
void Awake()
|
|
{
|
|
tr = GetComponent<Transform>();
|
|
}
|
|
|
|
//
|
|
void OnEnable()
|
|
{
|
|
t = Time.realtimeSinceStartup;
|
|
}
|
|
|
|
//
|
|
void Update()
|
|
{
|
|
float timeNow = Time.realtimeSinceStartup;
|
|
float dT = timeNow - t;
|
|
t = timeNow;
|
|
|
|
HandleMouseInput(dT);
|
|
HandleControllerInput(dT);
|
|
}
|
|
|
|
//
|
|
void HandleMouseInput(float dT)
|
|
{
|
|
Vector3 mp = mousePosition;
|
|
|
|
// Unlock cursor on mouse move
|
|
if (InputHelper.GetAxis(axisMouseX) != 0f || InputHelper.GetAxis(axisMouseY) != 0f)
|
|
{
|
|
Cursor.lockState = CursorLockMode.None;
|
|
}
|
|
|
|
bool rmbDown = Input.GetMouseButtonDown(1);
|
|
bool rmbHeld = Input.GetMouseButton(1);
|
|
bool mouseInCameraRect = mp.x >= 0f && mp.x < 1f && mp.y >= 0f && mp.y < 1f;
|
|
|
|
rmbDownInRect = (rmbDownInRect && rmbHeld) || (mouseInCameraRect && rmbDown);
|
|
|
|
// Movement
|
|
if (rmbDownInRect || (!rmbHeld && mouseInCameraRect))
|
|
{
|
|
Vector3 moveDirection = new Vector3(InputHelper.GetKey(keysRight, keysLeft), InputHelper.GetKey(keysUp, keysDown), InputHelper.GetKey(keysForward, keysBackward));
|
|
float speedMultiplier = InputHelper.GetKey(keysRun) ? 2f : 1f;
|
|
tr.position += tr.TransformDirection(moveDirection * keyboardMoveSpeed * speedMultiplier * dT);
|
|
}
|
|
|
|
// Rotation
|
|
if (rmbDownInRect)
|
|
{
|
|
// Right Mouse Button Down
|
|
if (rmbDown)
|
|
{
|
|
originalRotation = tr.localEulerAngles;
|
|
mpStart = mp;
|
|
}
|
|
|
|
// Right Mouse Button Hold
|
|
if (rmbHeld)
|
|
{
|
|
Vector2 offs = new Vector2((mp.x - mpStart.x), (mpStart.y - mp.y));
|
|
tr.localEulerAngles = originalRotation + new Vector3(offs.y * 360f, offs.x * 360f, 0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
void HandleControllerInput(float dT)
|
|
{
|
|
float axis1 = InputHelper.GetAxis(axisJoystickAxis1);
|
|
float axis2 = InputHelper.GetAxis(axisJoystickAxis2);
|
|
float axis4 = InputHelper.GetAxis(axisJoystickAxis4);
|
|
float axis5 = InputHelper.GetAxis(axisJoystickAxis5);
|
|
int vertical = InputHelper.GetKey(joystickUp, joystickDown);
|
|
bool run = Input.GetKey(KeyCode.JoystickButton8);
|
|
|
|
Vector3 moveDirection = new Vector3
|
|
(
|
|
InputHelper.Remap(axis1, joystickAxisThresholdMin, joystickAxisThresholdMax, joystickMoveSpeedXMin, joystickMoveSpeedXMax),
|
|
vertical * joystickMoveSpeedY,
|
|
InputHelper.Remap(-axis2, joystickAxisThresholdMin, joystickAxisThresholdMax, joystickMoveSpeedZMin, joystickMoveSpeedZMax)
|
|
);
|
|
|
|
Vector3 rotation = new Vector3
|
|
(
|
|
InputHelper.Remap(axis5, joystickAxisThresholdMin, joystickAxisThresholdMax, joystickRotationSpeedMin, joystickRotationSpeedMax),
|
|
InputHelper.Remap(axis4, joystickAxisThresholdMin, joystickAxisThresholdMax, joystickRotationSpeedMin, joystickRotationSpeedMax),
|
|
0f
|
|
);
|
|
|
|
bool anyInput = moveDirection.sqrMagnitude > 0f || rotation.sqrMagnitude > 0f || vertical != 0 || run;
|
|
|
|
// Lock cursor on gamepad input
|
|
if (anyInput)
|
|
{
|
|
Cursor.lockState = CursorLockMode.Locked;
|
|
}
|
|
|
|
float speedMultiplier = run ? 2f : 1f;
|
|
tr.position += tr.TransformDirection(moveDirection * speedMultiplier * dT);
|
|
tr.localEulerAngles += rotation * dT;
|
|
}
|
|
}
|
|
|
|
static public class InputHelper
|
|
{
|
|
//
|
|
static public bool GetKey(KeyCode[] keys)
|
|
{
|
|
if (keys != null)
|
|
{
|
|
for (int i = 0, l = keys.Length; i < l; i++)
|
|
{
|
|
if (Input.GetKey(keys[i])) { return true; }
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//
|
|
static public bool GetKeyDown(KeyCode[] keys)
|
|
{
|
|
if (keys != null)
|
|
{
|
|
for (int i = 0, l = keys.Length; i < l; i++)
|
|
{
|
|
if (Input.GetKeyDown(keys[i])) { return true; }
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//
|
|
static public int GetKey(KeyCode[] keysPositive, KeyCode[] keysNegative)
|
|
{
|
|
int result = 0;
|
|
|
|
if (GetKey(keysPositive)) { result++; }
|
|
if (GetKey(keysNegative)) { result--; }
|
|
|
|
return result;
|
|
}
|
|
|
|
//
|
|
static public int GetKeyDown(KeyCode[] keysPositive, KeyCode[] keysNegative)
|
|
{
|
|
int result = 0;
|
|
|
|
if (GetKeyDown(keysPositive)) { result++; }
|
|
if (GetKeyDown(keysNegative)) { result--; }
|
|
|
|
return result;
|
|
}
|
|
|
|
//
|
|
static public float GetAxis(string axisName)
|
|
{
|
|
if (HasAxis(axisName)) { return Input.GetAxisRaw(axisName); }
|
|
else { return 0f; }
|
|
}
|
|
|
|
// There is currently (Unity 5.5.0f3) no other way in Unity to check if a specific axis is defined in Input Manager settings or not
|
|
static private Dictionary<string, bool> cachedHasAxis = new Dictionary<string, bool>();
|
|
static public bool HasAxis(string axisName)
|
|
{
|
|
bool value;
|
|
if (cachedHasAxis.TryGetValue(axisName, out value))
|
|
{
|
|
return value;
|
|
}
|
|
|
|
try { Input.GetAxisRaw(axisName); }
|
|
catch
|
|
{
|
|
cachedHasAxis.Add(axisName, false);
|
|
return false;
|
|
}
|
|
|
|
// No exception occured - axis defined in Input settings
|
|
cachedHasAxis.Add(axisName, true);
|
|
return true;
|
|
}
|
|
|
|
//
|
|
static public float Remap(float x, float xMin, float xMax, float yMin, float yMax)
|
|
{
|
|
float sign;
|
|
float abs;
|
|
if (x >= 0f)
|
|
{
|
|
sign = 1f;
|
|
abs = x;
|
|
}
|
|
else
|
|
{
|
|
sign = -1f;
|
|
abs = -x;
|
|
}
|
|
|
|
if (abs < xMin) { return 0f; }
|
|
if (abs > xMax) { return xMax; }
|
|
|
|
float t = (abs - xMin) / (xMax - xMin);
|
|
return sign * Mathf.Lerp(yMin, yMax, t);
|
|
}
|
|
}
|
|
} |