-
Notifications
You must be signed in to change notification settings - Fork 19
/
FirstPersonController.cs
153 lines (123 loc) · 4.83 KB
/
FirstPersonController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FirstPersonController : MonoBehaviour
{
// References
[SerializeField] private Transform cameraTransform;
[SerializeField] private CharacterController characterController;
// Player settings
[SerializeField] private float cameraSensitivity;
[SerializeField] private float moveSpeed;
[SerializeField] private float moveInputDeadZone;
// Touch detection
private int leftFingerId, rightFingerId;
private float halfScreenWidth;
// Camera control
private Vector2 lookInput;
private float cameraPitch;
// Player movement
private Vector2 moveTouchStartPosition;
private Vector2 moveInput;
// Start is called before the first frame update
void Start()
{
// id = -1 means the finger is not being tracked
leftFingerId = -1;
rightFingerId = -1;
// only calculate once
halfScreenWidth = Screen.width / 2;
// calculate the movement input dead zone
moveInputDeadZone = Mathf.Pow(Screen.height / moveInputDeadZone, 2);
}
// Update is called once per frame
void Update()
{
// Handles input
GetTouchInput();
if (rightFingerId != -1) {
// Ony look around if the right finger is being tracked
Debug.Log("Rotating");
LookAround();
}
if (leftFingerId != -1)
{
// Ony move if the left finger is being tracked
Debug.Log("Moving");
Move();
}
}
void GetTouchInput() {
// Iterate through all the detected touches
for (int i = 0; i < Input.touchCount; i++)
{
Touch t = Input.GetTouch(i);
// Check each touch's phase
switch (t.phase)
{
case TouchPhase.Began:
if (t.position.x < halfScreenWidth && leftFingerId == -1)
{
// Start tracking the left finger if it was not previously being tracked
leftFingerId = t.fingerId;
// Set the start position for the movement control finger
moveTouchStartPosition = t.position;
}
else if (t.position.x > halfScreenWidth && rightFingerId == -1)
{
// Start tracking the rightfinger if it was not previously being tracked
rightFingerId = t.fingerId;
}
break;
case TouchPhase.Ended:
case TouchPhase.Canceled:
if (t.fingerId == leftFingerId)
{
// Stop tracking the left finger
leftFingerId = -1;
Debug.Log("Stopped tracking left finger");
}
else if (t.fingerId == rightFingerId)
{
// Stop tracking the right finger
rightFingerId = -1;
Debug.Log("Stopped tracking right finger");
}
break;
case TouchPhase.Moved:
// Get input for looking around
if (t.fingerId == rightFingerId)
{
lookInput = t.deltaPosition * cameraSensitivity * Time.deltaTime;
}
else if (t.fingerId == leftFingerId) {
// calculating the position delta from the start position
moveInput = t.position - moveTouchStartPosition;
}
break;
case TouchPhase.Stationary:
// Set the look input to zero if the finger is still
if (t.fingerId == rightFingerId)
{
lookInput = Vector2.zero;
}
break;
}
}
}
void LookAround() {
// vertical (pitch) rotation
cameraPitch = Mathf.Clamp(cameraPitch - lookInput.y, -90f, 90f);
cameraTransform.localRotation = Quaternion.Euler(cameraPitch, 0, 0);
// horizontal (yaw) rotation
transform.Rotate(transform.up, lookInput.x);
}
void Move() {
// Don't move if the touch delta is shorter than the designated dead zone
if (moveInput.sqrMagnitude <= moveInputDeadZone) return;
// Multiply the normalized direction by the speed
Vector2 movementDirection = moveInput.normalized * moveSpeed * Time.deltaTime;
// Move relatively to the local transform's direction
characterController.Move(transform.right * movementDirection.x + transform.forward * movementDirection.y);
}
}