Skip to content

Commit 88feb63

Browse files
committed
working rigidbody character controller. needs lotsa cleanup.
1 parent d922ab5 commit 88feb63

File tree

4 files changed

+269
-16
lines changed

4 files changed

+269
-16
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
using System.Collections.Generic;
2+
using UnityEngine;
3+
4+
namespace ZO {
5+
6+
public class ZOGroundDetector : MonoBehaviour {
7+
8+
public float _maxFloorAngle = 45;
9+
public bool _debug = false;
10+
11+
public float MaxFloorAngle {
12+
get => _maxFloorAngle;
13+
set => _maxFloorAngle = value;
14+
}
15+
16+
public CapsuleCollider CapsuleCollider {
17+
get {
18+
return GetComponent<CapsuleCollider>();
19+
}
20+
}
21+
22+
bool _isGrounded = false;
23+
public bool IsGrounded {
24+
get {
25+
return _isGrounded;
26+
}
27+
private set {
28+
_isGrounded = value;
29+
}
30+
}
31+
32+
Vector3 _groundNormal = -UnityEngine.Physics.gravity.normalized;
33+
public Vector3 GroundNormal {
34+
get => _groundNormal;
35+
private set => _groundNormal = value;
36+
}
37+
38+
Vector3 _groundPoint = Vector3.zero;
39+
public Vector3 GroundPoint {
40+
get => _groundPoint;
41+
private set => _groundPoint = value;
42+
}
43+
44+
// void OnCollisionEnter(Collision collision) {
45+
// IsGrounded = CheckIsGrounded(collision, CapsuleCollider, out _groundNormal);
46+
// }
47+
48+
void OnCollisionStay(Collision collision) {
49+
IsGrounded = CheckIsGrounded(collision);
50+
}
51+
52+
void OnCollisionExit(Collision collision) {
53+
IsGrounded = CheckIsGrounded(collision);
54+
}
55+
56+
bool CheckIsGrounded(Collision collision) {
57+
foreach (ContactPoint contactPoint in collision.contacts) {
58+
// if (contactPoint.thisCollider == capsuleCollider) {
59+
if (MaxFloorAngle > Vector3.Angle(contactPoint.normal, -UnityEngine.Physics.gravity.normalized)) {
60+
GroundNormal = contactPoint.normal;
61+
GroundPoint = contactPoint.point;
62+
63+
// Debug.DrawRay(contactPoint.point, contactPoint.normal * 100, Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f), 3f);
64+
65+
return true;
66+
}
67+
// }
68+
}
69+
70+
GroundNormal = -UnityEngine.Physics.gravity.normalized;
71+
72+
// foreach (var item in collision.contacts) {
73+
// Debug.DrawRay(item.point, item.normal * 100, Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f), 10f);
74+
// }
75+
76+
77+
return false;
78+
}
79+
80+
public void OnGUI() {
81+
if (_debug) {
82+
if (IsGrounded) {
83+
GUI.TextField(new Rect(10, 10, 500, 22), "On Ground");
84+
} else {
85+
GUI.TextField(new Rect(10, 10, 500, 22), "Off Ground");
86+
}
87+
88+
// Draw a different colored ray for every normal in the collision
89+
90+
}
91+
}
92+
93+
94+
}
95+
}

Runtime/Scripts/Controllers/Robots/Spot/ZOGroundDetector.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/Scripts/Controllers/Robots/Spot/ZOSpotCharacterController.cs

Lines changed: 145 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,50 @@ public class ZOSpotCharacterController : MonoBehaviour {
1111

1212
public Rigidbody _rigidBody;
1313
public Transform _frontCollider = null;
14+
15+
public CapsuleCollider FrontColliderCapsule {
16+
get {
17+
return _frontCollider?.GetComponent<CapsuleCollider>();
18+
}
19+
}
20+
21+
public Rigidbody FrontColliderRigidBody {
22+
get {
23+
return _frontCollider?.GetComponent<Rigidbody>();
24+
}
25+
}
26+
27+
public ZOGroundDetector FrontGroundDetector {
28+
get {
29+
return _frontCollider?.GetComponent<ZOGroundDetector>();
30+
}
31+
}
1432
public Transform _rearCollider = null;
33+
public CapsuleCollider RearColliderCapsule {
34+
get {
35+
return _rearCollider?.GetComponent<CapsuleCollider>();
36+
}
37+
}
38+
39+
public ZOGroundDetector RearGroundDetector {
40+
get {
41+
return _rearCollider?.GetComponent<ZOGroundDetector>();
42+
}
43+
}
44+
45+
public Rigidbody RearColliderRigidBody {
46+
get {
47+
return _rearCollider?.GetComponent<Rigidbody>();
48+
}
49+
}
50+
51+
1552
public float _maxFloorAngle = 45;
53+
54+
public float MaxFloorAngle {
55+
get => _maxFloorAngle;
56+
set => _maxFloorAngle = value;
57+
}
1658
public float _maxForwardVelocity = 1.0f;
1759

1860
public float MaxForwardVelocity {
@@ -34,10 +76,41 @@ public float MaxTurnVelocityDegreesSecond {
3476
private Vector2 _targetVelocity = Vector2.zero;
3577
private float _targetTurnVelocityDegreesPerSecond = 0.0f;
3678

79+
private float _lieDownScale = 0.5f;
80+
81+
private bool IsFrontGrounded {
82+
get {
83+
return FrontGroundDetector.IsGrounded;
84+
}
85+
}
86+
87+
private bool IsRearGrounded {
88+
get {
89+
return RearGroundDetector.IsGrounded;
90+
}
91+
}
92+
93+
94+
private Vector3 FrontGroundNormal {
95+
get {
96+
return FrontGroundDetector.GroundNormal;
97+
}
98+
}
99+
100+
101+
private Vector3 RearGroundNormal {
102+
get {
103+
return RearGroundDetector.GroundNormal;
104+
}
105+
}
106+
107+
108+
37109
public enum StateEnum {
38110
Off,
39-
Down,
111+
Sitting,
40112
UpAndReady,
113+
Busy,
41114
Error
42115
}
43116

@@ -60,46 +133,105 @@ public ZOSpotCharacterController.ErrorEnum Error {
60133

61134

62135
public delegate void SpotControllerStatusDelegate(ZOSpotCharacterController thisClass, Vector2 linearVelocity, float turnVelocityDegreesPerSecond, float orientationDegrees, ZOSpotCharacterController.StateEnum state, ZOSpotCharacterController.ErrorEnum error);
63-
private event SpotControllerStatusDelegate _spotContrllerStatusDelegate;
136+
private event SpotControllerStatusDelegate _spotControllerStatusDelegate;
64137
public event SpotControllerStatusDelegate SpotControllerStatus {
65138
add {
66-
_spotContrllerStatusDelegate += value;
139+
_spotControllerStatusDelegate += value;
67140
}
68141
remove {
69-
_spotContrllerStatusDelegate -= value;
142+
_spotControllerStatusDelegate -= value;
70143
}
71144
}
72145

73146

74147

75148
// Start is called before the first frame update
76149
void Start() {
77-
150+
// start sitting down
151+
Sit();
78152
}
79153

80154
// Update is called once per frame
81155
void Update() {
82156

83157
}
84158

159+
160+
85161
void FixedUpdate() {
86162

87-
_rigidBody.velocity = _rigidBody.transform.rotation * new Vector3(_targetVelocity.x, _rigidBody.velocity.y, _targetVelocity.y);
163+
if (IsFrontGrounded || IsRearGrounded) {
164+
165+
Vector3 angularVelocity = _rigidBody.angularVelocity;
166+
float torqueYaw = (_targetTurnVelocityDegreesPerSecond * Mathf.Deg2Rad) - angularVelocity.y;
167+
_rigidBody.AddRelativeTorque(new Vector3(0, torqueYaw, 0), ForceMode.VelocityChange);
88168

89-
Vector3 angularVelocity = _rigidBody.angularVelocity;
90-
angularVelocity.y = _targetTurnVelocityDegreesPerSecond * Mathf.Deg2Rad;
91-
_rigidBody.angularVelocity = angularVelocity;
169+
Vector3 localVelocity = _rigidBody.transform.InverseTransformDirection(_rigidBody.velocity);
170+
Vector3 targetVelocity = new Vector3(_targetVelocity.x, 0, _targetVelocity.y);
171+
Vector3 deltaVelocity = targetVelocity - localVelocity;
172+
deltaVelocity = _rigidBody.transform.TransformDirection(deltaVelocity);
173+
_rigidBody.AddForce(deltaVelocity, ForceMode.VelocityChange);
92174

93-
if (_spotContrllerStatusDelegate != null) {
94-
_spotContrllerStatusDelegate.Invoke(this, new Vector2(_rigidBody.velocity.x, _rigidBody.velocity.z), _rigidBody.angularVelocity.y * Mathf.Rad2Deg, transform.rotation.eulerAngles.y, State, Error);
95175

96176
}
177+
178+
179+
if (_spotControllerStatusDelegate != null) {
180+
_spotControllerStatusDelegate.Invoke(this, new Vector2(_rigidBody.velocity.x, _rigidBody.velocity.z), _rigidBody.angularVelocity.y * Mathf.Rad2Deg, transform.rotation.eulerAngles.y, State, Error);
181+
182+
}
183+
184+
// obey gravity
185+
if (IsFrontGrounded == true) {
186+
Vector3 gravity = -FrontGroundNormal * UnityEngine.Physics.gravity.magnitude * 20.2f;
187+
FrontColliderRigidBody.AddForce(gravity, ForceMode.Acceleration);
188+
} else {
189+
FrontColliderRigidBody.AddForce(UnityEngine.Physics.gravity * 2.2f, ForceMode.Acceleration);
190+
}
191+
192+
if (IsRearGrounded == true) {
193+
Vector3 gravity = -RearGroundNormal * UnityEngine.Physics.gravity.magnitude * 20.2f;
194+
RearColliderRigidBody.AddForce(gravity, ForceMode.Acceleration);
195+
} else {
196+
RearColliderRigidBody.AddForce(UnityEngine.Physics.gravity * 2.2f, ForceMode.Acceleration);
197+
}
198+
199+
// if (IsFrontGrounded == false || IsRearGrounded == false) {
200+
// _rigidBody.AddForce(UnityEngine.Physics.gravity, ForceMode.Acceleration);
201+
// }
202+
203+
}
204+
205+
206+
207+
208+
public void TurnOn() {
209+
210+
}
211+
212+
public void Stand() {
213+
if (State == ZOSpotCharacterController.StateEnum.Sitting) {
214+
FrontColliderCapsule.height = FrontColliderCapsule.height * (1.0f / _lieDownScale);
215+
RearColliderCapsule.height = RearColliderCapsule.height * (1.0f / _lieDownScale);
216+
State = ZOSpotCharacterController.StateEnum.UpAndReady;
217+
}
218+
}
219+
220+
public void Sit() {
221+
if (State == ZOSpotCharacterController.StateEnum.UpAndReady || State == ZOSpotCharacterController.StateEnum.Off) {
222+
FrontColliderCapsule.height = FrontColliderCapsule.height * _lieDownScale;
223+
RearColliderCapsule.height = RearColliderCapsule.height * _lieDownScale;
224+
State = ZOSpotCharacterController.StateEnum.Sitting;
225+
}
226+
97227
}
98228

99229

100230
public void Move(Vector2 targetVelocity, float targetTurnVelocityDegreesPerSecond) {
101-
_targetVelocity = targetVelocity;
102-
_targetTurnVelocityDegreesPerSecond = targetTurnVelocityDegreesPerSecond;
231+
if (State == ZOSpotCharacterController.StateEnum.UpAndReady) {
232+
_targetVelocity = targetVelocity;
233+
_targetTurnVelocityDegreesPerSecond = targetTurnVelocityDegreesPerSecond;
234+
}
103235
}
104236
// void Sit(Delegate OnSitFinishedOrError)
105237
// void Stand(Delegate OnStandFinishedOrError)

Runtime/Scripts/Controllers/Robots/Spot/ZOSpotJoystickCmdVel.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,39 @@
11
using System.Collections;
22
using System.Collections.Generic;
33
using UnityEngine;
4-
54
namespace ZO {
65
public class ZOSpotJoystickCmdVel : MonoBehaviour {
76

87
public ZOSpotCharacterController _spotCharacterController;
98

9+
1010
// Start is called before the first frame update
1111
void Start() {
12-
1312
}
1413

14+
// public void SitCB(InputAction.CallbackContext context) {
15+
// Debug.Log("YO");
16+
// }
17+
1518
// Update is called once per frame
16-
void Update() {
19+
void FixedUpdate() {
20+
21+
if (Input.GetAxis("Sit") > 0) {
22+
Debug.Log("INFO: Sit");
23+
_spotCharacterController.Sit();
24+
}
25+
26+
if (Input.GetButtonDown("Stand") == true) {
27+
Debug.Log("INFO: Stand");
28+
_spotCharacterController.Stand();
29+
}
30+
1731

1832
if (_spotCharacterController != null) {
1933
Vector2 targetVelocity = new Vector2(Input.GetAxis("Roll") * _spotCharacterController.MaxSideMoveVelocity, Input.GetAxis("Pitch") * _spotCharacterController.MaxForwardVelocity);
2034
_spotCharacterController.Move(targetVelocity, Input.GetAxis("Yaw") * _spotCharacterController._maxTurnVelocityDegreesSecond); // hack no turning yet
2135

36+
2237
}
2338

2439
}

0 commit comments

Comments
 (0)