VR Development Framework
v 1.0.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties Events Pages
AVR_PlayerRig.cs
1 using System.Collections;
2 using System.Collections.Generic;
3 using UnityEngine;
4 
5 #if AVR_NET
6 using Unity.Netcode;
7 #endif
8 
9 namespace AVR.Core {
10  /// <summary>
11  /// Represents the players VR setup. Only one instance at a time is allowed.
12  /// </summary>
13  [AVR.Core.Attributes.DocumentationUrl("class_a_v_r_1_1_core_1_1_a_v_r___player_rig.html")]
14  public class AVR_PlayerRig : AVR_SingletonComponent<AVR_PlayerRig>
15  {
16  private Vector3 _RigPosInWorldSpace =>
17 #if AVR_NET
18  !IsOwner? m_ReplicatedState.Value.rigPos :
19 #endif
20  this.transform.position;
21 
22  private Quaternion _RigRotInWorldSpace =>
23 #if AVR_NET
24  !IsOwner ? m_ReplicatedState.Value.rigRot :
25 #endif
26  this.transform.rotation;
27 
28  private Vector3 _CameraPosInWorldSpace =>
29 #if AVR_NET
30  !IsOwner ? m_ReplicatedState.Value.camPos :
31 #endif
32  this.MainCamera.transform.position;
33 
34  private Quaternion _CameraRotInWorldSpace =>
35 #if AVR_NET
36  !IsOwner ? m_ReplicatedState.Value.camRot :
37 #endif
38  this.MainCamera.transform.rotation;
39 
40  /// <summary>
41  /// Average motion of the players feet over the last 0.5s.
42  /// </summary>
43  public Vector3 AvgMotion {
44  get { return _motion; }
45  }
46  private Vector3 _motion = Vector3.zero;
47  private Vector3 _lastFPos;
48 
49  /// <summary>
50  /// Camera that represents the HMD
51  /// </summary>
52  public Camera MainCamera;
53 
54  /// <summary>
55  /// CharacterController represeting the player. Null if no charactercontroller is present.
56  /// </summary>
57  public CharacterController characterController {
58  get { return _characterController; }
59  }
60  private CharacterController _characterController;
61 
62  // -------------------------- RIG ----------------------------
63  /// <summary>
64  /// Player Rig location in world space
65  /// </summary>
66  public Vector3 RigInWorldSpace {
67  get { return _RigPosInWorldSpace; }
68  }
69 
70  /// <summary>
71  /// Player rig rotation in world space
72  /// </summary>
73  public Quaternion RigRotationInWorldSpace
74  {
75  get { return _RigRotInWorldSpace; }
76  }
77 
78  /// <summary>
79  /// Player camera in world space
80  /// </summary>
81  public Vector3 CameraInWorldSpace {
82  get { return _CameraPosInWorldSpace; }
83  }
84 
85  /// <summary>
86  /// Camera rotation in world space
87  /// </summary>
88  public Quaternion CameraRotationInWorldSpace
89  {
90  get { return _CameraRotInWorldSpace; }
91  }
92 
93  /// <summary>
94  /// View-vector in local coordinates relative to the camera
95  /// </summary>
96  public Vector3 LocalViewVector {
97  get { return MainCamera.transform.InverseTransformDirection(MainCamera.transform.forward); }
98  }
99 
100  /// <summary>
101  /// View-vector in world space
102  /// </summary>
103  public Vector3 ViewVector {
104  get { return MainCamera.transform.forward; }
105  }
106 
107  /// <summary>
108  /// Position of the cameras view-vector tip in world space
109  /// </summary>
110  public Vector3 ViewPos
111  {
112  get { return MainCamera.transform.position + MainCamera.transform.forward; }
113  }
114 
115  /// <summary>
116  /// Returns a vector in the XZ plane that corresponds to the direction the player is facing with his body.
117  /// This is NOT equivalent with the facing direction of the camera. (For instance when the player bows or leans backward.)
118  /// </summary>
119  public Vector3 XZPlaneFacingDirection {
120  get { Vector3 tf = Vector3.Cross(MainCamera.transform.right, Vector3.up); tf.y = 0; return tf; }
121  }
122 
123  /// <summary>
124  /// Player camera in local space (relative to the AVR_PlayerRig object)
125  /// </summary>
126  public Vector3 CameraInRigSpace {
127  get { return transform.InverseTransformPoint(MainCamera.transform.position); }
128  }
129 
130  /// <summary>
131  /// Height of the camera in local space. Equivalent to the distance between HMD from the gorund.
132  /// </summary>
133  public float CameraHeightInRigSpace {
134  get { return CameraInWorldSpace.y - RigInWorldSpace.y; }
135  }
136 
137  /// <summary>
138  /// Position on the gorund directly underneath the camera. (World space)
139  /// </summary>
140  public Vector3 FeetInWorldSpace {
141  get { return CameraInWorldSpace - transform.up*CameraHeightInRigSpace; }
142  }
143 
144  /// <summary>
145  /// Position on the gorund directly underneath the camera. (local space, relative to AVR_PlayerRig object)
146  /// </summary>
147  public Vector3 FeetInRigSpace {
148  get { return transform.InverseTransformPoint(FeetInWorldSpace); }
149  }
150 
151  /// <summary>
152  /// Instantly moves the PlayerRig so that the players feet (anchor) end up at world coordinates 'pos'
153  /// </summary>
154  public void MoveRigToFeetPosition(Vector3 pos, bool affectMotion=true) {
155  transform.position = (pos + (RigInWorldSpace - FeetInWorldSpace));
156  if(!affectMotion) _lastFPos = pos;
157  }
158 
159  /// <summary>
160  /// Instantly moves the PlayerRig to a given location
161  /// </summary>
162  public void MoveRigToPosition(Vector3 pos, bool affectMotion=true) {
163  transform.position = pos;
164  if(!affectMotion) _lastFPos = FeetInWorldSpace;
165  }
166 
167  /// <summary>
168  /// Instantly moves the PlayerRig so that the camera ends up at world coordinates 'pos'
169  /// </summary>
170  public void MoveRigToCameraPosition(Vector3 pos, bool affectMotion=true) {
171  transform.position += (pos - CameraInWorldSpace);
172  if(!affectMotion) _lastFPos = FeetInWorldSpace;
173  }
174 
175  /// <summary>
176  /// Returns true if the player is crouching / crawling. Uses the "/settings/calibration/player_height" setting to determine this.
177  /// </summary>
178  public bool isCrouching()
179  {
180  float val1 = CameraHeightInRigSpace;
181  float hf = AVR_Settings.get_float("/settings/calibration/player_height");
182 
183  if (leftHandController && rightHandController)
184  {
185  float val2 = 0.5f * ((leftHandController.transform.position.y - transform.position.y) + (rightHandController.transform.position.y - transform.position.y));
186  return val1 < 0.72f * hf || val2 < 0.36f * hf;
187  }
188  return val1 < hf;
189  }
190 
191  /// <summary>
192  /// Returns true if the player is leaning forwards / bowing.
193  /// </summary>
194  public bool isLeaningForwards()
195  {
196  return MainCamera.transform.rotation.eulerAngles.x > 55.0f && MainCamera.transform.rotation.eulerAngles.x < 120.0f;
197  }
198 
199  /// <summary>
200  /// Returns a confidence value of how much the player is leaning forwards / bowing.
201  /// </summary>
203  {
204  return Mathf.Clamp((MainCamera.transform.rotation.eulerAngles.x - 40.0f) / 30.0f, 0.0f, 1.0f);
205  }
206 
207  /// <summary>
208  /// Returns the AVR_Controller that represents the left hand controller (if it exists). This value depends on the controllerNode value and is not updated if this one is changed during runtime.
209  /// </summary>
210  public AVR_Controller leftHandController => AVR_Controller.leftHandController;
211 
212  /// <summary>
213  /// Returns the AVR_Controller that represents the right hand controller (if it exists). This value depends on the controllerNode value and is not updated if this one is changed during runtime.
214  /// </summary>
215  public AVR_Controller rightHandController => AVR_Controller.rightHandController;
216 
217  protected override void Start() {
218  base.Start();
219 
220  _characterController = GetComponent<CharacterController>();
221  if (characterController)
222  {
223  AVR_DevConsole.print(gameObject.name + " got CharacterController.");
224  }
225 
226  if(!MainCamera) MainCamera = Camera.main;
227  if(!MainCamera) AVR_DevConsole.cerror("The MainCamera property is not set and there is no Camera.main component in the scene!", this);
228  }
229 
230  protected void LateUpdate() {
231  Vector3.SmoothDamp(_motion, (FeetInWorldSpace - _lastFPos) / Time.deltaTime, ref _motion, 0.5f);
232  _lastFPos = FeetInWorldSpace;
233  }
234 
235  protected void Update() {
236  if(characterController) {
237  // Set charactercontroller height based on camera height
238  characterController.height = Mathf.Clamp(AVR_PlayerRig.Instance.CameraHeightInRigSpace, AVR_Settings.get_float("/settings/core/charactercontroller/min_height"), AVR_Settings.get_float("/settings/core/charactercontroller/max_height"));
239 
240  // Set charactercontroller center to camera position in rig space. NOTE: This assumes that this.transform.pos is
241  // the same as rig.position. Eg. transform.localPosition = Vector3.zero.
242  Vector3 center = CameraInRigSpace;
243  center.y = characterController.skinWidth + (characterController.height * 0.5f);
244  characterController.center = center;
245  }
246  }
247 
248 #if AVR_NET
249  [HideInInspector]
251  public bool synchronizeRigPositions = false;
252 
253  [ServerRpc(RequireOwnership = false)]
254  private void syncServerRpc(InternalState state)
255  {
256  m_ReplicatedState.Value = state;
257  }
258 
259  private void sync()
260  {
261  if (IsOwner)
262  {
263  InternalState state = new InternalState();
264  state.FromReference(this);
265  }
266  else
267  {
268  m_ReplicatedState.Value.ApplyState(this);
269  }
270  }
271 
272  private readonly NetworkVariable<InternalState> m_ReplicatedState = new NetworkVariable<InternalState>(NetworkVariableReadPermission.Everyone, new InternalState());
273 
274  private struct InternalState : IInternalState<AVR_PlayerRig>
275  {
276  public Vector3 rigPos;
277  public Quaternion rigRot;
278  public Vector3 camPos;
279  public Quaternion camRot;
280 
281  public void FromReference(AVR_PlayerRig reference)
282  {
283  rigPos = reference.RigInWorldSpace;
284  rigRot = reference.RigRotationInWorldSpace;
285  camPos = reference.CameraInWorldSpace;
286  camRot = reference.CameraRotationInWorldSpace;
287  }
288 
289  public void ApplyState(AVR_PlayerRig reference)
290  {
291 
292  }
293 
294  public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
295  {
296  serializer.SerializeValue(ref rigPos);
297  serializer.SerializeValue(ref rigRot);
298  serializer.SerializeValue(ref camPos);
299  serializer.SerializeValue(ref camRot);
300  }
301  }
302 #endif
303  }
304 }
CharacterController _characterController
void MoveRigToCameraPosition(Vector3 pos, bool affectMotion=true)
Instantly moves the PlayerRig so that the camera ends up at world coordinates 'pos' ...
Camera MainCamera
Camera that represents the HMD
Represents the players VR setup. Only one instance at a time is allowed.
Represents a VR controller. Provides functionality for spacial tracking and haptic feedback...
void MoveRigToPosition(Vector3 pos, bool affectMotion=true)
Instantly moves the PlayerRig to a given location
Contains constan values, settings etc. which can all be set through *.avr files. Duplicate settings w...
Definition: AVR_Settings.cs:14
bool isCrouching()
Returns true if the player is crouching / crawling. Uses the "/settings/calibration/player_height" se...
bool isLeaningForwards()
Returns true if the player is leaning forwards / bowing.
Makes a property of an object only show in the Network-behaviour window. Also works for private/prote...
static float get_float(string token)
Get a registered setting of the type float.
Sets the documentation html file inside of Packages/com.avr.core/Documentation/html of a given class...
float isLeaningForwardsConfidence()
Returns a confidence value of how much the player is leaning forwards / bowing.
void MoveRigToFeetPosition(Vector3 pos, bool affectMotion=true)
Instantly moves the PlayerRig so that the players feet (anchor) end up at world coordinates 'pos' ...
override void Start()